summaryrefslogtreecommitdiffstats
path: root/drivers/char/vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/vt.c')
-rw-r--r--drivers/char/vt.c288
1 files changed, 169 insertions, 119 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 360ca915f..01c973576 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -22,6 +22,7 @@
#include <linux/malloc.h>
#include <linux/major.h>
#include <linux/fs.h>
+#include <linux/config.h>
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -31,6 +32,10 @@
#include <linux/kbd_diacr.h>
#include <linux/selection.h>
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <asm/vc_ioctl.h>
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
char vt_dont_switch = 0;
extern struct tty_driver console_driver;
@@ -56,39 +61,9 @@ struct vt_struct *vt_cons[MAX_NR_CONSOLES];
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
#endif
-extern int getkeycode(unsigned int scancode);
-extern int setkeycode(unsigned int scancode, unsigned int keycode);
-extern void compute_shiftstate(void);
-extern void complete_change_console(unsigned int new_console);
-extern int vt_waitactive(int vt);
-extern void do_blank_screen(int nopowersave);
-
-extern unsigned int keymap_count;
-
-/*
- * routines to load custom translation table, EGA/VGA font and
- * VGA colour palette from console.c
- */
-extern int con_set_trans_old(unsigned char * table);
-extern int con_get_trans_old(unsigned char * table);
-extern int con_set_trans_new(unsigned short * table);
-extern int con_get_trans_new(unsigned short * table);
-extern void con_clear_unimap(struct unimapinit *ui);
-extern int con_set_unimap(ushort ct, struct unipair *list);
-extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
-extern void con_set_default_unimap(void);
-extern int con_set_font(char * fontmap, int ch512);
-extern int con_get_font(char * fontmap);
-extern int con_set_cmap(unsigned char *cmap);
-extern int con_get_cmap(unsigned char *cmap);
-extern void reset_palette(int currcons);
-extern void set_palette(void) ;
-extern int con_adjust_height(unsigned long fontheight);
-
-extern int video_mode_512ch;
-extern unsigned long video_font_height;
-extern unsigned long default_font_height;
-extern unsigned long video_scan_lines;
+unsigned int video_font_height;
+unsigned int default_font_height;
+unsigned int video_scan_lines;
/*
* these are the valid i/o ports we're allowed to change. they map all the
@@ -138,20 +113,19 @@ kd_size_changed(int row, int col)
}
/*
- * Generates sound of some count for some number of clock ticks
- * [count = 1193180 / frequency]
+ * Generates sound of some frequency for some number of clock ticks
*
* If freq is 0, will turn off sound, else will turn it on for that time.
* If msec is 0, will return immediately, else will sleep for msec time, then
* turn sound off.
*
- * We use the BEEP_TIMER vector since we're using the same method to
- * generate sound, and we'll overwrite any beep in progress. That may
- * be something to fix later, if we like.
- *
* We also return immediately, which is what was implied within the X
* comments - KDMKTONE doesn't put the process to sleep.
*/
+
+#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__)
+ || (defined(__mips__) && !defined(CONFIG_SGI))
+
static void
kd_nosound(unsigned long ignored)
{
@@ -192,13 +166,17 @@ _kd_mksound(unsigned int hz, unsigned int ticks)
return;
}
-#ifdef CONFIG_SGI
-void _kd_nullsound(unsigned int hz, unsigned int ticks) { }
-void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_nullsound;
#else
-void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
+
+void
+_kd_mksound(unsigned int hz, unsigned int ticks)
+{
+}
+
#endif
+void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
+
#define i (tmp.kb_index)
#define s (tmp.kb_table)
@@ -247,9 +225,12 @@ do_kdsk_ioctl(int cmd, struct kbentry *user_kbe, int perm, struct kbd_struct *kb
if (kbd->kbdmode != VC_UNICODE)
return -EINVAL;
+ /* ++Geert: non-PC keyboards may generate keycode zero */
+#if !defined(__mc68000__) && !defined(__powerpc__)
/* assignment to entry 0 only tests validity of args */
if (!i)
break;
+#endif
if (!(key_map = key_maps[s])) {
int j;
@@ -401,44 +382,42 @@ do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
static inline int
do_fontx_ioctl(int cmd, struct consolefontdesc *user_cfd, int perm)
{
- int nchar;
struct consolefontdesc cfdarg;
- int i = 0;
+ struct console_font_op op;
+ int i;
if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc)))
return -EFAULT;
- if (vt_cons[fg_console]->vc_mode != KD_TEXT)
- return -EINVAL;
switch (cmd) {
case PIO_FONTX:
if (!perm)
return -EPERM;
- if ( cfdarg.charcount == 256 ||
- cfdarg.charcount == 512 ) {
- i = con_set_font(cfdarg.chardata,
- cfdarg.charcount == 512);
- if (i)
- return i;
- i = con_adjust_height(cfdarg.charheight);
- return (i <= 0) ? i : kd_size_changed(i, 0);
- } else
- return -EINVAL;
- case GIO_FONTX:
- i = cfdarg.charcount;
- cfdarg.charcount = nchar = video_mode_512ch ? 512 : 256;
- cfdarg.charheight = video_font_height;
- __copy_to_user(user_cfd, &cfdarg,
- sizeof(struct consolefontdesc));
- if ( cfdarg.chardata )
- {
- if ( i < nchar )
- return -ENOMEM;
- return con_get_font(cfdarg.chardata);
- } else
- return 0;
+ op.op = KD_FONT_OP_SET;
+ op.flags = KD_FONT_FLAG_OLD;
+ op.width = 8;
+ op.height = cfdarg.charheight;
+ op.charcount = cfdarg.charcount;
+ op.data = cfdarg.chardata;
+ return con_font_op(fg_console, &op);
+ case GIO_FONTX: {
+ op.op = KD_FONT_OP_GET;
+ op.flags = KD_FONT_FLAG_OLD;
+ op.width = 8;
+ op.height = cfdarg.charheight;
+ op.charcount = cfdarg.charcount;
+ op.data = cfdarg.chardata;
+ i = con_font_op(fg_console, &op);
+ if (i)
+ return i;
+ cfdarg.charheight = op.height;
+ cfdarg.charcount = op.charcount;
+ if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
+ return -EFAULT;
+ return 0;
+ }
}
- return 0;
+ return -EINVAL;
}
static inline int
@@ -458,9 +437,9 @@ do_unimap_ioctl(int cmd, struct unimapdesc *user_ud,int perm)
case PIO_UNIMAP:
if (!perm)
return -EPERM;
- return con_set_unimap(tmp.entry_ct, tmp.entries);
+ return con_set_unimap(fg_console, tmp.entry_ct, tmp.entries);
case GIO_UNIMAP:
- return con_get_unimap(tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
+ return con_get_unimap(fg_console, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
}
return 0;
}
@@ -803,7 +782,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (arg == 0 || arg > MAX_NR_CONSOLES)
return -ENXIO;
arg--;
- i = vc_allocate(arg);
+ i = vc_allocate(arg, 0);
if (i)
return i;
set_console(arg);
@@ -855,7 +834,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
*/
int newvt = vt_cons[console]->vt_newvt;
vt_cons[console]->vt_newvt = -1;
- i = vc_allocate(newvt);
+ i = vc_allocate(newvt, 0);
if (i)
return i;
/*
@@ -915,7 +894,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return i;
__get_user(ll, &vtsizes->v_rows);
__get_user(cc, &vtsizes->v_cols);
- i = vc_resize(ll, cc);
+ i = vc_resize_all(ll, cc);
return i ? i : kd_size_changed(ll, cc);
}
@@ -964,7 +943,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if ( clin )
video_font_height = clin;
- i = vc_resize(ll, cc);
+ i = vc_resize_all(ll, cc);
if (i)
return i;
@@ -972,30 +951,37 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return 0;
}
- case PIO_FONT:
+ case PIO_FONT: {
+ struct console_font_op op;
if (!perm)
return -EPERM;
- if (vt_cons[fg_console]->vc_mode != KD_TEXT)
- return -EINVAL;
- return con_set_font((char *)arg, 0);
- /* con_set_font() defined in console.c */
+ op.op = KD_FONT_OP_SET;
+ op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
+ op.width = 8;
+ op.height = 0;
+ op.charcount = 256;
+ op.data = (char *) arg;
+ return con_font_op(fg_console, &op);
+ }
- case GIO_FONT:
- if (vt_cons[fg_console]->vc_mode != KD_TEXT ||
- video_mode_512ch)
- return -EINVAL;
- return con_get_font((char *)arg);
- /* con_get_font() defined in console.c */
+ case GIO_FONT: {
+ struct console_font_op op;
+ op.op = KD_FONT_OP_GET;
+ op.flags = KD_FONT_FLAG_OLD;
+ op.width = 8;
+ op.height = 32;
+ op.charcount = 256;
+ op.data = (char *) arg;
+ return con_font_op(fg_console, &op);
+ }
case PIO_CMAP:
if (!perm)
return -EPERM;
return con_set_cmap((char *)arg);
- /* con_set_cmap() defined in console.c */
case GIO_CMAP:
return con_get_cmap((char *)arg);
- /* con_get_cmap() defined in console.c */
case PIO_FONTX:
case GIO_FONTX:
@@ -1005,26 +991,37 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
{
if (!perm)
return -EPERM;
- if (vt_cons[fg_console]->vc_mode != KD_TEXT)
- return -EINVAL;
#ifdef BROKEN_GRAPHICS_PROGRAMS
/* With BROKEN_GRAPHICS_PROGRAMS defined, the default
font is not saved. */
return -ENOSYS;
#else
-
- i = con_set_font(NULL, 0); /* Set font to default */
+ {
+ struct console_font_op op;
+ op.op = KD_FONT_OP_SET_DEFAULT;
+ op.data = NULL;
+ i = con_font_op(fg_console, &op);
if (i) return i;
-
- i = con_adjust_height(default_font_height);
- if ( i > 0 ) kd_size_changed(i, 0);
- con_set_default_unimap();
-
+ con_set_default_unimap(fg_console);
return 0;
+ }
#endif
}
+ case KDFONTOP: {
+ struct console_font_op op;
+ if (copy_from_user(&op, (void *) arg, sizeof(op)))
+ return -EFAULT;
+ if (!perm && op.op != KD_FONT_OP_GET)
+ return -EPERM;
+ i = con_font_op(console, &op);
+ if (i) return i;
+ if (copy_to_user((void *) arg, &op, sizeof(op)))
+ return -EFAULT;
+ return 0;
+ }
+
case PIO_SCRNMAP:
if (!perm)
return -EPERM;
@@ -1047,7 +1044,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return -EPERM;
i = copy_from_user(&ui, (void *)arg, sizeof(struct unimapinit));
if (i) return -EFAULT;
- con_clear_unimap(&ui);
+ con_clear_unimap(fg_console, &ui);
return 0;
}
@@ -1065,6 +1062,76 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return -EPERM;
vt_dont_switch = 0;
return 0;
+#ifdef CONFIG_FB_COMPAT_XPMAC
+ case VC_GETMODE:
+ {
+ struct vc_mode mode;
+
+ i = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(struct vc_mode));
+ if (i == 0)
+ i = console_getmode(&mode);
+ if (i)
+ return i;
+ if (copy_to_user((void *) arg, &mode, sizeof(mode)))
+ return -EFAULT;
+ return 0;
+ }
+ case VC_SETMODE:
+ case VC_INQMODE:
+ {
+ struct vc_mode mode;
+
+ if (!perm)
+ return -EPERM;
+ i = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(struct vc_mode));
+ if (i)
+ return i;
+ if (copy_from_user(&mode, (void *) arg, sizeof(mode)))
+ return -EFAULT;
+ return console_setmode(&mode, cmd == VC_SETMODE);
+ }
+ case VC_SETCMAP:
+ {
+ unsigned char cmap[3][256], *p;
+ int n_entries, cmap_size, i, j;
+
+ if (!perm)
+ return -EPERM;
+ if (arg == (unsigned long) VC_POWERMODE_INQUIRY
+ || arg <= VESA_POWERDOWN) {
+ /* compatibility hack: VC_POWERMODE
+ was changed from 0x766a to 0x766c */
+ return console_powermode((int) arg);
+ }
+ i = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(int));
+ if (i)
+ return i;
+ if (get_user(cmap_size, (int *) arg))
+ return -EFAULT;
+ if (cmap_size % 3)
+ return -EINVAL;
+ n_entries = cmap_size / 3;
+ if ((unsigned) n_entries > 256)
+ return -EINVAL;
+ p = (unsigned char *) (arg + sizeof(int));
+ for (j = 0; j < n_entries; ++j)
+ for (i = 0; i < 3; ++i)
+ if (get_user(cmap[i][j], p++))
+ return -EFAULT;
+ return console_setcmap(n_entries, cmap[0],
+ cmap[1], cmap[2]);
+ }
+ case VC_GETCMAP:
+ /* not implemented yet */
+ return -ENOIOCTLCMD;
+ case VC_POWERMODE:
+ if (!perm)
+ return -EPERM;
+ return console_powermode((int) arg);
+#endif /* CONFIG_FB_COMPAT_XPMAC */
default:
return -ENOIOCTLCMD;
}
@@ -1127,10 +1194,6 @@ void complete_change_console(unsigned int new_console)
{
unsigned char old_vc_mode;
- if ((new_console == fg_console) || (vt_dont_switch))
- return;
- if (!vc_cons_allocated(new_console))
- return;
last_console = fg_console;
/*
@@ -1185,21 +1248,8 @@ void complete_change_console(unsigned int new_console)
/* Set the colour palette for this VT */
if (vt_cons[new_console]->vc_mode == KD_TEXT)
set_palette() ;
-
-#ifdef CONFIG_SUN_CONSOLE
- if (old_vc_mode != vt_cons[new_console]->vc_mode)
- {
- if (old_vc_mode == KD_GRAPHICS)
- {
- suncons_ops.clear_margin();
- suncons_ops.render_screen();
- suncons_ops.set_cursor(fg_console);
- }
- else
- suncons_ops.hide_cursor();
- }
-#endif
- /*
+
+ /*
* Wake anyone waiting for their VT to activate
*/
vt_wake_waitactive();