Merge tag 'v3.3.7' into 3.3/master
[zen-stable.git] / drivers / tty / vt / vt.c
blobfceb65dda3920fbfd4bb4d61d2b4333044bc95c9
1 /*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 */
5 /*
6 * Hopefully this will be a rather complete VT102 implementation.
8 * Beeping thanks to John T Kohl.
10 * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
11 * Chars, and VT100 enhancements by Peter MacDonald.
13 * Copy and paste function by Andrew Haylett,
14 * some enhancements by Alessandro Rubini.
16 * Code to check for different video-cards mostly by Galen Hunt,
17 * <g-hunt@ee.utah.edu>
19 * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
20 * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
22 * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
23 * Resizing of consoles, aeb, 940926
25 * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
26 * <poe@daimi.aau.dk>
28 * User-defined bell sound, new setterm control sequences and printk
29 * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
31 * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
33 * Merge with the abstract console driver by Geert Uytterhoeven
34 * <geert@linux-m68k.org>, Jan 1997.
36 * Original m68k console driver modifications by
38 * - Arno Griffioen <arno@usn.nl>
39 * - David Carter <carter@cs.bris.ac.uk>
41 * The abstract console driver provides a generic interface for a text
42 * console. It supports VGA text mode, frame buffer based graphical consoles
43 * and special graphics processors that are only accessible through some
44 * registers (e.g. a TMS340x0 GSP).
46 * The interface to the hardware is specified using a special structure
47 * (struct consw) which contains function pointers to console operations
48 * (see <linux/console.h> for more information).
50 * Support for changeable cursor shape
51 * by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>, August 1997
53 * Ported to i386 and con_scrolldelta fixed
54 * by Emmanuel Marty <core@ggi-project.org>, April 1998
56 * Resurrected character buffers in videoram plus lots of other trickery
57 * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
59 * Removed old-style timers, introduced console_timer, made timer
60 * deletion SMP-safe. 17Jun00, Andrew Morton
62 * Removed console_lock, enabled interrupts across all console operations
63 * 13 March 2001, Andrew Morton
65 * Fixed UTF-8 mode so alternate charset modes always work according
66 * to control sequences interpreted in do_con_trol function
67 * preserving backward VT100 semigraphics compatibility,
68 * malformed UTF sequences represented as sequences of replacement glyphs,
69 * original codes or '?' as a last resort if replacement glyph is undefined
70 * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
73 #include <linux/module.h>
74 #include <linux/moduleparam.h>
75 #include <linux/types.h>
76 #include <linux/sched.h>
77 #include <linux/tty.h>
78 #include <linux/tty_flip.h>
79 #include <linux/kernel.h>
80 #include <linux/string.h>
81 #include <linux/errno.h>
82 #include <linux/kd.h>
83 #include <linux/slab.h>
84 #include <linux/major.h>
85 #include <linux/mm.h>
86 #include <linux/console.h>
87 #include <linux/init.h>
88 #include <linux/mutex.h>
89 #include <linux/vt_kern.h>
90 #include <linux/selection.h>
91 #include <linux/tiocl.h>
92 #include <linux/kbd_kern.h>
93 #include <linux/consolemap.h>
94 #include <linux/timer.h>
95 #include <linux/interrupt.h>
96 #include <linux/workqueue.h>
97 #include <linux/pm.h>
98 #include <linux/font.h>
99 #include <linux/bitops.h>
100 #include <linux/notifier.h>
101 #include <linux/device.h>
102 #include <linux/io.h>
103 #include <asm/system.h>
104 #include <linux/uaccess.h>
105 #include <linux/kdb.h>
106 #include <linux/ctype.h>
108 #define MAX_NR_CON_DRIVER 16
110 #define CON_DRIVER_FLAG_MODULE 1
111 #define CON_DRIVER_FLAG_INIT 2
112 #define CON_DRIVER_FLAG_ATTR 4
114 struct con_driver {
115 const struct consw *con;
116 const char *desc;
117 struct device *dev;
118 int node;
119 int first;
120 int last;
121 int flag;
124 static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
125 const struct consw *conswitchp;
127 /* A bitmap for codes <32. A bit of 1 indicates that the code
128 * corresponding to that bit number invokes some special action
129 * (such as cursor movement) and should not be displayed as a
130 * glyph unless the disp_ctrl mode is explicitly enabled.
132 #define CTRL_ACTION 0x0d00ff81
133 #define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
136 * Here is the default bell parameters: 750HZ, 1/8th of a second
138 #define DEFAULT_BELL_PITCH 750
139 #define DEFAULT_BELL_DURATION (HZ/8)
141 struct vc vc_cons [MAX_NR_CONSOLES];
143 #ifndef VT_SINGLE_DRIVER
144 static const struct consw *con_driver_map[MAX_NR_CONSOLES];
145 #endif
147 static int con_open(struct tty_struct *, struct file *);
148 static void vc_init(struct vc_data *vc, unsigned int rows,
149 unsigned int cols, int do_clear);
150 static void gotoxy(struct vc_data *vc, int new_x, int new_y);
151 static void save_cur(struct vc_data *vc);
152 static void reset_terminal(struct vc_data *vc, int do_clear);
153 static void con_flush_chars(struct tty_struct *tty);
154 static int set_vesa_blanking(char __user *p);
155 static void set_cursor(struct vc_data *vc);
156 static void hide_cursor(struct vc_data *vc);
157 static void console_callback(struct work_struct *ignored);
158 static void blank_screen_t(unsigned long dummy);
159 static void set_palette(struct vc_data *vc);
161 static int printable; /* Is console ready for printing? */
162 int default_utf8 = true;
163 module_param(default_utf8, int, S_IRUGO | S_IWUSR);
164 int global_cursor_default = -1;
165 module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
167 static int cur_default = CUR_DEFAULT;
168 module_param(cur_default, int, S_IRUGO | S_IWUSR);
171 * ignore_poke: don't unblank the screen when things are typed. This is
172 * mainly for the privacy of braille terminal users.
174 static int ignore_poke;
176 int do_poke_blanked_console;
177 int console_blanked;
179 static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
180 static int vesa_off_interval;
181 static int blankinterval = 10*60;
182 core_param(consoleblank, blankinterval, int, 0444);
184 static DECLARE_WORK(console_work, console_callback);
187 * fg_console is the current virtual console,
188 * last_console is the last used one,
189 * want_console is the console we want to switch to,
190 * saved_* variants are for save/restore around kernel debugger enter/leave
192 int fg_console;
193 int last_console;
194 int want_console = -1;
195 static int saved_fg_console;
196 static int saved_last_console;
197 static int saved_want_console;
198 static int saved_vc_mode;
199 static int saved_console_blanked;
202 * For each existing display, we have a pointer to console currently visible
203 * on that display, allowing consoles other than fg_console to be refreshed
204 * appropriately. Unless the low-level driver supplies its own display_fg
205 * variable, we use this one for the "master display".
207 static struct vc_data *master_display_fg;
210 * Unfortunately, we need to delay tty echo when we're currently writing to the
211 * console since the code is (and always was) not re-entrant, so we schedule
212 * all flip requests to process context with schedule-task() and run it from
213 * console_callback().
217 * For the same reason, we defer scrollback to the console callback.
219 static int scrollback_delta;
222 * Hook so that the power management routines can (un)blank
223 * the console on our behalf.
225 int (*console_blank_hook)(int);
227 static DEFINE_TIMER(console_timer, blank_screen_t, 0, 0);
228 static int blank_state;
229 static int blank_timer_expired;
230 enum {
231 blank_off = 0,
232 blank_normal_wait,
233 blank_vesa_wait,
237 * /sys/class/tty/tty0/
239 * the attribute 'active' contains the name of the current vc
240 * console and it supports poll() to detect vc switches
242 static struct device *tty0dev;
245 * Notifier list for console events.
247 static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
249 int register_vt_notifier(struct notifier_block *nb)
251 return atomic_notifier_chain_register(&vt_notifier_list, nb);
253 EXPORT_SYMBOL_GPL(register_vt_notifier);
255 int unregister_vt_notifier(struct notifier_block *nb)
257 return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
259 EXPORT_SYMBOL_GPL(unregister_vt_notifier);
261 static void notify_write(struct vc_data *vc, unsigned int unicode)
263 struct vt_notifier_param param = { .vc = vc, .c = unicode };
264 atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
267 static void notify_update(struct vc_data *vc)
269 struct vt_notifier_param param = { .vc = vc };
270 atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
273 * Low-Level Functions
276 #define IS_FG(vc) ((vc)->vc_num == fg_console)
278 #ifdef VT_BUF_VRAM_ONLY
279 #define DO_UPDATE(vc) 0
280 #else
281 #define DO_UPDATE(vc) (CON_IS_VISIBLE(vc) && !console_blanked)
282 #endif
284 static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
286 unsigned short *p;
288 if (!viewed)
289 p = (unsigned short *)(vc->vc_origin + offset);
290 else if (!vc->vc_sw->con_screen_pos)
291 p = (unsigned short *)(vc->vc_visible_origin + offset);
292 else
293 p = vc->vc_sw->con_screen_pos(vc, offset);
294 return p;
297 /* Called from the keyboard irq path.. */
298 static inline void scrolldelta(int lines)
300 /* FIXME */
301 /* scrolldelta needs some kind of consistency lock, but the BKL was
302 and still is not protecting versus the scheduled back end */
303 scrollback_delta += lines;
304 schedule_console_callback();
307 void schedule_console_callback(void)
309 schedule_work(&console_work);
312 static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
314 unsigned short *d, *s;
316 if (t+nr >= b)
317 nr = b - t - 1;
318 if (b > vc->vc_rows || t >= b || nr < 1)
319 return;
320 if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr))
321 return;
322 d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
323 s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
324 scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);
325 scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char,
326 vc->vc_size_row * nr);
329 static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
331 unsigned short *s;
332 unsigned int step;
334 if (t+nr >= b)
335 nr = b - t - 1;
336 if (b > vc->vc_rows || t >= b || nr < 1)
337 return;
338 if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr))
339 return;
340 s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
341 step = vc->vc_cols * nr;
342 scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);
343 scr_memsetw(s, vc->vc_video_erase_char, 2 * step);
346 static void do_update_region(struct vc_data *vc, unsigned long start, int count)
348 #ifndef VT_BUF_VRAM_ONLY
349 unsigned int xx, yy, offset;
350 u16 *p;
352 p = (u16 *) start;
353 if (!vc->vc_sw->con_getxy) {
354 offset = (start - vc->vc_origin) / 2;
355 xx = offset % vc->vc_cols;
356 yy = offset / vc->vc_cols;
357 } else {
358 int nxx, nyy;
359 start = vc->vc_sw->con_getxy(vc, start, &nxx, &nyy);
360 xx = nxx; yy = nyy;
362 for(;;) {
363 u16 attrib = scr_readw(p) & 0xff00;
364 int startx = xx;
365 u16 *q = p;
366 while (xx < vc->vc_cols && count) {
367 if (attrib != (scr_readw(p) & 0xff00)) {
368 if (p > q)
369 vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
370 startx = xx;
371 q = p;
372 attrib = scr_readw(p) & 0xff00;
374 p++;
375 xx++;
376 count--;
378 if (p > q)
379 vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
380 if (!count)
381 break;
382 xx = 0;
383 yy++;
384 if (vc->vc_sw->con_getxy) {
385 p = (u16 *)start;
386 start = vc->vc_sw->con_getxy(vc, start, NULL, NULL);
389 #endif
392 void update_region(struct vc_data *vc, unsigned long start, int count)
394 WARN_CONSOLE_UNLOCKED();
396 if (DO_UPDATE(vc)) {
397 hide_cursor(vc);
398 do_update_region(vc, start, count);
399 set_cursor(vc);
403 /* Structure of attributes is hardware-dependent */
405 static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
406 u8 _underline, u8 _reverse, u8 _italic)
408 if (vc->vc_sw->con_build_attr)
409 return vc->vc_sw->con_build_attr(vc, _color, _intensity,
410 _blink, _underline, _reverse, _italic);
412 #ifndef VT_BUF_VRAM_ONLY
414 * ++roman: I completely changed the attribute format for monochrome
415 * mode (!can_do_color). The formerly used MDA (monochrome display
416 * adapter) format didn't allow the combination of certain effects.
417 * Now the attribute is just a bit vector:
418 * Bit 0..1: intensity (0..2)
419 * Bit 2 : underline
420 * Bit 3 : reverse
421 * Bit 7 : blink
424 u8 a = _color;
425 if (!vc->vc_can_do_color)
426 return _intensity |
427 (_italic ? 2 : 0) |
428 (_underline ? 4 : 0) |
429 (_reverse ? 8 : 0) |
430 (_blink ? 0x80 : 0);
431 if (_italic)
432 a = (a & 0xF0) | vc->vc_itcolor;
433 else if (_underline)
434 a = (a & 0xf0) | vc->vc_ulcolor;
435 else if (_intensity == 0)
436 a = (a & 0xf0) | vc->vc_ulcolor;
437 if (_reverse)
438 a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
439 if (_blink)
440 a ^= 0x80;
441 if (_intensity == 2)
442 a ^= 0x08;
443 if (vc->vc_hi_font_mask == 0x100)
444 a <<= 1;
445 return a;
447 #else
448 return 0;
449 #endif
452 static void update_attr(struct vc_data *vc)
454 vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
455 vc->vc_blink, vc->vc_underline,
456 vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
457 vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
460 /* Note: inverting the screen twice should revert to the original state */
461 void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
463 unsigned short *p;
465 WARN_CONSOLE_UNLOCKED();
467 count /= 2;
468 p = screenpos(vc, offset, viewed);
469 if (vc->vc_sw->con_invert_region)
470 vc->vc_sw->con_invert_region(vc, p, count);
471 #ifndef VT_BUF_VRAM_ONLY
472 else {
473 u16 *q = p;
474 int cnt = count;
475 u16 a;
477 if (!vc->vc_can_do_color) {
478 while (cnt--) {
479 a = scr_readw(q);
480 a ^= 0x0800;
481 scr_writew(a, q);
482 q++;
484 } else if (vc->vc_hi_font_mask == 0x100) {
485 while (cnt--) {
486 a = scr_readw(q);
487 a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
488 scr_writew(a, q);
489 q++;
491 } else {
492 while (cnt--) {
493 a = scr_readw(q);
494 a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
495 scr_writew(a, q);
496 q++;
500 #endif
501 if (DO_UPDATE(vc))
502 do_update_region(vc, (unsigned long) p, count);
505 /* used by selection: complement pointer position */
506 void complement_pos(struct vc_data *vc, int offset)
508 static int old_offset = -1;
509 static unsigned short old;
510 static unsigned short oldx, oldy;
512 WARN_CONSOLE_UNLOCKED();
514 if (old_offset != -1 && old_offset >= 0 &&
515 old_offset < vc->vc_screenbuf_size) {
516 scr_writew(old, screenpos(vc, old_offset, 1));
517 if (DO_UPDATE(vc))
518 vc->vc_sw->con_putc(vc, old, oldy, oldx);
521 old_offset = offset;
523 if (offset != -1 && offset >= 0 &&
524 offset < vc->vc_screenbuf_size) {
525 unsigned short new;
526 unsigned short *p;
527 p = screenpos(vc, offset, 1);
528 old = scr_readw(p);
529 new = old ^ vc->vc_complement_mask;
530 scr_writew(new, p);
531 if (DO_UPDATE(vc)) {
532 oldx = (offset >> 1) % vc->vc_cols;
533 oldy = (offset >> 1) / vc->vc_cols;
534 vc->vc_sw->con_putc(vc, new, oldy, oldx);
540 static void insert_char(struct vc_data *vc, unsigned int nr)
542 unsigned short *p, *q = (unsigned short *)vc->vc_pos;
544 p = q + vc->vc_cols - nr - vc->vc_x;
545 while (--p >= q)
546 scr_writew(scr_readw(p), p + nr);
547 scr_memsetw(q, vc->vc_video_erase_char, nr * 2);
548 vc->vc_need_wrap = 0;
549 if (DO_UPDATE(vc)) {
550 unsigned short oldattr = vc->vc_attr;
551 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1,
552 vc->vc_cols - vc->vc_x - nr);
553 vc->vc_attr = vc->vc_video_erase_char >> 8;
554 while (nr--)
555 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr);
556 vc->vc_attr = oldattr;
560 static void delete_char(struct vc_data *vc, unsigned int nr)
562 unsigned int i = vc->vc_x;
563 unsigned short *p = (unsigned short *)vc->vc_pos;
565 while (++i <= vc->vc_cols - nr) {
566 scr_writew(scr_readw(p+nr), p);
567 p++;
569 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
570 vc->vc_need_wrap = 0;
571 if (DO_UPDATE(vc)) {
572 unsigned short oldattr = vc->vc_attr;
573 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1,
574 vc->vc_cols - vc->vc_x - nr);
575 vc->vc_attr = vc->vc_video_erase_char >> 8;
576 while (nr--)
577 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y,
578 vc->vc_cols - 1 - nr);
579 vc->vc_attr = oldattr;
583 static int softcursor_original;
585 static void add_softcursor(struct vc_data *vc)
587 int i = scr_readw((u16 *) vc->vc_pos);
588 u32 type = vc->vc_cursor_type;
590 if (! (type & 0x10)) return;
591 if (softcursor_original != -1) return;
592 softcursor_original = i;
593 i |= ((type >> 8) & 0xff00 );
594 i ^= ((type) & 0xff00 );
595 if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
596 if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
597 scr_writew(i, (u16 *) vc->vc_pos);
598 if (DO_UPDATE(vc))
599 vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
602 static void hide_softcursor(struct vc_data *vc)
604 if (softcursor_original != -1) {
605 scr_writew(softcursor_original, (u16 *)vc->vc_pos);
606 if (DO_UPDATE(vc))
607 vc->vc_sw->con_putc(vc, softcursor_original,
608 vc->vc_y, vc->vc_x);
609 softcursor_original = -1;
613 static void hide_cursor(struct vc_data *vc)
615 if (vc == sel_cons)
616 clear_selection();
617 vc->vc_sw->con_cursor(vc, CM_ERASE);
618 hide_softcursor(vc);
621 static void set_cursor(struct vc_data *vc)
623 if (!IS_FG(vc) || console_blanked ||
624 vc->vc_mode == KD_GRAPHICS)
625 return;
626 if (vc->vc_deccm) {
627 if (vc == sel_cons)
628 clear_selection();
629 add_softcursor(vc);
630 if ((vc->vc_cursor_type & 0x0f) != 1)
631 vc->vc_sw->con_cursor(vc, CM_DRAW);
632 } else
633 hide_cursor(vc);
636 static void set_origin(struct vc_data *vc)
638 WARN_CONSOLE_UNLOCKED();
640 if (!CON_IS_VISIBLE(vc) ||
641 !vc->vc_sw->con_set_origin ||
642 !vc->vc_sw->con_set_origin(vc))
643 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
644 vc->vc_visible_origin = vc->vc_origin;
645 vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
646 vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
649 static inline void save_screen(struct vc_data *vc)
651 WARN_CONSOLE_UNLOCKED();
653 if (vc->vc_sw->con_save_screen)
654 vc->vc_sw->con_save_screen(vc);
658 * Redrawing of screen
661 static void clear_buffer_attributes(struct vc_data *vc)
663 unsigned short *p = (unsigned short *)vc->vc_origin;
664 int count = vc->vc_screenbuf_size / 2;
665 int mask = vc->vc_hi_font_mask | 0xff;
667 for (; count > 0; count--, p++) {
668 scr_writew((scr_readw(p)&mask) | (vc->vc_video_erase_char & ~mask), p);
672 void redraw_screen(struct vc_data *vc, int is_switch)
674 int redraw = 0;
676 WARN_CONSOLE_UNLOCKED();
678 if (!vc) {
679 /* strange ... */
680 /* printk("redraw_screen: tty %d not allocated ??\n", new_console+1); */
681 return;
684 if (is_switch) {
685 struct vc_data *old_vc = vc_cons[fg_console].d;
686 if (old_vc == vc)
687 return;
688 if (!CON_IS_VISIBLE(vc))
689 redraw = 1;
690 *vc->vc_display_fg = vc;
691 fg_console = vc->vc_num;
692 hide_cursor(old_vc);
693 if (!CON_IS_VISIBLE(old_vc)) {
694 save_screen(old_vc);
695 set_origin(old_vc);
697 if (tty0dev)
698 sysfs_notify(&tty0dev->kobj, NULL, "active");
699 } else {
700 hide_cursor(vc);
701 redraw = 1;
704 if (redraw) {
705 int update;
706 int old_was_color = vc->vc_can_do_color;
708 set_origin(vc);
709 update = vc->vc_sw->con_switch(vc);
710 set_palette(vc);
712 * If console changed from mono<->color, the best we can do
713 * is to clear the buffer attributes. As it currently stands,
714 * rebuilding new attributes from the old buffer is not doable
715 * without overly complex code.
717 if (old_was_color != vc->vc_can_do_color) {
718 update_attr(vc);
719 clear_buffer_attributes(vc);
722 /* Forcibly update if we're panicing */
723 if ((update && vc->vc_mode != KD_GRAPHICS) ||
724 vt_force_oops_output(vc))
725 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
727 set_cursor(vc);
728 if (is_switch) {
729 set_leds();
730 compute_shiftstate();
731 notify_update(vc);
736 * Allocation, freeing and resizing of VTs.
739 int vc_cons_allocated(unsigned int i)
741 return (i < MAX_NR_CONSOLES && vc_cons[i].d);
744 static void visual_init(struct vc_data *vc, int num, int init)
746 /* ++Geert: vc->vc_sw->con_init determines console size */
747 if (vc->vc_sw)
748 module_put(vc->vc_sw->owner);
749 vc->vc_sw = conswitchp;
750 #ifndef VT_SINGLE_DRIVER
751 if (con_driver_map[num])
752 vc->vc_sw = con_driver_map[num];
753 #endif
754 __module_get(vc->vc_sw->owner);
755 vc->vc_num = num;
756 vc->vc_display_fg = &master_display_fg;
757 vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
758 vc->vc_uni_pagedir = 0;
759 vc->vc_hi_font_mask = 0;
760 vc->vc_complement_mask = 0;
761 vc->vc_can_do_color = 0;
762 vc->vc_panic_force_write = false;
763 vc->vc_sw->con_init(vc, init);
764 if (!vc->vc_complement_mask)
765 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
766 vc->vc_s_complement_mask = vc->vc_complement_mask;
767 vc->vc_size_row = vc->vc_cols << 1;
768 vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
771 int vc_allocate(unsigned int currcons) /* return 0 on success */
773 WARN_CONSOLE_UNLOCKED();
775 if (currcons >= MAX_NR_CONSOLES)
776 return -ENXIO;
777 if (!vc_cons[currcons].d) {
778 struct vc_data *vc;
779 struct vt_notifier_param param;
781 /* prevent users from taking too much memory */
782 if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
783 return -EPERM;
785 /* due to the granularity of kmalloc, we waste some memory here */
786 /* the alloc is done in two steps, to optimize the common situation
787 of a 25x80 console (structsize=216, screenbuf_size=4000) */
788 /* although the numbers above are not valid since long ago, the
789 point is still up-to-date and the comment still has its value
790 even if only as a historical artifact. --mj, July 1998 */
791 param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
792 if (!vc)
793 return -ENOMEM;
794 vc_cons[currcons].d = vc;
795 tty_port_init(&vc->port);
796 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
797 visual_init(vc, currcons, 1);
798 if (!*vc->vc_uni_pagedir_loc)
799 con_set_default_unimap(vc);
800 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
801 if (!vc->vc_screenbuf) {
802 kfree(vc);
803 vc_cons[currcons].d = NULL;
804 return -ENOMEM;
807 /* If no drivers have overridden us and the user didn't pass a
808 boot option, default to displaying the cursor */
809 if (global_cursor_default == -1)
810 global_cursor_default = 1;
812 vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
813 vcs_make_sysfs(currcons);
814 atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
816 return 0;
819 static inline int resize_screen(struct vc_data *vc, int width, int height,
820 int user)
822 /* Resizes the resolution of the display adapater */
823 int err = 0;
825 if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
826 err = vc->vc_sw->con_resize(vc, width, height, user);
828 return err;
832 * Change # of rows and columns (0 means unchanged/the size of fg_console)
833 * [this is to be used together with some user program
834 * like resize that changes the hardware videomode]
836 #define VC_RESIZE_MAXCOL (32767)
837 #define VC_RESIZE_MAXROW (32767)
840 * vc_do_resize - resizing method for the tty
841 * @tty: tty being resized
842 * @real_tty: real tty (different to tty if a pty/tty pair)
843 * @vc: virtual console private data
844 * @cols: columns
845 * @lines: lines
847 * Resize a virtual console, clipping according to the actual constraints.
848 * If the caller passes a tty structure then update the termios winsize
849 * information and perform any necessary signal handling.
851 * Caller must hold the console semaphore. Takes the termios mutex and
852 * ctrl_lock of the tty IFF a tty is passed.
855 static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
856 unsigned int cols, unsigned int lines)
858 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
859 unsigned long end;
860 unsigned int old_rows, old_row_size;
861 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
862 unsigned int user;
863 unsigned short *newscreen;
865 WARN_CONSOLE_UNLOCKED();
867 if (!vc)
868 return -ENXIO;
870 user = vc->vc_resize_user;
871 vc->vc_resize_user = 0;
873 if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
874 return -EINVAL;
876 new_cols = (cols ? cols : vc->vc_cols);
877 new_rows = (lines ? lines : vc->vc_rows);
878 new_row_size = new_cols << 1;
879 new_screen_size = new_row_size * new_rows;
881 if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
882 return 0;
884 newscreen = kmalloc(new_screen_size, GFP_USER);
885 if (!newscreen)
886 return -ENOMEM;
888 old_rows = vc->vc_rows;
889 old_row_size = vc->vc_size_row;
891 err = resize_screen(vc, new_cols, new_rows, user);
892 if (err) {
893 kfree(newscreen);
894 return err;
897 vc->vc_rows = new_rows;
898 vc->vc_cols = new_cols;
899 vc->vc_size_row = new_row_size;
900 vc->vc_screenbuf_size = new_screen_size;
902 rlth = min(old_row_size, new_row_size);
903 rrem = new_row_size - rlth;
904 old_origin = vc->vc_origin;
905 new_origin = (long) newscreen;
906 new_scr_end = new_origin + new_screen_size;
908 if (vc->vc_y > new_rows) {
909 if (old_rows - vc->vc_y < new_rows) {
911 * Cursor near the bottom, copy contents from the
912 * bottom of buffer
914 old_origin += (old_rows - new_rows) * old_row_size;
915 } else {
917 * Cursor is in no man's land, copy 1/2 screenful
918 * from the top and bottom of cursor position
920 old_origin += (vc->vc_y - new_rows/2) * old_row_size;
924 end = old_origin + old_row_size * min(old_rows, new_rows);
926 update_attr(vc);
928 while (old_origin < end) {
929 scr_memcpyw((unsigned short *) new_origin,
930 (unsigned short *) old_origin, rlth);
931 if (rrem)
932 scr_memsetw((void *)(new_origin + rlth),
933 vc->vc_video_erase_char, rrem);
934 old_origin += old_row_size;
935 new_origin += new_row_size;
937 if (new_scr_end > new_origin)
938 scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
939 new_scr_end - new_origin);
940 kfree(vc->vc_screenbuf);
941 vc->vc_screenbuf = newscreen;
942 vc->vc_screenbuf_size = new_screen_size;
943 set_origin(vc);
945 /* do part of a reset_terminal() */
946 vc->vc_top = 0;
947 vc->vc_bottom = vc->vc_rows;
948 gotoxy(vc, vc->vc_x, vc->vc_y);
949 save_cur(vc);
951 if (tty) {
952 /* Rewrite the requested winsize data with the actual
953 resulting sizes */
954 struct winsize ws;
955 memset(&ws, 0, sizeof(ws));
956 ws.ws_row = vc->vc_rows;
957 ws.ws_col = vc->vc_cols;
958 ws.ws_ypixel = vc->vc_scan_lines;
959 tty_do_resize(tty, &ws);
962 if (CON_IS_VISIBLE(vc))
963 update_screen(vc);
964 vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
965 return err;
969 * vc_resize - resize a VT
970 * @vc: virtual console
971 * @cols: columns
972 * @rows: rows
974 * Resize a virtual console as seen from the console end of things. We
975 * use the common vc_do_resize methods to update the structures. The
976 * caller must hold the console sem to protect console internals and
977 * vc->port.tty
980 int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
982 return vc_do_resize(vc->port.tty, vc, cols, rows);
986 * vt_resize - resize a VT
987 * @tty: tty to resize
988 * @ws: winsize attributes
990 * Resize a virtual terminal. This is called by the tty layer as we
991 * register our own handler for resizing. The mutual helper does all
992 * the actual work.
994 * Takes the console sem and the called methods then take the tty
995 * termios_mutex and the tty ctrl_lock in that order.
997 static int vt_resize(struct tty_struct *tty, struct winsize *ws)
999 struct vc_data *vc = tty->driver_data;
1000 int ret;
1002 console_lock();
1003 ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row);
1004 console_unlock();
1005 return ret;
1008 void vc_deallocate(unsigned int currcons)
1010 WARN_CONSOLE_UNLOCKED();
1012 if (vc_cons_allocated(currcons)) {
1013 struct vc_data *vc = vc_cons[currcons].d;
1014 struct vt_notifier_param param = { .vc = vc };
1016 atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
1017 vcs_remove_sysfs(currcons);
1018 vc->vc_sw->con_deinit(vc);
1019 put_pid(vc->vt_pid);
1020 module_put(vc->vc_sw->owner);
1021 kfree(vc->vc_screenbuf);
1022 if (currcons >= MIN_NR_CONSOLES)
1023 kfree(vc);
1024 vc_cons[currcons].d = NULL;
1029 * VT102 emulator
1032 #define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1033 #define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1034 #define is_kbd(vc, x) vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1036 #define decarm VC_REPEAT
1037 #define decckm VC_CKMODE
1038 #define kbdapplic VC_APPLIC
1039 #define lnm VC_CRLF
1042 * this is what the terminal answers to a ESC-Z or csi0c query.
1044 #define VT100ID "\033[?1;2c"
1045 #define VT102ID "\033[?6c"
1047 unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
1048 8,12,10,14, 9,13,11,15 };
1050 /* the default colour table, for VGA+ colour systems */
1051 int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
1052 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
1053 int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
1054 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
1055 int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
1056 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
1058 module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
1059 module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
1060 module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
1063 * gotoxy() must verify all boundaries, because the arguments
1064 * might also be negative. If the given position is out of
1065 * bounds, the cursor is placed at the nearest margin.
1067 static void gotoxy(struct vc_data *vc, int new_x, int new_y)
1069 int min_y, max_y;
1071 if (new_x < 0)
1072 vc->vc_x = 0;
1073 else {
1074 if (new_x >= vc->vc_cols)
1075 vc->vc_x = vc->vc_cols - 1;
1076 else
1077 vc->vc_x = new_x;
1080 if (vc->vc_decom) {
1081 min_y = vc->vc_top;
1082 max_y = vc->vc_bottom;
1083 } else {
1084 min_y = 0;
1085 max_y = vc->vc_rows;
1087 if (new_y < min_y)
1088 vc->vc_y = min_y;
1089 else if (new_y >= max_y)
1090 vc->vc_y = max_y - 1;
1091 else
1092 vc->vc_y = new_y;
1093 vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
1094 vc->vc_need_wrap = 0;
1097 /* for absolute user moves, when decom is set */
1098 static void gotoxay(struct vc_data *vc, int new_x, int new_y)
1100 gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y);
1103 void scrollback(struct vc_data *vc, int lines)
1105 if (!lines)
1106 lines = vc->vc_rows / 2;
1107 scrolldelta(-lines);
1110 void scrollfront(struct vc_data *vc, int lines)
1112 if (!lines)
1113 lines = vc->vc_rows / 2;
1114 scrolldelta(lines);
1117 static void lf(struct vc_data *vc)
1119 /* don't scroll if above bottom of scrolling region, or
1120 * if below scrolling region
1122 if (vc->vc_y + 1 == vc->vc_bottom)
1123 scrup(vc, vc->vc_top, vc->vc_bottom, 1);
1124 else if (vc->vc_y < vc->vc_rows - 1) {
1125 vc->vc_y++;
1126 vc->vc_pos += vc->vc_size_row;
1128 vc->vc_need_wrap = 0;
1129 notify_write(vc, '\n');
1132 static void ri(struct vc_data *vc)
1134 /* don't scroll if below top of scrolling region, or
1135 * if above scrolling region
1137 if (vc->vc_y == vc->vc_top)
1138 scrdown(vc, vc->vc_top, vc->vc_bottom, 1);
1139 else if (vc->vc_y > 0) {
1140 vc->vc_y--;
1141 vc->vc_pos -= vc->vc_size_row;
1143 vc->vc_need_wrap = 0;
1146 static inline void cr(struct vc_data *vc)
1148 vc->vc_pos -= vc->vc_x << 1;
1149 vc->vc_need_wrap = vc->vc_x = 0;
1150 notify_write(vc, '\r');
1153 static inline void bs(struct vc_data *vc)
1155 if (vc->vc_x) {
1156 vc->vc_pos -= 2;
1157 vc->vc_x--;
1158 vc->vc_need_wrap = 0;
1159 notify_write(vc, '\b');
1163 static inline void del(struct vc_data *vc)
1165 /* ignored */
1168 static void csi_J(struct vc_data *vc, int vpar)
1170 unsigned int count;
1171 unsigned short * start;
1173 switch (vpar) {
1174 case 0: /* erase from cursor to end of display */
1175 count = (vc->vc_scr_end - vc->vc_pos) >> 1;
1176 start = (unsigned short *)vc->vc_pos;
1177 if (DO_UPDATE(vc)) {
1178 /* do in two stages */
1179 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1180 vc->vc_cols - vc->vc_x);
1181 vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0,
1182 vc->vc_rows - vc->vc_y - 1,
1183 vc->vc_cols);
1185 break;
1186 case 1: /* erase from start to cursor */
1187 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
1188 start = (unsigned short *)vc->vc_origin;
1189 if (DO_UPDATE(vc)) {
1190 /* do in two stages */
1191 vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y,
1192 vc->vc_cols);
1193 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1194 vc->vc_x + 1);
1196 break;
1197 case 3: /* erase scroll-back buffer (and whole display) */
1198 scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
1199 vc->vc_screenbuf_size >> 1);
1200 set_origin(vc);
1201 if (CON_IS_VISIBLE(vc))
1202 update_screen(vc);
1203 /* fall through */
1204 case 2: /* erase whole display */
1205 count = vc->vc_cols * vc->vc_rows;
1206 start = (unsigned short *)vc->vc_origin;
1207 if (DO_UPDATE(vc))
1208 vc->vc_sw->con_clear(vc, 0, 0,
1209 vc->vc_rows,
1210 vc->vc_cols);
1211 break;
1212 default:
1213 return;
1215 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1216 vc->vc_need_wrap = 0;
1219 static void csi_K(struct vc_data *vc, int vpar)
1221 unsigned int count;
1222 unsigned short * start;
1224 switch (vpar) {
1225 case 0: /* erase from cursor to end of line */
1226 count = vc->vc_cols - vc->vc_x;
1227 start = (unsigned short *)vc->vc_pos;
1228 if (DO_UPDATE(vc))
1229 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1230 vc->vc_cols - vc->vc_x);
1231 break;
1232 case 1: /* erase from start of line to cursor */
1233 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1234 count = vc->vc_x + 1;
1235 if (DO_UPDATE(vc))
1236 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1237 vc->vc_x + 1);
1238 break;
1239 case 2: /* erase whole line */
1240 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1241 count = vc->vc_cols;
1242 if (DO_UPDATE(vc))
1243 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1244 vc->vc_cols);
1245 break;
1246 default:
1247 return;
1249 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1250 vc->vc_need_wrap = 0;
1253 static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
1254 { /* not vt100? */
1255 int count;
1257 if (!vpar)
1258 vpar++;
1259 count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
1261 scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
1262 if (DO_UPDATE(vc))
1263 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
1264 vc->vc_need_wrap = 0;
1267 static void default_attr(struct vc_data *vc)
1269 vc->vc_intensity = 1;
1270 vc->vc_italic = 0;
1271 vc->vc_underline = 0;
1272 vc->vc_reverse = 0;
1273 vc->vc_blink = 0;
1274 vc->vc_color = vc->vc_def_color;
1277 /* console_lock is held */
1278 static void csi_m(struct vc_data *vc)
1280 int i;
1282 for (i = 0; i <= vc->vc_npar; i++)
1283 switch (vc->vc_par[i]) {
1284 case 0: /* all attributes off */
1285 default_attr(vc);
1286 break;
1287 case 1:
1288 vc->vc_intensity = 2;
1289 break;
1290 case 2:
1291 vc->vc_intensity = 0;
1292 break;
1293 case 3:
1294 vc->vc_italic = 1;
1295 break;
1296 case 4:
1297 vc->vc_underline = 1;
1298 break;
1299 case 5:
1300 vc->vc_blink = 1;
1301 break;
1302 case 7:
1303 vc->vc_reverse = 1;
1304 break;
1305 case 10: /* ANSI X3.64-1979 (SCO-ish?)
1306 * Select primary font, don't display
1307 * control chars if defined, don't set
1308 * bit 8 on output.
1310 vc->vc_translate = set_translate(vc->vc_charset == 0
1311 ? vc->vc_G0_charset
1312 : vc->vc_G1_charset, vc);
1313 vc->vc_disp_ctrl = 0;
1314 vc->vc_toggle_meta = 0;
1315 break;
1316 case 11: /* ANSI X3.64-1979 (SCO-ish?)
1317 * Select first alternate font, lets
1318 * chars < 32 be displayed as ROM chars.
1320 vc->vc_translate = set_translate(IBMPC_MAP, vc);
1321 vc->vc_disp_ctrl = 1;
1322 vc->vc_toggle_meta = 0;
1323 break;
1324 case 12: /* ANSI X3.64-1979 (SCO-ish?)
1325 * Select second alternate font, toggle
1326 * high bit before displaying as ROM char.
1328 vc->vc_translate = set_translate(IBMPC_MAP, vc);
1329 vc->vc_disp_ctrl = 1;
1330 vc->vc_toggle_meta = 1;
1331 break;
1332 case 21:
1333 case 22:
1334 vc->vc_intensity = 1;
1335 break;
1336 case 23:
1337 vc->vc_italic = 0;
1338 break;
1339 case 24:
1340 vc->vc_underline = 0;
1341 break;
1342 case 25:
1343 vc->vc_blink = 0;
1344 break;
1345 case 27:
1346 vc->vc_reverse = 0;
1347 break;
1348 case 38: /* ANSI X3.64-1979 (SCO-ish?)
1349 * Enables underscore, white foreground
1350 * with white underscore (Linux - use
1351 * default foreground).
1353 vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
1354 vc->vc_underline = 1;
1355 break;
1356 case 39: /* ANSI X3.64-1979 (SCO-ish?)
1357 * Disable underline option.
1358 * Reset colour to default? It did this
1359 * before...
1361 vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
1362 vc->vc_underline = 0;
1363 break;
1364 case 49:
1365 vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f);
1366 break;
1367 default:
1368 if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
1369 vc->vc_color = color_table[vc->vc_par[i] - 30]
1370 | (vc->vc_color & 0xf0);
1371 else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
1372 vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
1373 | (vc->vc_color & 0x0f);
1374 break;
1376 update_attr(vc);
1379 static void respond_string(const char *p, struct tty_struct *tty)
1381 while (*p) {
1382 tty_insert_flip_char(tty, *p, 0);
1383 p++;
1385 con_schedule_flip(tty);
1388 static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
1390 char buf[40];
1392 sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1);
1393 respond_string(buf, tty);
1396 static inline void status_report(struct tty_struct *tty)
1398 respond_string("\033[0n", tty); /* Terminal ok */
1401 static inline void respond_ID(struct tty_struct * tty)
1403 respond_string(VT102ID, tty);
1406 void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
1408 char buf[8];
1410 sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
1411 (char)('!' + mry));
1412 respond_string(buf, tty);
1415 /* invoked via ioctl(TIOCLINUX) and through set_selection */
1416 int mouse_reporting(void)
1418 return vc_cons[fg_console].d->vc_report_mouse;
1421 /* console_lock is held */
1422 static void set_mode(struct vc_data *vc, int on_off)
1424 int i;
1426 for (i = 0; i <= vc->vc_npar; i++)
1427 if (vc->vc_ques) {
1428 switch(vc->vc_par[i]) { /* DEC private modes set/reset */
1429 case 1: /* Cursor keys send ^[Ox/^[[x */
1430 if (on_off)
1431 set_kbd(vc, decckm);
1432 else
1433 clr_kbd(vc, decckm);
1434 break;
1435 case 3: /* 80/132 mode switch unimplemented */
1436 vc->vc_deccolm = on_off;
1437 #if 0
1438 vc_resize(deccolm ? 132 : 80, vc->vc_rows);
1439 /* this alone does not suffice; some user mode
1440 utility has to change the hardware regs */
1441 #endif
1442 break;
1443 case 5: /* Inverted screen on/off */
1444 if (vc->vc_decscnm != on_off) {
1445 vc->vc_decscnm = on_off;
1446 invert_screen(vc, 0, vc->vc_screenbuf_size, 0);
1447 update_attr(vc);
1449 break;
1450 case 6: /* Origin relative/absolute */
1451 vc->vc_decom = on_off;
1452 gotoxay(vc, 0, 0);
1453 break;
1454 case 7: /* Autowrap on/off */
1455 vc->vc_decawm = on_off;
1456 break;
1457 case 8: /* Autorepeat on/off */
1458 if (on_off)
1459 set_kbd(vc, decarm);
1460 else
1461 clr_kbd(vc, decarm);
1462 break;
1463 case 9:
1464 vc->vc_report_mouse = on_off ? 1 : 0;
1465 break;
1466 case 25: /* Cursor on/off */
1467 vc->vc_deccm = on_off;
1468 break;
1469 case 1000:
1470 vc->vc_report_mouse = on_off ? 2 : 0;
1471 break;
1473 } else {
1474 switch(vc->vc_par[i]) { /* ANSI modes set/reset */
1475 case 3: /* Monitor (display ctrls) */
1476 vc->vc_disp_ctrl = on_off;
1477 break;
1478 case 4: /* Insert Mode on/off */
1479 vc->vc_decim = on_off;
1480 break;
1481 case 20: /* Lf, Enter == CrLf/Lf */
1482 if (on_off)
1483 set_kbd(vc, lnm);
1484 else
1485 clr_kbd(vc, lnm);
1486 break;
1491 /* console_lock is held */
1492 static void setterm_command(struct vc_data *vc)
1494 switch(vc->vc_par[0]) {
1495 case 1: /* set color for underline mode */
1496 if (vc->vc_can_do_color &&
1497 vc->vc_par[1] < 16) {
1498 vc->vc_ulcolor = color_table[vc->vc_par[1]];
1499 if (vc->vc_underline)
1500 update_attr(vc);
1502 break;
1503 case 2: /* set color for half intensity mode */
1504 if (vc->vc_can_do_color &&
1505 vc->vc_par[1] < 16) {
1506 vc->vc_halfcolor = color_table[vc->vc_par[1]];
1507 if (vc->vc_intensity == 0)
1508 update_attr(vc);
1510 break;
1511 case 8: /* store colors as defaults */
1512 vc->vc_def_color = vc->vc_attr;
1513 if (vc->vc_hi_font_mask == 0x100)
1514 vc->vc_def_color >>= 1;
1515 default_attr(vc);
1516 update_attr(vc);
1517 break;
1518 case 9: /* set blanking interval */
1519 blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60;
1520 poke_blanked_console();
1521 break;
1522 case 10: /* set bell frequency in Hz */
1523 if (vc->vc_npar >= 1)
1524 vc->vc_bell_pitch = vc->vc_par[1];
1525 else
1526 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
1527 break;
1528 case 11: /* set bell duration in msec */
1529 if (vc->vc_npar >= 1)
1530 vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
1531 vc->vc_par[1] * HZ / 1000 : 0;
1532 else
1533 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
1534 break;
1535 case 12: /* bring specified console to the front */
1536 if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
1537 set_console(vc->vc_par[1] - 1);
1538 break;
1539 case 13: /* unblank the screen */
1540 poke_blanked_console();
1541 break;
1542 case 14: /* set vesa powerdown interval */
1543 vesa_off_interval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ;
1544 break;
1545 case 15: /* activate the previous console */
1546 set_console(last_console);
1547 break;
1551 /* console_lock is held */
1552 static void csi_at(struct vc_data *vc, unsigned int nr)
1554 if (nr > vc->vc_cols - vc->vc_x)
1555 nr = vc->vc_cols - vc->vc_x;
1556 else if (!nr)
1557 nr = 1;
1558 insert_char(vc, nr);
1561 /* console_lock is held */
1562 static void csi_L(struct vc_data *vc, unsigned int nr)
1564 if (nr > vc->vc_rows - vc->vc_y)
1565 nr = vc->vc_rows - vc->vc_y;
1566 else if (!nr)
1567 nr = 1;
1568 scrdown(vc, vc->vc_y, vc->vc_bottom, nr);
1569 vc->vc_need_wrap = 0;
1572 /* console_lock is held */
1573 static void csi_P(struct vc_data *vc, unsigned int nr)
1575 if (nr > vc->vc_cols - vc->vc_x)
1576 nr = vc->vc_cols - vc->vc_x;
1577 else if (!nr)
1578 nr = 1;
1579 delete_char(vc, nr);
1582 /* console_lock is held */
1583 static void csi_M(struct vc_data *vc, unsigned int nr)
1585 if (nr > vc->vc_rows - vc->vc_y)
1586 nr = vc->vc_rows - vc->vc_y;
1587 else if (!nr)
1588 nr=1;
1589 scrup(vc, vc->vc_y, vc->vc_bottom, nr);
1590 vc->vc_need_wrap = 0;
1593 /* console_lock is held (except via vc_init->reset_terminal */
1594 static void save_cur(struct vc_data *vc)
1596 vc->vc_saved_x = vc->vc_x;
1597 vc->vc_saved_y = vc->vc_y;
1598 vc->vc_s_intensity = vc->vc_intensity;
1599 vc->vc_s_italic = vc->vc_italic;
1600 vc->vc_s_underline = vc->vc_underline;
1601 vc->vc_s_blink = vc->vc_blink;
1602 vc->vc_s_reverse = vc->vc_reverse;
1603 vc->vc_s_charset = vc->vc_charset;
1604 vc->vc_s_color = vc->vc_color;
1605 vc->vc_saved_G0 = vc->vc_G0_charset;
1606 vc->vc_saved_G1 = vc->vc_G1_charset;
1609 /* console_lock is held */
1610 static void restore_cur(struct vc_data *vc)
1612 gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
1613 vc->vc_intensity = vc->vc_s_intensity;
1614 vc->vc_italic = vc->vc_s_italic;
1615 vc->vc_underline = vc->vc_s_underline;
1616 vc->vc_blink = vc->vc_s_blink;
1617 vc->vc_reverse = vc->vc_s_reverse;
1618 vc->vc_charset = vc->vc_s_charset;
1619 vc->vc_color = vc->vc_s_color;
1620 vc->vc_G0_charset = vc->vc_saved_G0;
1621 vc->vc_G1_charset = vc->vc_saved_G1;
1622 vc->vc_translate = set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc);
1623 update_attr(vc);
1624 vc->vc_need_wrap = 0;
1627 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
1628 EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
1629 ESpalette };
1631 /* console_lock is held (except via vc_init()) */
1632 static void reset_terminal(struct vc_data *vc, int do_clear)
1634 vc->vc_top = 0;
1635 vc->vc_bottom = vc->vc_rows;
1636 vc->vc_state = ESnormal;
1637 vc->vc_ques = 0;
1638 vc->vc_translate = set_translate(LAT1_MAP, vc);
1639 vc->vc_G0_charset = LAT1_MAP;
1640 vc->vc_G1_charset = GRAF_MAP;
1641 vc->vc_charset = 0;
1642 vc->vc_need_wrap = 0;
1643 vc->vc_report_mouse = 0;
1644 vc->vc_utf = default_utf8;
1645 vc->vc_utf_count = 0;
1647 vc->vc_disp_ctrl = 0;
1648 vc->vc_toggle_meta = 0;
1650 vc->vc_decscnm = 0;
1651 vc->vc_decom = 0;
1652 vc->vc_decawm = 1;
1653 vc->vc_deccm = global_cursor_default;
1654 vc->vc_decim = 0;
1656 set_kbd(vc, decarm);
1657 clr_kbd(vc, decckm);
1658 clr_kbd(vc, kbdapplic);
1659 clr_kbd(vc, lnm);
1660 kbd_table[vc->vc_num].lockstate = 0;
1661 kbd_table[vc->vc_num].slockstate = 0;
1662 kbd_table[vc->vc_num].ledmode = LED_SHOW_FLAGS;
1663 kbd_table[vc->vc_num].ledflagstate = kbd_table[vc->vc_num].default_ledflagstate;
1664 /* do not do set_leds here because this causes an endless tasklet loop
1665 when the keyboard hasn't been initialized yet */
1667 vc->vc_cursor_type = cur_default;
1668 vc->vc_complement_mask = vc->vc_s_complement_mask;
1670 default_attr(vc);
1671 update_attr(vc);
1673 vc->vc_tab_stop[0] = 0x01010100;
1674 vc->vc_tab_stop[1] =
1675 vc->vc_tab_stop[2] =
1676 vc->vc_tab_stop[3] =
1677 vc->vc_tab_stop[4] =
1678 vc->vc_tab_stop[5] =
1679 vc->vc_tab_stop[6] =
1680 vc->vc_tab_stop[7] = 0x01010101;
1682 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
1683 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
1685 gotoxy(vc, 0, 0);
1686 save_cur(vc);
1687 if (do_clear)
1688 csi_J(vc, 2);
1691 /* console_lock is held */
1692 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
1695 * Control characters can be used in the _middle_
1696 * of an escape sequence.
1698 switch (c) {
1699 case 0:
1700 return;
1701 case 7:
1702 if (vc->vc_bell_duration)
1703 kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
1704 return;
1705 case 8:
1706 bs(vc);
1707 return;
1708 case 9:
1709 vc->vc_pos -= (vc->vc_x << 1);
1710 while (vc->vc_x < vc->vc_cols - 1) {
1711 vc->vc_x++;
1712 if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
1713 break;
1715 vc->vc_pos += (vc->vc_x << 1);
1716 notify_write(vc, '\t');
1717 return;
1718 case 10: case 11: case 12:
1719 lf(vc);
1720 if (!is_kbd(vc, lnm))
1721 return;
1722 case 13:
1723 cr(vc);
1724 return;
1725 case 14:
1726 vc->vc_charset = 1;
1727 vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
1728 vc->vc_disp_ctrl = 1;
1729 return;
1730 case 15:
1731 vc->vc_charset = 0;
1732 vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
1733 vc->vc_disp_ctrl = 0;
1734 return;
1735 case 24: case 26:
1736 vc->vc_state = ESnormal;
1737 return;
1738 case 27:
1739 vc->vc_state = ESesc;
1740 return;
1741 case 127:
1742 del(vc);
1743 return;
1744 case 128+27:
1745 vc->vc_state = ESsquare;
1746 return;
1748 switch(vc->vc_state) {
1749 case ESesc:
1750 vc->vc_state = ESnormal;
1751 switch (c) {
1752 case '[':
1753 vc->vc_state = ESsquare;
1754 return;
1755 case ']':
1756 vc->vc_state = ESnonstd;
1757 return;
1758 case '%':
1759 vc->vc_state = ESpercent;
1760 return;
1761 case 'E':
1762 cr(vc);
1763 lf(vc);
1764 return;
1765 case 'M':
1766 ri(vc);
1767 return;
1768 case 'D':
1769 lf(vc);
1770 return;
1771 case 'H':
1772 vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31));
1773 return;
1774 case 'Z':
1775 respond_ID(tty);
1776 return;
1777 case '7':
1778 save_cur(vc);
1779 return;
1780 case '8':
1781 restore_cur(vc);
1782 return;
1783 case '(':
1784 vc->vc_state = ESsetG0;
1785 return;
1786 case ')':
1787 vc->vc_state = ESsetG1;
1788 return;
1789 case '#':
1790 vc->vc_state = EShash;
1791 return;
1792 case 'c':
1793 reset_terminal(vc, 1);
1794 return;
1795 case '>': /* Numeric keypad */
1796 clr_kbd(vc, kbdapplic);
1797 return;
1798 case '=': /* Appl. keypad */
1799 set_kbd(vc, kbdapplic);
1800 return;
1802 return;
1803 case ESnonstd:
1804 if (c=='P') { /* palette escape sequence */
1805 for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
1806 vc->vc_par[vc->vc_npar] = 0;
1807 vc->vc_npar = 0;
1808 vc->vc_state = ESpalette;
1809 return;
1810 } else if (c=='R') { /* reset palette */
1811 reset_palette(vc);
1812 vc->vc_state = ESnormal;
1813 } else
1814 vc->vc_state = ESnormal;
1815 return;
1816 case ESpalette:
1817 if (isxdigit(c)) {
1818 vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
1819 if (vc->vc_npar == 7) {
1820 int i = vc->vc_par[0] * 3, j = 1;
1821 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1822 vc->vc_palette[i++] += vc->vc_par[j++];
1823 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1824 vc->vc_palette[i++] += vc->vc_par[j++];
1825 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1826 vc->vc_palette[i] += vc->vc_par[j];
1827 set_palette(vc);
1828 vc->vc_state = ESnormal;
1830 } else
1831 vc->vc_state = ESnormal;
1832 return;
1833 case ESsquare:
1834 for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
1835 vc->vc_par[vc->vc_npar] = 0;
1836 vc->vc_npar = 0;
1837 vc->vc_state = ESgetpars;
1838 if (c == '[') { /* Function key */
1839 vc->vc_state=ESfunckey;
1840 return;
1842 vc->vc_ques = (c == '?');
1843 if (vc->vc_ques)
1844 return;
1845 case ESgetpars:
1846 if (c == ';' && vc->vc_npar < NPAR - 1) {
1847 vc->vc_npar++;
1848 return;
1849 } else if (c>='0' && c<='9') {
1850 vc->vc_par[vc->vc_npar] *= 10;
1851 vc->vc_par[vc->vc_npar] += c - '0';
1852 return;
1853 } else
1854 vc->vc_state = ESgotpars;
1855 case ESgotpars:
1856 vc->vc_state = ESnormal;
1857 switch(c) {
1858 case 'h':
1859 set_mode(vc, 1);
1860 return;
1861 case 'l':
1862 set_mode(vc, 0);
1863 return;
1864 case 'c':
1865 if (vc->vc_ques) {
1866 if (vc->vc_par[0])
1867 vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
1868 else
1869 vc->vc_cursor_type = cur_default;
1870 return;
1872 break;
1873 case 'm':
1874 if (vc->vc_ques) {
1875 clear_selection();
1876 if (vc->vc_par[0])
1877 vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
1878 else
1879 vc->vc_complement_mask = vc->vc_s_complement_mask;
1880 return;
1882 break;
1883 case 'n':
1884 if (!vc->vc_ques) {
1885 if (vc->vc_par[0] == 5)
1886 status_report(tty);
1887 else if (vc->vc_par[0] == 6)
1888 cursor_report(vc, tty);
1890 return;
1892 if (vc->vc_ques) {
1893 vc->vc_ques = 0;
1894 return;
1896 switch(c) {
1897 case 'G': case '`':
1898 if (vc->vc_par[0])
1899 vc->vc_par[0]--;
1900 gotoxy(vc, vc->vc_par[0], vc->vc_y);
1901 return;
1902 case 'A':
1903 if (!vc->vc_par[0])
1904 vc->vc_par[0]++;
1905 gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]);
1906 return;
1907 case 'B': case 'e':
1908 if (!vc->vc_par[0])
1909 vc->vc_par[0]++;
1910 gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]);
1911 return;
1912 case 'C': case 'a':
1913 if (!vc->vc_par[0])
1914 vc->vc_par[0]++;
1915 gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y);
1916 return;
1917 case 'D':
1918 if (!vc->vc_par[0])
1919 vc->vc_par[0]++;
1920 gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y);
1921 return;
1922 case 'E':
1923 if (!vc->vc_par[0])
1924 vc->vc_par[0]++;
1925 gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]);
1926 return;
1927 case 'F':
1928 if (!vc->vc_par[0])
1929 vc->vc_par[0]++;
1930 gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]);
1931 return;
1932 case 'd':
1933 if (vc->vc_par[0])
1934 vc->vc_par[0]--;
1935 gotoxay(vc, vc->vc_x ,vc->vc_par[0]);
1936 return;
1937 case 'H': case 'f':
1938 if (vc->vc_par[0])
1939 vc->vc_par[0]--;
1940 if (vc->vc_par[1])
1941 vc->vc_par[1]--;
1942 gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
1943 return;
1944 case 'J':
1945 csi_J(vc, vc->vc_par[0]);
1946 return;
1947 case 'K':
1948 csi_K(vc, vc->vc_par[0]);
1949 return;
1950 case 'L':
1951 csi_L(vc, vc->vc_par[0]);
1952 return;
1953 case 'M':
1954 csi_M(vc, vc->vc_par[0]);
1955 return;
1956 case 'P':
1957 csi_P(vc, vc->vc_par[0]);
1958 return;
1959 case 'c':
1960 if (!vc->vc_par[0])
1961 respond_ID(tty);
1962 return;
1963 case 'g':
1964 if (!vc->vc_par[0])
1965 vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31));
1966 else if (vc->vc_par[0] == 3) {
1967 vc->vc_tab_stop[0] =
1968 vc->vc_tab_stop[1] =
1969 vc->vc_tab_stop[2] =
1970 vc->vc_tab_stop[3] =
1971 vc->vc_tab_stop[4] =
1972 vc->vc_tab_stop[5] =
1973 vc->vc_tab_stop[6] =
1974 vc->vc_tab_stop[7] = 0;
1976 return;
1977 case 'm':
1978 csi_m(vc);
1979 return;
1980 case 'q': /* DECLL - but only 3 leds */
1981 /* map 0,1,2,3 to 0,1,2,4 */
1982 if (vc->vc_par[0] < 4)
1983 setledstate(kbd_table + vc->vc_num,
1984 (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
1985 return;
1986 case 'r':
1987 if (!vc->vc_par[0])
1988 vc->vc_par[0]++;
1989 if (!vc->vc_par[1])
1990 vc->vc_par[1] = vc->vc_rows;
1991 /* Minimum allowed region is 2 lines */
1992 if (vc->vc_par[0] < vc->vc_par[1] &&
1993 vc->vc_par[1] <= vc->vc_rows) {
1994 vc->vc_top = vc->vc_par[0] - 1;
1995 vc->vc_bottom = vc->vc_par[1];
1996 gotoxay(vc, 0, 0);
1998 return;
1999 case 's':
2000 save_cur(vc);
2001 return;
2002 case 'u':
2003 restore_cur(vc);
2004 return;
2005 case 'X':
2006 csi_X(vc, vc->vc_par[0]);
2007 return;
2008 case '@':
2009 csi_at(vc, vc->vc_par[0]);
2010 return;
2011 case ']': /* setterm functions */
2012 setterm_command(vc);
2013 return;
2015 return;
2016 case ESpercent:
2017 vc->vc_state = ESnormal;
2018 switch (c) {
2019 case '@': /* defined in ISO 2022 */
2020 vc->vc_utf = 0;
2021 return;
2022 case 'G': /* prelim official escape code */
2023 case '8': /* retained for compatibility */
2024 vc->vc_utf = 1;
2025 return;
2027 return;
2028 case ESfunckey:
2029 vc->vc_state = ESnormal;
2030 return;
2031 case EShash:
2032 vc->vc_state = ESnormal;
2033 if (c == '8') {
2034 /* DEC screen alignment test. kludge :-) */
2035 vc->vc_video_erase_char =
2036 (vc->vc_video_erase_char & 0xff00) | 'E';
2037 csi_J(vc, 2);
2038 vc->vc_video_erase_char =
2039 (vc->vc_video_erase_char & 0xff00) | ' ';
2040 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
2042 return;
2043 case ESsetG0:
2044 if (c == '0')
2045 vc->vc_G0_charset = GRAF_MAP;
2046 else if (c == 'B')
2047 vc->vc_G0_charset = LAT1_MAP;
2048 else if (c == 'U')
2049 vc->vc_G0_charset = IBMPC_MAP;
2050 else if (c == 'K')
2051 vc->vc_G0_charset = USER_MAP;
2052 if (vc->vc_charset == 0)
2053 vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
2054 vc->vc_state = ESnormal;
2055 return;
2056 case ESsetG1:
2057 if (c == '0')
2058 vc->vc_G1_charset = GRAF_MAP;
2059 else if (c == 'B')
2060 vc->vc_G1_charset = LAT1_MAP;
2061 else if (c == 'U')
2062 vc->vc_G1_charset = IBMPC_MAP;
2063 else if (c == 'K')
2064 vc->vc_G1_charset = USER_MAP;
2065 if (vc->vc_charset == 1)
2066 vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
2067 vc->vc_state = ESnormal;
2068 return;
2069 default:
2070 vc->vc_state = ESnormal;
2074 /* is_double_width() is based on the wcwidth() implementation by
2075 * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
2076 * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
2078 struct interval {
2079 uint32_t first;
2080 uint32_t last;
2083 static int bisearch(uint32_t ucs, const struct interval *table, int max)
2085 int min = 0;
2086 int mid;
2088 if (ucs < table[0].first || ucs > table[max].last)
2089 return 0;
2090 while (max >= min) {
2091 mid = (min + max) / 2;
2092 if (ucs > table[mid].last)
2093 min = mid + 1;
2094 else if (ucs < table[mid].first)
2095 max = mid - 1;
2096 else
2097 return 1;
2099 return 0;
2102 static int is_double_width(uint32_t ucs)
2104 static const struct interval double_width[] = {
2105 { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
2106 { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
2107 { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 },
2108 { 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
2110 return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1);
2113 /* acquires console_lock */
2114 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
2116 #ifdef VT_BUF_VRAM_ONLY
2117 #define FLUSH do { } while(0);
2118 #else
2119 #define FLUSH if (draw_x >= 0) { \
2120 vc->vc_sw->con_putcs(vc, (u16 *)draw_from, (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, draw_x); \
2121 draw_x = -1; \
2123 #endif
2125 int c, tc, ok, n = 0, draw_x = -1;
2126 unsigned int currcons;
2127 unsigned long draw_from = 0, draw_to = 0;
2128 struct vc_data *vc;
2129 unsigned char vc_attr;
2130 struct vt_notifier_param param;
2131 uint8_t rescan;
2132 uint8_t inverse;
2133 uint8_t width;
2134 u16 himask, charmask;
2136 if (in_interrupt())
2137 return count;
2139 might_sleep();
2141 console_lock();
2142 vc = tty->driver_data;
2143 if (vc == NULL) {
2144 printk(KERN_ERR "vt: argh, driver_data is NULL !\n");
2145 console_unlock();
2146 return 0;
2149 currcons = vc->vc_num;
2150 if (!vc_cons_allocated(currcons)) {
2151 /* could this happen? */
2152 pr_warn_once("con_write: tty %d not allocated\n", currcons+1);
2153 console_unlock();
2154 return 0;
2157 himask = vc->vc_hi_font_mask;
2158 charmask = himask ? 0x1ff : 0xff;
2160 /* undraw cursor first */
2161 if (IS_FG(vc))
2162 hide_cursor(vc);
2164 param.vc = vc;
2166 while (!tty->stopped && count) {
2167 int orig = *buf;
2168 c = orig;
2169 buf++;
2170 n++;
2171 count--;
2172 rescan = 0;
2173 inverse = 0;
2174 width = 1;
2176 /* Do no translation at all in control states */
2177 if (vc->vc_state != ESnormal) {
2178 tc = c;
2179 } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
2180 /* Combine UTF-8 into Unicode in vc_utf_char.
2181 * vc_utf_count is the number of continuation bytes still
2182 * expected to arrive.
2183 * vc_npar is the number of continuation bytes arrived so
2184 * far
2186 rescan_last_byte:
2187 if ((c & 0xc0) == 0x80) {
2188 /* Continuation byte received */
2189 static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
2190 if (vc->vc_utf_count) {
2191 vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2192 vc->vc_npar++;
2193 if (--vc->vc_utf_count) {
2194 /* Still need some bytes */
2195 continue;
2197 /* Got a whole character */
2198 c = vc->vc_utf_char;
2199 /* Reject overlong sequences */
2200 if (c <= utf8_length_changes[vc->vc_npar - 1] ||
2201 c > utf8_length_changes[vc->vc_npar])
2202 c = 0xfffd;
2203 } else {
2204 /* Unexpected continuation byte */
2205 vc->vc_utf_count = 0;
2206 c = 0xfffd;
2208 } else {
2209 /* Single ASCII byte or first byte of a sequence received */
2210 if (vc->vc_utf_count) {
2211 /* Continuation byte expected */
2212 rescan = 1;
2213 vc->vc_utf_count = 0;
2214 c = 0xfffd;
2215 } else if (c > 0x7f) {
2216 /* First byte of a multibyte sequence received */
2217 vc->vc_npar = 0;
2218 if ((c & 0xe0) == 0xc0) {
2219 vc->vc_utf_count = 1;
2220 vc->vc_utf_char = (c & 0x1f);
2221 } else if ((c & 0xf0) == 0xe0) {
2222 vc->vc_utf_count = 2;
2223 vc->vc_utf_char = (c & 0x0f);
2224 } else if ((c & 0xf8) == 0xf0) {
2225 vc->vc_utf_count = 3;
2226 vc->vc_utf_char = (c & 0x07);
2227 } else if ((c & 0xfc) == 0xf8) {
2228 vc->vc_utf_count = 4;
2229 vc->vc_utf_char = (c & 0x03);
2230 } else if ((c & 0xfe) == 0xfc) {
2231 vc->vc_utf_count = 5;
2232 vc->vc_utf_char = (c & 0x01);
2233 } else {
2234 /* 254 and 255 are invalid */
2235 c = 0xfffd;
2237 if (vc->vc_utf_count) {
2238 /* Still need some bytes */
2239 continue;
2242 /* Nothing to do if an ASCII byte was received */
2244 /* End of UTF-8 decoding. */
2245 /* c is the received character, or U+FFFD for invalid sequences. */
2246 /* Replace invalid Unicode code points with U+FFFD too */
2247 if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
2248 c = 0xfffd;
2249 tc = c;
2250 } else { /* no utf or alternate charset mode */
2251 tc = vc_translate(vc, c);
2254 param.c = tc;
2255 if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE,
2256 &param) == NOTIFY_STOP)
2257 continue;
2259 /* If the original code was a control character we
2260 * only allow a glyph to be displayed if the code is
2261 * not normally used (such as for cursor movement) or
2262 * if the disp_ctrl mode has been explicitly enabled.
2263 * Certain characters (as given by the CTRL_ALWAYS
2264 * bitmap) are always displayed as control characters,
2265 * as the console would be pretty useless without
2266 * them; to display an arbitrary font position use the
2267 * direct-to-font zone in UTF-8 mode.
2269 ok = tc && (c >= 32 ||
2270 !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
2271 vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
2272 && (c != 127 || vc->vc_disp_ctrl)
2273 && (c != 128+27);
2275 if (vc->vc_state == ESnormal && ok) {
2276 if (vc->vc_utf && !vc->vc_disp_ctrl) {
2277 if (is_double_width(c))
2278 width = 2;
2280 /* Now try to find out how to display it */
2281 tc = conv_uni_to_pc(vc, tc);
2282 if (tc & ~charmask) {
2283 if (tc == -1 || tc == -2) {
2284 continue; /* nothing to display */
2286 /* Glyph not found */
2287 if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
2288 /* In legacy mode use the glyph we get by a 1:1 mapping.
2289 This would make absolutely no sense with Unicode in mind,
2290 but do this for ASCII characters since a font may lack
2291 Unicode mapping info and we don't want to end up with
2292 having question marks only. */
2293 tc = c;
2294 } else {
2295 /* Display U+FFFD. If it's not found, display an inverse question mark. */
2296 tc = conv_uni_to_pc(vc, 0xfffd);
2297 if (tc < 0) {
2298 inverse = 1;
2299 tc = conv_uni_to_pc(vc, '?');
2300 if (tc < 0) tc = '?';
2305 if (!inverse) {
2306 vc_attr = vc->vc_attr;
2307 } else {
2308 /* invert vc_attr */
2309 if (!vc->vc_can_do_color) {
2310 vc_attr = (vc->vc_attr) ^ 0x08;
2311 } else if (vc->vc_hi_font_mask == 0x100) {
2312 vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
2313 } else {
2314 vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
2316 FLUSH
2319 while (1) {
2320 if (vc->vc_need_wrap || vc->vc_decim)
2321 FLUSH
2322 if (vc->vc_need_wrap) {
2323 cr(vc);
2324 lf(vc);
2326 if (vc->vc_decim)
2327 insert_char(vc, 1);
2328 scr_writew(himask ?
2329 ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
2330 (vc_attr << 8) + tc,
2331 (u16 *) vc->vc_pos);
2332 if (DO_UPDATE(vc) && draw_x < 0) {
2333 draw_x = vc->vc_x;
2334 draw_from = vc->vc_pos;
2336 if (vc->vc_x == vc->vc_cols - 1) {
2337 vc->vc_need_wrap = vc->vc_decawm;
2338 draw_to = vc->vc_pos + 2;
2339 } else {
2340 vc->vc_x++;
2341 draw_to = (vc->vc_pos += 2);
2344 if (!--width) break;
2346 tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
2347 if (tc < 0) tc = ' ';
2349 notify_write(vc, c);
2351 if (inverse) {
2352 FLUSH
2355 if (rescan) {
2356 rescan = 0;
2357 inverse = 0;
2358 width = 1;
2359 c = orig;
2360 goto rescan_last_byte;
2362 continue;
2364 FLUSH
2365 do_con_trol(tty, vc, orig);
2367 FLUSH
2368 console_conditional_schedule();
2369 console_unlock();
2370 notify_update(vc);
2371 return n;
2372 #undef FLUSH
2376 * This is the console switching callback.
2378 * Doing console switching in a process context allows
2379 * us to do the switches asynchronously (needed when we want
2380 * to switch due to a keyboard interrupt). Synchronization
2381 * with other console code and prevention of re-entrancy is
2382 * ensured with console_lock.
2384 static void console_callback(struct work_struct *ignored)
2386 console_lock();
2388 if (want_console >= 0) {
2389 if (want_console != fg_console &&
2390 vc_cons_allocated(want_console)) {
2391 hide_cursor(vc_cons[fg_console].d);
2392 change_console(vc_cons[want_console].d);
2393 /* we only changed when the console had already
2394 been allocated - a new console is not created
2395 in an interrupt routine */
2397 want_console = -1;
2399 if (do_poke_blanked_console) { /* do not unblank for a LED change */
2400 do_poke_blanked_console = 0;
2401 poke_blanked_console();
2403 if (scrollback_delta) {
2404 struct vc_data *vc = vc_cons[fg_console].d;
2405 clear_selection();
2406 if (vc->vc_mode == KD_TEXT)
2407 vc->vc_sw->con_scrolldelta(vc, scrollback_delta);
2408 scrollback_delta = 0;
2410 if (blank_timer_expired) {
2411 do_blank_screen(0);
2412 blank_timer_expired = 0;
2414 notify_update(vc_cons[fg_console].d);
2416 console_unlock();
2419 int set_console(int nr)
2421 struct vc_data *vc = vc_cons[fg_console].d;
2423 if (!vc_cons_allocated(nr) || vt_dont_switch ||
2424 (vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) {
2427 * Console switch will fail in console_callback() or
2428 * change_console() so there is no point scheduling
2429 * the callback
2431 * Existing set_console() users don't check the return
2432 * value so this shouldn't break anything
2434 return -EINVAL;
2437 want_console = nr;
2438 schedule_console_callback();
2440 return 0;
2443 struct tty_driver *console_driver;
2445 #ifdef CONFIG_VT_CONSOLE
2448 * vt_kmsg_redirect() - Sets/gets the kernel message console
2449 * @new: The new virtual terminal number or -1 if the console should stay
2450 * unchanged
2452 * By default, the kernel messages are always printed on the current virtual
2453 * console. However, the user may modify that default with the
2454 * TIOCL_SETKMSGREDIRECT ioctl call.
2456 * This function sets the kernel message console to be @new. It returns the old
2457 * virtual console number. The virtual terminal number 0 (both as parameter and
2458 * return value) means no redirection (i.e. always printed on the currently
2459 * active console).
2461 * The parameter -1 means that only the current console is returned, but the
2462 * value is not modified. You may use the macro vt_get_kmsg_redirect() in that
2463 * case to make the code more understandable.
2465 * When the kernel is compiled without CONFIG_VT_CONSOLE, this function ignores
2466 * the parameter and always returns 0.
2468 int vt_kmsg_redirect(int new)
2470 static int kmsg_con;
2472 if (new != -1)
2473 return xchg(&kmsg_con, new);
2474 else
2475 return kmsg_con;
2478 #ifdef CONFIG_VT_CKO
2479 static unsigned int printk_color[8] __read_mostly = {
2480 CONFIG_VT_PRINTK_EMERG_COLOR, /* KERN_EMERG */
2481 CONFIG_VT_PRINTK_ALERT_COLOR, /* KERN_ALERT */
2482 CONFIG_VT_PRINTK_CRIT_COLOR, /* KERN_CRIT */
2483 CONFIG_VT_PRINTK_ERR_COLOR, /* KERN_ERR */
2484 CONFIG_VT_PRINTK_WARNING_COLOR, /* KERN_WARNING */
2485 CONFIG_VT_PRINTK_NOTICE_COLOR, /* KERN_NOTICE */
2486 CONFIG_VT_PRINTK_INFO_COLOR, /* KERN_INFO */
2487 CONFIG_VT_PRINTK_DEBUG_COLOR, /* KERN_DEBUG */
2489 module_param_array(printk_color, uint, NULL, S_IRUGO | S_IWUSR);
2491 static inline void vc_set_color(struct vc_data *vc, unsigned char color)
2493 vc->vc_color = color_table[color & 0xF] |
2494 (color_table[(color >> 4) & 0x7] << 4) |
2495 (color & 0x80);
2496 update_attr(vc);
2498 #else
2499 static unsigned int printk_color[8];
2500 static inline void vc_set_color(const struct vc_data *vc, unsigned char c)
2503 #endif
2506 * Console on virtual terminal
2508 * The console must be locked when we get here.
2511 static void vt_console_print(struct console *co, const char *b, unsigned count,
2512 unsigned int loglevel)
2514 struct vc_data *vc = vc_cons[fg_console].d;
2515 static DEFINE_SPINLOCK(printing_lock);
2516 unsigned char current_color, c;
2517 const ushort *start;
2518 ushort cnt = 0;
2519 ushort myx;
2520 int kmsg_console;
2522 /* console busy or not yet initialized */
2523 if (!printable)
2524 return;
2525 if (!spin_trylock(&printing_lock))
2526 return;
2528 kmsg_console = vt_get_kmsg_redirect();
2529 if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
2530 vc = vc_cons[kmsg_console - 1].d;
2532 /* read `x' only after setting currcons properly (otherwise
2533 the `x' macro will read the x of the foreground console). */
2534 myx = vc->vc_x;
2536 if (!vc_cons_allocated(fg_console)) {
2537 /* impossible */
2538 /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
2539 goto quit;
2542 if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
2543 goto quit;
2545 /* undraw cursor first */
2546 if (IS_FG(vc))
2547 hide_cursor(vc);
2549 start = (ushort *)vc->vc_pos;
2552 * We always get a valid loglevel - <8> and "no level" is transformed
2553 * to <4> in the typical kernel.
2555 current_color = printk_color[loglevel];
2556 vc_set_color(vc, current_color);
2558 /* Contrived structure to try to emulate original need_wrap behaviour
2559 * Problems caused when we have need_wrap set on '\n' character */
2560 while (count--) {
2561 c = *b++;
2562 if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
2563 vc_set_color(vc, vc->vc_def_color);
2564 if (cnt > 0) {
2565 if (CON_IS_VISIBLE(vc))
2566 vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
2567 vc->vc_x += cnt;
2568 if (vc->vc_need_wrap)
2569 vc->vc_x--;
2570 cnt = 0;
2572 if (c == 8) { /* backspace */
2573 bs(vc);
2574 start = (ushort *)vc->vc_pos;
2575 myx = vc->vc_x;
2576 vc_set_color(vc, current_color);
2577 continue;
2579 if (c != 13)
2580 lf(vc);
2581 cr(vc);
2582 start = (ushort *)vc->vc_pos;
2583 myx = vc->vc_x;
2584 vc_set_color(vc, current_color);
2585 if (c == 10 || c == 13)
2586 continue;
2588 scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
2589 notify_write(vc, c);
2590 cnt++;
2591 if (myx == vc->vc_cols - 1) {
2592 vc->vc_need_wrap = 1;
2593 continue;
2595 vc->vc_pos += 2;
2596 myx++;
2598 if (cnt > 0) {
2599 if (CON_IS_VISIBLE(vc))
2600 vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
2601 vc->vc_x += cnt;
2602 if (vc->vc_x == vc->vc_cols) {
2603 vc->vc_x--;
2604 vc->vc_need_wrap = 1;
2607 vc_set_color(vc, vc->vc_def_color);
2608 set_cursor(vc);
2609 notify_update(vc);
2611 quit:
2612 spin_unlock(&printing_lock);
2615 static struct tty_driver *vt_console_device(struct console *c, int *index)
2617 *index = c->index ? c->index-1 : fg_console;
2618 return console_driver;
2621 static struct console vt_console_driver = {
2622 .name = "tty",
2623 .write = vt_console_print,
2624 .device = vt_console_device,
2625 .unblank = unblank_screen,
2626 .flags = CON_PRINTBUFFER,
2627 .index = -1,
2629 #endif
2632 * Handling of Linux-specific VC ioctls
2636 * Generally a bit racy with respect to console_lock();.
2638 * There are some functions which don't need it.
2640 * There are some functions which can sleep for arbitrary periods
2641 * (paste_selection) but we don't need the lock there anyway.
2643 * set_selection has locking, and definitely needs it
2646 int tioclinux(struct tty_struct *tty, unsigned long arg)
2648 char type, data;
2649 char __user *p = (char __user *)arg;
2650 int lines;
2651 int ret;
2653 if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN))
2654 return -EPERM;
2655 if (get_user(type, p))
2656 return -EFAULT;
2657 ret = 0;
2659 switch (type)
2661 case TIOCL_SETSEL:
2662 console_lock();
2663 ret = set_selection((struct tiocl_selection __user *)(p+1), tty);
2664 console_unlock();
2665 break;
2666 case TIOCL_PASTESEL:
2667 ret = paste_selection(tty);
2668 break;
2669 case TIOCL_UNBLANKSCREEN:
2670 console_lock();
2671 unblank_screen();
2672 console_unlock();
2673 break;
2674 case TIOCL_SELLOADLUT:
2675 ret = sel_loadlut(p);
2676 break;
2677 case TIOCL_GETSHIFTSTATE:
2680 * Make it possible to react to Shift+Mousebutton.
2681 * Note that 'shift_state' is an undocumented
2682 * kernel-internal variable; programs not closely
2683 * related to the kernel should not use this.
2685 data = shift_state;
2686 ret = __put_user(data, p);
2687 break;
2688 case TIOCL_GETMOUSEREPORTING:
2689 data = mouse_reporting();
2690 ret = __put_user(data, p);
2691 break;
2692 case TIOCL_SETVESABLANK:
2693 ret = set_vesa_blanking(p);
2694 break;
2695 case TIOCL_GETKMSGREDIRECT:
2696 data = vt_get_kmsg_redirect();
2697 ret = __put_user(data, p);
2698 break;
2699 case TIOCL_SETKMSGREDIRECT:
2700 if (!capable(CAP_SYS_ADMIN)) {
2701 ret = -EPERM;
2702 } else {
2703 if (get_user(data, p+1))
2704 ret = -EFAULT;
2705 else
2706 vt_kmsg_redirect(data);
2708 break;
2709 case TIOCL_GETFGCONSOLE:
2710 ret = fg_console;
2711 break;
2712 case TIOCL_SCROLLCONSOLE:
2713 if (get_user(lines, (s32 __user *)(p+4))) {
2714 ret = -EFAULT;
2715 } else {
2716 scrollfront(vc_cons[fg_console].d, lines);
2717 ret = 0;
2719 break;
2720 case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */
2721 console_lock();
2722 ignore_poke = 1;
2723 do_blank_screen(0);
2724 console_unlock();
2725 break;
2726 case TIOCL_BLANKEDSCREEN:
2727 ret = console_blanked;
2728 break;
2729 default:
2730 ret = -EINVAL;
2731 break;
2733 return ret;
2737 * /dev/ttyN handling
2740 static int con_write(struct tty_struct *tty, const unsigned char *buf, int count)
2742 int retval;
2744 retval = do_con_write(tty, buf, count);
2745 con_flush_chars(tty);
2747 return retval;
2750 static int con_put_char(struct tty_struct *tty, unsigned char ch)
2752 if (in_interrupt())
2753 return 0; /* n_r3964 calls put_char() from interrupt context */
2754 return do_con_write(tty, &ch, 1);
2757 static int con_write_room(struct tty_struct *tty)
2759 if (tty->stopped)
2760 return 0;
2761 return 32768; /* No limit, really; we're not buffering */
2764 static int con_chars_in_buffer(struct tty_struct *tty)
2766 return 0; /* we're not buffering */
2770 * con_throttle and con_unthrottle are only used for
2771 * paste_selection(), which has to stuff in a large number of
2772 * characters...
2774 static void con_throttle(struct tty_struct *tty)
2778 static void con_unthrottle(struct tty_struct *tty)
2780 struct vc_data *vc = tty->driver_data;
2782 wake_up_interruptible(&vc->paste_wait);
2786 * Turn the Scroll-Lock LED on when the tty is stopped
2788 static void con_stop(struct tty_struct *tty)
2790 int console_num;
2791 if (!tty)
2792 return;
2793 console_num = tty->index;
2794 if (!vc_cons_allocated(console_num))
2795 return;
2796 set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
2797 set_leds();
2801 * Turn the Scroll-Lock LED off when the console is started
2803 static void con_start(struct tty_struct *tty)
2805 int console_num;
2806 if (!tty)
2807 return;
2808 console_num = tty->index;
2809 if (!vc_cons_allocated(console_num))
2810 return;
2811 clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
2812 set_leds();
2815 static void con_flush_chars(struct tty_struct *tty)
2817 struct vc_data *vc;
2819 if (in_interrupt()) /* from flush_to_ldisc */
2820 return;
2822 /* if we race with con_close(), vt may be null */
2823 console_lock();
2824 vc = tty->driver_data;
2825 if (vc)
2826 set_cursor(vc);
2827 console_unlock();
2831 * Allocate the console screen memory.
2833 static int con_open(struct tty_struct *tty, struct file *filp)
2835 unsigned int currcons = tty->index;
2836 int ret = 0;
2838 console_lock();
2839 if (tty->driver_data == NULL) {
2840 ret = vc_allocate(currcons);
2841 if (ret == 0) {
2842 struct vc_data *vc = vc_cons[currcons].d;
2844 /* Still being freed */
2845 if (vc->port.tty) {
2846 console_unlock();
2847 return -ERESTARTSYS;
2849 tty->driver_data = vc;
2850 vc->port.tty = tty;
2852 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2853 tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
2854 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
2856 if (vc->vc_utf)
2857 tty->termios->c_iflag |= IUTF8;
2858 else
2859 tty->termios->c_iflag &= ~IUTF8;
2860 console_unlock();
2861 return ret;
2864 console_unlock();
2865 return ret;
2868 static void con_close(struct tty_struct *tty, struct file *filp)
2870 /* Nothing to do - we defer to shutdown */
2873 static void con_shutdown(struct tty_struct *tty)
2875 struct vc_data *vc = tty->driver_data;
2876 BUG_ON(vc == NULL);
2877 console_lock();
2878 vc->port.tty = NULL;
2879 console_unlock();
2880 tty_shutdown(tty);
2883 static int default_italic_color = 2; // green (ASCII)
2884 static int default_underline_color = 3; // cyan (ASCII)
2885 module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
2886 module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
2888 static void vc_init(struct vc_data *vc, unsigned int rows,
2889 unsigned int cols, int do_clear)
2891 int j, k ;
2893 vc->vc_cols = cols;
2894 vc->vc_rows = rows;
2895 vc->vc_size_row = cols << 1;
2896 vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
2898 set_origin(vc);
2899 vc->vc_pos = vc->vc_origin;
2900 reset_vc(vc);
2901 for (j=k=0; j<16; j++) {
2902 vc->vc_palette[k++] = default_red[j] ;
2903 vc->vc_palette[k++] = default_grn[j] ;
2904 vc->vc_palette[k++] = default_blu[j] ;
2906 vc->vc_def_color = 0x07; /* white */
2907 vc->vc_ulcolor = default_underline_color;
2908 vc->vc_itcolor = default_italic_color;
2909 vc->vc_halfcolor = 0x08; /* grey */
2910 init_waitqueue_head(&vc->paste_wait);
2911 reset_terminal(vc, do_clear);
2915 * This routine initializes console interrupts, and does nothing
2916 * else. If you want the screen to clear, call tty_write with
2917 * the appropriate escape-sequence.
2920 static int __init con_init(void)
2922 const char *display_desc = NULL;
2923 struct vc_data *vc;
2924 unsigned int currcons = 0, i;
2926 console_lock();
2928 if (conswitchp)
2929 display_desc = conswitchp->con_startup();
2930 if (!display_desc) {
2931 fg_console = 0;
2932 console_unlock();
2933 return 0;
2936 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
2937 struct con_driver *con_driver = &registered_con_driver[i];
2939 if (con_driver->con == NULL) {
2940 con_driver->con = conswitchp;
2941 con_driver->desc = display_desc;
2942 con_driver->flag = CON_DRIVER_FLAG_INIT;
2943 con_driver->first = 0;
2944 con_driver->last = MAX_NR_CONSOLES - 1;
2945 break;
2949 for (i = 0; i < MAX_NR_CONSOLES; i++)
2950 con_driver_map[i] = conswitchp;
2952 if (blankinterval) {
2953 blank_state = blank_normal_wait;
2954 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
2957 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
2958 vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
2959 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
2960 tty_port_init(&vc->port);
2961 visual_init(vc, currcons, 1);
2962 vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
2963 vc_init(vc, vc->vc_rows, vc->vc_cols,
2964 currcons || !vc->vc_sw->con_save_screen);
2966 currcons = fg_console = 0;
2967 master_display_fg = vc = vc_cons[currcons].d;
2968 set_origin(vc);
2969 save_screen(vc);
2970 gotoxy(vc, vc->vc_x, vc->vc_y);
2971 csi_J(vc, 0);
2972 update_screen(vc);
2973 pr_info("Console: %s %s %dx%d",
2974 vc->vc_can_do_color ? "colour" : "mono",
2975 display_desc, vc->vc_cols, vc->vc_rows);
2976 printable = 1;
2977 printk("\n");
2979 console_unlock();
2981 #ifdef CONFIG_VT_CONSOLE
2982 register_console(&vt_console_driver);
2983 #endif
2984 return 0;
2986 console_initcall(con_init);
2988 static const struct tty_operations con_ops = {
2989 .open = con_open,
2990 .close = con_close,
2991 .write = con_write,
2992 .write_room = con_write_room,
2993 .put_char = con_put_char,
2994 .flush_chars = con_flush_chars,
2995 .chars_in_buffer = con_chars_in_buffer,
2996 .ioctl = vt_ioctl,
2997 #ifdef CONFIG_COMPAT
2998 .compat_ioctl = vt_compat_ioctl,
2999 #endif
3000 .stop = con_stop,
3001 .start = con_start,
3002 .throttle = con_throttle,
3003 .unthrottle = con_unthrottle,
3004 .resize = vt_resize,
3005 .shutdown = con_shutdown
3008 static struct cdev vc0_cdev;
3010 static ssize_t show_tty_active(struct device *dev,
3011 struct device_attribute *attr, char *buf)
3013 return sprintf(buf, "tty%d\n", fg_console + 1);
3015 static DEVICE_ATTR(active, S_IRUGO, show_tty_active, NULL);
3017 int __init vty_init(const struct file_operations *console_fops)
3019 cdev_init(&vc0_cdev, console_fops);
3020 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
3021 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
3022 panic("Couldn't register /dev/tty0 driver\n");
3023 tty0dev = device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
3024 if (IS_ERR(tty0dev))
3025 tty0dev = NULL;
3026 else
3027 WARN_ON(device_create_file(tty0dev, &dev_attr_active) < 0);
3029 vcs_init();
3031 console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
3032 if (!console_driver)
3033 panic("Couldn't allocate console driver\n");
3034 console_driver->owner = THIS_MODULE;
3035 console_driver->name = "tty";
3036 console_driver->name_base = 1;
3037 console_driver->major = TTY_MAJOR;
3038 console_driver->minor_start = 1;
3039 console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
3040 console_driver->init_termios = tty_std_termios;
3041 if (default_utf8)
3042 console_driver->init_termios.c_iflag |= IUTF8;
3043 console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
3044 tty_set_operations(console_driver, &con_ops);
3045 if (tty_register_driver(console_driver))
3046 panic("Couldn't register console driver\n");
3047 kbd_init();
3048 console_map_init();
3049 #ifdef CONFIG_MDA_CONSOLE
3050 mda_console_init();
3051 #endif
3052 return 0;
3055 #ifndef VT_SINGLE_DRIVER
3057 static struct class *vtconsole_class;
3059 static int bind_con_driver(const struct consw *csw, int first, int last,
3060 int deflt)
3062 struct module *owner = csw->owner;
3063 const char *desc = NULL;
3064 struct con_driver *con_driver;
3065 int i, j = -1, k = -1, retval = -ENODEV;
3067 if (!try_module_get(owner))
3068 return -ENODEV;
3070 console_lock();
3072 /* check if driver is registered */
3073 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3074 con_driver = &registered_con_driver[i];
3076 if (con_driver->con == csw) {
3077 desc = con_driver->desc;
3078 retval = 0;
3079 break;
3083 if (retval)
3084 goto err;
3086 if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) {
3087 csw->con_startup();
3088 con_driver->flag |= CON_DRIVER_FLAG_INIT;
3091 if (deflt) {
3092 if (conswitchp)
3093 module_put(conswitchp->owner);
3095 __module_get(owner);
3096 conswitchp = csw;
3099 first = max(first, con_driver->first);
3100 last = min(last, con_driver->last);
3102 for (i = first; i <= last; i++) {
3103 int old_was_color;
3104 struct vc_data *vc = vc_cons[i].d;
3106 if (con_driver_map[i])
3107 module_put(con_driver_map[i]->owner);
3108 __module_get(owner);
3109 con_driver_map[i] = csw;
3111 if (!vc || !vc->vc_sw)
3112 continue;
3114 j = i;
3116 if (CON_IS_VISIBLE(vc)) {
3117 k = i;
3118 save_screen(vc);
3121 old_was_color = vc->vc_can_do_color;
3122 vc->vc_sw->con_deinit(vc);
3123 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
3124 visual_init(vc, i, 0);
3125 set_origin(vc);
3126 update_attr(vc);
3128 /* If the console changed between mono <-> color, then
3129 * the attributes in the screenbuf will be wrong. The
3130 * following resets all attributes to something sane.
3132 if (old_was_color != vc->vc_can_do_color)
3133 clear_buffer_attributes(vc);
3136 pr_info("Console: switching ");
3137 if (!deflt)
3138 printk("consoles %d-%d ", first+1, last+1);
3139 if (j >= 0) {
3140 struct vc_data *vc = vc_cons[j].d;
3142 printk("to %s %s %dx%d\n",
3143 vc->vc_can_do_color ? "colour" : "mono",
3144 desc, vc->vc_cols, vc->vc_rows);
3146 if (k >= 0) {
3147 vc = vc_cons[k].d;
3148 update_screen(vc);
3150 } else
3151 printk("to %s\n", desc);
3153 retval = 0;
3154 err:
3155 console_unlock();
3156 module_put(owner);
3157 return retval;
3160 #ifdef CONFIG_VT_HW_CONSOLE_BINDING
3161 static int con_is_graphics(const struct consw *csw, int first, int last)
3163 int i, retval = 0;
3165 for (i = first; i <= last; i++) {
3166 struct vc_data *vc = vc_cons[i].d;
3168 if (vc && vc->vc_mode == KD_GRAPHICS) {
3169 retval = 1;
3170 break;
3174 return retval;
3178 * unbind_con_driver - unbind a console driver
3179 * @csw: pointer to console driver to unregister
3180 * @first: first in range of consoles that @csw should be unbound from
3181 * @last: last in range of consoles that @csw should be unbound from
3182 * @deflt: should next bound console driver be default after @csw is unbound?
3184 * To unbind a driver from all possible consoles, pass 0 as @first and
3185 * %MAX_NR_CONSOLES as @last.
3187 * @deflt controls whether the console that ends up replacing @csw should be
3188 * the default console.
3190 * RETURNS:
3191 * -ENODEV if @csw isn't a registered console driver or can't be unregistered
3192 * or 0 on success.
3194 int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3196 struct module *owner = csw->owner;
3197 const struct consw *defcsw = NULL;
3198 struct con_driver *con_driver = NULL, *con_back = NULL;
3199 int i, retval = -ENODEV;
3201 if (!try_module_get(owner))
3202 return -ENODEV;
3204 console_lock();
3206 /* check if driver is registered and if it is unbindable */
3207 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3208 con_driver = &registered_con_driver[i];
3210 if (con_driver->con == csw &&
3211 con_driver->flag & CON_DRIVER_FLAG_MODULE) {
3212 retval = 0;
3213 break;
3217 if (retval) {
3218 console_unlock();
3219 goto err;
3222 retval = -ENODEV;
3224 /* check if backup driver exists */
3225 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3226 con_back = &registered_con_driver[i];
3228 if (con_back->con &&
3229 !(con_back->flag & CON_DRIVER_FLAG_MODULE)) {
3230 defcsw = con_back->con;
3231 retval = 0;
3232 break;
3236 if (retval) {
3237 console_unlock();
3238 goto err;
3241 if (!con_is_bound(csw)) {
3242 console_unlock();
3243 goto err;
3246 first = max(first, con_driver->first);
3247 last = min(last, con_driver->last);
3249 for (i = first; i <= last; i++) {
3250 if (con_driver_map[i] == csw) {
3251 module_put(csw->owner);
3252 con_driver_map[i] = NULL;
3256 if (!con_is_bound(defcsw)) {
3257 const struct consw *defconsw = conswitchp;
3259 defcsw->con_startup();
3260 con_back->flag |= CON_DRIVER_FLAG_INIT;
3262 * vgacon may change the default driver to point
3263 * to dummycon, we restore it here...
3265 conswitchp = defconsw;
3268 if (!con_is_bound(csw))
3269 con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
3271 console_unlock();
3272 /* ignore return value, binding should not fail */
3273 bind_con_driver(defcsw, first, last, deflt);
3274 err:
3275 module_put(owner);
3276 return retval;
3279 EXPORT_SYMBOL(unbind_con_driver);
3281 static int vt_bind(struct con_driver *con)
3283 const struct consw *defcsw = NULL, *csw = NULL;
3284 int i, more = 1, first = -1, last = -1, deflt = 0;
3286 if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
3287 con_is_graphics(con->con, con->first, con->last))
3288 goto err;
3290 csw = con->con;
3292 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3293 struct con_driver *con = &registered_con_driver[i];
3295 if (con->con && !(con->flag & CON_DRIVER_FLAG_MODULE)) {
3296 defcsw = con->con;
3297 break;
3301 if (!defcsw)
3302 goto err;
3304 while (more) {
3305 more = 0;
3307 for (i = con->first; i <= con->last; i++) {
3308 if (con_driver_map[i] == defcsw) {
3309 if (first == -1)
3310 first = i;
3311 last = i;
3312 more = 1;
3313 } else if (first != -1)
3314 break;
3317 if (first == 0 && last == MAX_NR_CONSOLES -1)
3318 deflt = 1;
3320 if (first != -1)
3321 bind_con_driver(csw, first, last, deflt);
3323 first = -1;
3324 last = -1;
3325 deflt = 0;
3328 err:
3329 return 0;
3332 static int vt_unbind(struct con_driver *con)
3334 const struct consw *csw = NULL;
3335 int i, more = 1, first = -1, last = -1, deflt = 0;
3337 if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
3338 con_is_graphics(con->con, con->first, con->last))
3339 goto err;
3341 csw = con->con;
3343 while (more) {
3344 more = 0;
3346 for (i = con->first; i <= con->last; i++) {
3347 if (con_driver_map[i] == csw) {
3348 if (first == -1)
3349 first = i;
3350 last = i;
3351 more = 1;
3352 } else if (first != -1)
3353 break;
3356 if (first == 0 && last == MAX_NR_CONSOLES -1)
3357 deflt = 1;
3359 if (first != -1)
3360 unbind_con_driver(csw, first, last, deflt);
3362 first = -1;
3363 last = -1;
3364 deflt = 0;
3367 err:
3368 return 0;
3370 #else
3371 static inline int vt_bind(struct con_driver *con)
3373 return 0;
3375 static inline int vt_unbind(struct con_driver *con)
3377 return 0;
3379 #endif /* CONFIG_VT_HW_CONSOLE_BINDING */
3381 static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
3382 const char *buf, size_t count)
3384 struct con_driver *con = dev_get_drvdata(dev);
3385 int bind = simple_strtoul(buf, NULL, 0);
3387 if (bind)
3388 vt_bind(con);
3389 else
3390 vt_unbind(con);
3392 return count;
3395 static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
3396 char *buf)
3398 struct con_driver *con = dev_get_drvdata(dev);
3399 int bind = con_is_bound(con->con);
3401 return snprintf(buf, PAGE_SIZE, "%i\n", bind);
3404 static ssize_t show_name(struct device *dev, struct device_attribute *attr,
3405 char *buf)
3407 struct con_driver *con = dev_get_drvdata(dev);
3409 return snprintf(buf, PAGE_SIZE, "%s %s\n",
3410 (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)",
3411 con->desc);
3415 static struct device_attribute device_attrs[] = {
3416 __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind),
3417 __ATTR(name, S_IRUGO, show_name, NULL),
3420 static int vtconsole_init_device(struct con_driver *con)
3422 int i;
3423 int error = 0;
3425 con->flag |= CON_DRIVER_FLAG_ATTR;
3426 dev_set_drvdata(con->dev, con);
3427 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
3428 error = device_create_file(con->dev, &device_attrs[i]);
3429 if (error)
3430 break;
3433 if (error) {
3434 while (--i >= 0)
3435 device_remove_file(con->dev, &device_attrs[i]);
3436 con->flag &= ~CON_DRIVER_FLAG_ATTR;
3439 return error;
3442 static void vtconsole_deinit_device(struct con_driver *con)
3444 int i;
3446 if (con->flag & CON_DRIVER_FLAG_ATTR) {
3447 for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
3448 device_remove_file(con->dev, &device_attrs[i]);
3449 con->flag &= ~CON_DRIVER_FLAG_ATTR;
3454 * con_is_bound - checks if driver is bound to the console
3455 * @csw: console driver
3457 * RETURNS: zero if unbound, nonzero if bound
3459 * Drivers can call this and if zero, they should release
3460 * all resources allocated on con_startup()
3462 int con_is_bound(const struct consw *csw)
3464 int i, bound = 0;
3466 for (i = 0; i < MAX_NR_CONSOLES; i++) {
3467 if (con_driver_map[i] == csw) {
3468 bound = 1;
3469 break;
3473 return bound;
3475 EXPORT_SYMBOL(con_is_bound);
3478 * con_debug_enter - prepare the console for the kernel debugger
3479 * @sw: console driver
3481 * Called when the console is taken over by the kernel debugger, this
3482 * function needs to save the current console state, then put the console
3483 * into a state suitable for the kernel debugger.
3485 * RETURNS:
3486 * Zero on success, nonzero if a failure occurred when trying to prepare
3487 * the console for the debugger.
3489 int con_debug_enter(struct vc_data *vc)
3491 int ret = 0;
3493 saved_fg_console = fg_console;
3494 saved_last_console = last_console;
3495 saved_want_console = want_console;
3496 saved_vc_mode = vc->vc_mode;
3497 saved_console_blanked = console_blanked;
3498 vc->vc_mode = KD_TEXT;
3499 console_blanked = 0;
3500 if (vc->vc_sw->con_debug_enter)
3501 ret = vc->vc_sw->con_debug_enter(vc);
3502 #ifdef CONFIG_KGDB_KDB
3503 /* Set the initial LINES variable if it is not already set */
3504 if (vc->vc_rows < 999) {
3505 int linecount;
3506 char lns[4];
3507 const char *setargs[3] = {
3508 "set",
3509 "LINES",
3510 lns,
3512 if (kdbgetintenv(setargs[0], &linecount)) {
3513 snprintf(lns, 4, "%i", vc->vc_rows);
3514 kdb_set(2, setargs);
3517 #endif /* CONFIG_KGDB_KDB */
3518 return ret;
3520 EXPORT_SYMBOL_GPL(con_debug_enter);
3523 * con_debug_leave - restore console state
3524 * @sw: console driver
3526 * Restore the console state to what it was before the kernel debugger
3527 * was invoked.
3529 * RETURNS:
3530 * Zero on success, nonzero if a failure occurred when trying to restore
3531 * the console.
3533 int con_debug_leave(void)
3535 struct vc_data *vc;
3536 int ret = 0;
3538 fg_console = saved_fg_console;
3539 last_console = saved_last_console;
3540 want_console = saved_want_console;
3541 console_blanked = saved_console_blanked;
3542 vc_cons[fg_console].d->vc_mode = saved_vc_mode;
3544 vc = vc_cons[fg_console].d;
3545 if (vc->vc_sw->con_debug_leave)
3546 ret = vc->vc_sw->con_debug_leave(vc);
3547 return ret;
3549 EXPORT_SYMBOL_GPL(con_debug_leave);
3552 * register_con_driver - register console driver to console layer
3553 * @csw: console driver
3554 * @first: the first console to take over, minimum value is 0
3555 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3557 * DESCRIPTION: This function registers a console driver which can later
3558 * bind to a range of consoles specified by @first and @last. It will
3559 * also initialize the console driver by calling con_startup().
3561 int register_con_driver(const struct consw *csw, int first, int last)
3563 struct module *owner = csw->owner;
3564 struct con_driver *con_driver;
3565 const char *desc;
3566 int i, retval = 0;
3568 if (!try_module_get(owner))
3569 return -ENODEV;
3571 console_lock();
3573 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3574 con_driver = &registered_con_driver[i];
3576 /* already registered */
3577 if (con_driver->con == csw)
3578 retval = -EBUSY;
3581 if (retval)
3582 goto err;
3584 desc = csw->con_startup();
3586 if (!desc)
3587 goto err;
3589 retval = -EINVAL;
3591 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3592 con_driver = &registered_con_driver[i];
3594 if (con_driver->con == NULL) {
3595 con_driver->con = csw;
3596 con_driver->desc = desc;
3597 con_driver->node = i;
3598 con_driver->flag = CON_DRIVER_FLAG_MODULE |
3599 CON_DRIVER_FLAG_INIT;
3600 con_driver->first = first;
3601 con_driver->last = last;
3602 retval = 0;
3603 break;
3607 if (retval)
3608 goto err;
3610 con_driver->dev = device_create(vtconsole_class, NULL,
3611 MKDEV(0, con_driver->node),
3612 NULL, "vtcon%i",
3613 con_driver->node);
3615 if (IS_ERR(con_driver->dev)) {
3616 printk(KERN_WARNING "Unable to create device for %s; "
3617 "errno = %ld\n", con_driver->desc,
3618 PTR_ERR(con_driver->dev));
3619 con_driver->dev = NULL;
3620 } else {
3621 vtconsole_init_device(con_driver);
3624 err:
3625 console_unlock();
3626 module_put(owner);
3627 return retval;
3629 EXPORT_SYMBOL(register_con_driver);
3632 * unregister_con_driver - unregister console driver from console layer
3633 * @csw: console driver
3635 * DESCRIPTION: All drivers that registers to the console layer must
3636 * call this function upon exit, or if the console driver is in a state
3637 * where it won't be able to handle console services, such as the
3638 * framebuffer console without loaded framebuffer drivers.
3640 * The driver must unbind first prior to unregistration.
3642 int unregister_con_driver(const struct consw *csw)
3644 int i, retval = -ENODEV;
3646 console_lock();
3648 /* cannot unregister a bound driver */
3649 if (con_is_bound(csw))
3650 goto err;
3652 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3653 struct con_driver *con_driver = &registered_con_driver[i];
3655 if (con_driver->con == csw &&
3656 con_driver->flag & CON_DRIVER_FLAG_MODULE) {
3657 vtconsole_deinit_device(con_driver);
3658 device_destroy(vtconsole_class,
3659 MKDEV(0, con_driver->node));
3660 con_driver->con = NULL;
3661 con_driver->desc = NULL;
3662 con_driver->dev = NULL;
3663 con_driver->node = 0;
3664 con_driver->flag = 0;
3665 con_driver->first = 0;
3666 con_driver->last = 0;
3667 retval = 0;
3668 break;
3671 err:
3672 console_unlock();
3673 return retval;
3675 EXPORT_SYMBOL(unregister_con_driver);
3678 * If we support more console drivers, this function is used
3679 * when a driver wants to take over some existing consoles
3680 * and become default driver for newly opened ones.
3682 * take_over_console is basically a register followed by unbind
3684 int take_over_console(const struct consw *csw, int first, int last, int deflt)
3686 int err;
3688 err = register_con_driver(csw, first, last);
3689 /* if we get an busy error we still want to bind the console driver
3690 * and return success, as we may have unbound the console driver
3691  * but not unregistered it.
3693 if (err == -EBUSY)
3694 err = 0;
3695 if (!err)
3696 bind_con_driver(csw, first, last, deflt);
3698 return err;
3702 * give_up_console is a wrapper to unregister_con_driver. It will only
3703 * work if driver is fully unbound.
3705 void give_up_console(const struct consw *csw)
3707 unregister_con_driver(csw);
3710 static int __init vtconsole_class_init(void)
3712 int i;
3714 vtconsole_class = class_create(THIS_MODULE, "vtconsole");
3715 if (IS_ERR(vtconsole_class)) {
3716 printk(KERN_WARNING "Unable to create vt console class; "
3717 "errno = %ld\n", PTR_ERR(vtconsole_class));
3718 vtconsole_class = NULL;
3721 /* Add system drivers to sysfs */
3722 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3723 struct con_driver *con = &registered_con_driver[i];
3725 if (con->con && !con->dev) {
3726 con->dev = device_create(vtconsole_class, NULL,
3727 MKDEV(0, con->node),
3728 NULL, "vtcon%i",
3729 con->node);
3731 if (IS_ERR(con->dev)) {
3732 printk(KERN_WARNING "Unable to create "
3733 "device for %s; errno = %ld\n",
3734 con->desc, PTR_ERR(con->dev));
3735 con->dev = NULL;
3736 } else {
3737 vtconsole_init_device(con);
3742 return 0;
3744 postcore_initcall(vtconsole_class_init);
3746 #endif
3749 * Screen blanking
3752 static int set_vesa_blanking(char __user *p)
3754 unsigned int mode;
3756 if (get_user(mode, p + 1))
3757 return -EFAULT;
3759 vesa_blank_mode = (mode < 4) ? mode : 0;
3760 return 0;
3763 void do_blank_screen(int entering_gfx)
3765 struct vc_data *vc = vc_cons[fg_console].d;
3766 int i;
3768 WARN_CONSOLE_UNLOCKED();
3770 if (console_blanked) {
3771 if (blank_state == blank_vesa_wait) {
3772 blank_state = blank_off;
3773 vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
3775 return;
3778 /* entering graphics mode? */
3779 if (entering_gfx) {
3780 hide_cursor(vc);
3781 save_screen(vc);
3782 vc->vc_sw->con_blank(vc, -1, 1);
3783 console_blanked = fg_console + 1;
3784 blank_state = blank_off;
3785 set_origin(vc);
3786 return;
3789 if (blank_state != blank_normal_wait)
3790 return;
3791 blank_state = blank_off;
3793 /* don't blank graphics */
3794 if (vc->vc_mode != KD_TEXT) {
3795 console_blanked = fg_console + 1;
3796 return;
3799 hide_cursor(vc);
3800 del_timer_sync(&console_timer);
3801 blank_timer_expired = 0;
3803 save_screen(vc);
3804 /* In case we need to reset origin, blanking hook returns 1 */
3805 i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
3806 console_blanked = fg_console + 1;
3807 if (i)
3808 set_origin(vc);
3810 if (console_blank_hook && console_blank_hook(1))
3811 return;
3813 if (vesa_off_interval && vesa_blank_mode) {
3814 blank_state = blank_vesa_wait;
3815 mod_timer(&console_timer, jiffies + vesa_off_interval);
3817 vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
3819 EXPORT_SYMBOL(do_blank_screen);
3822 * Called by timer as well as from vt_console_driver
3824 void do_unblank_screen(int leaving_gfx)
3826 struct vc_data *vc;
3828 /* This should now always be called from a "sane" (read: can schedule)
3829 * context for the sake of the low level drivers, except in the special
3830 * case of oops_in_progress
3832 if (!oops_in_progress)
3833 might_sleep();
3835 WARN_CONSOLE_UNLOCKED();
3837 ignore_poke = 0;
3838 if (!console_blanked)
3839 return;
3840 if (!vc_cons_allocated(fg_console)) {
3841 /* impossible */
3842 pr_warning("unblank_screen: tty %d not allocated ??\n",
3843 fg_console+1);
3844 return;
3846 vc = vc_cons[fg_console].d;
3847 /* Try to unblank in oops case too */
3848 if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
3849 return; /* but leave console_blanked != 0 */
3851 if (blankinterval) {
3852 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3853 blank_state = blank_normal_wait;
3856 console_blanked = 0;
3857 if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
3858 /* Low-level driver cannot restore -> do it ourselves */
3859 update_screen(vc);
3860 if (console_blank_hook)
3861 console_blank_hook(0);
3862 set_palette(vc);
3863 set_cursor(vc);
3864 vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
3866 EXPORT_SYMBOL(do_unblank_screen);
3869 * This is called by the outside world to cause a forced unblank, mostly for
3870 * oopses. Currently, I just call do_unblank_screen(0), but we could eventually
3871 * call it with 1 as an argument and so force a mode restore... that may kill
3872 * X or at least garbage the screen but would also make the Oops visible...
3874 void unblank_screen(void)
3876 do_unblank_screen(0);
3880 * We defer the timer blanking to work queue so it can take the console mutex
3881 * (console operations can still happen at irq time, but only from printk which
3882 * has the console mutex. Not perfect yet, but better than no locking
3884 static void blank_screen_t(unsigned long dummy)
3886 if (unlikely(!keventd_up())) {
3887 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3888 return;
3890 blank_timer_expired = 1;
3891 schedule_work(&console_work);
3894 void poke_blanked_console(void)
3896 WARN_CONSOLE_UNLOCKED();
3898 /* Add this so we quickly catch whoever might call us in a non
3899 * safe context. Nowadays, unblank_screen() isn't to be called in
3900 * atomic contexts and is allowed to schedule (with the special case
3901 * of oops_in_progress, but that isn't of any concern for this
3902 * function. --BenH.
3904 might_sleep();
3906 /* This isn't perfectly race free, but a race here would be mostly harmless,
3907 * at worse, we'll do a spurrious blank and it's unlikely
3909 del_timer(&console_timer);
3910 blank_timer_expired = 0;
3912 if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS)
3913 return;
3914 if (console_blanked)
3915 unblank_screen();
3916 else if (blankinterval) {
3917 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3918 blank_state = blank_normal_wait;
3923 * Palettes
3926 static void set_palette(struct vc_data *vc)
3928 WARN_CONSOLE_UNLOCKED();
3930 if (vc->vc_mode != KD_GRAPHICS)
3931 vc->vc_sw->con_set_palette(vc, color_table);
3934 static int set_get_cmap(unsigned char __user *arg, int set)
3936 int i, j, k;
3938 WARN_CONSOLE_UNLOCKED();
3940 for (i = 0; i < 16; i++)
3941 if (set) {
3942 get_user(default_red[i], arg++);
3943 get_user(default_grn[i], arg++);
3944 get_user(default_blu[i], arg++);
3945 } else {
3946 put_user(default_red[i], arg++);
3947 put_user(default_grn[i], arg++);
3948 put_user(default_blu[i], arg++);
3950 if (set) {
3951 for (i = 0; i < MAX_NR_CONSOLES; i++)
3952 if (vc_cons_allocated(i)) {
3953 for (j = k = 0; j < 16; j++) {
3954 vc_cons[i].d->vc_palette[k++] = default_red[j];
3955 vc_cons[i].d->vc_palette[k++] = default_grn[j];
3956 vc_cons[i].d->vc_palette[k++] = default_blu[j];
3958 set_palette(vc_cons[i].d);
3961 return 0;
3965 * Load palette into the DAC registers. arg points to a colour
3966 * map, 3 bytes per colour, 16 colours, range from 0 to 255.
3969 int con_set_cmap(unsigned char __user *arg)
3971 int rc;
3973 console_lock();
3974 rc = set_get_cmap (arg,1);
3975 console_unlock();
3977 return rc;
3980 int con_get_cmap(unsigned char __user *arg)
3982 int rc;
3984 console_lock();
3985 rc = set_get_cmap (arg,0);
3986 console_unlock();
3988 return rc;
3991 void reset_palette(struct vc_data *vc)
3993 int j, k;
3994 for (j=k=0; j<16; j++) {
3995 vc->vc_palette[k++] = default_red[j];
3996 vc->vc_palette[k++] = default_grn[j];
3997 vc->vc_palette[k++] = default_blu[j];
3999 set_palette(vc);
4003 * Font switching
4005 * Currently we only support fonts up to 32 pixels wide, at a maximum height
4006 * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints,
4007 * depending on width) reserved for each character which is kinda wasty, but
4008 * this is done in order to maintain compatibility with the EGA/VGA fonts. It
4009 * is up to the actual low-level console-driver convert data into its favorite
4010 * format (maybe we should add a `fontoffset' field to the `display'
4011 * structure so we won't have to convert the fontdata all the time.
4012 * /Jes
4015 #define max_font_size 65536
4017 static int con_font_get(struct vc_data *vc, struct console_font_op *op)
4019 struct console_font font;
4020 int rc = -EINVAL;
4021 int c;
4023 if (vc->vc_mode != KD_TEXT)
4024 return -EINVAL;
4026 if (op->data) {
4027 font.data = kmalloc(max_font_size, GFP_KERNEL);
4028 if (!font.data)
4029 return -ENOMEM;
4030 } else
4031 font.data = NULL;
4033 console_lock();
4034 if (vc->vc_sw->con_font_get)
4035 rc = vc->vc_sw->con_font_get(vc, &font);
4036 else
4037 rc = -ENOSYS;
4038 console_unlock();
4040 if (rc)
4041 goto out;
4043 c = (font.width+7)/8 * 32 * font.charcount;
4045 if (op->data && font.charcount > op->charcount)
4046 rc = -ENOSPC;
4047 if (!(op->flags & KD_FONT_FLAG_OLD)) {
4048 if (font.width > op->width || font.height > op->height)
4049 rc = -ENOSPC;
4050 } else {
4051 if (font.width != 8)
4052 rc = -EIO;
4053 else if ((op->height && font.height > op->height) ||
4054 font.height > 32)
4055 rc = -ENOSPC;
4057 if (rc)
4058 goto out;
4060 op->height = font.height;
4061 op->width = font.width;
4062 op->charcount = font.charcount;
4064 if (op->data && copy_to_user(op->data, font.data, c))
4065 rc = -EFAULT;
4067 out:
4068 kfree(font.data);
4069 return rc;
4072 static int con_font_set(struct vc_data *vc, struct console_font_op *op)
4074 struct console_font font;
4075 int rc = -EINVAL;
4076 int size;
4078 if (vc->vc_mode != KD_TEXT)
4079 return -EINVAL;
4080 if (!op->data)
4081 return -EINVAL;
4082 if (op->charcount > 512)
4083 return -EINVAL;
4084 if (!op->height) { /* Need to guess font height [compat] */
4085 int h, i;
4086 u8 __user *charmap = op->data;
4087 u8 tmp;
4089 /* If from KDFONTOP ioctl, don't allow things which can be done in userland,
4090 so that we can get rid of this soon */
4091 if (!(op->flags & KD_FONT_FLAG_OLD))
4092 return -EINVAL;
4093 for (h = 32; h > 0; h--)
4094 for (i = 0; i < op->charcount; i++) {
4095 if (get_user(tmp, &charmap[32*i+h-1]))
4096 return -EFAULT;
4097 if (tmp)
4098 goto nonzero;
4100 return -EINVAL;
4101 nonzero:
4102 op->height = h;
4104 if (op->width <= 0 || op->width > 32 || op->height > 32)
4105 return -EINVAL;
4106 size = (op->width+7)/8 * 32 * op->charcount;
4107 if (size > max_font_size)
4108 return -ENOSPC;
4109 font.charcount = op->charcount;
4110 font.height = op->height;
4111 font.width = op->width;
4112 font.data = memdup_user(op->data, size);
4113 if (IS_ERR(font.data))
4114 return PTR_ERR(font.data);
4115 console_lock();
4116 if (vc->vc_sw->con_font_set)
4117 rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
4118 else
4119 rc = -ENOSYS;
4120 console_unlock();
4121 kfree(font.data);
4122 return rc;
4125 static int con_font_default(struct vc_data *vc, struct console_font_op *op)
4127 struct console_font font = {.width = op->width, .height = op->height};
4128 char name[MAX_FONT_NAME];
4129 char *s = name;
4130 int rc;
4132 if (vc->vc_mode != KD_TEXT)
4133 return -EINVAL;
4135 if (!op->data)
4136 s = NULL;
4137 else if (strncpy_from_user(name, op->data, MAX_FONT_NAME - 1) < 0)
4138 return -EFAULT;
4139 else
4140 name[MAX_FONT_NAME - 1] = 0;
4142 console_lock();
4143 if (vc->vc_sw->con_font_default)
4144 rc = vc->vc_sw->con_font_default(vc, &font, s);
4145 else
4146 rc = -ENOSYS;
4147 console_unlock();
4148 if (!rc) {
4149 op->width = font.width;
4150 op->height = font.height;
4152 return rc;
4155 static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
4157 int con = op->height;
4158 int rc;
4160 if (vc->vc_mode != KD_TEXT)
4161 return -EINVAL;
4163 console_lock();
4164 if (!vc->vc_sw->con_font_copy)
4165 rc = -ENOSYS;
4166 else if (con < 0 || !vc_cons_allocated(con))
4167 rc = -ENOTTY;
4168 else if (con == vc->vc_num) /* nothing to do */
4169 rc = 0;
4170 else
4171 rc = vc->vc_sw->con_font_copy(vc, con);
4172 console_unlock();
4173 return rc;
4176 int con_font_op(struct vc_data *vc, struct console_font_op *op)
4178 switch (op->op) {
4179 case KD_FONT_OP_SET:
4180 return con_font_set(vc, op);
4181 case KD_FONT_OP_GET:
4182 return con_font_get(vc, op);
4183 case KD_FONT_OP_SET_DEFAULT:
4184 return con_font_default(vc, op);
4185 case KD_FONT_OP_COPY:
4186 return con_font_copy(vc, op);
4188 return -ENOSYS;
4192 * Interface exported to selection and vcs.
4195 /* used by selection */
4196 u16 screen_glyph(struct vc_data *vc, int offset)
4198 u16 w = scr_readw(screenpos(vc, offset, 1));
4199 u16 c = w & 0xff;
4201 if (w & vc->vc_hi_font_mask)
4202 c |= 0x100;
4203 return c;
4205 EXPORT_SYMBOL_GPL(screen_glyph);
4207 /* used by vcs - note the word offset */
4208 unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
4210 return screenpos(vc, 2 * w_offset, viewed);
4213 void getconsxy(struct vc_data *vc, unsigned char *p)
4215 p[0] = vc->vc_x;
4216 p[1] = vc->vc_y;
4219 void putconsxy(struct vc_data *vc, unsigned char *p)
4221 hide_cursor(vc);
4222 gotoxy(vc, p[0], p[1]);
4223 set_cursor(vc);
4226 u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
4228 if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
4229 return softcursor_original;
4230 return scr_readw(org);
4233 void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
4235 scr_writew(val, org);
4236 if ((unsigned long)org == vc->vc_pos) {
4237 softcursor_original = -1;
4238 add_softcursor(vc);
4242 void vcs_scr_updated(struct vc_data *vc)
4244 notify_update(vc);
4248 * Visible symbols for modules
4251 EXPORT_SYMBOL(color_table);
4252 EXPORT_SYMBOL(default_red);
4253 EXPORT_SYMBOL(default_grn);
4254 EXPORT_SYMBOL(default_blu);
4255 EXPORT_SYMBOL(update_region);
4256 EXPORT_SYMBOL(redraw_screen);
4257 EXPORT_SYMBOL(vc_resize);
4258 EXPORT_SYMBOL(fg_console);
4259 EXPORT_SYMBOL(console_blank_hook);
4260 EXPORT_SYMBOL(console_blanked);
4261 EXPORT_SYMBOL(vc_cons);
4262 EXPORT_SYMBOL(global_cursor_default);
4263 #ifndef VT_SINGLE_DRIVER
4264 EXPORT_SYMBOL(take_over_console);
4265 EXPORT_SYMBOL(give_up_console);
4266 #endif