1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_vcl.hxx" 26 27 #ifndef SOLARIS 28 #include <tools/prex.h> 29 #include <X11/XKBlib.h> 30 #include <tools/postx.h> 31 #endif 32 33 #include <unx/saldisp.hxx> 34 #include <X11/keysym.h> 35 36 #if !defined (SunXK_Undo) 37 #define SunXK_Undo 0x0000FF65 // XK_Undo 38 #define SunXK_Again 0x0000FF66 // XK_Redo 39 #define SunXK_Find 0x0000FF68 // XK_Find 40 #define SunXK_Stop 0x0000FF69 // XK_Cancel 41 #define SunXK_Props 0x1005FF70 42 #define SunXK_Front 0x1005FF71 43 #define SunXK_Copy 0x1005FF72 44 #define SunXK_Open 0x1005FF73 45 #define SunXK_Paste 0x1005FF74 46 #define SunXK_Cut 0x1005FF75 47 #endif 48 49 #ifdef SOLARIS 50 #include <sys/types.h> 51 #include <sys/ioctl.h> 52 #include <sys/kbio.h> 53 #include <sys/kbd.h> 54 #include <stdio.h> 55 #include <fcntl.h> 56 #include <deflt.h> 57 #include <unistd.h> 58 #include <stdlib.h> 59 #endif 60 61 #include <string.h> 62 63 namespace vcl_sal { 64 65 struct KeysymNameReplacement 66 { 67 KeySym aSymbol; 68 const char* pName; 69 }; 70 71 struct KeyboardReplacements 72 { 73 const char* pKeyboardName; 74 const KeysymNameReplacement* pReplacements; 75 int nReplacements; 76 }; 77 78 // ==================================================================== 79 // 80 // CAUTION CAUTION CAUTION 81 // every string value in the replacements tables must be in UTF8 82 // be careful with your editor ! 83 // 84 // ==================================================================== 85 86 static const struct KeysymNameReplacement aImplReplacements_English[] = 87 { 88 { XK_Control_L, "Ctrl" }, 89 { XK_Control_R, "Ctrl" }, 90 { XK_Escape, "Esc" }, 91 { XK_space, "Space" }, 92 { XK_minus, "-" }, 93 { XK_plus, "+" } 94 }; 95 96 static const struct KeysymNameReplacement aImplReplacements_Turkish[] = 97 { 98 { XK_Control_L, "Ctrl" }, 99 { XK_Control_R, "Ctrl" }, 100 { XK_Right, "Sağ" }, 101 { XK_Left, "Sol" }, 102 { XK_Up, "Yukarı" }, 103 { XK_Down, "Aşağı" }, 104 { XK_space, "Boşluk" } 105 }; 106 107 static const struct KeysymNameReplacement aImplReplacements_Russian[] = 108 { 109 { XK_Right, "Вправо" }, 110 { XK_Left, "Влево" }, 111 { XK_Up, "Вверх" }, 112 { XK_Down, "Вниз" }, 113 { XK_space, "Пробел" } 114 }; 115 116 static const struct KeysymNameReplacement aImplReplacements_German[] = 117 { 118 { XK_Control_L, "Strg" }, 119 { XK_Control_R, "Strg" }, 120 { XK_Shift_L, "Umschalt" }, 121 { XK_Shift_R, "Umschalt" }, 122 { XK_Alt_L, "Alt" }, 123 { XK_Alt_R, "Alt Gr" }, 124 { XK_Page_Up, "Bild auf" }, 125 { XK_Page_Down, "Bild ab" }, 126 { XK_End, "Ende" }, 127 { XK_Home, "Pos 1" }, 128 { XK_Insert, "Einfg" }, 129 { XK_Delete, "Entf" }, 130 { XK_Escape, "Esc" }, 131 { XK_Right, "Rechts" }, 132 { XK_Left, "Links" }, 133 { XK_Up, "Oben" }, 134 { XK_Down, "Unten" }, 135 { XK_BackSpace, "Rückschritt" }, 136 { XK_Return, "Eingabe" }, 137 { XK_slash, "Schrägstrich" }, 138 { XK_space, "Leertaste" }, 139 { SunXK_Stop, "Stop" }, 140 { SunXK_Again, "Wiederholen" }, 141 { SunXK_Props, "Eigenschaften" }, 142 { SunXK_Undo, "Zurücknehmen" }, 143 { SunXK_Front, "Vordergrund" }, 144 { SunXK_Copy, "Kopieren" }, 145 { SunXK_Open, "Öffnen" }, 146 { SunXK_Paste, "Einsetzen" }, 147 { SunXK_Find, "Suchen" }, 148 { SunXK_Cut, "Ausschneiden" }, 149 { XK_minus, "-" }, 150 { XK_plus, "+" } 151 }; 152 153 static const struct KeysymNameReplacement aImplReplacements_French[] = 154 { 155 { XK_Shift_L, "Maj" }, 156 { XK_Shift_R, "Maj" }, 157 { XK_Page_Up, "Pg. Préc" }, 158 { XK_Page_Down, "Pg. Suiv" }, 159 { XK_End, "Fin" }, 160 { XK_Home, "Origine" }, 161 { XK_Insert, "Insérer" }, 162 { XK_Delete, "Suppr" }, 163 { XK_Escape, "Esc" }, 164 { XK_Right, "Droite" }, 165 { XK_Left, "Gauche" }, 166 { XK_Up, "Haut" }, 167 { XK_Down, "Bas" }, 168 { XK_BackSpace, "Ret. Arr" }, 169 { XK_Return, "Retour" }, 170 { XK_space, "Espace" }, 171 { XK_KP_Enter, "Entrée" }, 172 { SunXK_Stop, "Stop" }, 173 { SunXK_Again, "Encore" }, 174 { SunXK_Props, "Props" }, 175 { SunXK_Undo, "Annuler" }, 176 { SunXK_Front, "Devant" }, 177 { SunXK_Copy, "Copy" }, 178 { SunXK_Open, "Ouvrir" }, 179 { SunXK_Paste, "Coller" }, 180 { SunXK_Find, "Cher." }, 181 { SunXK_Cut, "Couper" }, 182 { XK_minus, "-" }, 183 { XK_plus, "+" } 184 }; 185 186 static const struct KeysymNameReplacement aImplReplacements_Italian[] = 187 { 188 { XK_Shift_L, "Maiusc" }, 189 { XK_Shift_R, "Maiusc" }, 190 { XK_Page_Up, "PgSu" }, 191 { XK_Page_Down, "PgGiu" }, 192 { XK_End, "Fine" }, 193 { XK_Insert, "Ins" }, 194 { XK_Delete, "Canc" }, 195 { XK_Escape, "Esc" }, 196 { XK_Right, "A destra" }, 197 { XK_Left, "A sinistra" }, 198 { XK_Up, "Sposta verso l'alto" }, 199 { XK_Down, "Sposta verso il basso" }, 200 { XK_BackSpace, "Backspace" }, 201 { XK_Return, "Invio" }, 202 { XK_space, "Spazio" }, 203 { SunXK_Stop, "Stop" }, 204 { SunXK_Again, "Ancora" }, 205 { SunXK_Props, "Proprietà" }, 206 { SunXK_Undo, "Annulla" }, 207 { SunXK_Front, "Davanti" }, 208 { SunXK_Copy, "Copia" }, 209 { SunXK_Open, "Apri" }, 210 { SunXK_Paste, "Incolla" }, 211 { SunXK_Find, "Trova" }, 212 { SunXK_Cut, "Taglia" }, 213 { XK_minus, "-" }, 214 { XK_plus, "+" } 215 }; 216 217 static const struct KeysymNameReplacement aImplReplacements_Dutch[] = 218 { 219 { XK_Page_Up, "PageUp" }, 220 { XK_Page_Down, "PageDown" }, 221 { XK_Escape, "Esc" }, 222 { XK_Right, "Rechts" }, 223 { XK_Left, "Links" }, 224 { XK_Up, "Boven" }, 225 { XK_Down, "Onder" }, 226 { XK_BackSpace, "Backspace" }, 227 { XK_Return, "Return" }, 228 { XK_space, "Spatiebalk" }, 229 { SunXK_Stop, "Stop" }, 230 { SunXK_Again, "Again" }, 231 { SunXK_Props, "Props" }, 232 { SunXK_Undo, "Undo" }, 233 { SunXK_Front, "Front" }, 234 { SunXK_Copy, "Copy" }, 235 { SunXK_Open, "Open" }, 236 { SunXK_Paste, "Paste" }, 237 { SunXK_Find, "Find" }, 238 { SunXK_Cut, "Cut" }, 239 { XK_minus, "-" }, 240 { XK_plus, "+" } 241 }; 242 243 static const struct KeysymNameReplacement aImplReplacements_Norwegian[] = 244 { 245 { XK_Shift_L, "Skift" }, 246 { XK_Shift_R, "Skift" }, 247 { XK_Page_Up, "PageUp" }, 248 { XK_Page_Down, "PageDown" }, 249 { XK_Escape, "Esc" }, 250 { XK_Right, "Hyre" }, 251 { XK_Left, "Venstre" }, 252 { XK_Up, "Opp" }, 253 { XK_Down, "Ned" }, 254 { XK_BackSpace, "Tilbake" }, 255 { XK_Return, "Enter" }, 256 { SunXK_Stop, "Avbryt" }, 257 { SunXK_Again, "Gjenta" }, 258 { SunXK_Props, "Egenskaper" }, 259 { SunXK_Undo, "Angre" }, 260 { SunXK_Front, "Front" }, 261 { SunXK_Copy, "Kopi" }, 262 { SunXK_Open, "Åpne" }, 263 { SunXK_Paste, "Lim" }, 264 { SunXK_Find, "Søk" }, 265 { SunXK_Cut, "Klipp" }, 266 { XK_minus, "-" }, 267 { XK_plus, "+" } 268 }; 269 270 static const struct KeysymNameReplacement aImplReplacements_Swedish[] = 271 { 272 { XK_Shift_L, "Skift" }, 273 { XK_Shift_R, "Skift" }, 274 { XK_Page_Up, "PageUp" }, 275 { XK_Page_Down, "PageDown" }, 276 { XK_Escape, "Esc" }, 277 { XK_Right, "Höger" }, 278 { XK_Left, "Vänster" }, 279 { XK_Up, "Up" }, 280 { XK_Down, "Ned" }, 281 { XK_BackSpace, "Backsteg" }, 282 { XK_Return, "Retur" }, 283 { XK_space, "Blank" }, 284 { SunXK_Stop, "Avbryt" }, 285 { SunXK_Again, "Upprepa" }, 286 { SunXK_Props, "Egenskaper" }, 287 { SunXK_Undo, "Ångra" }, 288 { SunXK_Front, "Fram" }, 289 { SunXK_Copy, "Kopiera" }, 290 { SunXK_Open, "Öppna" }, 291 { SunXK_Paste, "Klistra in" }, 292 { SunXK_Find, "Sök" }, 293 { SunXK_Cut, "Klipp ut" }, 294 { XK_minus, "-" }, 295 { XK_plus, "+" } 296 }; 297 298 static const struct KeysymNameReplacement aImplReplacements_Portuguese[] = 299 { 300 { XK_Page_Up, "PageUp" }, 301 { XK_Page_Down, "PageDown" }, 302 { XK_Escape, "Esc" }, 303 { XK_Right, "Direita" }, 304 { XK_Left, "Esquerda" }, 305 { XK_Up, "Acima" }, 306 { XK_Down, "Abaixo" }, 307 { XK_BackSpace, "Backspace" }, 308 { XK_Return, "Enter" }, 309 { XK_slash, "Barra" }, 310 { SunXK_Stop, "Stop" }, 311 { SunXK_Again, "Again" }, 312 { SunXK_Props, "Props" }, 313 { SunXK_Undo, "Undo" }, 314 { SunXK_Front, "Front" }, 315 { SunXK_Copy, "Copy" }, 316 { SunXK_Open, "Open" }, 317 { SunXK_Paste, "Paste" }, 318 { SunXK_Find, "Find" }, 319 { SunXK_Cut, "Cut" }, 320 { XK_minus, "-" }, 321 { XK_plus, "+" } 322 }; 323 324 static const struct KeysymNameReplacement aImplReplacements_Spanish[] = 325 { 326 { XK_Shift_L, "Mayús" }, 327 { XK_Shift_R, "Mayús" }, 328 { XK_Page_Up, "RePág" }, 329 { XK_Page_Down, "AvPág" }, 330 { XK_End, "Fin" }, 331 { XK_Home, "Inicio" }, 332 { XK_Delete, "Supr" }, 333 { XK_Escape, "Esc" }, 334 { XK_Right, "Hacia la derecha" }, 335 { XK_Left, "Hacia la izquierda" }, 336 { XK_Up, "Hacia arriba" }, 337 { XK_Down, "Hacia abajo" }, 338 { XK_BackSpace, "Ret" }, 339 { XK_Return, "Entrada" }, 340 { XK_space, "Espacio" }, 341 { XK_KP_Enter, "Intro" }, 342 { SunXK_Stop, "Stop" }, 343 { SunXK_Again, "Repetir" }, 344 { SunXK_Props, "Props" }, 345 { SunXK_Undo, "Anular" }, 346 { SunXK_Front, "Delante" }, 347 { SunXK_Copy, "Copiar" }, 348 { SunXK_Open, "Abrir" }, 349 { SunXK_Paste, "Pegar" }, 350 { SunXK_Find, "Buscar" }, 351 { SunXK_Cut, "Cortar" }, 352 { XK_minus, "-" }, 353 { XK_plus, "+" } 354 }; 355 356 static const struct KeyboardReplacements aKeyboards[] = 357 { 358 #ifdef SOLARIS 359 { "Germany5", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]) }, 360 { "Germany4", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]) }, 361 { "France5", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 362 { "France6", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 363 { "France_x86", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 364 { "Italy5", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 365 { "Italy5-Hobo", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 366 { "Italy4", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 367 { "Italy6", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 368 { "Italy_x86", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 369 { "Netherland4", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 370 { "Netherland5", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 371 { "Netherland5-Hobo", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 372 { "Netherland6", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 373 { "Netherland_x86", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 374 { "Norway5", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 375 { "Norway5-Hobo", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 376 { "Norway4", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 377 { "Norway6", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 378 { "Norway_x86", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 379 { "Portugal5", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 380 { "Portugal5-Hobo", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 381 { "Portugal4", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 382 { "Portugal6", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 383 { "Portugal_x86", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 384 { "Spain5", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 385 { "Spain5-Hobo", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 386 { "Spain4", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 387 { "Spain6", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 388 { "Spain_x86", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 389 { "Sweden5", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 390 { "Sweden5-Hobo", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 391 { "Sweden4", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 392 { "Sweden6", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 393 { "Sweden_x86", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 394 #endif 395 { "U.S. English", aImplReplacements_English, sizeof(aImplReplacements_English)/sizeof(aImplReplacements_English[0]) }, 396 { "United Kingdom", aImplReplacements_English, sizeof(aImplReplacements_English)/sizeof(aImplReplacements_English[0]) }, 397 // Germany, German 398 { "German", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]) }, 399 { "France", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 400 { "French", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 401 // Italy, Italian 402 { "Ital", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 403 // Norway, Norwegian 404 { "Norw", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 405 // Portugal, Portuguese 406 { "Portu", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 407 { "Spain", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 408 { "Spanish", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 409 // Sweden, Swedish 410 { "Swed", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 411 { "Netherland", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 412 { "Dutch", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 413 // Turkish, Turkey 414 { "Turk", aImplReplacements_Turkish, sizeof(aImplReplacements_Turkish)/sizeof(aImplReplacements_Turkish[0]) }, 415 // Russian, Russia 416 { "Russia", aImplReplacements_Russian, sizeof(aImplReplacements_Russian)/sizeof(aImplReplacements_Russian[0]) }, 417 { "English", aImplReplacements_English, sizeof(aImplReplacements_English)/sizeof(aImplReplacements_English[0]) } 418 }; 419 420 String getKeysymReplacementName( const char* pKeyboard, KeySym nSymbol ) 421 { 422 for( unsigned int n = 0; n < sizeof(aKeyboards)/sizeof(aKeyboards[0]); n++ ) 423 { 424 if( ! strncasecmp( pKeyboard, aKeyboards[n].pKeyboardName, strlen( aKeyboards[n].pKeyboardName ) ) ) 425 { 426 const struct KeysymNameReplacement* pRepl = aKeyboards[n].pReplacements; 427 for( int m = aKeyboards[n].nReplacements ; m ; ) 428 { 429 if( nSymbol == pRepl[--m].aSymbol ) 430 return String( pRepl[m].pName, RTL_TEXTENCODING_UTF8 ); 431 } 432 } 433 } 434 // try english fallbacks 435 const struct KeysymNameReplacement* pRepl = aImplReplacements_English; 436 for( int m = sizeof(aImplReplacements_English)/sizeof(aImplReplacements_English[0]) ; m ; ) 437 { 438 if( nSymbol == pRepl[--m].aSymbol ) 439 return String( pRepl[m].pName, RTL_TEXTENCODING_UTF8 ); 440 } 441 return String(); 442 } 443 444 } 445 446 #ifdef SOLARIS 447 typedef struct { 448 int n_layout; 449 const char* p_description; 450 } keyboard_layout; 451 452 static const keyboard_layout type0_layout[] = 453 { 454 { 0, "US4" }, 455 { -1, NULL } 456 }; 457 458 static const keyboard_layout type3_layout[] = 459 { 460 { 0, "US3" }, 461 { -1, NULL } 462 }; 463 464 static const keyboard_layout type4_layout[] = 465 { 466 { 0, "US4" }, 467 { 1, "US4" }, 468 { 2, "FranceBelg4" }, 469 { 3, "Canada4" }, 470 { 4, "Denmark4" }, 471 { 5, "Germany4" }, 472 { 6, "Italy4" }, 473 { 7, "Netherland4" }, 474 { 8, "Norway4" }, 475 { 9, "Portugal4" }, 476 { 10, "SpainLatAm4" }, 477 { 11, "SwedenFin4" }, 478 { 12, "Switzer_Fr4" }, 479 { 13, "Switzer_Ge4" }, 480 { 14, "UK4" }, 481 { 16, "Korea4" }, 482 { 17, "Taiwan4" }, 483 { 19, "US101A_PC" }, 484 { 19, "US101A_Sun" }, 485 { 32, "Japan4" }, 486 { 33, "US5" }, 487 { 34, "US_UNIX5" }, 488 { 35, "France5" }, 489 { 36, "Denmark5" }, 490 { 37, "Germany5" }, 491 { 38, "Italy5" }, 492 { 39, "Netherland5" }, 493 { 40, "Norway5" }, 494 { 41, "Portugal5" }, 495 { 42, "Spain5" }, 496 { 43, "Sweden5" }, 497 { 44, "Switzer_Fr5" }, 498 { 45, "Switzer_Ge5" }, 499 { 46, "UK5" }, 500 { 47, "Korea5" }, 501 { 48, "Taiwan5" }, 502 { 49, "Japan5" }, 503 { 50, "Canada_Fr5" }, 504 { 51, "Hungary5" }, 505 { 52, "Poland5" }, 506 { 53, "Czech5" }, 507 { 54, "Russia5" }, 508 { 55, "Latvia5" }, 509 { 56, "Turkey5" }, 510 { 57, "Greece5" }, 511 { 58, "Estonia5" }, 512 { 59, "Lithuania5" }, 513 { 63, "Canada_Fr5_TBITS5" }, 514 { 80, "US5_Hobo" }, 515 { 81, "US_UNIX5_Hobo" }, 516 { 82, "France5_Hobo" }, 517 { 83, "Denmark5_Hobo" }, 518 { 84, "Germany5_Hobo" }, 519 { 85, "Italy5_Hobo" }, 520 { 86, "Netherland5_Hobo" }, 521 { 87, "Norway5_Hobo" }, 522 { 88, "Portugal5_Hobo" }, 523 { 89, "Spain5_Hobo" }, 524 { 90, "Sweden5_Hobo" }, 525 { 91, "Switzer_Fr5_Hobo" }, 526 { 92, "Switzer_Ge5_Hobo" }, 527 { 93, "UK5_Hobo" }, 528 { 94, "Korea5_Hobo" }, 529 { 95, "Taiwan5_Hobo" }, 530 { 96, "Japan5_Hobo" }, 531 { 97, "Canada_Fr5_Hobo" }, 532 { -1, NULL } 533 }; 534 535 static const keyboard_layout type101_layout[] = 536 { 537 { 0, "US101A_x86" }, 538 { 1, "US101A_x86" }, 539 { 34, "J3100_x86" }, 540 { 35, "France_x86" }, 541 { 36, "Denmark_x86" }, 542 { 37, "Germany_x86" }, 543 { 38, "Italy_x86" }, 544 { 39, "Netherland_x86" }, 545 { 40, "Norway_x86" }, 546 { 41, "Portugal_x86" }, 547 { 42, "Spain_x86" }, 548 { 43, "Sweden_x86" }, 549 { 44, "Switzer_Fr_x86" }, 550 { 45, "Switzer_Ge_x86" }, 551 { 46, "UK_x86" }, 552 { 47, "Korea_x86" }, 553 { 48, "Taiwan_x86" }, 554 { 49, "Japan_x86" }, 555 { 50, "Canada_Fr2_x86" }, 556 { 51, "Hungary_x86" }, 557 { 52, "Poland_x86" }, 558 { 53, "Czech_x86" }, 559 { 54, "Russia_x86" }, 560 { 55, "Latvia_x86" }, 561 { 56, "Turkey_x86" }, 562 { 57, "Greece_x86" }, 563 { 59, "Lithuania_x86" }, 564 { 1001, "MS_US101A_x86" }, 565 { -1, NULL } 566 }; 567 568 static const keyboard_layout type6_layout[] = 569 { 570 { 0, "US6" }, 571 { 6, "Denmark6" }, 572 { 7, "Finnish6" }, 573 { 8, "France6" }, 574 { 9, "Germany6" }, 575 { 14, "Italy6" }, 576 { 15, "Japan6" }, 577 { 16, "Korea6" }, 578 { 18, "Netherland6" }, 579 { 19, "Norway6" }, 580 { 22, "Portugal6" }, 581 { 25, "Spain6" }, 582 { 26, "Sweden6" }, 583 { 27, "Switzer_Fr6" }, 584 { 28, "Switzer_Ge6" }, 585 { 30, "Taiwan6" }, 586 { 32, "UK6" }, 587 { 33, "US6" }, 588 { -1, NULL } 589 }; 590 #endif 591 592 593 #if OSL_DEBUG_LEVEL > 1 594 #include <stdio.h> 595 #endif 596 597 const char* SalDisplay::GetKeyboardName( sal_Bool bRefresh ) 598 { 599 if( bRefresh || ! m_aKeyboardName.Len() ) 600 { 601 #ifdef SOLARIS 602 if( IsLocal() ) 603 { 604 int kbd = open( "/dev/kbd", O_RDONLY ); 605 if( kbd >= 0 ) 606 { 607 int kbd_type = 0; 608 if( ! ioctl( kbd, KIOCTYPE, &kbd_type ) ) 609 { 610 int kbd_layout = 0; 611 if( ! ioctl( kbd, KIOCLAYOUT, &kbd_layout ) ) 612 { 613 const keyboard_layout *p_layout = NULL; 614 switch( kbd_type ) 615 { 616 case KB_KLUNK: p_layout = type0_layout; break; 617 case KB_SUN3: p_layout = type3_layout; break; 618 case KB_SUN4: p_layout = type4_layout; break; 619 case KB_USB: p_layout = type6_layout; break; 620 case KB_PC: p_layout = type101_layout; break; 621 } 622 623 if( p_layout ) 624 { 625 while( p_layout->n_layout != -1 ) 626 { 627 if ( p_layout->n_layout == kbd_layout ) 628 { 629 m_aKeyboardName = p_layout->p_description; 630 break; 631 } 632 p_layout++; 633 } 634 } 635 } 636 } 637 close(kbd); 638 } 639 } 640 #else 641 int opcode, event, error; 642 int major = XkbMajorVersion, minor = XkbMinorVersion; 643 if( XkbQueryExtension( GetDisplay(), &opcode, &event,&error, &major, &minor ) ) 644 { 645 XkbDescPtr pXkbDesc = NULL; 646 // try X keyboard extension 647 if( (pXkbDesc = XkbGetKeyboard( GetDisplay(), XkbAllComponentsMask, XkbUseCoreKbd )) ) 648 { 649 const char* pAtom = NULL; 650 if( pXkbDesc->names->groups[0] ) 651 { 652 pAtom = XGetAtomName( GetDisplay(), pXkbDesc->names->groups[0] ); 653 m_aKeyboardName = pAtom; 654 XFree( (void*)pAtom ); 655 } 656 else 657 m_aKeyboardName = "<unknown keyboard>"; 658 #if OSL_DEBUG_LEVEL > 1 659 #define PRINT_ATOM( x ) { if( pXkbDesc->names->x ) { pAtom = XGetAtomName( GetDisplay(), pXkbDesc->names->x ); fprintf( stderr, "%s: %s\n", #x, pAtom ); XFree( (void*)pAtom ); } else fprintf( stderr, "%s: <nil>\n", #x ); } 660 661 PRINT_ATOM( keycodes ); 662 PRINT_ATOM( geometry ); 663 PRINT_ATOM( symbols ); 664 PRINT_ATOM( types ); 665 PRINT_ATOM( compat ); 666 PRINT_ATOM( phys_symbols ); 667 668 #define PRINT_ATOM_2( x ) { if( pXkbDesc->names->x[i] ) { pAtom = XGetAtomName( GetDisplay(), pXkbDesc->names->x[i] ); fprintf( stderr, "%s[%d]: %s\n", #x, i, pAtom ); XFree( (void*)pAtom ); } else fprintf( stderr, "%s[%d]: <nil>\n", #x, i ); } 669 int i; 670 for( i = 0; i < XkbNumVirtualMods; i++ ) 671 PRINT_ATOM_2( vmods ); 672 for( i = 0; i < XkbNumIndicators; i++ ) 673 PRINT_ATOM_2( indicators ); 674 for( i = 0; i < XkbNumKbdGroups; i++ ) 675 PRINT_ATOM_2( groups ); 676 #endif 677 XkbFreeKeyboard( pXkbDesc, XkbAllComponentsMask, True ); 678 } 679 } 680 #endif 681 if( ! m_aKeyboardName.Len() ) 682 m_aKeyboardName = "<unknown keyboard>"; 683 } 684 return m_aKeyboardName.GetBuffer(); 685 } 686