Import 1.3.87
[davej-history.git] / drivers / char / consolemap.c
blob9a78c2f87d4f12df8f48be14154b86a2483dda93
1 /*
2 * consolemap.c
4 * Mapping from internal code (such as Latin-1 or Unicode or IBM PC code)
5 * to font positions.
7 * aeb, 950210
8 */
10 #include <linux/kd.h>
11 #include <linux/errno.h>
12 #include <linux/mm.h>
13 #include <linux/malloc.h>
14 #include <asm/segment.h>
15 #include"consolemap.h"
17 static unsigned short translations[][256] = {
18 /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
20 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
21 0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
22 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
23 0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f,
24 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
25 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
26 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
27 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
28 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
29 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
30 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
31 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
32 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
33 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
34 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
35 0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f,
36 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
37 0x0088,0x0089,0x008a,0x008b,0x008c,0x008d,0x008e,0x008f,
38 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
39 0x0098,0x0099,0x009a,0x009b,0x009c,0x009d,0x009e,0x009f,
40 0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,
41 0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,
42 0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,
43 0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,
44 0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,
45 0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,
46 0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,
47 0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,
48 0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,
49 0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,
50 0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,
51 0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff
53 /* VT100 graphics mapped to Unicode */
55 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
56 0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
57 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
58 0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f,
59 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
60 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
61 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
62 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
63 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
64 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
65 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
66 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x00a0,
67 0x25c6,0x2592,0x2409,0x240c,0x240d,0x240a,0x00b0,0x00b1,
68 0x2424,0x240b,0x2518,0x2510,0x250c,0x2514,0x253c,0xf800,
69 0xf801,0x2500,0xf803,0xf804,0x251c,0x2524,0x2534,0x252c,
70 0x2502,0x2264,0x2265,0x03c0,0x2260,0x00a3,0x00b7,0x007f,
71 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
72 0x0088,0x0089,0x008a,0x008b,0x008c,0x008d,0x008e,0x008f,
73 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
74 0x0098,0x0099,0x009a,0x009b,0x009c,0x009d,0x009e,0x009f,
75 0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,
76 0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,
77 0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,
78 0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,
79 0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,
80 0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,
81 0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,
82 0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,
83 0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,
84 0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,
85 0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,
86 0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff
88 /* IBM Codepage 437 mapped to Unicode */
90 0x0000,0x263a,0x263b,0x2665,0x2666,0x2663,0x2660,0x2022,
91 0x25d8,0x25cb,0x25d9,0x2642,0x2640,0x266a,0x266b,0x263c,
92 0x25ba,0x25c4,0x2195,0x203c,0x00b6,0x00a7,0x25ac,0x21a8,
93 0x2191,0x2193,0x2192,0x2190,0x221f,0x2194,0x25b2,0x25bc,
94 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
95 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
96 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
97 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
98 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
99 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
100 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
101 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
102 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
103 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
104 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
105 0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302,
106 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,
107 0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5,
108 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,
109 0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192,
110 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,
111 0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb,
112 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,
113 0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510,
114 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,
115 0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567,
116 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,
117 0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580,
118 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,
119 0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229,
120 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,
121 0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0
123 /* User mapping -- default to codes for direct font mapping */
125 0xf000,0xf001,0xf002,0xf003,0xf004,0xf005,0xf006,0xf007,
126 0xf008,0xf009,0xf00a,0xf00b,0xf00c,0xf00d,0xf00e,0xf00f,
127 0xf010,0xf011,0xf012,0xf013,0xf014,0xf015,0xf016,0xf017,
128 0xf018,0xf019,0xf01a,0xf01b,0xf01c,0xf01d,0xf01e,0xf01f,
129 0xf020,0xf021,0xf022,0xf023,0xf024,0xf025,0xf026,0xf027,
130 0xf028,0xf029,0xf02a,0xf02b,0xf02c,0xf02d,0xf02e,0xf02f,
131 0xf030,0xf031,0xf032,0xf033,0xf034,0xf035,0xf036,0xf037,
132 0xf038,0xf039,0xf03a,0xf03b,0xf03c,0xf03d,0xf03e,0xf03f,
133 0xf040,0xf041,0xf042,0xf043,0xf044,0xf045,0xf046,0xf047,
134 0xf048,0xf049,0xf04a,0xf04b,0xf04c,0xf04d,0xf04e,0xf04f,
135 0xf050,0xf051,0xf052,0xf053,0xf054,0xf055,0xf056,0xf057,
136 0xf058,0xf059,0xf05a,0xf05b,0xf05c,0xf05d,0xf05e,0xf05f,
137 0xf060,0xf061,0xf062,0xf063,0xf064,0xf065,0xf066,0xf067,
138 0xf068,0xf069,0xf06a,0xf06b,0xf06c,0xf06d,0xf06e,0xf06f,
139 0xf070,0xf071,0xf072,0xf073,0xf074,0xf075,0xf076,0xf077,
140 0xf078,0xf079,0xf07a,0xf07b,0xf07c,0xf07d,0xf07e,0xf07f,
141 0xf080,0xf081,0xf082,0xf083,0xf084,0xf085,0xf086,0xf087,
142 0xf088,0xf089,0xf08a,0xf08b,0xf08c,0xf08d,0xf08e,0xf08f,
143 0xf090,0xf091,0xf092,0xf093,0xf094,0xf095,0xf096,0xf097,
144 0xf098,0xf099,0xf09a,0xf09b,0xf09c,0xf09d,0xf09e,0xf09f,
145 0xf0a0,0xf0a1,0xf0a2,0xf0a3,0xf0a4,0xf0a5,0xf0a6,0xf0a7,
146 0xf0a8,0xf0a9,0xf0aa,0xf0ab,0xf0ac,0xf0ad,0xf0ae,0xf0af,
147 0xf0b0,0xf0b1,0xf0b2,0xf0b3,0xf0b4,0xf0b5,0xf0b6,0xf0b7,
148 0xf0b8,0xf0b9,0xf0ba,0xf0bb,0xf0bc,0xf0bd,0xf0be,0xf0bf,
149 0xf0c0,0xf0c1,0xf0c2,0xf0c3,0xf0c4,0xf0c5,0xf0c6,0xf0c7,
150 0xf0c8,0xf0c9,0xf0ca,0xf0cb,0xf0cc,0xf0cd,0xf0ce,0xf0cf,
151 0xf0d0,0xf0d1,0xf0d2,0xf0d3,0xf0d4,0xf0d5,0xf0d6,0xf0d7,
152 0xf0d8,0xf0d9,0xf0da,0xf0db,0xf0dc,0xf0dd,0xf0de,0xf0df,
153 0xf0e0,0xf0e1,0xf0e2,0xf0e3,0xf0e4,0xf0e5,0xf0e6,0xf0e7,
154 0xf0e8,0xf0e9,0xf0ea,0xf0eb,0xf0ec,0xf0ed,0xf0ee,0xf0ef,
155 0xf0f0,0xf0f1,0xf0f2,0xf0f3,0xf0f4,0xf0f5,0xf0f6,0xf0f7,
156 0xf0f8,0xf0f9,0xf0fa,0xf0fb,0xf0fc,0xf0fd,0xf0fe,0xf0ff
160 /* The standard kernel character-to-font mappings are not invertible
161 -- this is just a best effort. */
163 #define MAX_GLYPH 512/* Max possible glyph value */
165 static unsigned char* inv_translate = NULL;
166 static unsigned char inv_norm_transl[MAX_GLYPH];
167 static unsigned char* inverse_translations[4] = { NULL, NULL, NULL, NULL };
169 static voidset_inverse_transl(int i)
171 int j, glyph;
172 unsigned short*p = translations[i];
173 unsigned char*q = inverse_translations[i];
175 if(!q) {
176 /* slightly messy to avoid calling kmalloc too early */
177 q = inverse_translations[i] = ((i == LAT1_MAP)
178 ? inv_norm_transl
179 : (unsigned char*)kmalloc(MAX_GLYPH, GFP_KERNEL));
180 if(!q)
181 return;
183 for(j=0; j<MAX_GLYPH; j++)
184 q[j] =0;
186 for(j=0; j<E_TABSZ; j++) {
187 glyph =conv_uni_to_pc(p[j]);
188 if(glyph >=0&& glyph < MAX_GLYPH && q[glyph] <32) {
189 /* prefer '-' above SHY etc. */
190 q[glyph] = j;
195 unsigned short*set_translate(int m)
197 if(!inverse_translations[m])
198 set_inverse_transl(m);
199 inv_translate = inverse_translations[m];
200 return translations[m];
204 * Inverse translation is impossible for several reasons:
205 * 1. The font<->character maps are not 1-1.
206 * 2. The text may have been written while a different translation map
207 * was active, or using Unicode.
208 * Still, it is now possible to a certain extent to cut and paste non-ASCII.
210 unsigned charinverse_translate(int glyph) {
211 if( glyph <0|| glyph >= MAX_GLYPH )
212 return0;
213 else
214 return((inv_translate && inv_translate[glyph])
215 ? inv_translate[glyph]
216 : (unsigned char)(glyph &0xff));
220 * Load customizable translation table
221 * arg points to a 256 byte translation table.
223 * The "old" variants are for translation directly to font (using the
224 * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
225 * Unicodes explicitly.
227 intcon_set_trans_old(unsigned char* arg)
229 int i;
230 unsigned short*p = translations[USER_MAP];
232 i =verify_area(VERIFY_READ, (void*)arg, E_TABSZ);
233 if(i)
234 return i;
236 for(i=0; i<E_TABSZ ; i++)
237 p[i] = UNI_DIRECT_BASE |get_user(arg+i);
239 set_inverse_transl(USER_MAP);
240 return0;
243 intcon_get_trans_old(unsigned char* arg)
245 int i, ch;
246 unsigned short*p = translations[USER_MAP];
248 i =verify_area(VERIFY_WRITE, (void*)arg, E_TABSZ);
249 if(i)
250 return i;
252 for(i=0; i<E_TABSZ ; i++)
254 ch =conv_uni_to_pc(p[i]);
255 put_user((ch & ~0xff) ?0: ch, arg+i);
257 return0;
260 intcon_set_trans_new(ushort * arg)
262 int i;
263 unsigned short*p = translations[USER_MAP];
265 i =verify_area(VERIFY_READ, (void*)arg,
266 E_TABSZ*sizeof(unsigned short));
267 if(i)
268 return i;
270 for(i=0; i<E_TABSZ ; i++)
271 p[i] =get_user(arg+i);
273 set_inverse_transl(USER_MAP);
274 return0;
277 intcon_get_trans_new(ushort * arg)
279 int i;
280 unsigned short*p = translations[USER_MAP];
282 i =verify_area(VERIFY_WRITE, (void*)arg,
283 E_TABSZ*sizeof(unsigned short));
284 if(i)
285 return i;
287 for(i=0; i<E_TABSZ ; i++)
288 put_user(p[i], arg+i);
290 return0;
294 * Unicode -> current font conversion
296 * A font has at most 512 chars, usually 256.
297 * But one font position may represent several Unicode chars.
298 * A hashtable is somewhat of a pain to deal with, so use a
299 * "paged table" instead. Simulation has shown the memory cost of
300 * this 3-level paged table scheme to be comparable to a hash table.
303 #include"uni_hash.tbl"/* Include hash tables & parameters */
305 int hashtable_contents_valid =0;/* Use ASCII-only mode for bootup*/
307 static u16 **uni_pagedir[32] =
309 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
310 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
311 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
312 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
315 static int
316 con_insert_unipair(u_short unicode, u_short fontpos)
318 int i, n;
319 u16 **p1, *p2;
321 if( !(p1 = uni_pagedir[n = unicode >>11]) )
323 p1 = uni_pagedir[n] =kmalloc(32*sizeof(u16 *), GFP_KERNEL);
324 if( !p1 )
325 return-ENOMEM;
327 for( i =0; i <32; i++ )
328 p1[i] = NULL;
331 if( !(p2 = p1[n = (unicode >>6) &0x1f]) )
333 p2 = p1[n] =kmalloc(64*sizeof(u16), GFP_KERNEL);
334 if( !p2 )
335 return-ENOMEM;
337 for( i =0; i <64; i++ )
338 p2[i] =0xffff;/* No glyph for this character (yet) */
341 p2[unicode &0x3f] = fontpos;
343 return0;
346 /* ui is a leftover from using a hashtable, but might be used again */
347 void
348 con_clear_unimap(struct unimapinit *ui)
350 int i, j;
351 u16 **p1;
353 for( i =0; i <32; i++ )
355 if( (p1 = uni_pagedir[i]) != NULL )
357 for( j =0; j <32; j++ )
359 if( p1[j] )
360 kfree(p1[j]);
362 kfree(p1);
364 uni_pagedir[i] = NULL;
367 hashtable_contents_valid =1;
371 con_set_unimap(ushort ct,struct unipair *list)
373 int err =0, err1, i;
375 while( ct-- )
377 if( (err1 =con_insert_unipair(get_user(&list->unicode),
378 get_user(&list->fontpos))) !=0)
379 err = err1;
380 list++;
383 for( i =0; i <=3; i++ )
384 set_inverse_transl(i);/* Update all inverse translations */
386 return err;
389 /* Loads the unimap for the hardware font, as defined in uni_hash.tbl.
390 The representation used was the most compact I could come up
391 with. This routine is executed at sys_setup time, and when the
392 PIO_FONTRESET ioctl is called. */
394 void
395 con_set_default_unimap(void)
397 int i, j;
398 u16 *p;
400 /* The default font is always 256 characters */
402 con_clear_unimap(NULL);
404 p = dfont_unitable;
405 for( i =0; i <256; i++ )
406 for( j = dfont_unicount[i] ; j ; j-- )
407 con_insert_unipair(*(p++), i);
409 for( i =0; i <=3; i++ )
410 set_inverse_transl(i);/* Update all inverse translations */
414 con_get_unimap(ushort ct, ushort *uct,struct unipair *list){
415 int i, j, k, ect;
416 u16 **p1, *p2;
418 ect =0;
419 if(hashtable_contents_valid)
421 for( i =0; i <32; i++ )
422 if( (p1 = uni_pagedir[i]) != NULL )
423 for( j =0; j <32; j++ )
424 if( (p2 = *(p1++)) != NULL )
425 for( k =0; k <64; k++ )
427 if( *p2 < MAX_GLYPH && ect++ < ct )
429 put_user((u_short)((i<<11)+(j<<6)+k),
430 &list->unicode);
431 put_user((u_short) *p2, &list->fontpos);
432 list++;
434 p2++;
437 put_user(ect, uct);
438 return((ect <= ct) ?0: -ENOMEM);
442 conv_uni_to_pc(long ucs)
444 int h;
445 u16 **p1, *p2;
447 /* Only 16-bit codes supported at this time */
448 if(ucs >0xffff)
449 ucs =0xfffd;/* U+FFFD: REPLACEMENT CHARACTER */
450 else if(ucs <0x20|| ucs >=0xfffe)
451 return-1;/* Not a printable character */
452 else if(ucs ==0xfeff|| (ucs >=0x200a&& ucs <=0x200f))
453 return-2;/* Zero-width space */
455 * UNI_DIRECT_BASE indicates the start of the region in the User Zone
456 * which always has a 1:1 mapping to the currently loaded font. The
457 * UNI_DIRECT_MASK indicates the bit span of the region.
459 else if( (ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE )
460 return ucs & UNI_DIRECT_MASK;
462 if(!hashtable_contents_valid)
463 return-3;
465 if( (p1 = uni_pagedir[ucs >>11]) &&
466 (p2 = p1[(ucs >>6) &0x1f]) &&
467 (h = p2[ucs &0x3f]) < MAX_GLYPH )
468 return h;
470 return-4;/* not found */
474 * This is called at sys_setup time, after memory and the console are
475 * initialized. It must be possible to call kmalloc(..., GFP_KERNEL)
476 * from this function, hence the call from sys_setup.
478 void
479 console_map_init(void)
481 con_set_default_unimap();
close