This source file includes following definitions.
- set_inverse_transl
 
- set_translate
 
- inverse_translate
 
- con_set_trans_old
 
- con_get_trans_old
 
- con_set_trans_new
 
- con_get_trans_new
 
- con_clear_unimap
 
- con_set_unimap
 
- con_get_unimap
 
- conv_uni_to_pc
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   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   
  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   
  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   
  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   
 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 
 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)
     
 166 {
 167         int j, glyph;
 168         unsigned short *p = translations[i];
 169         unsigned char *q = inverse_translations[i];
 170 
 171         if (!q) {
 172                 
 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                   
 184                   q[glyph] = j;
 185 }
 186 
 187 unsigned short *set_translate(int m)
     
 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 
 197 
 198 
 199 
 200 
 201 
 202 unsigned char inverse_translate(unsigned char c) {
     
 203         return ((inv_translate && inv_translate[c]) ? inv_translate[c] : c);
 204 }
 205 
 206 
 207 
 208 
 209 
 210 
 211 
 212 
 213 
 214 int con_set_trans_old(unsigned char * arg)
     
 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)
     
 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)
     
 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)
     
 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 
 281 
 282 
 283 
 284 
 285 
 286 
 287 
 288 
 289 
 290 
 291 
 292 
 293 
 294 
 295 
 296 
 297 #include "uni_hash_tbl.h"       
 298 
 299 int hashtable_contents_valid = 1;
 300 
 301 void
 302 con_clear_unimap(struct unimapinit *ui) {
     
 303         int i;
 304 
 305         
 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         
 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){
     
 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); 
 354 
 355         return 0;
 356 }
 357 
 358 int
 359 con_get_unimap(ushort ct, ushort *uct, struct unipair *list){
     
 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) {
     
 378       int i, h;
 379       
 380       
 381       if (ucs > 0xffff)
 382         ucs = 0xfffd;           
 383       else if (ucs < 0x20 || ucs >= 0xfffe)
 384         return -1;              
 385       else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
 386         return -2;              
 387       
 388 
 389 
 390 
 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;                
 407 }