]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkmain-win32.c
Win32: Philippe Colantoni <colanton@aris.ss.uci.edu> suggests a way to get
[~andy/gtk] / gdk / win32 / gdkmain-win32.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 1998-1999 Tor Lillqvist
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include "config.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <limits.h>
34 #include <io.h>
35
36 #include <gdk/gdk.h>
37 #include <gdk/gdkkeysyms.h>
38 #include <gdk/gdki18n.h>
39 #include "gdkx.h"
40 #include "gdkinput.h"
41
42 static void      gdkx_XConvertCase      (KeySym        symbol,
43                                          KeySym       *lower,
44                                          KeySym       *upper);
45 #define XConvertCase gdkx_XConvertCase
46
47 static void         gdk_exit_func                (void);
48
49 static RETSIGTYPE   gdk_signal                   (int          signum);
50
51
52 /* Private variable declarations
53  */
54 static int gdk_initialized = 0; /* 1 if the library is initialized,
55                                  * 0 otherwise.
56                                  */
57 static guint start;             /* We use the millisecond
58                                  * timestamps from GetTickCount
59                                  */
60 static gboolean timerp = TRUE;  /* If TRUE use timeouts when waiting
61                                  * for Windows messages
62                                  */
63 static guint32 timer_val = 20;  /* Timeout in milliseconds.
64                                  */
65
66 #ifdef G_ENABLE_DEBUG
67 static const GDebugKey gdk_debug_keys[] = {
68   {"events",        GDK_DEBUG_EVENTS},
69   {"misc",          GDK_DEBUG_MISC},
70   {"dnd",           GDK_DEBUG_DND},
71   {"color-context", GDK_DEBUG_COLOR_CONTEXT},
72   {"xim",           GDK_DEBUG_XIM},
73   {"selection",     GDK_DEBUG_SELECTION}
74 };
75
76 static const int gdk_ndebug_keys = sizeof(gdk_debug_keys)/sizeof(GDebugKey);
77
78 #endif /* G_ENABLE_DEBUG */
79
80 int __stdcall
81 DllMain(HINSTANCE hinstDLL,
82         DWORD dwReason,
83         LPVOID reserved)
84 {
85   gdk_DLLInstance = hinstDLL;
86
87   return TRUE;
88 }
89
90 /*
91  *--------------------------------------------------------------
92  * gdk_init
93  *
94  *   Initialize the library for use.
95  *
96  * Arguments:
97  *   "argc" is the number of arguments.
98  *   "argv" is an array of strings.
99  *
100  * Results:
101  *   "argc" and "argv" are modified to reflect any arguments
102  *   which were not handled. (Such arguments should either
103  *   be handled by the application or dismissed).
104  *
105  * Side effects:
106  *   The library is initialized.
107  *
108  *--------------------------------------------------------------
109  */
110
111 gboolean
112 gdk_init_check (int    *argc,
113                 char ***argv)
114 {
115   HRESULT hres;
116   gint i, j, k;
117   
118   if (gdk_initialized)
119     return TRUE;
120   
121   if (g_thread_supported ())
122     gdk_threads_mutex = g_mutex_new ();
123   
124   start = GetTickCount ();
125
126 #ifdef G_ENABLE_DEBUG
127   {
128     gchar *debug_string = getenv("GDK_DEBUG");
129     if (debug_string != NULL)
130       gdk_debug_flags = g_parse_debug_string (debug_string,
131                                               (GDebugKey *) gdk_debug_keys,
132                                               gdk_ndebug_keys);
133   }
134 #endif  /* G_ENABLE_DEBUG */
135   
136   if (getenv ("GDK_IGNORE_WINTAB") != NULL)
137     gdk_input_ignore_wintab = TRUE;
138
139   if (getenv ("GDK_EVENT_FUNC_FROM_WINDOW_PROC") != NULL)
140     gdk_event_func_from_window_proc = TRUE;
141
142   if (argc && argv)
143     {
144       if (*argc > 0)
145         {
146           gchar *d;
147           
148           d = strrchr((*argv)[0], G_DIR_SEPARATOR);
149           if (d != NULL)
150             g_set_prgname (d + 1);
151           else
152             g_set_prgname ((*argv)[0]);
153         }
154       
155       for (i = 1; i < *argc;)
156         {
157 #ifdef G_ENABLE_DEBUG     
158           if ((strcmp ("--gdk-debug", (*argv)[i]) == 0) ||
159               (strncmp ("--gdk-debug=", (*argv)[i], 12) == 0))
160             {
161               gchar *equal_pos = strchr ((*argv)[i], '=');
162               
163               if (equal_pos != NULL)
164                 {
165                   gdk_debug_flags |= g_parse_debug_string (equal_pos+1,
166                                                            (GDebugKey *) gdk_debug_keys,
167                                                            gdk_ndebug_keys);
168                 }
169               else if ((i + 1) < *argc && (*argv)[i + 1])
170                 {
171                   gdk_debug_flags |= g_parse_debug_string ((*argv)[i+1],
172                                                            (GDebugKey *) gdk_debug_keys,
173                                                            gdk_ndebug_keys);
174                   (*argv)[i] = NULL;
175                   i += 1;
176                 }
177               (*argv)[i] = NULL;
178             }
179           else if ((strcmp ("--gdk-no-debug", (*argv)[i]) == 0) ||
180                    (strncmp ("--gdk-no-debug=", (*argv)[i], 15) == 0))
181             {
182               gchar *equal_pos = strchr ((*argv)[i], '=');
183
184               if (equal_pos != NULL)
185                 {
186                   gdk_debug_flags &= ~g_parse_debug_string (equal_pos+1,
187                                                             (GDebugKey *) gdk_debug_keys,
188                                                             gdk_ndebug_keys);
189                 }
190               else if ((i + 1) < *argc && (*argv)[i + 1])
191                 {
192                   gdk_debug_flags &= ~g_parse_debug_string ((*argv)[i+1],
193                                                             (GDebugKey *) gdk_debug_keys,
194                                                             gdk_ndebug_keys);
195                   (*argv)[i] = NULL;
196                   i += 1;
197                 }
198               (*argv)[i] = NULL;
199             }
200           else 
201 #endif /* G_ENABLE_DEBUG */
202             if (strcmp ("--sync", (*argv)[i]) == 0)
203               {
204                 (*argv)[i] = NULL;
205                 GdiSetBatchLimit (1);
206               }
207             else if (strcmp ("--name", (*argv)[i]) == 0)
208               {
209                 if ((i + 1) < *argc && (*argv)[i + 1])
210                   {
211                     (*argv)[i++] = NULL;
212                     g_set_prgname ((*argv)[i]);
213                     (*argv)[i] = NULL;
214                   }
215               }
216             else if (strcmp ("--gdk-no-wintab", (*argv)[i]) == 0
217                      || strcmp ("--gdk-ignore-wintab", (*argv)[i]) == 0)
218               {
219                 (*argv)[i] = NULL;
220                 gdk_input_ignore_wintab = TRUE;
221               }
222             else if (strcmp ("--gdk-event-func-from-window-proc", (*argv)[i]) == 0)
223               {
224                 (*argv)[i] = NULL;
225                 gdk_event_func_from_window_proc = TRUE;
226               }
227           i += 1;
228         }
229       
230       for (i = 1; i < *argc; i++)
231         {
232           for (k = i; k < *argc; k++)
233             if ((*argv)[k] != NULL)
234               break;
235           
236           if (k > i)
237             {
238               k -= i;
239               for (j = i + k; j < *argc; j++)
240                 (*argv)[j-k] = (*argv)[j];
241               *argc -= k;
242             }
243         }
244     }
245   else
246     {
247       g_set_prgname ("<unknown>");
248     }
249   
250   gdk_ProgInstance = GetModuleHandle (NULL);
251   gdk_DC = CreateDC ("DISPLAY", NULL, NULL, NULL);
252
253   gdk_selection_request_msg = RegisterWindowMessage ("gdk-selection-request");
254   gdk_selection_notify_msg = RegisterWindowMessage ("gdk-selection-notify");
255   gdk_selection_clear_msg = RegisterWindowMessage ("gdk-selection-clear");
256
257   gdk_selection_property = gdk_atom_intern ("GDK_SELECTION", FALSE);
258   gdk_clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
259   gdk_win32_dropfiles_atom = gdk_atom_intern ("DROPFILES_DND", FALSE);
260   gdk_ole2_dnd_atom = gdk_atom_intern ("OLE2_DND", FALSE);
261
262   gdk_progclass = g_basename (g_get_prgname ());
263   gdk_progclass[0] = toupper (gdk_progclass[0]);
264
265   gdk_root_window = HWND_DESKTOP;
266
267   g_atexit (gdk_exit_func);
268   
269   gdk_events_init ();
270   gdk_visual_init ();
271   gdk_window_init ();
272   gdk_image_init ();
273   gdk_input_init ();
274   gdk_selection_init ();
275   gdk_dnd_init ();
276
277   gdk_initialized = 1;
278
279   return TRUE;
280 }
281
282 void
283 gdk_init (int *argc, char ***argv)
284 {
285   if (!gdk_init_check (argc, argv))
286     {
287       g_warning ("cannot initialize GDK");
288       exit(1);
289     }
290 }
291
292 /*
293  *--------------------------------------------------------------
294  * gdk_exit
295  *
296  *   Restores the library to an un-itialized state and exits
297  *   the program using the "exit" system call.
298  *
299  * Arguments:
300  *   "errorcode" is the error value to pass to "exit".
301  *
302  * Results:
303  *   Allocated structures are freed and the program exits
304  *   cleanly.
305  *
306  * Side effects:
307  *
308  *--------------------------------------------------------------
309  */
310
311 void
312 gdk_exit (int errorcode)
313 {
314   /* de-initialisation is done by the gdk_exit_func(),
315      no need to do this here (Alex J.) */
316   exit (errorcode);
317 }
318
319 void
320 gdk_set_use_xshm (gint use_xshm)
321 {
322   /* Always on */
323 }
324
325 gint
326 gdk_get_use_xshm (void)
327 {
328   return TRUE;
329 }
330
331 /*
332  *--------------------------------------------------------------
333  * gdk_time_get
334  *
335  *   Get the number of milliseconds since the library was
336  *   initialized.
337  *
338  * Arguments:
339  *
340  * Results:
341  *   The time since the library was initialized is returned.
342  *   This time value is accurate to milliseconds even though
343  *   a more accurate time down to the microsecond could be
344  *   returned.
345  *
346  * Side effects:
347  *
348  *--------------------------------------------------------------
349  */
350
351 guint32
352 gdk_time_get (void)
353 {
354   guint32 milliseconds;
355   guint32 end = GetTickCount ();
356
357   if (end < start)
358     milliseconds = 0xFFFFFFFF - (start - end) + 1;
359   else
360     milliseconds = end - start;
361
362   return milliseconds;
363 }
364
365 /*
366  *--------------------------------------------------------------
367  * gdk_timer_get
368  *
369  *   Returns the current timer.
370  *
371  * Arguments:
372  *
373  * Results:
374  *   Returns the current timer interval. This interval is
375  *   in units of milliseconds.
376  *
377  * Side effects:
378  *
379  *--------------------------------------------------------------
380  */
381
382 guint32
383 gdk_timer_get (void)
384 {
385   return timer_val;
386 }
387
388 /*
389  *--------------------------------------------------------------
390  * gdk_timer_set
391  *
392  *   Sets the timer interval.
393  *
394  * Arguments:
395  *   "milliseconds" is the new value for the timer.
396  *
397  * Results:
398  *
399  * Side effects:
400  *   Calls to "gdk_event_get" will last for a maximum
401  *   of time of "milliseconds". However, a value of 0
402  *   milliseconds will cause "gdk_event_get" to block
403  *   indefinately until an event is received.
404  *
405  *--------------------------------------------------------------
406  */
407
408 void
409 gdk_timer_set (guint32 milliseconds)
410 {
411   timer_val = milliseconds;
412 #ifdef USE_PEEKNAMEDPIPE
413   /* When using PeekNamedPipe, can't have too long timeouts.
414    */
415   if (timer_val > 10)
416     timer_val = 10;
417   else if (timer_val == 0)
418     timer_val = 0;
419 #endif
420 }
421
422 void
423 gdk_timer_enable (void)
424 {
425   timerp = TRUE;
426 }
427
428 void
429 gdk_timer_disable (void)
430 {
431 #ifdef USE_PEEKNAMEDPIPE
432   /* Can't disable timeouts when using PeekNamedPipe */
433 #else
434   timerp = FALSE;
435 #endif
436 }
437
438 /*
439  *--------------------------------------------------------------
440  * gdk_screen_width
441  *
442  *   Return the width of the screen.
443  *
444  * Arguments:
445  *
446  * Results:
447  *
448  * Side effects:
449  *
450  *--------------------------------------------------------------
451  */
452
453 gint
454 gdk_screen_width (void)
455 {
456   gint return_val;
457   
458   return_val = gdk_root_parent.width;
459
460   return return_val;
461 }
462
463 /*
464  *--------------------------------------------------------------
465  * gdk_screen_height
466  *
467  *   Return the height of the screen.
468  *
469  * Arguments:
470  *
471  * Results:
472  *
473  * Side effects:
474  *
475  *--------------------------------------------------------------
476  */
477
478 gint
479 gdk_screen_height (void)
480 {
481   gint return_val;
482   
483   return_val = gdk_root_parent.height;
484
485   return return_val;
486 }
487
488 /*
489  *--------------------------------------------------------------
490  * gdk_screen_width_mm
491  *
492  *   Return the width of the screen in millimetres.
493  *
494  * Arguments:
495  *
496  * Results:
497  *
498  * Side effects:
499  *
500  *--------------------------------------------------------------
501  */
502
503 gint
504 gdk_screen_width_mm (void)
505 {
506   HDC hdc;
507   gint return_val;
508
509   hdc = GetDC (NULL);
510   return_val = GetDeviceCaps (hdc, HORZSIZE);
511   ReleaseDC (NULL, hdc);
512
513   return return_val;
514 }
515
516 /*
517  *--------------------------------------------------------------
518  * gdk_screen_height
519  *
520  *   Return the height of the screen in millimetres.
521  *
522  * Arguments:
523  *
524  * Results:
525  *
526  * Side effects:
527  *
528  *--------------------------------------------------------------
529  */
530
531 gint
532 gdk_screen_height_mm (void)
533 {
534   HDC hdc;
535   gint return_val;
536
537   hdc = GetDC (NULL);
538   return_val = GetDeviceCaps (hdc, VERTSIZE);
539   ReleaseDC (NULL, hdc);
540   
541   return return_val;
542 }
543
544 void
545 gdk_key_repeat_disable (void)
546 {
547   /* XXX */
548 }
549
550 void
551 gdk_key_repeat_restore (void)
552 {
553   /* XXX */
554 }
555
556
557 /*
558  *--------------------------------------------------------------
559  * gdk_flush
560  *
561  *   Flushes the Xlib output buffer and then waits
562  *   until all requests have been received and processed
563  *   by the X server. The only real use for this function
564  *   is in dealing with XShm.
565  *
566  * Arguments:
567  *
568  * Results:
569  *
570  * Side effects:
571  *
572  *--------------------------------------------------------------
573  */
574
575 void
576 gdk_flush (void)
577 {
578   GdiFlush ();
579 }
580
581 void
582 gdk_beep (void)
583 {
584   Beep(1000, 50);
585 }
586
587 /*
588  *--------------------------------------------------------------
589  * gdk_exit_func
590  *
591  *   This is the "atexit" function that makes sure the
592  *   library gets a chance to cleanup.
593  *
594  * Arguments:
595  *
596  * Results:
597  *
598  * Side effects:
599  *   The library is un-initialized and the program exits.
600  *
601  *--------------------------------------------------------------
602  */
603
604 static void
605 gdk_exit_func (void)
606 {
607   static gboolean in_gdk_exit_func = FALSE;
608   
609   GDK_NOTE (MISC, g_print ("gdk_exit_func\n"));
610   /* This is to avoid an infinite loop if a program segfaults in
611      an atexit() handler (and yes, it does happen, especially if a program
612      has trounced over memory too badly for even g_message to work) */
613   if (in_gdk_exit_func == TRUE)
614     return;
615   in_gdk_exit_func = TRUE;
616   
617   if (gdk_initialized)
618     {
619       gdk_image_exit ();
620       gdk_input_exit ();
621       gdk_key_repeat_restore ();
622       gdk_dnd_exit ();
623       gdk_initialized = 0;
624     }
625 }
626
627 gchar *
628 gdk_get_display(void)
629 {
630   return "local:";
631 }
632
633 /*************************************************************
634  * gdk_error_trap_push:
635  *     Push an error trap. X errors will be trapped until
636  *     the corresponding gdk_error_pop(), which will return
637  *     the error code, if any.
638  *   arguments:
639  *     
640  *   results:
641  *************************************************************/
642
643 void
644 gdk_error_trap_push (void)
645 {
646   /* ??? */
647 }
648
649 /*************************************************************
650  * gdk_error_trap_pop:
651  *     Pop an error trap added with gdk_error_push()
652  *   arguments:
653  *     
654  *   results:
655  *     0, if no error occured, otherwise the error code.
656  *************************************************************/
657
658 gint
659 gdk_error_trap_pop (void)
660 {
661   /* ??? */
662   return 0;
663 }
664
665 static void
666 gdkx_XConvertCase (KeySym symbol,
667                    KeySym *lower,
668                    KeySym *upper)
669 {
670   register KeySym sym = symbol;
671   
672   g_return_if_fail (lower != NULL);
673   g_return_if_fail (upper != NULL);
674   
675   *lower = sym;
676   *upper = sym;
677   
678   switch (sym >> 8)
679     {
680 #if     defined (GDK_A) && defined (GDK_Ooblique)
681     case 0: /* Latin 1 */
682       if ((sym >= GDK_A) && (sym <= GDK_Z))
683         *lower += (GDK_a - GDK_A);
684       else if ((sym >= GDK_a) && (sym <= GDK_z))
685         *upper -= (GDK_a - GDK_A);
686       else if ((sym >= GDK_Agrave) && (sym <= GDK_Odiaeresis))
687         *lower += (GDK_agrave - GDK_Agrave);
688       else if ((sym >= GDK_agrave) && (sym <= GDK_odiaeresis))
689         *upper -= (GDK_agrave - GDK_Agrave);
690       else if ((sym >= GDK_Ooblique) && (sym <= GDK_Thorn))
691         *lower += (GDK_oslash - GDK_Ooblique);
692       else if ((sym >= GDK_oslash) && (sym <= GDK_thorn))
693         *upper -= (GDK_oslash - GDK_Ooblique);
694       break;
695 #endif  /* LATIN1 */
696       
697 #if     defined (GDK_Aogonek) && defined (GDK_tcedilla)
698     case 1: /* Latin 2 */
699       /* Assume the KeySym is a legal value (ignore discontinuities) */
700       if (sym == GDK_Aogonek)
701         *lower = GDK_aogonek;
702       else if (sym >= GDK_Lstroke && sym <= GDK_Sacute)
703         *lower += (GDK_lstroke - GDK_Lstroke);
704       else if (sym >= GDK_Scaron && sym <= GDK_Zacute)
705         *lower += (GDK_scaron - GDK_Scaron);
706       else if (sym >= GDK_Zcaron && sym <= GDK_Zabovedot)
707         *lower += (GDK_zcaron - GDK_Zcaron);
708       else if (sym == GDK_aogonek)
709         *upper = GDK_Aogonek;
710       else if (sym >= GDK_lstroke && sym <= GDK_sacute)
711         *upper -= (GDK_lstroke - GDK_Lstroke);
712       else if (sym >= GDK_scaron && sym <= GDK_zacute)
713         *upper -= (GDK_scaron - GDK_Scaron);
714       else if (sym >= GDK_zcaron && sym <= GDK_zabovedot)
715         *upper -= (GDK_zcaron - GDK_Zcaron);
716       else if (sym >= GDK_Racute && sym <= GDK_Tcedilla)
717         *lower += (GDK_racute - GDK_Racute);
718       else if (sym >= GDK_racute && sym <= GDK_tcedilla)
719         *upper -= (GDK_racute - GDK_Racute);
720       break;
721 #endif  /* LATIN2 */
722       
723 #if     defined (GDK_Hstroke) && defined (GDK_Cabovedot)
724     case 2: /* Latin 3 */
725       /* Assume the KeySym is a legal value (ignore discontinuities) */
726       if (sym >= GDK_Hstroke && sym <= GDK_Hcircumflex)
727         *lower += (GDK_hstroke - GDK_Hstroke);
728       else if (sym >= GDK_Gbreve && sym <= GDK_Jcircumflex)
729         *lower += (GDK_gbreve - GDK_Gbreve);
730       else if (sym >= GDK_hstroke && sym <= GDK_hcircumflex)
731         *upper -= (GDK_hstroke - GDK_Hstroke);
732       else if (sym >= GDK_gbreve && sym <= GDK_jcircumflex)
733         *upper -= (GDK_gbreve - GDK_Gbreve);
734       else if (sym >= GDK_Cabovedot && sym <= GDK_Scircumflex)
735         *lower += (GDK_cabovedot - GDK_Cabovedot);
736       else if (sym >= GDK_cabovedot && sym <= GDK_scircumflex)
737         *upper -= (GDK_cabovedot - GDK_Cabovedot);
738       break;
739 #endif  /* LATIN3 */
740       
741 #if     defined (GDK_Rcedilla) && defined (GDK_Amacron)
742     case 3: /* Latin 4 */
743       /* Assume the KeySym is a legal value (ignore discontinuities) */
744       if (sym >= GDK_Rcedilla && sym <= GDK_Tslash)
745         *lower += (GDK_rcedilla - GDK_Rcedilla);
746       else if (sym >= GDK_rcedilla && sym <= GDK_tslash)
747         *upper -= (GDK_rcedilla - GDK_Rcedilla);
748       else if (sym == GDK_ENG)
749         *lower = GDK_eng;
750       else if (sym == GDK_eng)
751         *upper = GDK_ENG;
752       else if (sym >= GDK_Amacron && sym <= GDK_Umacron)
753         *lower += (GDK_amacron - GDK_Amacron);
754       else if (sym >= GDK_amacron && sym <= GDK_umacron)
755         *upper -= (GDK_amacron - GDK_Amacron);
756       break;
757 #endif  /* LATIN4 */
758       
759 #if     defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu)
760     case 6: /* Cyrillic */
761       /* Assume the KeySym is a legal value (ignore discontinuities) */
762       if (sym >= GDK_Serbian_DJE && sym <= GDK_Serbian_DZE)
763         *lower -= (GDK_Serbian_DJE - GDK_Serbian_dje);
764       else if (sym >= GDK_Serbian_dje && sym <= GDK_Serbian_dze)
765         *upper += (GDK_Serbian_DJE - GDK_Serbian_dje);
766       else if (sym >= GDK_Cyrillic_YU && sym <= GDK_Cyrillic_HARDSIGN)
767         *lower -= (GDK_Cyrillic_YU - GDK_Cyrillic_yu);
768       else if (sym >= GDK_Cyrillic_yu && sym <= GDK_Cyrillic_hardsign)
769         *upper += (GDK_Cyrillic_YU - GDK_Cyrillic_yu);
770       break;
771 #endif  /* CYRILLIC */
772
773 #if     defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma)
774     case 7: /* Greek */
775       /* Assume the KeySym is a legal value (ignore discontinuities) */
776       if (sym >= GDK_Greek_ALPHAaccent && sym <= GDK_Greek_OMEGAaccent)
777         *lower += (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent);
778       else if (sym >= GDK_Greek_alphaaccent && sym <= GDK_Greek_omegaaccent &&
779                sym != GDK_Greek_iotaaccentdieresis &&
780                sym != GDK_Greek_upsilonaccentdieresis)
781         *upper -= (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent);
782       else if (sym >= GDK_Greek_ALPHA && sym <= GDK_Greek_OMEGA)
783         *lower += (GDK_Greek_alpha - GDK_Greek_ALPHA);
784       else if (sym >= GDK_Greek_alpha && sym <= GDK_Greek_omega &&
785                sym != GDK_Greek_finalsmallsigma)
786         *upper -= (GDK_Greek_alpha - GDK_Greek_ALPHA);
787       break;
788 #endif  /* GREEK */
789     }
790 }
791
792 static struct gdk_key {
793   guint keyval;
794   const char *name;
795 } gdk_keys_by_keyval[] = {
796   { 0x000020, "space" },
797   { 0x000021, "exclam" },
798   { 0x000022, "quotedbl" },
799   { 0x000023, "numbersign" },
800   { 0x000024, "dollar" },
801   { 0x000025, "percent" },
802   { 0x000026, "ampersand" },
803   { 0x000027, "apostrophe" },
804   { 0x000027, "quoteright" },
805   { 0x000028, "parenleft" },
806   { 0x000029, "parenright" },
807   { 0x00002a, "asterisk" },
808   { 0x00002b, "plus" },
809   { 0x00002c, "comma" },
810   { 0x00002d, "minus" },
811   { 0x00002e, "period" },
812   { 0x00002f, "slash" },
813   { 0x000030, "0" },
814   { 0x000031, "1" },
815   { 0x000032, "2" },
816   { 0x000033, "3" },
817   { 0x000034, "4" },
818   { 0x000035, "5" },
819   { 0x000036, "6" },
820   { 0x000037, "7" },
821   { 0x000038, "8" },
822   { 0x000039, "9" },
823   { 0x00003a, "colon" },
824   { 0x00003b, "semicolon" },
825   { 0x00003c, "less" },
826   { 0x00003d, "equal" },
827   { 0x00003e, "greater" },
828   { 0x00003f, "question" },
829   { 0x000040, "at" },
830   { 0x000041, "A" },
831   { 0x000042, "B" },
832   { 0x000043, "C" },
833   { 0x000044, "D" },
834   { 0x000045, "E" },
835   { 0x000046, "F" },
836   { 0x000047, "G" },
837   { 0x000048, "H" },
838   { 0x000049, "I" },
839   { 0x00004a, "J" },
840   { 0x00004b, "K" },
841   { 0x00004c, "L" },
842   { 0x00004d, "M" },
843   { 0x00004e, "N" },
844   { 0x00004f, "O" },
845   { 0x000050, "P" },
846   { 0x000051, "Q" },
847   { 0x000052, "R" },
848   { 0x000053, "S" },
849   { 0x000054, "T" },
850   { 0x000055, "U" },
851   { 0x000056, "V" },
852   { 0x000057, "W" },
853   { 0x000058, "X" },
854   { 0x000059, "Y" },
855   { 0x00005a, "Z" },
856   { 0x00005b, "bracketleft" },
857   { 0x00005c, "backslash" },
858   { 0x00005d, "bracketright" },
859   { 0x00005e, "asciicircum" },
860   { 0x00005f, "underscore" },
861   { 0x000060, "grave" },
862   { 0x000060, "quoteleft" },
863   { 0x000061, "a" },
864   { 0x000062, "b" },
865   { 0x000063, "c" },
866   { 0x000064, "d" },
867   { 0x000065, "e" },
868   { 0x000066, "f" },
869   { 0x000067, "g" },
870   { 0x000068, "h" },
871   { 0x000069, "i" },
872   { 0x00006a, "j" },
873   { 0x00006b, "k" },
874   { 0x00006c, "l" },
875   { 0x00006d, "m" },
876   { 0x00006e, "n" },
877   { 0x00006f, "o" },
878   { 0x000070, "p" },
879   { 0x000071, "q" },
880   { 0x000072, "r" },
881   { 0x000073, "s" },
882   { 0x000074, "t" },
883   { 0x000075, "u" },
884   { 0x000076, "v" },
885   { 0x000077, "w" },
886   { 0x000078, "x" },
887   { 0x000079, "y" },
888   { 0x00007a, "z" },
889   { 0x00007b, "braceleft" },
890   { 0x00007c, "bar" },
891   { 0x00007d, "braceright" },
892   { 0x00007e, "asciitilde" },
893   { 0x0000a0, "nobreakspace" },
894   { 0x0000a1, "exclamdown" },
895   { 0x0000a2, "cent" },
896   { 0x0000a3, "sterling" },
897   { 0x0000a4, "currency" },
898   { 0x0000a5, "yen" },
899   { 0x0000a6, "brokenbar" },
900   { 0x0000a7, "section" },
901   { 0x0000a8, "diaeresis" },
902   { 0x0000a9, "copyright" },
903   { 0x0000aa, "ordfeminine" },
904   { 0x0000ab, "guillemotleft" },
905   { 0x0000ac, "notsign" },
906   { 0x0000ad, "hyphen" },
907   { 0x0000ae, "registered" },
908   { 0x0000af, "macron" },
909   { 0x0000b0, "degree" },
910   { 0x0000b1, "plusminus" },
911   { 0x0000b2, "twosuperior" },
912   { 0x0000b3, "threesuperior" },
913   { 0x0000b4, "acute" },
914   { 0x0000b5, "mu" },
915   { 0x0000b6, "paragraph" },
916   { 0x0000b7, "periodcentered" },
917   { 0x0000b8, "cedilla" },
918   { 0x0000b9, "onesuperior" },
919   { 0x0000ba, "masculine" },
920   { 0x0000bb, "guillemotright" },
921   { 0x0000bc, "onequarter" },
922   { 0x0000bd, "onehalf" },
923   { 0x0000be, "threequarters" },
924   { 0x0000bf, "questiondown" },
925   { 0x0000c0, "Agrave" },
926   { 0x0000c1, "Aacute" },
927   { 0x0000c2, "Acircumflex" },
928   { 0x0000c3, "Atilde" },
929   { 0x0000c4, "Adiaeresis" },
930   { 0x0000c5, "Aring" },
931   { 0x0000c6, "AE" },
932   { 0x0000c7, "Ccedilla" },
933   { 0x0000c8, "Egrave" },
934   { 0x0000c9, "Eacute" },
935   { 0x0000ca, "Ecircumflex" },
936   { 0x0000cb, "Ediaeresis" },
937   { 0x0000cc, "Igrave" },
938   { 0x0000cd, "Iacute" },
939   { 0x0000ce, "Icircumflex" },
940   { 0x0000cf, "Idiaeresis" },
941   { 0x0000d0, "ETH" },
942   { 0x0000d0, "Eth" },
943   { 0x0000d1, "Ntilde" },
944   { 0x0000d2, "Ograve" },
945   { 0x0000d3, "Oacute" },
946   { 0x0000d4, "Ocircumflex" },
947   { 0x0000d5, "Otilde" },
948   { 0x0000d6, "Odiaeresis" },
949   { 0x0000d7, "multiply" },
950   { 0x0000d8, "Ooblique" },
951   { 0x0000d9, "Ugrave" },
952   { 0x0000da, "Uacute" },
953   { 0x0000db, "Ucircumflex" },
954   { 0x0000dc, "Udiaeresis" },
955   { 0x0000dd, "Yacute" },
956   { 0x0000de, "THORN" },
957   { 0x0000de, "Thorn" },
958   { 0x0000df, "ssharp" },
959   { 0x0000e0, "agrave" },
960   { 0x0000e1, "aacute" },
961   { 0x0000e2, "acircumflex" },
962   { 0x0000e3, "atilde" },
963   { 0x0000e4, "adiaeresis" },
964   { 0x0000e5, "aring" },
965   { 0x0000e6, "ae" },
966   { 0x0000e7, "ccedilla" },
967   { 0x0000e8, "egrave" },
968   { 0x0000e9, "eacute" },
969   { 0x0000ea, "ecircumflex" },
970   { 0x0000eb, "ediaeresis" },
971   { 0x0000ec, "igrave" },
972   { 0x0000ed, "iacute" },
973   { 0x0000ee, "icircumflex" },
974   { 0x0000ef, "idiaeresis" },
975   { 0x0000f0, "eth" },
976   { 0x0000f1, "ntilde" },
977   { 0x0000f2, "ograve" },
978   { 0x0000f3, "oacute" },
979   { 0x0000f4, "ocircumflex" },
980   { 0x0000f5, "otilde" },
981   { 0x0000f6, "odiaeresis" },
982   { 0x0000f7, "division" },
983   { 0x0000f8, "oslash" },
984   { 0x0000f9, "ugrave" },
985   { 0x0000fa, "uacute" },
986   { 0x0000fb, "ucircumflex" },
987   { 0x0000fc, "udiaeresis" },
988   { 0x0000fd, "yacute" },
989   { 0x0000fe, "thorn" },
990   { 0x0000ff, "ydiaeresis" },
991   { 0x0001a1, "Aogonek" },
992   { 0x0001a2, "breve" },
993   { 0x0001a3, "Lstroke" },
994   { 0x0001a5, "Lcaron" },
995   { 0x0001a6, "Sacute" },
996   { 0x0001a9, "Scaron" },
997   { 0x0001aa, "Scedilla" },
998   { 0x0001ab, "Tcaron" },
999   { 0x0001ac, "Zacute" },
1000   { 0x0001ae, "Zcaron" },
1001   { 0x0001af, "Zabovedot" },
1002   { 0x0001b1, "aogonek" },
1003   { 0x0001b2, "ogonek" },
1004   { 0x0001b3, "lstroke" },
1005   { 0x0001b5, "lcaron" },
1006   { 0x0001b6, "sacute" },
1007   { 0x0001b7, "caron" },
1008   { 0x0001b9, "scaron" },
1009   { 0x0001ba, "scedilla" },
1010   { 0x0001bb, "tcaron" },
1011   { 0x0001bc, "zacute" },
1012   { 0x0001bd, "doubleacute" },
1013   { 0x0001be, "zcaron" },
1014   { 0x0001bf, "zabovedot" },
1015   { 0x0001c0, "Racute" },
1016   { 0x0001c3, "Abreve" },
1017   { 0x0001c5, "Lacute" },
1018   { 0x0001c6, "Cacute" },
1019   { 0x0001c8, "Ccaron" },
1020   { 0x0001ca, "Eogonek" },
1021   { 0x0001cc, "Ecaron" },
1022   { 0x0001cf, "Dcaron" },
1023   { 0x0001d0, "Dstroke" },
1024   { 0x0001d1, "Nacute" },
1025   { 0x0001d2, "Ncaron" },
1026   { 0x0001d5, "Odoubleacute" },
1027   { 0x0001d8, "Rcaron" },
1028   { 0x0001d9, "Uring" },
1029   { 0x0001db, "Udoubleacute" },
1030   { 0x0001de, "Tcedilla" },
1031   { 0x0001e0, "racute" },
1032   { 0x0001e3, "abreve" },
1033   { 0x0001e5, "lacute" },
1034   { 0x0001e6, "cacute" },
1035   { 0x0001e8, "ccaron" },
1036   { 0x0001ea, "eogonek" },
1037   { 0x0001ec, "ecaron" },
1038   { 0x0001ef, "dcaron" },
1039   { 0x0001f0, "dstroke" },
1040   { 0x0001f1, "nacute" },
1041   { 0x0001f2, "ncaron" },
1042   { 0x0001f5, "odoubleacute" },
1043   { 0x0001f8, "rcaron" },
1044   { 0x0001f9, "uring" },
1045   { 0x0001fb, "udoubleacute" },
1046   { 0x0001fe, "tcedilla" },
1047   { 0x0001ff, "abovedot" },
1048   { 0x0002a1, "Hstroke" },
1049   { 0x0002a6, "Hcircumflex" },
1050   { 0x0002a9, "Iabovedot" },
1051   { 0x0002ab, "Gbreve" },
1052   { 0x0002ac, "Jcircumflex" },
1053   { 0x0002b1, "hstroke" },
1054   { 0x0002b6, "hcircumflex" },
1055   { 0x0002b9, "idotless" },
1056   { 0x0002bb, "gbreve" },
1057   { 0x0002bc, "jcircumflex" },
1058   { 0x0002c5, "Cabovedot" },
1059   { 0x0002c6, "Ccircumflex" },
1060   { 0x0002d5, "Gabovedot" },
1061   { 0x0002d8, "Gcircumflex" },
1062   { 0x0002dd, "Ubreve" },
1063   { 0x0002de, "Scircumflex" },
1064   { 0x0002e5, "cabovedot" },
1065   { 0x0002e6, "ccircumflex" },
1066   { 0x0002f5, "gabovedot" },
1067   { 0x0002f8, "gcircumflex" },
1068   { 0x0002fd, "ubreve" },
1069   { 0x0002fe, "scircumflex" },
1070   { 0x0003a2, "kappa" },
1071   { 0x0003a2, "kra" },
1072   { 0x0003a3, "Rcedilla" },
1073   { 0x0003a5, "Itilde" },
1074   { 0x0003a6, "Lcedilla" },
1075   { 0x0003aa, "Emacron" },
1076   { 0x0003ab, "Gcedilla" },
1077   { 0x0003ac, "Tslash" },
1078   { 0x0003b3, "rcedilla" },
1079   { 0x0003b5, "itilde" },
1080   { 0x0003b6, "lcedilla" },
1081   { 0x0003ba, "emacron" },
1082   { 0x0003bb, "gcedilla" },
1083   { 0x0003bc, "tslash" },
1084   { 0x0003bd, "ENG" },
1085   { 0x0003bf, "eng" },
1086   { 0x0003c0, "Amacron" },
1087   { 0x0003c7, "Iogonek" },
1088   { 0x0003cc, "Eabovedot" },
1089   { 0x0003cf, "Imacron" },
1090   { 0x0003d1, "Ncedilla" },
1091   { 0x0003d2, "Omacron" },
1092   { 0x0003d3, "Kcedilla" },
1093   { 0x0003d9, "Uogonek" },
1094   { 0x0003dd, "Utilde" },
1095   { 0x0003de, "Umacron" },
1096   { 0x0003e0, "amacron" },
1097   { 0x0003e7, "iogonek" },
1098   { 0x0003ec, "eabovedot" },
1099   { 0x0003ef, "imacron" },
1100   { 0x0003f1, "ncedilla" },
1101   { 0x0003f2, "omacron" },
1102   { 0x0003f3, "kcedilla" },
1103   { 0x0003f9, "uogonek" },
1104   { 0x0003fd, "utilde" },
1105   { 0x0003fe, "umacron" },
1106   { 0x00047e, "overline" },
1107   { 0x0004a1, "kana_fullstop" },
1108   { 0x0004a2, "kana_openingbracket" },
1109   { 0x0004a3, "kana_closingbracket" },
1110   { 0x0004a4, "kana_comma" },
1111   { 0x0004a5, "kana_conjunctive" },
1112   { 0x0004a5, "kana_middledot" },
1113   { 0x0004a6, "kana_WO" },
1114   { 0x0004a7, "kana_a" },
1115   { 0x0004a8, "kana_i" },
1116   { 0x0004a9, "kana_u" },
1117   { 0x0004aa, "kana_e" },
1118   { 0x0004ab, "kana_o" },
1119   { 0x0004ac, "kana_ya" },
1120   { 0x0004ad, "kana_yu" },
1121   { 0x0004ae, "kana_yo" },
1122   { 0x0004af, "kana_tsu" },
1123   { 0x0004af, "kana_tu" },
1124   { 0x0004b0, "prolongedsound" },
1125   { 0x0004b1, "kana_A" },
1126   { 0x0004b2, "kana_I" },
1127   { 0x0004b3, "kana_U" },
1128   { 0x0004b4, "kana_E" },
1129   { 0x0004b5, "kana_O" },
1130   { 0x0004b6, "kana_KA" },
1131   { 0x0004b7, "kana_KI" },
1132   { 0x0004b8, "kana_KU" },
1133   { 0x0004b9, "kana_KE" },
1134   { 0x0004ba, "kana_KO" },
1135   { 0x0004bb, "kana_SA" },
1136   { 0x0004bc, "kana_SHI" },
1137   { 0x0004bd, "kana_SU" },
1138   { 0x0004be, "kana_SE" },
1139   { 0x0004bf, "kana_SO" },
1140   { 0x0004c0, "kana_TA" },
1141   { 0x0004c1, "kana_CHI" },
1142   { 0x0004c1, "kana_TI" },
1143   { 0x0004c2, "kana_TSU" },
1144   { 0x0004c2, "kana_TU" },
1145   { 0x0004c3, "kana_TE" },
1146   { 0x0004c4, "kana_TO" },
1147   { 0x0004c5, "kana_NA" },
1148   { 0x0004c6, "kana_NI" },
1149   { 0x0004c7, "kana_NU" },
1150   { 0x0004c8, "kana_NE" },
1151   { 0x0004c9, "kana_NO" },
1152   { 0x0004ca, "kana_HA" },
1153   { 0x0004cb, "kana_HI" },
1154   { 0x0004cc, "kana_FU" },
1155   { 0x0004cc, "kana_HU" },
1156   { 0x0004cd, "kana_HE" },
1157   { 0x0004ce, "kana_HO" },
1158   { 0x0004cf, "kana_MA" },
1159   { 0x0004d0, "kana_MI" },
1160   { 0x0004d1, "kana_MU" },
1161   { 0x0004d2, "kana_ME" },
1162   { 0x0004d3, "kana_MO" },
1163   { 0x0004d4, "kana_YA" },
1164   { 0x0004d5, "kana_YU" },
1165   { 0x0004d6, "kana_YO" },
1166   { 0x0004d7, "kana_RA" },
1167   { 0x0004d8, "kana_RI" },
1168   { 0x0004d9, "kana_RU" },
1169   { 0x0004da, "kana_RE" },
1170   { 0x0004db, "kana_RO" },
1171   { 0x0004dc, "kana_WA" },
1172   { 0x0004dd, "kana_N" },
1173   { 0x0004de, "voicedsound" },
1174   { 0x0004df, "semivoicedsound" },
1175   { 0x0005ac, "Arabic_comma" },
1176   { 0x0005bb, "Arabic_semicolon" },
1177   { 0x0005bf, "Arabic_question_mark" },
1178   { 0x0005c1, "Arabic_hamza" },
1179   { 0x0005c2, "Arabic_maddaonalef" },
1180   { 0x0005c3, "Arabic_hamzaonalef" },
1181   { 0x0005c4, "Arabic_hamzaonwaw" },
1182   { 0x0005c5, "Arabic_hamzaunderalef" },
1183   { 0x0005c6, "Arabic_hamzaonyeh" },
1184   { 0x0005c7, "Arabic_alef" },
1185   { 0x0005c8, "Arabic_beh" },
1186   { 0x0005c9, "Arabic_tehmarbuta" },
1187   { 0x0005ca, "Arabic_teh" },
1188   { 0x0005cb, "Arabic_theh" },
1189   { 0x0005cc, "Arabic_jeem" },
1190   { 0x0005cd, "Arabic_hah" },
1191   { 0x0005ce, "Arabic_khah" },
1192   { 0x0005cf, "Arabic_dal" },
1193   { 0x0005d0, "Arabic_thal" },
1194   { 0x0005d1, "Arabic_ra" },
1195   { 0x0005d2, "Arabic_zain" },
1196   { 0x0005d3, "Arabic_seen" },
1197   { 0x0005d4, "Arabic_sheen" },
1198   { 0x0005d5, "Arabic_sad" },
1199   { 0x0005d6, "Arabic_dad" },
1200   { 0x0005d7, "Arabic_tah" },
1201   { 0x0005d8, "Arabic_zah" },
1202   { 0x0005d9, "Arabic_ain" },
1203   { 0x0005da, "Arabic_ghain" },
1204   { 0x0005e0, "Arabic_tatweel" },
1205   { 0x0005e1, "Arabic_feh" },
1206   { 0x0005e2, "Arabic_qaf" },
1207   { 0x0005e3, "Arabic_kaf" },
1208   { 0x0005e4, "Arabic_lam" },
1209   { 0x0005e5, "Arabic_meem" },
1210   { 0x0005e6, "Arabic_noon" },
1211   { 0x0005e7, "Arabic_ha" },
1212   { 0x0005e7, "Arabic_heh" },
1213   { 0x0005e8, "Arabic_waw" },
1214   { 0x0005e9, "Arabic_alefmaksura" },
1215   { 0x0005ea, "Arabic_yeh" },
1216   { 0x0005eb, "Arabic_fathatan" },
1217   { 0x0005ec, "Arabic_dammatan" },
1218   { 0x0005ed, "Arabic_kasratan" },
1219   { 0x0005ee, "Arabic_fatha" },
1220   { 0x0005ef, "Arabic_damma" },
1221   { 0x0005f0, "Arabic_kasra" },
1222   { 0x0005f1, "Arabic_shadda" },
1223   { 0x0005f2, "Arabic_sukun" },
1224   { 0x0006a1, "Serbian_dje" },
1225   { 0x0006a2, "Macedonia_gje" },
1226   { 0x0006a3, "Cyrillic_io" },
1227   { 0x0006a4, "Ukrainian_ie" },
1228   { 0x0006a4, "Ukranian_je" },
1229   { 0x0006a5, "Macedonia_dse" },
1230   { 0x0006a6, "Ukrainian_i" },
1231   { 0x0006a6, "Ukranian_i" },
1232   { 0x0006a7, "Ukrainian_yi" },
1233   { 0x0006a7, "Ukranian_yi" },
1234   { 0x0006a8, "Cyrillic_je" },
1235   { 0x0006a8, "Serbian_je" },
1236   { 0x0006a9, "Cyrillic_lje" },
1237   { 0x0006a9, "Serbian_lje" },
1238   { 0x0006aa, "Cyrillic_nje" },
1239   { 0x0006aa, "Serbian_nje" },
1240   { 0x0006ab, "Serbian_tshe" },
1241   { 0x0006ac, "Macedonia_kje" },
1242   { 0x0006ae, "Byelorussian_shortu" },
1243   { 0x0006af, "Cyrillic_dzhe" },
1244   { 0x0006af, "Serbian_dze" },
1245   { 0x0006b0, "numerosign" },
1246   { 0x0006b1, "Serbian_DJE" },
1247   { 0x0006b2, "Macedonia_GJE" },
1248   { 0x0006b3, "Cyrillic_IO" },
1249   { 0x0006b4, "Ukrainian_IE" },
1250   { 0x0006b4, "Ukranian_JE" },
1251   { 0x0006b5, "Macedonia_DSE" },
1252   { 0x0006b6, "Ukrainian_I" },
1253   { 0x0006b6, "Ukranian_I" },
1254   { 0x0006b7, "Ukrainian_YI" },
1255   { 0x0006b7, "Ukranian_YI" },
1256   { 0x0006b8, "Cyrillic_JE" },
1257   { 0x0006b8, "Serbian_JE" },
1258   { 0x0006b9, "Cyrillic_LJE" },
1259   { 0x0006b9, "Serbian_LJE" },
1260   { 0x0006ba, "Cyrillic_NJE" },
1261   { 0x0006ba, "Serbian_NJE" },
1262   { 0x0006bb, "Serbian_TSHE" },
1263   { 0x0006bc, "Macedonia_KJE" },
1264   { 0x0006be, "Byelorussian_SHORTU" },
1265   { 0x0006bf, "Cyrillic_DZHE" },
1266   { 0x0006bf, "Serbian_DZE" },
1267   { 0x0006c0, "Cyrillic_yu" },
1268   { 0x0006c1, "Cyrillic_a" },
1269   { 0x0006c2, "Cyrillic_be" },
1270   { 0x0006c3, "Cyrillic_tse" },
1271   { 0x0006c4, "Cyrillic_de" },
1272   { 0x0006c5, "Cyrillic_ie" },
1273   { 0x0006c6, "Cyrillic_ef" },
1274   { 0x0006c7, "Cyrillic_ghe" },
1275   { 0x0006c8, "Cyrillic_ha" },
1276   { 0x0006c9, "Cyrillic_i" },
1277   { 0x0006ca, "Cyrillic_shorti" },
1278   { 0x0006cb, "Cyrillic_ka" },
1279   { 0x0006cc, "Cyrillic_el" },
1280   { 0x0006cd, "Cyrillic_em" },
1281   { 0x0006ce, "Cyrillic_en" },
1282   { 0x0006cf, "Cyrillic_o" },
1283   { 0x0006d0, "Cyrillic_pe" },
1284   { 0x0006d1, "Cyrillic_ya" },
1285   { 0x0006d2, "Cyrillic_er" },
1286   { 0x0006d3, "Cyrillic_es" },
1287   { 0x0006d4, "Cyrillic_te" },
1288   { 0x0006d5, "Cyrillic_u" },
1289   { 0x0006d6, "Cyrillic_zhe" },
1290   { 0x0006d7, "Cyrillic_ve" },
1291   { 0x0006d8, "Cyrillic_softsign" },
1292   { 0x0006d9, "Cyrillic_yeru" },
1293   { 0x0006da, "Cyrillic_ze" },
1294   { 0x0006db, "Cyrillic_sha" },
1295   { 0x0006dc, "Cyrillic_e" },
1296   { 0x0006dd, "Cyrillic_shcha" },
1297   { 0x0006de, "Cyrillic_che" },
1298   { 0x0006df, "Cyrillic_hardsign" },
1299   { 0x0006e0, "Cyrillic_YU" },
1300   { 0x0006e1, "Cyrillic_A" },
1301   { 0x0006e2, "Cyrillic_BE" },
1302   { 0x0006e3, "Cyrillic_TSE" },
1303   { 0x0006e4, "Cyrillic_DE" },
1304   { 0x0006e5, "Cyrillic_IE" },
1305   { 0x0006e6, "Cyrillic_EF" },
1306   { 0x0006e7, "Cyrillic_GHE" },
1307   { 0x0006e8, "Cyrillic_HA" },
1308   { 0x0006e9, "Cyrillic_I" },
1309   { 0x0006ea, "Cyrillic_SHORTI" },
1310   { 0x0006eb, "Cyrillic_KA" },
1311   { 0x0006ec, "Cyrillic_EL" },
1312   { 0x0006ed, "Cyrillic_EM" },
1313   { 0x0006ee, "Cyrillic_EN" },
1314   { 0x0006ef, "Cyrillic_O" },
1315   { 0x0006f0, "Cyrillic_PE" },
1316   { 0x0006f1, "Cyrillic_YA" },
1317   { 0x0006f2, "Cyrillic_ER" },
1318   { 0x0006f3, "Cyrillic_ES" },
1319   { 0x0006f4, "Cyrillic_TE" },
1320   { 0x0006f5, "Cyrillic_U" },
1321   { 0x0006f6, "Cyrillic_ZHE" },
1322   { 0x0006f7, "Cyrillic_VE" },
1323   { 0x0006f8, "Cyrillic_SOFTSIGN" },
1324   { 0x0006f9, "Cyrillic_YERU" },
1325   { 0x0006fa, "Cyrillic_ZE" },
1326   { 0x0006fb, "Cyrillic_SHA" },
1327   { 0x0006fc, "Cyrillic_E" },
1328   { 0x0006fd, "Cyrillic_SHCHA" },
1329   { 0x0006fe, "Cyrillic_CHE" },
1330   { 0x0006ff, "Cyrillic_HARDSIGN" },
1331   { 0x0007a1, "Greek_ALPHAaccent" },
1332   { 0x0007a2, "Greek_EPSILONaccent" },
1333   { 0x0007a3, "Greek_ETAaccent" },
1334   { 0x0007a4, "Greek_IOTAaccent" },
1335   { 0x0007a5, "Greek_IOTAdiaeresis" },
1336   { 0x0007a7, "Greek_OMICRONaccent" },
1337   { 0x0007a8, "Greek_UPSILONaccent" },
1338   { 0x0007a9, "Greek_UPSILONdieresis" },
1339   { 0x0007ab, "Greek_OMEGAaccent" },
1340   { 0x0007ae, "Greek_accentdieresis" },
1341   { 0x0007af, "Greek_horizbar" },
1342   { 0x0007b1, "Greek_alphaaccent" },
1343   { 0x0007b2, "Greek_epsilonaccent" },
1344   { 0x0007b3, "Greek_etaaccent" },
1345   { 0x0007b4, "Greek_iotaaccent" },
1346   { 0x0007b5, "Greek_iotadieresis" },
1347   { 0x0007b6, "Greek_iotaaccentdieresis" },
1348   { 0x0007b7, "Greek_omicronaccent" },
1349   { 0x0007b8, "Greek_upsilonaccent" },
1350   { 0x0007b9, "Greek_upsilondieresis" },
1351   { 0x0007ba, "Greek_upsilonaccentdieresis" },
1352   { 0x0007bb, "Greek_omegaaccent" },
1353   { 0x0007c1, "Greek_ALPHA" },
1354   { 0x0007c2, "Greek_BETA" },
1355   { 0x0007c3, "Greek_GAMMA" },
1356   { 0x0007c4, "Greek_DELTA" },
1357   { 0x0007c5, "Greek_EPSILON" },
1358   { 0x0007c6, "Greek_ZETA" },
1359   { 0x0007c7, "Greek_ETA" },
1360   { 0x0007c8, "Greek_THETA" },
1361   { 0x0007c9, "Greek_IOTA" },
1362   { 0x0007ca, "Greek_KAPPA" },
1363   { 0x0007cb, "Greek_LAMBDA" },
1364   { 0x0007cb, "Greek_LAMDA" },
1365   { 0x0007cc, "Greek_MU" },
1366   { 0x0007cd, "Greek_NU" },
1367   { 0x0007ce, "Greek_XI" },
1368   { 0x0007cf, "Greek_OMICRON" },
1369   { 0x0007d0, "Greek_PI" },
1370   { 0x0007d1, "Greek_RHO" },
1371   { 0x0007d2, "Greek_SIGMA" },
1372   { 0x0007d4, "Greek_TAU" },
1373   { 0x0007d5, "Greek_UPSILON" },
1374   { 0x0007d6, "Greek_PHI" },
1375   { 0x0007d7, "Greek_CHI" },
1376   { 0x0007d8, "Greek_PSI" },
1377   { 0x0007d9, "Greek_OMEGA" },
1378   { 0x0007e1, "Greek_alpha" },
1379   { 0x0007e2, "Greek_beta" },
1380   { 0x0007e3, "Greek_gamma" },
1381   { 0x0007e4, "Greek_delta" },
1382   { 0x0007e5, "Greek_epsilon" },
1383   { 0x0007e6, "Greek_zeta" },
1384   { 0x0007e7, "Greek_eta" },
1385   { 0x0007e8, "Greek_theta" },
1386   { 0x0007e9, "Greek_iota" },
1387   { 0x0007ea, "Greek_kappa" },
1388   { 0x0007eb, "Greek_lambda" },
1389   { 0x0007eb, "Greek_lamda" },
1390   { 0x0007ec, "Greek_mu" },
1391   { 0x0007ed, "Greek_nu" },
1392   { 0x0007ee, "Greek_xi" },
1393   { 0x0007ef, "Greek_omicron" },
1394   { 0x0007f0, "Greek_pi" },
1395   { 0x0007f1, "Greek_rho" },
1396   { 0x0007f2, "Greek_sigma" },
1397   { 0x0007f3, "Greek_finalsmallsigma" },
1398   { 0x0007f4, "Greek_tau" },
1399   { 0x0007f5, "Greek_upsilon" },
1400   { 0x0007f6, "Greek_phi" },
1401   { 0x0007f7, "Greek_chi" },
1402   { 0x0007f8, "Greek_psi" },
1403   { 0x0007f9, "Greek_omega" },
1404   { 0x0008a1, "leftradical" },
1405   { 0x0008a2, "topleftradical" },
1406   { 0x0008a3, "horizconnector" },
1407   { 0x0008a4, "topintegral" },
1408   { 0x0008a5, "botintegral" },
1409   { 0x0008a6, "vertconnector" },
1410   { 0x0008a7, "topleftsqbracket" },
1411   { 0x0008a8, "botleftsqbracket" },
1412   { 0x0008a9, "toprightsqbracket" },
1413   { 0x0008aa, "botrightsqbracket" },
1414   { 0x0008ab, "topleftparens" },
1415   { 0x0008ac, "botleftparens" },
1416   { 0x0008ad, "toprightparens" },
1417   { 0x0008ae, "botrightparens" },
1418   { 0x0008af, "leftmiddlecurlybrace" },
1419   { 0x0008b0, "rightmiddlecurlybrace" },
1420   { 0x0008b1, "topleftsummation" },
1421   { 0x0008b2, "botleftsummation" },
1422   { 0x0008b3, "topvertsummationconnector" },
1423   { 0x0008b4, "botvertsummationconnector" },
1424   { 0x0008b5, "toprightsummation" },
1425   { 0x0008b6, "botrightsummation" },
1426   { 0x0008b7, "rightmiddlesummation" },
1427   { 0x0008bc, "lessthanequal" },
1428   { 0x0008bd, "notequal" },
1429   { 0x0008be, "greaterthanequal" },
1430   { 0x0008bf, "integral" },
1431   { 0x0008c0, "therefore" },
1432   { 0x0008c1, "variation" },
1433   { 0x0008c2, "infinity" },
1434   { 0x0008c5, "nabla" },
1435   { 0x0008c8, "approximate" },
1436   { 0x0008c9, "similarequal" },
1437   { 0x0008cd, "ifonlyif" },
1438   { 0x0008ce, "implies" },
1439   { 0x0008cf, "identical" },
1440   { 0x0008d6, "radical" },
1441   { 0x0008da, "includedin" },
1442   { 0x0008db, "includes" },
1443   { 0x0008dc, "intersection" },
1444   { 0x0008dd, "union" },
1445   { 0x0008de, "logicaland" },
1446   { 0x0008df, "logicalor" },
1447   { 0x0008ef, "partialderivative" },
1448   { 0x0008f6, "function" },
1449   { 0x0008fb, "leftarrow" },
1450   { 0x0008fc, "uparrow" },
1451   { 0x0008fd, "rightarrow" },
1452   { 0x0008fe, "downarrow" },
1453   { 0x0009df, "blank" },
1454   { 0x0009e0, "soliddiamond" },
1455   { 0x0009e1, "checkerboard" },
1456   { 0x0009e2, "ht" },
1457   { 0x0009e3, "ff" },
1458   { 0x0009e4, "cr" },
1459   { 0x0009e5, "lf" },
1460   { 0x0009e8, "nl" },
1461   { 0x0009e9, "vt" },
1462   { 0x0009ea, "lowrightcorner" },
1463   { 0x0009eb, "uprightcorner" },
1464   { 0x0009ec, "upleftcorner" },
1465   { 0x0009ed, "lowleftcorner" },
1466   { 0x0009ee, "crossinglines" },
1467   { 0x0009ef, "horizlinescan1" },
1468   { 0x0009f0, "horizlinescan3" },
1469   { 0x0009f1, "horizlinescan5" },
1470   { 0x0009f2, "horizlinescan7" },
1471   { 0x0009f3, "horizlinescan9" },
1472   { 0x0009f4, "leftt" },
1473   { 0x0009f5, "rightt" },
1474   { 0x0009f6, "bott" },
1475   { 0x0009f7, "topt" },
1476   { 0x0009f8, "vertbar" },
1477   { 0x000aa1, "emspace" },
1478   { 0x000aa2, "enspace" },
1479   { 0x000aa3, "em3space" },
1480   { 0x000aa4, "em4space" },
1481   { 0x000aa5, "digitspace" },
1482   { 0x000aa6, "punctspace" },
1483   { 0x000aa7, "thinspace" },
1484   { 0x000aa8, "hairspace" },
1485   { 0x000aa9, "emdash" },
1486   { 0x000aaa, "endash" },
1487   { 0x000aac, "signifblank" },
1488   { 0x000aae, "ellipsis" },
1489   { 0x000aaf, "doubbaselinedot" },
1490   { 0x000ab0, "onethird" },
1491   { 0x000ab1, "twothirds" },
1492   { 0x000ab2, "onefifth" },
1493   { 0x000ab3, "twofifths" },
1494   { 0x000ab4, "threefifths" },
1495   { 0x000ab5, "fourfifths" },
1496   { 0x000ab6, "onesixth" },
1497   { 0x000ab7, "fivesixths" },
1498   { 0x000ab8, "careof" },
1499   { 0x000abb, "figdash" },
1500   { 0x000abc, "leftanglebracket" },
1501   { 0x000abd, "decimalpoint" },
1502   { 0x000abe, "rightanglebracket" },
1503   { 0x000abf, "marker" },
1504   { 0x000ac3, "oneeighth" },
1505   { 0x000ac4, "threeeighths" },
1506   { 0x000ac5, "fiveeighths" },
1507   { 0x000ac6, "seveneighths" },
1508   { 0x000ac9, "trademark" },
1509   { 0x000aca, "signaturemark" },
1510   { 0x000acb, "trademarkincircle" },
1511   { 0x000acc, "leftopentriangle" },
1512   { 0x000acd, "rightopentriangle" },
1513   { 0x000ace, "emopencircle" },
1514   { 0x000acf, "emopenrectangle" },
1515   { 0x000ad0, "leftsinglequotemark" },
1516   { 0x000ad1, "rightsinglequotemark" },
1517   { 0x000ad2, "leftdoublequotemark" },
1518   { 0x000ad3, "rightdoublequotemark" },
1519   { 0x000ad4, "prescription" },
1520   { 0x000ad6, "minutes" },
1521   { 0x000ad7, "seconds" },
1522   { 0x000ad9, "latincross" },
1523   { 0x000ada, "hexagram" },
1524   { 0x000adb, "filledrectbullet" },
1525   { 0x000adc, "filledlefttribullet" },
1526   { 0x000add, "filledrighttribullet" },
1527   { 0x000ade, "emfilledcircle" },
1528   { 0x000adf, "emfilledrect" },
1529   { 0x000ae0, "enopencircbullet" },
1530   { 0x000ae1, "enopensquarebullet" },
1531   { 0x000ae2, "openrectbullet" },
1532   { 0x000ae3, "opentribulletup" },
1533   { 0x000ae4, "opentribulletdown" },
1534   { 0x000ae5, "openstar" },
1535   { 0x000ae6, "enfilledcircbullet" },
1536   { 0x000ae7, "enfilledsqbullet" },
1537   { 0x000ae8, "filledtribulletup" },
1538   { 0x000ae9, "filledtribulletdown" },
1539   { 0x000aea, "leftpointer" },
1540   { 0x000aeb, "rightpointer" },
1541   { 0x000aec, "club" },
1542   { 0x000aed, "diamond" },
1543   { 0x000aee, "heart" },
1544   { 0x000af0, "maltesecross" },
1545   { 0x000af1, "dagger" },
1546   { 0x000af2, "doubledagger" },
1547   { 0x000af3, "checkmark" },
1548   { 0x000af4, "ballotcross" },
1549   { 0x000af5, "musicalsharp" },
1550   { 0x000af6, "musicalflat" },
1551   { 0x000af7, "malesymbol" },
1552   { 0x000af8, "femalesymbol" },
1553   { 0x000af9, "telephone" },
1554   { 0x000afa, "telephonerecorder" },
1555   { 0x000afb, "phonographcopyright" },
1556   { 0x000afc, "caret" },
1557   { 0x000afd, "singlelowquotemark" },
1558   { 0x000afe, "doublelowquotemark" },
1559   { 0x000aff, "cursor" },
1560   { 0x000ba3, "leftcaret" },
1561   { 0x000ba6, "rightcaret" },
1562   { 0x000ba8, "downcaret" },
1563   { 0x000ba9, "upcaret" },
1564   { 0x000bc0, "overbar" },
1565   { 0x000bc2, "downtack" },
1566   { 0x000bc3, "upshoe" },
1567   { 0x000bc4, "downstile" },
1568   { 0x000bc6, "underbar" },
1569   { 0x000bca, "jot" },
1570   { 0x000bcc, "quad" },
1571   { 0x000bce, "uptack" },
1572   { 0x000bcf, "circle" },
1573   { 0x000bd3, "upstile" },
1574   { 0x000bd6, "downshoe" },
1575   { 0x000bd8, "rightshoe" },
1576   { 0x000bda, "leftshoe" },
1577   { 0x000bdc, "lefttack" },
1578   { 0x000bfc, "righttack" },
1579   { 0x000cdf, "hebrew_doublelowline" },
1580   { 0x000ce0, "hebrew_aleph" },
1581   { 0x000ce1, "hebrew_bet" },
1582   { 0x000ce1, "hebrew_beth" },
1583   { 0x000ce2, "hebrew_gimel" },
1584   { 0x000ce2, "hebrew_gimmel" },
1585   { 0x000ce3, "hebrew_dalet" },
1586   { 0x000ce3, "hebrew_daleth" },
1587   { 0x000ce4, "hebrew_he" },
1588   { 0x000ce5, "hebrew_waw" },
1589   { 0x000ce6, "hebrew_zain" },
1590   { 0x000ce6, "hebrew_zayin" },
1591   { 0x000ce7, "hebrew_chet" },
1592   { 0x000ce7, "hebrew_het" },
1593   { 0x000ce8, "hebrew_tet" },
1594   { 0x000ce8, "hebrew_teth" },
1595   { 0x000ce9, "hebrew_yod" },
1596   { 0x000cea, "hebrew_finalkaph" },
1597   { 0x000ceb, "hebrew_kaph" },
1598   { 0x000cec, "hebrew_lamed" },
1599   { 0x000ced, "hebrew_finalmem" },
1600   { 0x000cee, "hebrew_mem" },
1601   { 0x000cef, "hebrew_finalnun" },
1602   { 0x000cf0, "hebrew_nun" },
1603   { 0x000cf1, "hebrew_samech" },
1604   { 0x000cf1, "hebrew_samekh" },
1605   { 0x000cf2, "hebrew_ayin" },
1606   { 0x000cf3, "hebrew_finalpe" },
1607   { 0x000cf4, "hebrew_pe" },
1608   { 0x000cf5, "hebrew_finalzade" },
1609   { 0x000cf5, "hebrew_finalzadi" },
1610   { 0x000cf6, "hebrew_zade" },
1611   { 0x000cf6, "hebrew_zadi" },
1612   { 0x000cf7, "hebrew_kuf" },
1613   { 0x000cf7, "hebrew_qoph" },
1614   { 0x000cf8, "hebrew_resh" },
1615   { 0x000cf9, "hebrew_shin" },
1616   { 0x000cfa, "hebrew_taf" },
1617   { 0x000cfa, "hebrew_taw" },
1618   { 0x000da1, "Thai_kokai" },
1619   { 0x000da2, "Thai_khokhai" },
1620   { 0x000da3, "Thai_khokhuat" },
1621   { 0x000da4, "Thai_khokhwai" },
1622   { 0x000da5, "Thai_khokhon" },
1623   { 0x000da6, "Thai_khorakhang" },
1624   { 0x000da7, "Thai_ngongu" },
1625   { 0x000da8, "Thai_chochan" },
1626   { 0x000da9, "Thai_choching" },
1627   { 0x000daa, "Thai_chochang" },
1628   { 0x000dab, "Thai_soso" },
1629   { 0x000dac, "Thai_chochoe" },
1630   { 0x000dad, "Thai_yoying" },
1631   { 0x000dae, "Thai_dochada" },
1632   { 0x000daf, "Thai_topatak" },
1633   { 0x000db0, "Thai_thothan" },
1634   { 0x000db1, "Thai_thonangmontho" },
1635   { 0x000db2, "Thai_thophuthao" },
1636   { 0x000db3, "Thai_nonen" },
1637   { 0x000db4, "Thai_dodek" },
1638   { 0x000db5, "Thai_totao" },
1639   { 0x000db6, "Thai_thothung" },
1640   { 0x000db7, "Thai_thothahan" },
1641   { 0x000db8, "Thai_thothong" },
1642   { 0x000db9, "Thai_nonu" },
1643   { 0x000dba, "Thai_bobaimai" },
1644   { 0x000dbb, "Thai_popla" },
1645   { 0x000dbc, "Thai_phophung" },
1646   { 0x000dbd, "Thai_fofa" },
1647   { 0x000dbe, "Thai_phophan" },
1648   { 0x000dbf, "Thai_fofan" },
1649   { 0x000dc0, "Thai_phosamphao" },
1650   { 0x000dc1, "Thai_moma" },
1651   { 0x000dc2, "Thai_yoyak" },
1652   { 0x000dc3, "Thai_rorua" },
1653   { 0x000dc4, "Thai_ru" },
1654   { 0x000dc5, "Thai_loling" },
1655   { 0x000dc6, "Thai_lu" },
1656   { 0x000dc7, "Thai_wowaen" },
1657   { 0x000dc8, "Thai_sosala" },
1658   { 0x000dc9, "Thai_sorusi" },
1659   { 0x000dca, "Thai_sosua" },
1660   { 0x000dcb, "Thai_hohip" },
1661   { 0x000dcc, "Thai_lochula" },
1662   { 0x000dcd, "Thai_oang" },
1663   { 0x000dce, "Thai_honokhuk" },
1664   { 0x000dcf, "Thai_paiyannoi" },
1665   { 0x000dd0, "Thai_saraa" },
1666   { 0x000dd1, "Thai_maihanakat" },
1667   { 0x000dd2, "Thai_saraaa" },
1668   { 0x000dd3, "Thai_saraam" },
1669   { 0x000dd4, "Thai_sarai" },
1670   { 0x000dd5, "Thai_saraii" },
1671   { 0x000dd6, "Thai_saraue" },
1672   { 0x000dd7, "Thai_sarauee" },
1673   { 0x000dd8, "Thai_sarau" },
1674   { 0x000dd9, "Thai_sarauu" },
1675   { 0x000dda, "Thai_phinthu" },
1676   { 0x000dde, "Thai_maihanakat_maitho" },
1677   { 0x000ddf, "Thai_baht" },
1678   { 0x000de0, "Thai_sarae" },
1679   { 0x000de1, "Thai_saraae" },
1680   { 0x000de2, "Thai_sarao" },
1681   { 0x000de3, "Thai_saraaimaimuan" },
1682   { 0x000de4, "Thai_saraaimaimalai" },
1683   { 0x000de5, "Thai_lakkhangyao" },
1684   { 0x000de6, "Thai_maiyamok" },
1685   { 0x000de7, "Thai_maitaikhu" },
1686   { 0x000de8, "Thai_maiek" },
1687   { 0x000de9, "Thai_maitho" },
1688   { 0x000dea, "Thai_maitri" },
1689   { 0x000deb, "Thai_maichattawa" },
1690   { 0x000dec, "Thai_thanthakhat" },
1691   { 0x000ded, "Thai_nikhahit" },
1692   { 0x000df0, "Thai_leksun" },
1693   { 0x000df1, "Thai_leknung" },
1694   { 0x000df2, "Thai_leksong" },
1695   { 0x000df3, "Thai_leksam" },
1696   { 0x000df4, "Thai_leksi" },
1697   { 0x000df5, "Thai_lekha" },
1698   { 0x000df6, "Thai_lekhok" },
1699   { 0x000df7, "Thai_lekchet" },
1700   { 0x000df8, "Thai_lekpaet" },
1701   { 0x000df9, "Thai_lekkao" },
1702   { 0x000ea1, "Hangul_Kiyeog" },
1703   { 0x000ea2, "Hangul_SsangKiyeog" },
1704   { 0x000ea3, "Hangul_KiyeogSios" },
1705   { 0x000ea4, "Hangul_Nieun" },
1706   { 0x000ea5, "Hangul_NieunJieuj" },
1707   { 0x000ea6, "Hangul_NieunHieuh" },
1708   { 0x000ea7, "Hangul_Dikeud" },
1709   { 0x000ea8, "Hangul_SsangDikeud" },
1710   { 0x000ea9, "Hangul_Rieul" },
1711   { 0x000eaa, "Hangul_RieulKiyeog" },
1712   { 0x000eab, "Hangul_RieulMieum" },
1713   { 0x000eac, "Hangul_RieulPieub" },
1714   { 0x000ead, "Hangul_RieulSios" },
1715   { 0x000eae, "Hangul_RieulTieut" },
1716   { 0x000eaf, "Hangul_RieulPhieuf" },
1717   { 0x000eb0, "Hangul_RieulHieuh" },
1718   { 0x000eb1, "Hangul_Mieum" },
1719   { 0x000eb2, "Hangul_Pieub" },
1720   { 0x000eb3, "Hangul_SsangPieub" },
1721   { 0x000eb4, "Hangul_PieubSios" },
1722   { 0x000eb5, "Hangul_Sios" },
1723   { 0x000eb6, "Hangul_SsangSios" },
1724   { 0x000eb7, "Hangul_Ieung" },
1725   { 0x000eb8, "Hangul_Jieuj" },
1726   { 0x000eb9, "Hangul_SsangJieuj" },
1727   { 0x000eba, "Hangul_Cieuc" },
1728   { 0x000ebb, "Hangul_Khieuq" },
1729   { 0x000ebc, "Hangul_Tieut" },
1730   { 0x000ebd, "Hangul_Phieuf" },
1731   { 0x000ebe, "Hangul_Hieuh" },
1732   { 0x000ebf, "Hangul_A" },
1733   { 0x000ec0, "Hangul_AE" },
1734   { 0x000ec1, "Hangul_YA" },
1735   { 0x000ec2, "Hangul_YAE" },
1736   { 0x000ec3, "Hangul_EO" },
1737   { 0x000ec4, "Hangul_E" },
1738   { 0x000ec5, "Hangul_YEO" },
1739   { 0x000ec6, "Hangul_YE" },
1740   { 0x000ec7, "Hangul_O" },
1741   { 0x000ec8, "Hangul_WA" },
1742   { 0x000ec9, "Hangul_WAE" },
1743   { 0x000eca, "Hangul_OE" },
1744   { 0x000ecb, "Hangul_YO" },
1745   { 0x000ecc, "Hangul_U" },
1746   { 0x000ecd, "Hangul_WEO" },
1747   { 0x000ece, "Hangul_WE" },
1748   { 0x000ecf, "Hangul_WI" },
1749   { 0x000ed0, "Hangul_YU" },
1750   { 0x000ed1, "Hangul_EU" },
1751   { 0x000ed2, "Hangul_YI" },
1752   { 0x000ed3, "Hangul_I" },
1753   { 0x000ed4, "Hangul_J_Kiyeog" },
1754   { 0x000ed5, "Hangul_J_SsangKiyeog" },
1755   { 0x000ed6, "Hangul_J_KiyeogSios" },
1756   { 0x000ed7, "Hangul_J_Nieun" },
1757   { 0x000ed8, "Hangul_J_NieunJieuj" },
1758   { 0x000ed9, "Hangul_J_NieunHieuh" },
1759   { 0x000eda, "Hangul_J_Dikeud" },
1760   { 0x000edb, "Hangul_J_Rieul" },
1761   { 0x000edc, "Hangul_J_RieulKiyeog" },
1762   { 0x000edd, "Hangul_J_RieulMieum" },
1763   { 0x000ede, "Hangul_J_RieulPieub" },
1764   { 0x000edf, "Hangul_J_RieulSios" },
1765   { 0x000ee0, "Hangul_J_RieulTieut" },
1766   { 0x000ee1, "Hangul_J_RieulPhieuf" },
1767   { 0x000ee2, "Hangul_J_RieulHieuh" },
1768   { 0x000ee3, "Hangul_J_Mieum" },
1769   { 0x000ee4, "Hangul_J_Pieub" },
1770   { 0x000ee5, "Hangul_J_PieubSios" },
1771   { 0x000ee6, "Hangul_J_Sios" },
1772   { 0x000ee7, "Hangul_J_SsangSios" },
1773   { 0x000ee8, "Hangul_J_Ieung" },
1774   { 0x000ee9, "Hangul_J_Jieuj" },
1775   { 0x000eea, "Hangul_J_Cieuc" },
1776   { 0x000eeb, "Hangul_J_Khieuq" },
1777   { 0x000eec, "Hangul_J_Tieut" },
1778   { 0x000eed, "Hangul_J_Phieuf" },
1779   { 0x000eee, "Hangul_J_Hieuh" },
1780   { 0x000eef, "Hangul_RieulYeorinHieuh" },
1781   { 0x000ef0, "Hangul_SunkyeongeumMieum" },
1782   { 0x000ef1, "Hangul_SunkyeongeumPieub" },
1783   { 0x000ef2, "Hangul_PanSios" },
1784   { 0x000ef3, "Hangul_KkogjiDalrinIeung" },
1785   { 0x000ef4, "Hangul_SunkyeongeumPhieuf" },
1786   { 0x000ef5, "Hangul_YeorinHieuh" },
1787   { 0x000ef6, "Hangul_AraeA" },
1788   { 0x000ef7, "Hangul_AraeAE" },
1789   { 0x000ef8, "Hangul_J_PanSios" },
1790   { 0x000ef9, "Hangul_J_KkogjiDalrinIeung" },
1791   { 0x000efa, "Hangul_J_YeorinHieuh" },
1792   { 0x000eff, "Korean_Won" },
1793   { 0x00fd01, "3270_Duplicate" },
1794   { 0x00fd02, "3270_FieldMark" },
1795   { 0x00fd03, "3270_Right2" },
1796   { 0x00fd04, "3270_Left2" },
1797   { 0x00fd05, "3270_BackTab" },
1798   { 0x00fd06, "3270_EraseEOF" },
1799   { 0x00fd07, "3270_EraseInput" },
1800   { 0x00fd08, "3270_Reset" },
1801   { 0x00fd09, "3270_Quit" },
1802   { 0x00fd0a, "3270_PA1" },
1803   { 0x00fd0b, "3270_PA2" },
1804   { 0x00fd0c, "3270_PA3" },
1805   { 0x00fd0d, "3270_Test" },
1806   { 0x00fd0e, "3270_Attn" },
1807   { 0x00fd0f, "3270_CursorBlink" },
1808   { 0x00fd10, "3270_AltCursor" },
1809   { 0x00fd11, "3270_KeyClick" },
1810   { 0x00fd12, "3270_Jump" },
1811   { 0x00fd13, "3270_Ident" },
1812   { 0x00fd14, "3270_Rule" },
1813   { 0x00fd15, "3270_Copy" },
1814   { 0x00fd16, "3270_Play" },
1815   { 0x00fd17, "3270_Setup" },
1816   { 0x00fd18, "3270_Record" },
1817   { 0x00fd19, "3270_ChangeScreen" },
1818   { 0x00fd1a, "3270_DeleteWord" },
1819   { 0x00fd1b, "3270_ExSelect" },
1820   { 0x00fd1c, "3270_CursorSelect" },
1821   { 0x00fd1d, "3270_PrintScreen" },
1822   { 0x00fd1e, "3270_Enter" },
1823   { 0x00fe01, "ISO_Lock" },
1824   { 0x00fe02, "ISO_Level2_Latch" },
1825   { 0x00fe03, "ISO_Level3_Shift" },
1826   { 0x00fe04, "ISO_Level3_Latch" },
1827   { 0x00fe05, "ISO_Level3_Lock" },
1828   { 0x00fe06, "ISO_Group_Latch" },
1829   { 0x00fe07, "ISO_Group_Lock" },
1830   { 0x00fe08, "ISO_Next_Group" },
1831   { 0x00fe09, "ISO_Next_Group_Lock" },
1832   { 0x00fe0a, "ISO_Prev_Group" },
1833   { 0x00fe0b, "ISO_Prev_Group_Lock" },
1834   { 0x00fe0c, "ISO_First_Group" },
1835   { 0x00fe0d, "ISO_First_Group_Lock" },
1836   { 0x00fe0e, "ISO_Last_Group" },
1837   { 0x00fe0f, "ISO_Last_Group_Lock" },
1838   { 0x00fe20, "ISO_Left_Tab" },
1839   { 0x00fe21, "ISO_Move_Line_Up" },
1840   { 0x00fe22, "ISO_Move_Line_Down" },
1841   { 0x00fe23, "ISO_Partial_Line_Up" },
1842   { 0x00fe24, "ISO_Partial_Line_Down" },
1843   { 0x00fe25, "ISO_Partial_Space_Left" },
1844   { 0x00fe26, "ISO_Partial_Space_Right" },
1845   { 0x00fe27, "ISO_Set_Margin_Left" },
1846   { 0x00fe28, "ISO_Set_Margin_Right" },
1847   { 0x00fe29, "ISO_Release_Margin_Left" },
1848   { 0x00fe2a, "ISO_Release_Margin_Right" },
1849   { 0x00fe2b, "ISO_Release_Both_Margins" },
1850   { 0x00fe2c, "ISO_Fast_Cursor_Left" },
1851   { 0x00fe2d, "ISO_Fast_Cursor_Right" },
1852   { 0x00fe2e, "ISO_Fast_Cursor_Up" },
1853   { 0x00fe2f, "ISO_Fast_Cursor_Down" },
1854   { 0x00fe30, "ISO_Continuous_Underline" },
1855   { 0x00fe31, "ISO_Discontinuous_Underline" },
1856   { 0x00fe32, "ISO_Emphasize" },
1857   { 0x00fe33, "ISO_Center_Object" },
1858   { 0x00fe34, "ISO_Enter" },
1859   { 0x00fe50, "dead_grave" },
1860   { 0x00fe51, "dead_acute" },
1861   { 0x00fe52, "dead_circumflex" },
1862   { 0x00fe53, "dead_tilde" },
1863   { 0x00fe54, "dead_macron" },
1864   { 0x00fe55, "dead_breve" },
1865   { 0x00fe56, "dead_abovedot" },
1866   { 0x00fe57, "dead_diaeresis" },
1867   { 0x00fe58, "dead_abovering" },
1868   { 0x00fe59, "dead_doubleacute" },
1869   { 0x00fe5a, "dead_caron" },
1870   { 0x00fe5b, "dead_cedilla" },
1871   { 0x00fe5c, "dead_ogonek" },
1872   { 0x00fe5d, "dead_iota" },
1873   { 0x00fe5e, "dead_voiced_sound" },
1874   { 0x00fe5f, "dead_semivoiced_sound" },
1875   { 0x00fe60, "dead_belowdot" },
1876   { 0x00fe70, "AccessX_Enable" },
1877   { 0x00fe71, "AccessX_Feedback_Enable" },
1878   { 0x00fe72, "RepeatKeys_Enable" },
1879   { 0x00fe73, "SlowKeys_Enable" },
1880   { 0x00fe74, "BounceKeys_Enable" },
1881   { 0x00fe75, "StickyKeys_Enable" },
1882   { 0x00fe76, "MouseKeys_Enable" },
1883   { 0x00fe77, "MouseKeys_Accel_Enable" },
1884   { 0x00fe78, "Overlay1_Enable" },
1885   { 0x00fe79, "Overlay2_Enable" },
1886   { 0x00fe7a, "AudibleBell_Enable" },
1887   { 0x00fed0, "First_Virtual_Screen" },
1888   { 0x00fed1, "Prev_Virtual_Screen" },
1889   { 0x00fed2, "Next_Virtual_Screen" },
1890   { 0x00fed4, "Last_Virtual_Screen" },
1891   { 0x00fed5, "Terminate_Server" },
1892   { 0x00fee0, "Pointer_Left" },
1893   { 0x00fee1, "Pointer_Right" },
1894   { 0x00fee2, "Pointer_Up" },
1895   { 0x00fee3, "Pointer_Down" },
1896   { 0x00fee4, "Pointer_UpLeft" },
1897   { 0x00fee5, "Pointer_UpRight" },
1898   { 0x00fee6, "Pointer_DownLeft" },
1899   { 0x00fee7, "Pointer_DownRight" },
1900   { 0x00fee8, "Pointer_Button_Dflt" },
1901   { 0x00fee9, "Pointer_Button1" },
1902   { 0x00feea, "Pointer_Button2" },
1903   { 0x00feeb, "Pointer_Button3" },
1904   { 0x00feec, "Pointer_Button4" },
1905   { 0x00feed, "Pointer_Button5" },
1906   { 0x00feee, "Pointer_DblClick_Dflt" },
1907   { 0x00feef, "Pointer_DblClick1" },
1908   { 0x00fef0, "Pointer_DblClick2" },
1909   { 0x00fef1, "Pointer_DblClick3" },
1910   { 0x00fef2, "Pointer_DblClick4" },
1911   { 0x00fef3, "Pointer_DblClick5" },
1912   { 0x00fef4, "Pointer_Drag_Dflt" },
1913   { 0x00fef5, "Pointer_Drag1" },
1914   { 0x00fef6, "Pointer_Drag2" },
1915   { 0x00fef7, "Pointer_Drag3" },
1916   { 0x00fef8, "Pointer_Drag4" },
1917   { 0x00fef9, "Pointer_EnableKeys" },
1918   { 0x00fefa, "Pointer_Accelerate" },
1919   { 0x00fefb, "Pointer_DfltBtnNext" },
1920   { 0x00fefc, "Pointer_DfltBtnPrev" },
1921   { 0x00fefd, "Pointer_Drag5" },
1922   { 0x00ff08, "BackSpace" },
1923   { 0x00ff09, "Tab" },
1924   { 0x00ff0a, "Linefeed" },
1925   { 0x00ff0b, "Clear" },
1926   { 0x00ff0d, "Return" },
1927   { 0x00ff13, "Pause" },
1928   { 0x00ff14, "Scroll_Lock" },
1929   { 0x00ff15, "Sys_Req" },
1930   { 0x00ff1b, "Escape" },
1931   { 0x00ff20, "Multi_key" },
1932   { 0x00ff21, "Kanji" },
1933   { 0x00ff22, "Muhenkan" },
1934   { 0x00ff23, "Henkan" },
1935   { 0x00ff23, "Henkan_Mode" },
1936   { 0x00ff24, "Romaji" },
1937   { 0x00ff25, "Hiragana" },
1938   { 0x00ff26, "Katakana" },
1939   { 0x00ff27, "Hiragana_Katakana" },
1940   { 0x00ff28, "Zenkaku" },
1941   { 0x00ff29, "Hankaku" },
1942   { 0x00ff2a, "Zenkaku_Hankaku" },
1943   { 0x00ff2b, "Touroku" },
1944   { 0x00ff2c, "Massyo" },
1945   { 0x00ff2d, "Kana_Lock" },
1946   { 0x00ff2e, "Kana_Shift" },
1947   { 0x00ff2f, "Eisu_Shift" },
1948   { 0x00ff30, "Eisu_toggle" },
1949   { 0x00ff3c, "SingleCandidate" },
1950   { 0x00ff3d, "MultipleCandidate" },
1951   { 0x00ff3d, "Zen_Koho" },
1952   { 0x00ff3e, "Mae_Koho" },
1953   { 0x00ff3e, "PreviousCandidate" },
1954   { 0x00ff50, "Home" },
1955   { 0x00ff51, "Left" },
1956   { 0x00ff52, "Up" },
1957   { 0x00ff53, "Right" },
1958   { 0x00ff54, "Down" },
1959   { 0x00ff55, "Page_Up" },
1960   { 0x00ff55, "Prior" },
1961   { 0x00ff56, "Next" },
1962   { 0x00ff56, "Page_Down" },
1963   { 0x00ff57, "End" },
1964   { 0x00ff58, "Begin" },
1965   { 0x00ff60, "Select" },
1966   { 0x00ff61, "Print" },
1967   { 0x00ff62, "Execute" },
1968   { 0x00ff63, "Insert" },
1969   { 0x00ff65, "Undo" },
1970   { 0x00ff66, "Redo" },
1971   { 0x00ff67, "Menu" },
1972   { 0x00ff68, "Find" },
1973   { 0x00ff69, "Cancel" },
1974   { 0x00ff6a, "Help" },
1975   { 0x00ff6b, "Break" },
1976   { 0x00ff7e, "Arabic_switch" },
1977   { 0x00ff7e, "Greek_switch" },
1978   { 0x00ff7e, "Hangul_switch" },
1979   { 0x00ff7e, "Hebrew_switch" },
1980   { 0x00ff7e, "ISO_Group_Shift" },
1981   { 0x00ff7e, "Mode_switch" },
1982   { 0x00ff7e, "kana_switch" },
1983   { 0x00ff7e, "script_switch" },
1984   { 0x00ff7f, "Num_Lock" },
1985   { 0x00ff80, "KP_Space" },
1986   { 0x00ff89, "KP_Tab" },
1987   { 0x00ff8d, "KP_Enter" },
1988   { 0x00ff91, "KP_F1" },
1989   { 0x00ff92, "KP_F2" },
1990   { 0x00ff93, "KP_F3" },
1991   { 0x00ff94, "KP_F4" },
1992   { 0x00ff95, "KP_Home" },
1993   { 0x00ff96, "KP_Left" },
1994   { 0x00ff97, "KP_Up" },
1995   { 0x00ff98, "KP_Right" },
1996   { 0x00ff99, "KP_Down" },
1997   { 0x00ff9a, "KP_Page_Up" },
1998   { 0x00ff9a, "KP_Prior" },
1999   { 0x00ff9b, "KP_Next" },
2000   { 0x00ff9b, "KP_Page_Down" },
2001   { 0x00ff9c, "KP_End" },
2002   { 0x00ff9d, "KP_Begin" },
2003   { 0x00ff9e, "KP_Insert" },
2004   { 0x00ff9f, "KP_Delete" },
2005   { 0x00ffaa, "KP_Multiply" },
2006   { 0x00ffab, "KP_Add" },
2007   { 0x00ffac, "KP_Separator" },
2008   { 0x00ffad, "KP_Subtract" },
2009   { 0x00ffae, "KP_Decimal" },
2010   { 0x00ffaf, "KP_Divide" },
2011   { 0x00ffb0, "KP_0" },
2012   { 0x00ffb1, "KP_1" },
2013   { 0x00ffb2, "KP_2" },
2014   { 0x00ffb3, "KP_3" },
2015   { 0x00ffb4, "KP_4" },
2016   { 0x00ffb5, "KP_5" },
2017   { 0x00ffb6, "KP_6" },
2018   { 0x00ffb7, "KP_7" },
2019   { 0x00ffb8, "KP_8" },
2020   { 0x00ffb9, "KP_9" },
2021   { 0x00ffbd, "KP_Equal" },
2022   { 0x00ffbe, "F1" },
2023   { 0x00ffbf, "F2" },
2024   { 0x00ffc0, "F3" },
2025   { 0x00ffc1, "F4" },
2026   { 0x00ffc2, "F5" },
2027   { 0x00ffc3, "F6" },
2028   { 0x00ffc4, "F7" },
2029   { 0x00ffc5, "F8" },
2030   { 0x00ffc6, "F9" },
2031   { 0x00ffc7, "F10" },
2032   { 0x00ffc8, "F11" },
2033   { 0x00ffc9, "F12" },
2034   { 0x00ffca, "F13" },
2035   { 0x00ffcb, "F14" },
2036   { 0x00ffcc, "F15" },
2037   { 0x00ffcd, "F16" },
2038   { 0x00ffce, "F17" },
2039   { 0x00ffcf, "F18" },
2040   { 0x00ffd0, "F19" },
2041   { 0x00ffd1, "F20" },
2042   { 0x00ffd2, "F21" },
2043   { 0x00ffd3, "F22" },
2044   { 0x00ffd4, "F23" },
2045   { 0x00ffd5, "F24" },
2046   { 0x00ffd6, "F25" },
2047   { 0x00ffd7, "F26" },
2048   { 0x00ffd8, "F27" },
2049   { 0x00ffd9, "F28" },
2050   { 0x00ffda, "F29" },
2051   { 0x00ffdb, "F30" },
2052   { 0x00ffdc, "F31" },
2053   { 0x00ffdd, "F32" },
2054   { 0x00ffde, "F33" },
2055   { 0x00ffdf, "F34" },
2056   { 0x00ffe0, "F35" },
2057   { 0x00ffe1, "Shift_L" },
2058   { 0x00ffe2, "Shift_R" },
2059   { 0x00ffe3, "Control_L" },
2060   { 0x00ffe4, "Control_R" },
2061   { 0x00ffe5, "Caps_Lock" },
2062   { 0x00ffe6, "Shift_Lock" },
2063   { 0x00ffe7, "Meta_L" },
2064   { 0x00ffe8, "Meta_R" },
2065   { 0x00ffe9, "Alt_L" },
2066   { 0x00ffea, "Alt_R" },
2067   { 0x00ffeb, "Super_L" },
2068   { 0x00ffec, "Super_R" },
2069   { 0x00ffed, "Hyper_L" },
2070   { 0x00ffee, "Hyper_R" },
2071   { 0x00ffff, "Delete" },
2072   { 0x00ff31, "Hangul" },
2073   { 0x00ff32, "Hangul_Start" },
2074   { 0x00ff33, "Hangul_End" },
2075   { 0x00ff34, "Hangul_Hanja" },
2076   { 0x00ff35, "Hangul_Jamo" },
2077   { 0x00ff36, "Hangul_Romaja" },
2078   { 0x00ff37, "Hangul_Codeinput" },
2079   { 0x00ff38, "Hangul_Jeonja" },
2080   { 0x00ff39, "Hangul_Banja" },
2081   { 0x00ff3a, "Hangul_PreHanja" },
2082   { 0x00ff3b, "Hangul_PostHanja" },
2083   { 0x00ff3c, "Hangul_SingleCandidate" },
2084   { 0x00ff3d, "Hangul_MultipleCandidate" },
2085   { 0x00ff3e, "Hangul_PreviousCandidate" },
2086   { 0x00ff3f, "Hangul_Special" },
2087   { 0xffffff, "VoidSymbol" },
2088 };
2089
2090 #define GDK_NUM_KEYS (sizeof (gdk_keys_by_keyval) / sizeof (gdk_keys_by_keyval[0]))
2091
2092 static struct gdk_key *gdk_keys_by_name = NULL;
2093
2094 static int
2095 gdk_keys_keyval_compare (const void *pkey, const void *pbase)
2096 {
2097   return (*(int *) pkey) - ((struct gdk_key *) pbase)->keyval;
2098 }
2099
2100 gchar*
2101 gdk_keyval_name (guint        keyval)
2102 {
2103   struct gdk_key *found =
2104     bsearch (&keyval, gdk_keys_by_keyval,
2105              GDK_NUM_KEYS, sizeof (struct gdk_key),
2106              gdk_keys_keyval_compare);
2107   if (found != NULL)
2108     return found->name;
2109   else
2110     return NULL;
2111 }
2112
2113 static int 
2114 gdk_key_compare_by_name (const void *a, const void *b)
2115 {
2116   return strcmp (((const struct gdk_key *) a)->name, ((const struct gdk_key *) b)->name);
2117 }
2118
2119 static int
2120 gdk_keys_name_compare (const void *pkey, const void *pbase)
2121 {
2122   return strcmp ((const char *) pkey, ((const struct gdk_key *) pbase)->name);
2123 }
2124
2125 guint
2126 gdk_keyval_from_name (const gchar *keyval_name)
2127 {
2128   struct gdk_key *found;
2129
2130   g_return_val_if_fail (keyval_name != NULL, 0);
2131   
2132   if (gdk_keys_by_name == NULL)
2133     {
2134       gdk_keys_by_name = g_new (struct gdk_key, GDK_NUM_KEYS);
2135
2136       memcpy (gdk_keys_by_name, gdk_keys_by_keyval,
2137               GDK_NUM_KEYS * sizeof (struct gdk_key));
2138
2139       qsort (gdk_keys_by_name, GDK_NUM_KEYS, sizeof (struct gdk_key),
2140              gdk_key_compare_by_name);
2141     }
2142
2143   found = bsearch (keyval_name, gdk_keys_by_name,
2144                    GDK_NUM_KEYS, sizeof (struct gdk_key),
2145                    gdk_keys_name_compare);
2146   if (found != NULL)
2147     return found->keyval;
2148   else
2149     return GDK_VoidSymbol;
2150 }
2151
2152 guint
2153 gdk_keyval_to_upper (guint        keyval)
2154 {
2155   if (keyval)
2156     {
2157       KeySym lower_val = 0;
2158       KeySym upper_val = 0;
2159       
2160       XConvertCase (keyval, &lower_val, &upper_val);
2161       return upper_val;
2162     }
2163   return 0;
2164 }
2165
2166 guint
2167 gdk_keyval_to_lower (guint        keyval)
2168 {
2169   if (keyval)
2170     {
2171       KeySym lower_val = 0;
2172       KeySym upper_val = 0;
2173       
2174       XConvertCase (keyval, &lower_val, &upper_val);
2175       return lower_val;
2176     }
2177   return 0;
2178 }
2179
2180 gboolean
2181 gdk_keyval_is_upper (guint        keyval)
2182 {
2183   if (keyval)
2184     {
2185       KeySym lower_val = 0;
2186       KeySym upper_val = 0;
2187       
2188       XConvertCase (keyval, &lower_val, &upper_val);
2189       return upper_val == keyval;
2190     }
2191   return TRUE;
2192 }
2193
2194 gboolean
2195 gdk_keyval_is_lower (guint        keyval)
2196 {
2197   if (keyval)
2198     {
2199       KeySym lower_val = 0;
2200       KeySym upper_val = 0;
2201       
2202       XConvertCase (keyval, &lower_val, &upper_val);
2203       return lower_val == keyval;
2204     }
2205   return TRUE;
2206 }
2207
2208
2209 void
2210 gdk_threads_enter ()
2211 {
2212   GDK_THREADS_ENTER ();
2213 }
2214
2215 void
2216 gdk_threads_leave ()
2217 {
2218   GDK_THREADS_LEAVE ();
2219 }