home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / drivers / char / consolemap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-15  |  9.1 KB  |  287 lines

  1. /*
  2.  * consolemap.c
  3.  *
  4.  * Mapping from internal code (such as Latin-1 or Unicode or IBM PC code)
  5.  * to font positions.
  6.  *
  7.  * aeb, 950210
  8.  */
  9.  
  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"
  16.  
  17. static unsigned char * translations[] = {
  18. /* 8-bit Latin-1 mapped to the PC character set: '\0' means non-printable */
  19. (unsigned char *)
  20.     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  21.     "\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
  22.     " !\"#$%&'()*+,-./0123456789:;<=>?"
  23.     "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
  24.     "`abcdefghijklmnopqrstuvwxyz{|}~\0"
  25.     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  26.     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  27.     "\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
  28.     "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
  29.     "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
  30.     "\376\245\376\376\376\376\231\376\350\376\376\376\232\376\376\341"
  31.     "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
  32.     "\376\244\225\242\223\376\224\366\355\227\243\226\201\376\376\230",
  33. /* vt100 graphics */
  34. (unsigned char *)
  35.     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  36.     "\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
  37.     " !\"#$%&'()*+,-./0123456789:;<=>?"
  38.     "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "
  39.     "\004\261\007\007\007\007\370\361\007\007\331\277\332\300\305\304"
  40.     "\304\304\137\137\303\264\301\302\263\363\362\343\330\234\007\0"
  41.     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  42.     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  43.     "\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
  44.     "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
  45.     "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
  46.     "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
  47.     "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
  48.     "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230",
  49. /* IBM graphics: minimal translations (BS, CR, LF, LL, SO, SI and ESC) */
  50. (unsigned char *)
  51.     "\000\001\002\003\004\005\006\007\000\011\000\013\000\000\000\000"
  52.     "\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
  53.     "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
  54.     "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
  55.     "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
  56.     "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
  57.     "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
  58.     "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
  59.     "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
  60.     "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
  61.     "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
  62.     "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
  63.     "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
  64.     "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
  65.     "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
  66.     "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377",
  67.  /* USER: customizable mappings, initialized as the previous one (IBM) */
  68. (unsigned char *)
  69.     "\000\001\002\003\004\005\006\007\010\011\000\013\000\000\016\017"
  70.     "\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
  71.     "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
  72.     "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
  73.     "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
  74.     "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
  75.     "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
  76.     "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
  77.     "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
  78.     "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
  79.     "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
  80.     "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
  81.     "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
  82.     "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
  83.     "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
  84.     "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
  85. };
  86.  
  87. /* the above mappings are not invertible - this is just a best effort */
  88. static unsigned char * inv_translate = NULL;
  89. static unsigned char inv_norm_transl[E_TABSZ];
  90. static unsigned char * inverse_translations[4] = { NULL, NULL, NULL, NULL };
  91.  
  92. static void set_inverse_transl(int i)
  93. {
  94.     int j;
  95.     unsigned char *p = translations[i];
  96.     unsigned char *q = inverse_translations[i];
  97.  
  98.     if (!q) {
  99.         /* slightly messy to avoid calling kmalloc too early */
  100.         q = inverse_translations[i] = ((i == NORM_MAP)
  101.             ? inv_norm_transl
  102.             : (unsigned char *) kmalloc(E_TABSZ, GFP_KERNEL));
  103.         if (!q)
  104.             return;
  105.     }
  106.     for (j=0; j<E_TABSZ; j++)
  107.         q[j] = 0;
  108.     for (j=0; j<E_TABSZ; j++)
  109.         if (q[p[j]] < 32)    /* prefer '-' above SHY etc. */
  110.             q[p[j]] = j;
  111. }
  112.  
  113. unsigned char *set_translate(int m)
  114. {
  115.     if (!inverse_translations[m])
  116.         set_inverse_transl(m);
  117.     inv_translate = inverse_translations[m];
  118.     return translations[m];
  119. }
  120.  
  121. /*
  122.  * Inverse translation is impossible for several reasons:
  123.  * 1. The translation maps are not 1-1
  124.  * 2. The text may have been written while a different translation map
  125.  *    was active
  126.  * Still, it is now possible to a certain extent to cut and paste non-ASCII.
  127.  */
  128. unsigned char inverse_translate(unsigned char c) {
  129.     return ((inv_translate && inv_translate[c]) ? inv_translate[c] : c);
  130. }
  131.  
  132. /*
  133.  * Load customizable translation table
  134.  * arg points to a 256 byte translation table.
  135.  */
  136. int con_set_trans(char * arg)
  137. {
  138.     int i;
  139.     unsigned char *p = translations[USER_MAP];
  140.  
  141.     i = verify_area(VERIFY_READ, (void *)arg, E_TABSZ);
  142.     if (i)
  143.         return i;
  144.  
  145.     for (i=0; i<E_TABSZ ; i++)
  146.         p[i] = get_fs_byte(arg+i);
  147.     p[012] = p[014] = p[015] = p[033] = 0;
  148.     set_inverse_transl(USER_MAP);
  149.     return 0;
  150. }
  151.  
  152. int con_get_trans(char * arg)
  153. {
  154.     int i;
  155.     unsigned char *p = translations[USER_MAP];
  156.  
  157.     i = verify_area(VERIFY_WRITE, (void *)arg, E_TABSZ);
  158.     if (i)
  159.         return i;
  160.  
  161.     for (i=0; i<E_TABSZ ; i++) put_fs_byte(p[i],arg+i);
  162.     return 0;
  163. }
  164.  
  165. /*
  166.  * Unicode -> current font conversion 
  167.  *
  168.  * A font has at most 512 chars, usually 256.
  169.  * But one font position may represent several Unicode chars
  170.  * (and moreover, hashtables work best when they are not too full),
  171.  * so pick HASHSIZE somewhat larger than 512.
  172.  * Since there are likely to be long consecutive stretches
  173.  * (like U+0000 to U+00FF), HASHSTEP should not be too small.
  174.  * Searches longer than MAXHASHLEVEL steps are refused, unless
  175.  * requested explicitly.
  176.  *
  177.  * Note: no conversion tables are compiled in, so the user
  178.  * must supply an explicit mapping herself. See kbd-0.90 (or an
  179.  * earlier kernel version) for the default Unicode-to-PC mapping.
  180.  * Usually, the mapping will be loaded simultaneously with the font.
  181.  */
  182.  
  183. #define HASHSIZE   641
  184. #define HASHSTEP   189        /* yields hashlevel = 3 initially */
  185. #define MAXHASHLEVEL 6
  186. static struct unipair hashtable[HASHSIZE];
  187.  
  188. int hashtable_contents_valid = 0;     /* cleared by setfont */
  189.  
  190. static unsigned int hashsize;
  191. static unsigned int hashstep;
  192. static unsigned int hashlevel;
  193. static unsigned int maxhashlevel;
  194.  
  195. void
  196. con_clear_unimap(struct unimapinit *ui) {
  197.     int i;
  198.  
  199.     /* read advisory values for hash algorithm */
  200.     hashsize = ui->advised_hashsize;
  201.     if (hashsize < 256 || hashsize > HASHSIZE)
  202.       hashsize = HASHSIZE;
  203.     hashstep = (ui->advised_hashstep % hashsize);
  204.     if (hashstep < 64)
  205.       hashstep = HASHSTEP;
  206.     maxhashlevel = ui->advised_hashlevel;
  207.     if (!maxhashlevel)
  208.       maxhashlevel = MAXHASHLEVEL;
  209.     if (maxhashlevel > hashsize)
  210.       maxhashlevel = hashsize;
  211.  
  212.     /* initialize */
  213.     hashlevel = 0;
  214.     for (i=0; i<hashsize; i++)
  215.       hashtable[i].unicode = 0xffff;
  216.     hashtable_contents_valid = 1;
  217. }
  218.  
  219. int
  220. con_set_unimap(ushort ct, struct unipair *list){
  221.     int i, lct;
  222.     ushort u, hu;
  223.     struct unimapinit hashdefaults = { 0, 0, 0 };
  224.  
  225.     if (!hashtable_contents_valid)
  226.       con_clear_unimap(&hashdefaults);
  227.     while(ct) {
  228.         u = get_fs_word(&list->unicode);
  229.         i = u % hashsize;
  230.         lct = 1;
  231.         while ((hu = hashtable[i].unicode) != 0xffff && hu != u) {
  232.         if (lct++ >=  maxhashlevel)
  233.           return -ENOMEM;
  234.         i += hashstep;
  235.         if (i >= hashsize)
  236.           i -= hashsize;
  237.         }
  238.         if (lct > hashlevel)
  239.           hashlevel = lct;
  240.         hashtable[i].unicode = u;
  241.         hashtable[i].fontpos = get_fs_word(&list->fontpos);
  242.         list++;
  243.         ct--;
  244.     }
  245.     return 0;
  246. }
  247.  
  248. int
  249. con_get_unimap(ushort ct, ushort *uct, struct unipair *list){
  250.     int i, ect;
  251.  
  252.     ect = 0;
  253.     if (hashtable_contents_valid)
  254.       for (i = 0; i<hashsize; i++)
  255.         if (hashtable[i].unicode != 0xffff) {
  256.         if (ect++ < ct) {
  257.             put_fs_word(hashtable[i].unicode, &list->unicode);
  258.             put_fs_word(hashtable[i].fontpos, &list->fontpos);
  259.             list++;
  260.         }
  261.         }
  262.     put_fs_word(ect, uct);
  263.     return ((ect <= ct) ? 0 : -ENOMEM);
  264. }
  265.  
  266. int
  267. conv_uni_to_pc(unsigned long ucs) {
  268.       int i, h;
  269.  
  270.       if (!hashtable_contents_valid || ucs < 0x20)
  271.     return -3;
  272.       if (ucs == 0xffff || ucs == 0xfffe)
  273.     return -1;
  274.       if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
  275.     return -2;
  276.       
  277.       h = ucs % hashsize;
  278.       for (i = 0; i < hashlevel; i++) {
  279.       if (hashtable[h].unicode == ucs)
  280.         return hashtable[h].fontpos;
  281.       if ((h += hashstep) >= hashsize)
  282.         h -= hashsize;
  283.       }
  284.  
  285.       return -4;        /* not found */
  286. }
  287.