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_KP_Enter, "Entrée" }, 171 { SunXK_Stop, "Stop" }, 172 { SunXK_Again, "Encore" }, 173 { SunXK_Props, "Props" }, 174 { SunXK_Undo, "Annuler" }, 175 { SunXK_Front, "Devant" }, 176 { SunXK_Copy, "Copy" }, 177 { SunXK_Open, "Ouvrir" }, 178 { SunXK_Paste, "Coller" }, 179 { SunXK_Find, "Cher." }, 180 { SunXK_Cut, "Couper" }, 181 { XK_minus, "-" }, 182 { XK_plus, "+" } 183 }; 184 185 static const struct KeysymNameReplacement aImplReplacements_Italian[] = 186 { 187 { XK_Shift_L, "Maiusc" }, 188 { XK_Shift_R, "Maiusc" }, 189 { XK_Page_Up, "PgSu" }, 190 { XK_Page_Down, "PgGiu" }, 191 { XK_End, "Fine" }, 192 { XK_Insert, "Ins" }, 193 { XK_Delete, "Canc" }, 194 { XK_Escape, "Esc" }, 195 { XK_Right, "A destra" }, 196 { XK_Left, "A sinistra" }, 197 { XK_Up, "Sposta verso l'alto" }, 198 { XK_Down, "Sposta verso il basso" }, 199 { XK_BackSpace, "Backspace" }, 200 { XK_Return, "Invio" }, 201 { XK_space, "Spazio" }, 202 { SunXK_Stop, "Stop" }, 203 { SunXK_Again, "Ancora" }, 204 { SunXK_Props, "Proprietà" }, 205 { SunXK_Undo, "Annulla" }, 206 { SunXK_Front, "Davanti" }, 207 { SunXK_Copy, "Copia" }, 208 { SunXK_Open, "Apri" }, 209 { SunXK_Paste, "Incolla" }, 210 { SunXK_Find, "Trova" }, 211 { SunXK_Cut, "Taglia" }, 212 { XK_minus, "-" }, 213 { XK_plus, "+" } 214 }; 215 216 static const struct KeysymNameReplacement aImplReplacements_Dutch[] = 217 { 218 { XK_Page_Up, "PageUp" }, 219 { XK_Page_Down, "PageDown" }, 220 { XK_Escape, "Esc" }, 221 { XK_Right, "Rechts" }, 222 { XK_Left, "Links" }, 223 { XK_Up, "Boven" }, 224 { XK_Down, "Onder" }, 225 { XK_BackSpace, "Backspace" }, 226 { XK_Return, "Return" }, 227 { XK_space, "Spatiebalk" }, 228 { SunXK_Stop, "Stop" }, 229 { SunXK_Again, "Again" }, 230 { SunXK_Props, "Props" }, 231 { SunXK_Undo, "Undo" }, 232 { SunXK_Front, "Front" }, 233 { SunXK_Copy, "Copy" }, 234 { SunXK_Open, "Open" }, 235 { SunXK_Paste, "Paste" }, 236 { SunXK_Find, "Find" }, 237 { SunXK_Cut, "Cut" }, 238 { XK_minus, "-" }, 239 { XK_plus, "+" } 240 }; 241 242 static const struct KeysymNameReplacement aImplReplacements_Norwegian[] = 243 { 244 { XK_Shift_L, "Skift" }, 245 { XK_Shift_R, "Skift" }, 246 { XK_Page_Up, "PageUp" }, 247 { XK_Page_Down, "PageDown" }, 248 { XK_Escape, "Esc" }, 249 { XK_Right, "Hyre" }, 250 { XK_Left, "Venstre" }, 251 { XK_Up, "Opp" }, 252 { XK_Down, "Ned" }, 253 { XK_BackSpace, "Tilbake" }, 254 { XK_Return, "Enter" }, 255 { SunXK_Stop, "Avbryt" }, 256 { SunXK_Again, "Gjenta" }, 257 { SunXK_Props, "Egenskaper" }, 258 { SunXK_Undo, "Angre" }, 259 { SunXK_Front, "Front" }, 260 { SunXK_Copy, "Kopi" }, 261 { SunXK_Open, "Åpne" }, 262 { SunXK_Paste, "Lim" }, 263 { SunXK_Find, "Søk" }, 264 { SunXK_Cut, "Klipp" }, 265 { XK_minus, "-" }, 266 { XK_plus, "+" } 267 }; 268 269 static const struct KeysymNameReplacement aImplReplacements_Swedish[] = 270 { 271 { XK_Shift_L, "Skift" }, 272 { XK_Shift_R, "Skift" }, 273 { XK_Page_Up, "PageUp" }, 274 { XK_Page_Down, "PageDown" }, 275 { XK_Escape, "Esc" }, 276 { XK_Right, "Höger" }, 277 { XK_Left, "Vänster" }, 278 { XK_Up, "Up" }, 279 { XK_Down, "Ned" }, 280 { XK_BackSpace, "Backsteg" }, 281 { XK_Return, "Retur" }, 282 { XK_space, "Blank" }, 283 { SunXK_Stop, "Avbryt" }, 284 { SunXK_Again, "Upprepa" }, 285 { SunXK_Props, "Egenskaper" }, 286 { SunXK_Undo, "Ångra" }, 287 { SunXK_Front, "Fram" }, 288 { SunXK_Copy, "Kopiera" }, 289 { SunXK_Open, "Öppna" }, 290 { SunXK_Paste, "Klistra in" }, 291 { SunXK_Find, "Sök" }, 292 { SunXK_Cut, "Klipp ut" }, 293 { XK_minus, "-" }, 294 { XK_plus, "+" } 295 }; 296 297 static const struct KeysymNameReplacement aImplReplacements_Portuguese[] = 298 { 299 { XK_Page_Up, "PageUp" }, 300 { XK_Page_Down, "PageDown" }, 301 { XK_Escape, "Esc" }, 302 { XK_Right, "Direita" }, 303 { XK_Left, "Esquerda" }, 304 { XK_Up, "Acima" }, 305 { XK_Down, "Abaixo" }, 306 { XK_BackSpace, "Backspace" }, 307 { XK_Return, "Enter" }, 308 { XK_slash, "Barra" }, 309 { SunXK_Stop, "Stop" }, 310 { SunXK_Again, "Again" }, 311 { SunXK_Props, "Props" }, 312 { SunXK_Undo, "Undo" }, 313 { SunXK_Front, "Front" }, 314 { SunXK_Copy, "Copy" }, 315 { SunXK_Open, "Open" }, 316 { SunXK_Paste, "Paste" }, 317 { SunXK_Find, "Find" }, 318 { SunXK_Cut, "Cut" }, 319 { XK_minus, "-" }, 320 { XK_plus, "+" } 321 }; 322 323 static const struct KeysymNameReplacement aImplReplacements_Spanish[] = 324 { 325 { XK_Shift_L, "Mayús" }, 326 { XK_Shift_R, "Mayús" }, 327 { XK_Page_Up, "RePág" }, 328 { XK_Page_Down, "AvPág" }, 329 { XK_End, "Fin" }, 330 { XK_Home, "Inicio" }, 331 { XK_Delete, "Supr" }, 332 { XK_Escape, "Esc" }, 333 { XK_Right, "Hacia la derecha" }, 334 { XK_Left, "Hacia la izquierda" }, 335 { XK_Up, "Hacia arriba" }, 336 { XK_Down, "Hacia abajo" }, 337 { XK_BackSpace, "Ret" }, 338 { XK_Return, "Entrada" }, 339 { XK_space, "Espacio" }, 340 { XK_KP_Enter, "Intro" }, 341 { SunXK_Stop, "Stop" }, 342 { SunXK_Again, "Repetir" }, 343 { SunXK_Props, "Props" }, 344 { SunXK_Undo, "Anular" }, 345 { SunXK_Front, "Delante" }, 346 { SunXK_Copy, "Copiar" }, 347 { SunXK_Open, "Abrir" }, 348 { SunXK_Paste, "Pegar" }, 349 { SunXK_Find, "Buscar" }, 350 { SunXK_Cut, "Cortar" }, 351 { XK_minus, "-" }, 352 { XK_plus, "+" } 353 }; 354 355 static const struct KeyboardReplacements aKeyboards[] = 356 { 357 #ifdef SOLARIS 358 { "Germany5", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]) }, 359 { "Germany4", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]) }, 360 { "France5", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 361 { "France6", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 362 { "France_x86", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 363 { "Italy5", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 364 { "Italy5-Hobo", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 365 { "Italy4", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 366 { "Italy6", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 367 { "Italy_x86", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 368 { "Netherland4", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 369 { "Netherland5", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 370 { "Netherland5-Hobo", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 371 { "Netherland6", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 372 { "Netherland_x86", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 373 { "Norway5", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 374 { "Norway5-Hobo", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 375 { "Norway4", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 376 { "Norway6", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 377 { "Norway_x86", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 378 { "Portugal5", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 379 { "Portugal5-Hobo", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 380 { "Portugal4", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 381 { "Portugal6", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 382 { "Portugal_x86", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 383 { "Spain5", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 384 { "Spain5-Hobo", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 385 { "Spain4", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 386 { "Spain6", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 387 { "Spain_x86", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 388 { "Sweden5", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 389 { "Sweden5-Hobo", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 390 { "Sweden4", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 391 { "Sweden6", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 392 { "Sweden_x86", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 393 #endif 394 { "U.S. English", aImplReplacements_English, sizeof(aImplReplacements_English)/sizeof(aImplReplacements_English[0]) }, 395 { "United Kingdom", aImplReplacements_English, sizeof(aImplReplacements_English)/sizeof(aImplReplacements_English[0]) }, 396 // Germany, German 397 { "German", aImplReplacements_German, sizeof(aImplReplacements_German)/sizeof(aImplReplacements_German[0]) }, 398 { "France", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 399 { "French", aImplReplacements_French, sizeof(aImplReplacements_French)/sizeof(aImplReplacements_French[0]) }, 400 // Italy, Italian 401 { "Ital", aImplReplacements_Italian, sizeof(aImplReplacements_Italian)/sizeof(aImplReplacements_Italian[0]) }, 402 // Norway, Norwegian 403 { "Norw", aImplReplacements_Norwegian, sizeof(aImplReplacements_Norwegian)/sizeof(aImplReplacements_Norwegian[0]) }, 404 // Portugal, Portuguese 405 { "Portu", aImplReplacements_Portuguese, sizeof(aImplReplacements_Portuguese)/sizeof(aImplReplacements_Portuguese[0]) }, 406 { "Spain", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 407 { "Spanish", aImplReplacements_Spanish, sizeof(aImplReplacements_Spanish)/sizeof(aImplReplacements_Spanish[0]) }, 408 // Sweden, Swedish 409 { "Swed", aImplReplacements_Swedish, sizeof(aImplReplacements_Swedish)/sizeof(aImplReplacements_Swedish[0]) }, 410 { "Netherland", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 411 { "Dutch", aImplReplacements_Dutch, sizeof(aImplReplacements_Dutch)/sizeof(aImplReplacements_Dutch[0]) }, 412 // Turkish, Turkey 413 { "Turk", aImplReplacements_Turkish, sizeof(aImplReplacements_Turkish)/sizeof(aImplReplacements_Turkish[0]) }, 414 // Russian, Russia 415 { "Russia", aImplReplacements_Russian, sizeof(aImplReplacements_Russian)/sizeof(aImplReplacements_Russian[0]) }, 416 { "English", aImplReplacements_English, sizeof(aImplReplacements_English)/sizeof(aImplReplacements_English[0]) } 417 }; 418 419 String getKeysymReplacementName( const char* pKeyboard, KeySym nSymbol ) 420 { 421 for( unsigned int n = 0; n < sizeof(aKeyboards)/sizeof(aKeyboards[0]); n++ ) 422 { 423 if( ! strncasecmp( pKeyboard, aKeyboards[n].pKeyboardName, strlen( aKeyboards[n].pKeyboardName ) ) ) 424 { 425 const struct KeysymNameReplacement* pRepl = aKeyboards[n].pReplacements; 426 for( int m = aKeyboards[n].nReplacements ; m ; ) 427 { 428 if( nSymbol == pRepl[--m].aSymbol ) 429 return String( pRepl[m].pName, RTL_TEXTENCODING_UTF8 ); 430 } 431 } 432 } 433 // try english fallbacks 434 const struct KeysymNameReplacement* pRepl = aImplReplacements_English; 435 for( int m = sizeof(aImplReplacements_English)/sizeof(aImplReplacements_English[0]) ; m ; ) 436 { 437 if( nSymbol == pRepl[--m].aSymbol ) 438 return String( pRepl[m].pName, RTL_TEXTENCODING_UTF8 ); 439 } 440 return String(); 441 } 442 443 } 444 445 #ifdef SOLARIS 446 typedef struct { 447 int n_layout; 448 const char* p_description; 449 } keyboard_layout; 450 451 static const keyboard_layout type0_layout[] = 452 { 453 { 0, "US4" }, 454 { -1, NULL } 455 }; 456 457 static const keyboard_layout type3_layout[] = 458 { 459 { 0, "US3" }, 460 { -1, NULL } 461 }; 462 463 static const keyboard_layout type4_layout[] = 464 { 465 { 0, "US4" }, 466 { 1, "US4" }, 467 { 2, "FranceBelg4" }, 468 { 3, "Canada4" }, 469 { 4, "Denmark4" }, 470 { 5, "Germany4" }, 471 { 6, "Italy4" }, 472 { 7, "Netherland4" }, 473 { 8, "Norway4" }, 474 { 9, "Portugal4" }, 475 { 10, "SpainLatAm4" }, 476 { 11, "SwedenFin4" }, 477 { 12, "Switzer_Fr4" }, 478 { 13, "Switzer_Ge4" }, 479 { 14, "UK4" }, 480 { 16, "Korea4" }, 481 { 17, "Taiwan4" }, 482 { 19, "US101A_PC" }, 483 { 19, "US101A_Sun" }, 484 { 32, "Japan4" }, 485 { 33, "US5" }, 486 { 34, "US_UNIX5" }, 487 { 35, "France5" }, 488 { 36, "Denmark5" }, 489 { 37, "Germany5" }, 490 { 38, "Italy5" }, 491 { 39, "Netherland5" }, 492 { 40, "Norway5" }, 493 { 41, "Portugal5" }, 494 { 42, "Spain5" }, 495 { 43, "Sweden5" }, 496 { 44, "Switzer_Fr5" }, 497 { 45, "Switzer_Ge5" }, 498 { 46, "UK5" }, 499 { 47, "Korea5" }, 500 { 48, "Taiwan5" }, 501 { 49, "Japan5" }, 502 { 50, "Canada_Fr5" }, 503 { 51, "Hungary5" }, 504 { 52, "Poland5" }, 505 { 53, "Czech5" }, 506 { 54, "Russia5" }, 507 { 55, "Latvia5" }, 508 { 56, "Turkey5" }, 509 { 57, "Greece5" }, 510 { 58, "Estonia5" }, 511 { 59, "Lithuania5" }, 512 { 63, "Canada_Fr5_TBITS5" }, 513 { 80, "US5_Hobo" }, 514 { 81, "US_UNIX5_Hobo" }, 515 { 82, "France5_Hobo" }, 516 { 83, "Denmark5_Hobo" }, 517 { 84, "Germany5_Hobo" }, 518 { 85, "Italy5_Hobo" }, 519 { 86, "Netherland5_Hobo" }, 520 { 87, "Norway5_Hobo" }, 521 { 88, "Portugal5_Hobo" }, 522 { 89, "Spain5_Hobo" }, 523 { 90, "Sweden5_Hobo" }, 524 { 91, "Switzer_Fr5_Hobo" }, 525 { 92, "Switzer_Ge5_Hobo" }, 526 { 93, "UK5_Hobo" }, 527 { 94, "Korea5_Hobo" }, 528 { 95, "Taiwan5_Hobo" }, 529 { 96, "Japan5_Hobo" }, 530 { 97, "Canada_Fr5_Hobo" }, 531 { -1, NULL } 532 }; 533 534 static const keyboard_layout type101_layout[] = 535 { 536 { 0, "US101A_x86" }, 537 { 1, "US101A_x86" }, 538 { 34, "J3100_x86" }, 539 { 35, "France_x86" }, 540 { 36, "Denmark_x86" }, 541 { 37, "Germany_x86" }, 542 { 38, "Italy_x86" }, 543 { 39, "Netherland_x86" }, 544 { 40, "Norway_x86" }, 545 { 41, "Portugal_x86" }, 546 { 42, "Spain_x86" }, 547 { 43, "Sweden_x86" }, 548 { 44, "Switzer_Fr_x86" }, 549 { 45, "Switzer_Ge_x86" }, 550 { 46, "UK_x86" }, 551 { 47, "Korea_x86" }, 552 { 48, "Taiwan_x86" }, 553 { 49, "Japan_x86" }, 554 { 50, "Canada_Fr2_x86" }, 555 { 51, "Hungary_x86" }, 556 { 52, "Poland_x86" }, 557 { 53, "Czech_x86" }, 558 { 54, "Russia_x86" }, 559 { 55, "Latvia_x86" }, 560 { 56, "Turkey_x86" }, 561 { 57, "Greece_x86" }, 562 { 59, "Lithuania_x86" }, 563 { 1001, "MS_US101A_x86" }, 564 { -1, NULL } 565 }; 566 567 static const keyboard_layout type6_layout[] = 568 { 569 { 0, "US6" }, 570 { 6, "Denmark6" }, 571 { 7, "Finnish6" }, 572 { 8, "France6" }, 573 { 9, "Germany6" }, 574 { 14, "Italy6" }, 575 { 15, "Japan6" }, 576 { 16, "Korea6" }, 577 { 18, "Netherland6" }, 578 { 19, "Norway6" }, 579 { 22, "Portugal6" }, 580 { 25, "Spain6" }, 581 { 26, "Sweden6" }, 582 { 27, "Switzer_Fr6" }, 583 { 28, "Switzer_Ge6" }, 584 { 30, "Taiwan6" }, 585 { 32, "UK6" }, 586 { 33, "US6" }, 587 { -1, NULL } 588 }; 589 #endif 590 591 592 #if OSL_DEBUG_LEVEL > 1 593 #include <stdio.h> 594 #endif 595 596 const char* SalDisplay::GetKeyboardName( sal_Bool bRefresh ) 597 { 598 if( bRefresh || ! m_aKeyboardName.Len() ) 599 { 600 #ifdef SOLARIS 601 if( IsLocal() ) 602 { 603 int kbd = open( "/dev/kbd", O_RDONLY ); 604 if( kbd >= 0 ) 605 { 606 int kbd_type = 0; 607 if( ! ioctl( kbd, KIOCTYPE, &kbd_type ) ) 608 { 609 int kbd_layout = 0; 610 if( ! ioctl( kbd, KIOCLAYOUT, &kbd_layout ) ) 611 { 612 const keyboard_layout *p_layout = NULL; 613 switch( kbd_type ) 614 { 615 case KB_KLUNK: p_layout = type0_layout; break; 616 case KB_SUN3: p_layout = type3_layout; break; 617 case KB_SUN4: p_layout = type4_layout; break; 618 case KB_USB: p_layout = type6_layout; break; 619 case KB_PC: p_layout = type101_layout; break; 620 } 621 622 if( p_layout ) 623 { 624 while( p_layout->n_layout != -1 ) 625 { 626 if ( p_layout->n_layout == kbd_layout ) 627 { 628 m_aKeyboardName = p_layout->p_description; 629 break; 630 } 631 p_layout++; 632 } 633 } 634 } 635 } 636 close(kbd); 637 } 638 } 639 #else 640 int opcode, event, error; 641 int major = XkbMajorVersion, minor = XkbMinorVersion; 642 if( XkbQueryExtension( GetDisplay(), &opcode, &event,&error, &major, &minor ) ) 643 { 644 XkbDescPtr pXkbDesc = NULL; 645 // try X keyboard extension 646 if( (pXkbDesc = XkbGetKeyboard( GetDisplay(), XkbAllComponentsMask, XkbUseCoreKbd )) ) 647 { 648 const char* pAtom = NULL; 649 if( pXkbDesc->names->groups[0] ) 650 { 651 pAtom = XGetAtomName( GetDisplay(), pXkbDesc->names->groups[0] ); 652 m_aKeyboardName = pAtom; 653 XFree( (void*)pAtom ); 654 } 655 else 656 m_aKeyboardName = "<unknown keyboard>"; 657 #if OSL_DEBUG_LEVEL > 1 658 #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 ); } 659 660 PRINT_ATOM( keycodes ); 661 PRINT_ATOM( geometry ); 662 PRINT_ATOM( symbols ); 663 PRINT_ATOM( types ); 664 PRINT_ATOM( compat ); 665 PRINT_ATOM( phys_symbols ); 666 667 #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 ); } 668 int i; 669 for( i = 0; i < XkbNumVirtualMods; i++ ) 670 PRINT_ATOM_2( vmods ); 671 for( i = 0; i < XkbNumIndicators; i++ ) 672 PRINT_ATOM_2( indicators ); 673 for( i = 0; i < XkbNumKbdGroups; i++ ) 674 PRINT_ATOM_2( groups ); 675 #endif 676 XkbFreeKeyboard( pXkbDesc, XkbAllComponentsMask, True ); 677 } 678 } 679 #endif 680 if( ! m_aKeyboardName.Len() ) 681 m_aKeyboardName = "<unknown keyboard>"; 682 } 683 return m_aKeyboardName.GetBuffer(); 684 } 685