Commit 77aa6cbf authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Linus Torvalds

[PATCH] cleanup virtual console <-> selection.c interface

Pass around pointers instead of indices into a global array between various
files of the virtual console implementation and stop using obsfucting
macros that expect certain variables to be in scope.

This is a first step to get rid of the various global arrays in the VC
code.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent cd3ae7b3
......@@ -33,7 +33,7 @@ extern void poke_blanked_console(void);
/* Variables for selection control. */
/* Use a dynamic buffer, instead of static (Dec 1994) */
int sel_cons; /* must not be disallocated */
struct vc_data *sel_cons; /* must not be disallocated */
static volatile int sel_start = -1; /* cleared by clear_selection */
static int sel_end;
static int sel_buffer_lth;
......@@ -44,20 +44,22 @@ static char *sel_buffer;
/* set reverse video on characters s-e of console with selection. */
inline static void
highlight(const int s, const int e) {
highlight(const int s, const int e)
{
invert_screen(sel_cons, s, e-s+2, 1);
}
/* use complementary color to show the pointer */
inline static void
highlight_pointer(const int where) {
highlight_pointer(const int where)
{
complement_pos(sel_cons, where);
}
static unsigned char
sel_pos(int n)
{
return inverse_translate(vc_cons[sel_cons].d, screen_glyph(sel_cons, n));
return inverse_translate(sel_cons, screen_glyph(sel_cons, n));
}
/* remove the current selection highlight, if any,
......@@ -111,10 +113,10 @@ static inline unsigned short limit(const unsigned short v, const unsigned short
/* set the current selection. Invoked by ioctl() or by kernel code. */
int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
{
struct vc_data *vc = vc_cons[fg_console].d;
int sel_mode, new_sel_start, new_sel_end, spc;
char *bp, *obp;
int i, ps, pe;
unsigned int currcons = fg_console;
poke_blanked_console();
......@@ -128,12 +130,12 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
__get_user(ye, &sel->ye);
__get_user(sel_mode, &sel->sel_mode);
xs--; ys--; xe--; ye--;
xs = limit(xs, video_num_columns - 1);
ys = limit(ys, video_num_lines - 1);
xe = limit(xe, video_num_columns - 1);
ye = limit(ye, video_num_lines - 1);
ps = ys * video_size_row + (xs << 1);
pe = ye * video_size_row + (xe << 1);
xs = limit(xs, vc->vc_cols - 1);
ys = limit(ys, vc->vc_rows - 1);
xe = limit(xe, vc->vc_cols - 1);
ye = limit(ye, vc->vc_rows - 1);
ps = ys * vc->vc_size_row + (xs << 1);
pe = ye * vc->vc_size_row + (xe << 1);
if (sel_mode == TIOCL_SELCLEAR) {
/* useful for screendump without selection highlights */
......@@ -154,9 +156,9 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
pe = tmp;
}
if (sel_cons != fg_console) {
if (sel_cons != vc_cons[fg_console].d) {
clear_selection();
sel_cons = fg_console;
sel_cons = vc_cons[fg_console].d;
}
switch (sel_mode)
......@@ -173,7 +175,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
(!spc && !inword(sel_pos(ps))))
break;
new_sel_start = ps;
if (!(ps % video_size_row))
if (!(ps % vc->vc_size_row))
break;
}
spc = isspace(sel_pos(pe));
......@@ -183,14 +185,14 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
(!spc && !inword(sel_pos(pe))))
break;
new_sel_end = pe;
if (!((pe + 2) % video_size_row))
if (!((pe + 2) % vc->vc_size_row))
break;
}
break;
case TIOCL_SELLINE: /* line-by-line selection */
new_sel_start = ps - ps % video_size_row;
new_sel_end = pe + video_size_row
- pe % video_size_row - 2;
new_sel_start = ps - ps % vc->vc_size_row;
new_sel_end = pe + vc->vc_size_row
- pe % vc->vc_size_row - 2;
break;
case TIOCL_SELPOINTER:
highlight_pointer(pe);
......@@ -204,11 +206,11 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
/* select to end of line if on trailing space */
if (new_sel_end > new_sel_start &&
!atedge(new_sel_end, video_size_row) &&
!atedge(new_sel_end, vc->vc_size_row) &&
isspace(sel_pos(new_sel_end))) {
for (pe = new_sel_end + 2; ; pe += 2)
if (!isspace(sel_pos(pe)) ||
atedge(pe, video_size_row))
atedge(pe, vc->vc_size_row))
break;
if (isspace(sel_pos(pe)))
new_sel_end = pe;
......@@ -255,7 +257,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
*bp = sel_pos(i);
if (!isspace(*bp++))
obp = bp;
if (! ((i + 2) % video_size_row)) {
if (! ((i + 2) % vc->vc_size_row)) {
/* strip trailing blanks from line and add newline,
unless non-space at end of line. */
if (obp != bp) {
......
......@@ -59,7 +59,7 @@ vcs_size(struct inode *inode)
if (!vc_cons_allocated(currcons))
return -ENXIO;
size = video_num_lines * video_num_columns;
size = vc_cons[currcons].d->vc_rows * vc_cons[currcons].d->vc_cols;
if (minor & 128)
size = 2*size + HEADER_SIZE;
......@@ -99,6 +99,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode;
unsigned int currcons = iminor(inode);
struct vc_data *vc;
long pos;
long viewed, attr, read;
int col, maxcol;
......@@ -126,6 +127,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
ret = -ENXIO;
if (!vc_cons_allocated(currcons))
goto unlock_out;
vc = vc_cons[currcons].d;
ret = -EINVAL;
if (pos < 0)
......@@ -159,15 +161,15 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
con_buf_start = con_buf0 = con_buf;
orig_count = this_round;
maxcol = video_num_columns;
maxcol = vc->vc_cols;
if (!attr) {
org = screen_pos(currcons, p, viewed);
org = screen_pos(vc, p, viewed);
col = p % maxcol;
p += maxcol - col;
while (this_round-- > 0) {
*con_buf0++ = (vcs_scr_readw(currcons, org++) & 0xff);
*con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff);
if (++col == maxcol) {
org = screen_pos(currcons, p, viewed);
org = screen_pos(vc, p, viewed);
col = 0;
p += maxcol;
}
......@@ -176,9 +178,9 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
if (p < HEADER_SIZE) {
size_t tmp_count;
con_buf0[0] = (char) video_num_lines;
con_buf0[1] = (char) video_num_columns;
getconsxy(currcons, con_buf0 + 2);
con_buf0[0] = (char)vc->vc_rows;
con_buf0[1] = (char)vc->vc_cols;
getconsxy(vc, con_buf0 + 2);
con_buf_start += p;
this_round += p;
......@@ -214,7 +216,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
p /= 2;
col = p % maxcol;
org = screen_pos(currcons, p, viewed);
org = screen_pos(vc, p, viewed);
p += maxcol - col;
/* Buffer has even length, so we can always copy
......@@ -224,10 +226,10 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
this_round = (this_round + 1) >> 1;
while (this_round) {
*tmp_buf++ = vcs_scr_readw(currcons, org++);
*tmp_buf++ = vcs_scr_readw(vc, org++);
this_round --;
if (++col == maxcol) {
org = screen_pos(currcons, p, viewed);
org = screen_pos(vc, p, viewed);
col = 0;
p += maxcol;
}
......@@ -270,6 +272,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode;
unsigned int currcons = iminor(inode);
struct vc_data *vc;
long pos;
long viewed, attr, size, written;
char *con_buf0;
......@@ -299,6 +302,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
ret = -ENXIO;
if (!vc_cons_allocated(currcons))
goto unlock_out;
vc = vc_cons[currcons].d;
size = vcs_size(inode);
ret = -EINVAL;
......@@ -351,10 +355,10 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
con_buf0 = con_buf;
orig_count = this_round;
maxcol = video_num_columns;
maxcol = vc->vc_cols;
p = pos;
if (!attr) {
org0 = org = screen_pos(currcons, p, viewed);
org0 = org = screen_pos(vc, p, viewed);
col = p % maxcol;
p += maxcol - col;
......@@ -362,11 +366,11 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
unsigned char c = *con_buf0++;
this_round--;
vcs_scr_writew(currcons,
(vcs_scr_readw(currcons, org) & 0xff00) | c, org);
vcs_scr_writew(vc,
(vcs_scr_readw(vc, org) & 0xff00) | c, org);
org++;
if (++col == maxcol) {
org = screen_pos(currcons, p, viewed);
org = screen_pos(vc, p, viewed);
col = 0;
p += maxcol;
}
......@@ -375,34 +379,34 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
if (p < HEADER_SIZE) {
char header[HEADER_SIZE];
getconsxy(currcons, header + 2);
getconsxy(vc, header + 2);
while (p < HEADER_SIZE && this_round > 0) {
this_round--;
header[p++] = *con_buf0++;
}
if (!viewed)
putconsxy(currcons, header + 2);
putconsxy(vc, header + 2);
}
p -= HEADER_SIZE;
col = (p/2) % maxcol;
if (this_round > 0) {
org0 = org = screen_pos(currcons, p/2, viewed);
org0 = org = screen_pos(vc, p/2, viewed);
if ((p & 1) && this_round > 0) {
char c;
this_round--;
c = *con_buf0++;
#ifdef __BIG_ENDIAN
vcs_scr_writew(currcons, c |
(vcs_scr_readw(currcons, org) & 0xff00), org);
vcs_scr_writew(vc, c |
(vcs_scr_readw(vc, org) & 0xff00), org);
#else
vcs_scr_writew(currcons, (c << 8) |
(vcs_scr_readw(currcons, org) & 0xff), org);
vcs_scr_writew(vc, (c << 8) |
(vcs_scr_readw(vc, org) & 0xff), org);
#endif
org++;
p++;
if (++col == maxcol) {
org = screen_pos(currcons, p/2, viewed);
org = screen_pos(vc, p/2, viewed);
col = 0;
}
}
......@@ -413,11 +417,11 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
unsigned short w;
w = get_unaligned(((const unsigned short *)con_buf0));
vcs_scr_writew(currcons, w, org++);
vcs_scr_writew(vc, w, org++);
con_buf0 += 2;
this_round -= 2;
if (++col == maxcol) {
org = screen_pos(currcons, p, viewed);
org = screen_pos(vc, p, viewed);
col = 0;
p += maxcol;
}
......@@ -427,9 +431,9 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
c = *con_buf0++;
#ifdef __BIG_ENDIAN
vcs_scr_writew(currcons, (vcs_scr_readw(currcons, org) & 0xff) | (c << 8), org);
vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org);
#else
vcs_scr_writew(currcons, (vcs_scr_readw(currcons, org) & 0xff00) | c, org);
vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org);
#endif
}
}
......
This diff is collapsed.
......@@ -37,7 +37,7 @@ char vt_dont_switch;
extern struct tty_driver *console_driver;
#define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count)
#define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || i == sel_cons)
#define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
/*
* Console (vt and kd) routines, as defined by USL SVR4 manual, and by
......
......@@ -9,6 +9,8 @@
* to achieve effects such as fast scrolling by changing the origin.
*/
struct vt_struct;
#define NPAR 16
struct vc_data {
......@@ -87,6 +89,7 @@ struct vc_data {
struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */
unsigned long vc_uni_pagedir;
unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
struct vt_struct *vc_vt;
/* additional information is in vt_kern.h */
};
......
......@@ -10,7 +10,7 @@
#include <linux/tiocl.h>
#include <linux/vt_buffer.h>
extern int sel_cons;
extern struct vc_data *sel_cons;
extern void clear_selection(void);
extern int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty);
......@@ -19,11 +19,6 @@ extern int sel_loadlut(char __user *p);
extern int mouse_reporting(void);
extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
#define video_num_columns (vc_cons[currcons].d->vc_cols)
#define video_num_lines (vc_cons[currcons].d->vc_rows)
#define video_size_row (vc_cons[currcons].d->vc_size_row)
#define can_do_color (vc_cons[currcons].d->vc_can_do_color)
extern int console_blanked;
extern unsigned char color_table[];
......@@ -31,15 +26,15 @@ extern int default_red[];
extern int default_grn[];
extern int default_blu[];
extern unsigned short *screen_pos(int currcons, int w_offset, int viewed);
extern u16 screen_glyph(int currcons, int offset);
extern void complement_pos(int currcons, int offset);
extern void invert_screen(int currcons, int offset, int count, int shift);
extern unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed);
extern u16 screen_glyph(struct vc_data *vc, int offset);
extern void complement_pos(struct vc_data *vc, int offset);
extern void invert_screen(struct vc_data *vc, int offset, int count, int shift);
extern void getconsxy(int currcons, unsigned char *p);
extern void putconsxy(int currcons, unsigned char *p);
extern void getconsxy(struct vc_data *vc, unsigned char *p);
extern void putconsxy(struct vc_data *vc, unsigned char *p);
extern u16 vcs_scr_readw(int currcons, const u16 *org);
extern void vcs_scr_writew(int currcons, u16 val, u16 *org);
extern u16 vcs_scr_readw(struct vc_data *vc, const u16 *org);
extern void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment