root/drivers/char/consolemap.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_inverse_transl
  2. set_translate
  3. inverse_translate
  4. con_set_trans_old
  5. con_get_trans_old
  6. con_set_trans_new
  7. con_get_trans_new
  8. con_clear_unimap
  9. con_set_unimap
  10. con_get_unimap
  11. conv_uni_to_pc

   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 short translations[][256] = {
  18   /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
  19   {
  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
  52   }, 
  53   /* VT100 graphics mapped to Unicode */
  54   {
  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
  87   },
  88   /* IBM Codepage 437 mapped to Unicode */
  89   {
  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
 122   }, 
 123   /* User mapping -- default to codes for direct font mapping */
 124   {
 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
 157   }
 158 };
 159 
 160 /* the above mappings are not invertible - this is just a best effort */
 161 static unsigned char * inv_translate = NULL;
 162 static unsigned char inv_norm_transl[E_TABSZ];
 163 static unsigned char * inverse_translations[4] = { NULL, NULL, NULL, NULL };
 164 
 165 static void set_inverse_transl(int i)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167         int j, glyph;
 168         unsigned short *p = translations[i];
 169         unsigned char *q = inverse_translations[i];
 170 
 171         if (!q) {
 172                 /* slightly messy to avoid calling kmalloc too early */
 173                 q = inverse_translations[i] = ((i == LAT1_MAP)
 174                         ? inv_norm_transl
 175                         : (unsigned char *) kmalloc(E_TABSZ, GFP_KERNEL));
 176                 if (!q)
 177                         return;
 178         }
 179         for (j=0; j<E_TABSZ; j++)
 180                 q[j] = 0;
 181         for (j=0; j<E_TABSZ; j++)
 182                 if (q[glyph = conv_uni_to_pc(p[j])] < 32) 
 183                   /* prefer '-' above SHY etc. */
 184                   q[glyph] = j;
 185 }
 186 
 187 unsigned short *set_translate(int m)
     /* [previous][next][first][last][top][bottom][index][help] */
 188 {
 189         if (!inverse_translations[m])
 190                 set_inverse_transl(m);
 191         inv_translate = inverse_translations[m];
 192         return translations[m];
 193 }
 194 
 195 /*
 196  * Inverse translation is impossible for several reasons:
 197  * 1. The translation maps are not 1-1
 198  * 2. The text may have been written while a different translation map
 199  *    was active
 200  * Still, it is now possible to a certain extent to cut and paste non-ASCII.
 201  */
 202 unsigned char inverse_translate(unsigned char c) {
     /* [previous][next][first][last][top][bottom][index][help] */
 203         return ((inv_translate && inv_translate[c]) ? inv_translate[c] : c);
 204 }
 205 
 206 /*
 207  * Load customizable translation table
 208  * arg points to a 256 byte translation table.
 209  *
 210  * The "old" variants are for translation directly to font (using the
 211  * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
 212  * unicodes explictly.
 213  */
 214 int con_set_trans_old(unsigned char * arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 215 {
 216         int i;
 217         unsigned short *p = translations[USER_MAP];
 218 
 219         i = verify_area(VERIFY_READ, (void *)arg, E_TABSZ);
 220         if (i)
 221                 return i;
 222 
 223         for (i=0; i<E_TABSZ ; i++)
 224                 p[i] = UNI_DIRECT_BASE | get_user(arg+i);
 225 
 226         set_inverse_transl(USER_MAP);
 227         return 0;
 228 }
 229 
 230 int con_get_trans_old(unsigned char * arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232         int i, ch;
 233         unsigned short *p = translations[USER_MAP];
 234 
 235         i = verify_area(VERIFY_WRITE, (void *)arg, E_TABSZ);
 236         if (i)
 237                 return i;
 238 
 239         for (i=0; i<E_TABSZ ; i++)
 240           {
 241             ch = conv_uni_to_pc(p[i]);
 242             put_user((ch & ~0xff) ? 0 : ch, arg+i);
 243           }
 244         return 0;
 245 }
 246 int con_set_trans_new(ushort * arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 247 {
 248         int i;
 249         unsigned short *p = translations[USER_MAP];
 250 
 251         i = verify_area(VERIFY_READ, (void *)arg,
 252                         E_TABSZ*sizeof(unsigned short));
 253         if (i)
 254                 return i;
 255 
 256         for (i=0; i<E_TABSZ ; i++)
 257           p[i] = get_user(arg+i);
 258 
 259         set_inverse_transl(USER_MAP);
 260         return 0;
 261 }
 262 
 263 int con_get_trans_new(ushort * arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265         int i;
 266         unsigned short *p = translations[USER_MAP];
 267 
 268         i = verify_area(VERIFY_WRITE, (void *)arg,
 269                         E_TABSZ*sizeof(unsigned short));
 270         if (i)
 271                 return i;
 272 
 273         for (i=0; i<E_TABSZ ; i++)
 274           put_user(p[i], arg+i);
 275         
 276         return 0;
 277 }
 278 
 279 /*
 280  * Unicode -> current font conversion 
 281  *
 282  * A font has at most 512 chars, usually 256.
 283  * But one font position may represent several Unicode chars
 284  * (and moreover, hashtables work best when they are not too full),
 285  * so pick HASHSIZE somewhat larger than 512.
 286  * Since there are likely to be long consecutive stretches
 287  * (like U+0000 to U+00FF), HASHSTEP should not be too small.
 288  * Searches longer than MAXHASHLEVEL steps are refused, unless
 289  * requested explicitly.
 290  *
 291  * Note: no conversion tables are compiled in, so the user
 292  * must supply an explicit mapping herself. See kbd-0.90 (or an
 293  * earlier kernel version) for the default Unicode-to-PC mapping.
 294  * Usually, the mapping will be loaded simultaneously with the font.
 295  */
 296 
 297 #include "uni_hash_tbl.h"       /* Include hash tables & parameters */
 298 
 299 int hashtable_contents_valid = 1;
 300 
 301 void
 302 con_clear_unimap(struct unimapinit *ui) {
     /* [previous][next][first][last][top][bottom][index][help] */
 303         int i;
 304 
 305         /* read advisory values for hash algorithm */
 306         hashsize = ui->advised_hashsize;
 307         if (hashsize < 256 || hashsize > HASHSIZE)
 308           hashsize = HASHSIZE;
 309         hashstep = (ui->advised_hashstep % hashsize);
 310         if (hashstep < 64)
 311           hashstep = HASHSTEP;
 312         maxhashlevel = ui->advised_hashlevel;
 313         if (!maxhashlevel)
 314           maxhashlevel = MAXHASHLEVEL;
 315         if (maxhashlevel > hashsize)
 316           maxhashlevel = hashsize;
 317 
 318         /* initialize */
 319         hashlevel = 0;
 320         for (i=0; i<hashsize; i++)
 321           hashtable[i].unicode = 0xffff;
 322         hashtable_contents_valid = 1;
 323 }
 324 
 325 int
 326 con_set_unimap(ushort ct, struct unipair *list){
     /* [previous][next][first][last][top][bottom][index][help] */
 327         int i, lct;
 328         ushort u, hu;
 329         struct unimapinit hashdefaults = { 0, 0, 0 };
 330 
 331         if (!hashtable_contents_valid)
 332           con_clear_unimap(&hashdefaults);
 333         while(ct) {
 334             u = get_user(&list->unicode);
 335             i = u % hashsize;
 336             lct = 1;
 337             while ((hu = hashtable[i].unicode) != 0xffff && hu != u) {
 338                 if (lct++ >=  maxhashlevel)
 339                   return -ENOMEM;
 340                 i += hashstep;
 341                 if (i >= hashsize)
 342                   i -= hashsize;
 343             }
 344             if (lct > hashlevel)
 345               hashlevel = lct;
 346             hashtable[i].unicode = u;
 347             hashtable[i].fontpos = get_user(&list->fontpos);
 348             list++;
 349             ct--;
 350         }
 351 
 352         for ( i = 0 ; i <= 3 ; i++ )
 353           set_inverse_transl(i); /* Update all inverse translations */
 354 
 355         return 0;
 356 }
 357 
 358 int
 359 con_get_unimap(ushort ct, ushort *uct, struct unipair *list){
     /* [previous][next][first][last][top][bottom][index][help] */
 360         int i, ect;
 361 
 362         ect = 0;
 363         if (hashtable_contents_valid)
 364           for (i = 0; i<hashsize; i++)
 365             if (hashtable[i].unicode != 0xffff) {
 366                 if (ect++ < ct) {
 367                     put_user(hashtable[i].unicode, &list->unicode);
 368                     put_user(hashtable[i].fontpos, &list->fontpos);
 369                     list++;
 370                 }
 371             }
 372         put_user(ect, uct);
 373         return ((ect <= ct) ? 0 : -ENOMEM);
 374 }
 375 
 376 int
 377 conv_uni_to_pc(long ucs) {
     /* [previous][next][first][last][top][bottom][index][help] */
 378       int i, h;
 379       
 380       /* Only 16-bit codes supported at this time */
 381       if (ucs > 0xffff)
 382         ucs = 0xfffd;           /* U+FFFD: REPLACEMENT CHARACTER */
 383       else if (ucs < 0x20 || ucs >= 0xfffe)
 384         return -1;              /* Not a printable character */
 385       else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
 386         return -2;              /* Zero-width space */
 387       /*
 388        * UNI_DIRECT_BASE indicates the start of the region in the User Zone
 389        * which always has a 1:1 mapping to the currently loaded font.  The
 390        * UNI_DIRECT_MASK indicates the bit span of the region.
 391        */
 392       else if ( (ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE )
 393         return ucs & UNI_DIRECT_MASK;
 394 
 395       if (!hashtable_contents_valid)
 396         return -3;
 397       
 398       h = ucs % hashsize;
 399       for (i = 0; i < hashlevel; i++) {
 400           if (hashtable[h].unicode == ucs)
 401             return hashtable[h].fontpos;
 402           if ((h += hashstep) >= hashsize)
 403             h -= hashsize;
 404       }
 405 
 406       return -4;                /* not found */
 407 }

/* [previous][next][first][last][top][bottom][index][help] */