keysym2scancode.c

Go to the documentation of this file.
00001 /* *******************************************************
00002  This file is part of fbvncserver.
00003 
00004  fbvncserver is free software; you can redistribute it
00005  and/or modify it under the terms of the
00006  GNU General Public License as published by
00007  the Free Software Foundation; either version 2 of the
00008  License, or (at your option) any later version.
00009 
00010  fbvncserver is distributed in the hope that it will be
00011  useful, but WITHOUT ANY WARRANTY; without even the
00012  implied warranty of MERCHANTABILITY or FITNESS FOR A
00013  PARTICULAR PURPOSE.  See the GNU General Public License
00014  for more details.
00015 
00016  You should have received a copy of the GNU General Public
00017  License along with fbvncserver; if not, write to the
00018  Free Software Foundation, Inc., 51 Franklin St,
00019  Fifth Floor, Boston, MA  02110-1301  USA
00020  ********************************************************/
00021 
00022 /* Project: */
00023 #include "keysym2scancode.h"
00024 
00025 static int get_keysym(const char *name)
00026 {
00027     name2keysym_t *p;
00028     for(p = name2keysym; p->name != NULL; p++) {
00029         if (!strcmp(p->name, name))
00030             return p->keysym;
00031     }
00032     return 0;
00033 }
00034 
00035 #define MAX_NORMAL_KEYCODE 512
00036 #define MAX_EXTRA_COUNT 256
00037 typedef struct {
00038     uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
00039     struct {
00040         int keysym;
00041         uint16_t keycode;
00042     } keysym2keycode_extra[MAX_EXTRA_COUNT];
00043     int extra_count;
00044 } kbd_layout_t;
00045 
00046 static kbd_layout_t *parse_keyboard_layout(const char *language,
00047                                            kbd_layout_t * k)
00048 {
00049     FILE *f;
00050     char file_name[1024];
00051     char line[1024];
00052     int len;
00053     char *dir = CONFIGBASEDIR;
00054 
00055     snprintf(file_name, sizeof(file_name),
00056              "%s/keymaps/%s", dir, language);
00057 
00058     if (!k)
00059         k = malloc(sizeof(kbd_layout_t));
00060     if (!k)
00061         return 0;
00062     if (!(f = fopen(file_name, "r"))) {
00063         fprintf(stderr,
00064                 "Could not read keymap file: '%s'\n", file_name);
00065         return 0;
00066     }
00067     for(;;) {
00068         if (fgets(line, 1024, f) == NULL)
00069             break;
00070         len = strlen(line);
00071         if (len > 0 && line[len - 1] == '\n')
00072             line[len - 1] = '\0';
00073         if (line[0] == '#')
00074             continue;
00075         if (!strncmp(line, "map ", 4))
00076             continue;
00077         if (!strncmp(line, "include ", 8)) {
00078             parse_keyboard_layout(line + 8, k);
00079         } else {
00080             char *end_of_keysym = line;
00081             while (*end_of_keysym != 0 && *end_of_keysym != ' ')
00082                 end_of_keysym++;
00083             if (*end_of_keysym) {
00084                 int keysym;
00085                 *end_of_keysym = 0;
00086                 keysym = get_keysym(line);
00087                 if (keysym == 0) {
00088                     //              fprintf(stderr, "Warning: unknown keysym %s\n", line);
00089                 } else {
00090                     const char *rest = end_of_keysym + 1;
00091                     int keycode = strtol(rest, NULL, 0);
00092                     /* if(keycode&0x80)
00093                        keycode=(keycode<<8)^0x80e0; */
00094                     if (keysym < MAX_NORMAL_KEYCODE) {
00095                         //fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
00096                         k->keysym2keycode[keysym] = keycode;
00097                     } else {
00098                         if (k->extra_count >= MAX_EXTRA_COUNT) {
00099                             fprintf(stderr,
00100                                     "Warning: Could not assign keysym %s (0x%x) because of memory constraints.\n",
00101                                     line, keysym);
00102                         } else {
00103 #if 0
00104                             fprintf(stderr, "Setting %d: %d,%d\n",
00105                                     k->extra_count, keysym, keycode);
00106 #endif
00107                             k->keysym2keycode_extra[k->extra_count].
00108                                 keysym = keysym;
00109                             k->keysym2keycode_extra[k->extra_count].
00110                                 keycode = keycode;
00111                             k->extra_count++;
00112                         }
00113                     }
00114                 }
00115             }
00116         }
00117     }
00118     fclose(f);
00119     return k;
00120 }
00121 
00122 void* init_keyboard_layout(const char *language)
00123 {
00124     return parse_keyboard_layout(language, 0);
00125 } // end of [init_keyboard_layout]
00126 
00127 int keysym2scancode(void *kbd_layout, int keysym)
00128 {
00129     kbd_layout_t *k = kbd_layout;
00130     if (keysym < MAX_NORMAL_KEYCODE) {
00131         if (k->keysym2keycode[keysym] == 0)
00132             fprintf(stderr, "Warning: no scancode found for keysym %d\n",
00133                     keysym);
00134         return k->keysym2keycode[keysym];
00135     } else {
00136         int i;
00137 #ifdef XK_ISO_Left_Tab
00138         if (keysym == XK_ISO_Left_Tab)
00139             keysym = XK_Tab;
00140 #endif
00141         for (i = 0; i < k->extra_count; i++)
00142             if (k->keysym2keycode_extra[i].keysym == keysym)
00143                 return k->keysym2keycode_extra[i].keycode;
00144     }
00145     return 0;
00146 }