1c82f2877SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3c82f2877SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4c82f2877SAndrew Rist * or more contributor license agreements. See the NOTICE file 5c82f2877SAndrew Rist * distributed with this work for additional information 6c82f2877SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7c82f2877SAndrew Rist * to you under the Apache License, Version 2.0 (the 8c82f2877SAndrew Rist * "License"); you may not use this file except in compliance 9c82f2877SAndrew Rist * with the License. You may obtain a copy of the License at 10c82f2877SAndrew Rist * 11c82f2877SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12c82f2877SAndrew Rist * 13c82f2877SAndrew Rist * Unless required by applicable law or agreed to in writing, 14c82f2877SAndrew Rist * software distributed under the License is distributed on an 15c82f2877SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16c82f2877SAndrew Rist * KIND, either express or implied. See the License for the 17c82f2877SAndrew Rist * specific language governing permissions and limitations 18c82f2877SAndrew Rist * under the License. 19c82f2877SAndrew Rist * 20c82f2877SAndrew Rist *************************************************************/ 21c82f2877SAndrew Rist 22c82f2877SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir 28cdf0e10cSrcweir #include <stdio.h> 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include "unx/saldisp.hxx" 31cdf0e10cSrcweir #include "unx/saldata.hxx" 32cdf0e10cSrcweir #include "unx/i18n_xkb.hxx" 33cdf0e10cSrcweir 34*e78229dfSHerbert Dürr SalI18N_KeyboardExtension::SalI18N_KeyboardExtension( Display* pDisplay) 35*e78229dfSHerbert Dürr : mbUseExtension( true ), 36*e78229dfSHerbert Dürr , mnDefaultGroup( 0 ) 37cdf0e10cSrcweir { 38cdf0e10cSrcweir mpDisplay = pDisplay; 39cdf0e10cSrcweir 40cdf0e10cSrcweir // allow user to set the default keyboard group idx or to disable the usage 41cdf0e10cSrcweir // of x keyboard extension at all: 42cdf0e10cSrcweir // setenv SAL_XKEYBOARDGROUP disables keyboard extension 43cdf0e10cSrcweir // setenv SAL_XKEYBOARDGROUP 2 sets the keyboard group index to 2 44cdf0e10cSrcweir // keyboard group index must be in [1,4], may be specified in hex or decimal 45cdf0e10cSrcweir static char *pUseKeyboardExtension = getenv( "SAL_XKEYBOARDGROUP" ); 46cdf0e10cSrcweir if ( pUseKeyboardExtension != NULL ) 47cdf0e10cSrcweir { 48cdf0e10cSrcweir mbUseExtension = pUseKeyboardExtension[0] != '\0' ; 49cdf0e10cSrcweir if ( mbUseExtension ) 50cdf0e10cSrcweir mnDefaultGroup = strtol( pUseKeyboardExtension, NULL, 0 ); 51cdf0e10cSrcweir if ( mnDefaultGroup > XkbMaxKbdGroup ) 52cdf0e10cSrcweir mnDefaultGroup = 0; 53cdf0e10cSrcweir } 54cdf0e10cSrcweir 55cdf0e10cSrcweir // query XServer support for XKB Extension, 56cdf0e10cSrcweir // do not call XQueryExtension() / XInitExtension() due to possible version 57cdf0e10cSrcweir // clashes ! 58cdf0e10cSrcweir if ( mbUseExtension ) 59cdf0e10cSrcweir { 60cdf0e10cSrcweir int nMajorExtOpcode; 61cdf0e10cSrcweir int nExtMajorVersion = XkbMajorVersion; 62cdf0e10cSrcweir int nExtMinorVersion = XkbMinorVersion; 63cdf0e10cSrcweir 64cdf0e10cSrcweir mbUseExtension = (sal_Bool)XkbQueryExtension( mpDisplay, 65cdf0e10cSrcweir &nMajorExtOpcode, (int*)&mnEventBase, (int*)&mnErrorBase, 66cdf0e10cSrcweir &nExtMajorVersion, &nExtMinorVersion ); 67cdf0e10cSrcweir } 68cdf0e10cSrcweir 69cdf0e10cSrcweir // query notification for changes of the keyboard group 70cdf0e10cSrcweir if ( mbUseExtension ) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir #define XkbGroupMask ( XkbGroupStateMask | XkbGroupBaseMask \ 73cdf0e10cSrcweir | XkbGroupLatchMask | XkbGroupLockMask ) 74cdf0e10cSrcweir 75cdf0e10cSrcweir mbUseExtension = XkbSelectEventDetails( mpDisplay, 76cdf0e10cSrcweir XkbUseCoreKbd, XkbStateNotify, XkbGroupMask, XkbGroupMask ); 77cdf0e10cSrcweir } 78cdf0e10cSrcweir 79cdf0e10cSrcweir // query initial keyboard group 80cdf0e10cSrcweir if ( mbUseExtension ) 81cdf0e10cSrcweir { 82cdf0e10cSrcweir XkbStateRec aStateRecord; 83cdf0e10cSrcweir XkbGetState( mpDisplay, XkbUseCoreKbd, &aStateRecord ); 84cdf0e10cSrcweir mnGroup = aStateRecord.group; 85cdf0e10cSrcweir } 86cdf0e10cSrcweir } 87cdf0e10cSrcweir 88cdf0e10cSrcweir void 89*e78229dfSHerbert Dürr SalI18N_KeyboardExtension::Dispatch( XEvent* pEvent) 90cdf0e10cSrcweir { 91cdf0e10cSrcweir // must the event be handled? 92cdf0e10cSrcweir if ( !mbUseExtension 93cdf0e10cSrcweir || (pEvent->type != mnEventBase) ) 94cdf0e10cSrcweir return; 95cdf0e10cSrcweir 96cdf0e10cSrcweir // only handle state notify events for now, and only interested 97cdf0e10cSrcweir // in group details 98cdf0e10cSrcweir sal_uInt32 nXKBType = ((XkbAnyEvent*)pEvent)->xkb_type; 99cdf0e10cSrcweir switch ( nXKBType ) 100cdf0e10cSrcweir { 101cdf0e10cSrcweir case XkbStateNotify: 102cdf0e10cSrcweir 103cdf0e10cSrcweir mnGroup = ((XkbStateNotifyEvent*)pEvent)->group; 104cdf0e10cSrcweir break; 105cdf0e10cSrcweir 106cdf0e10cSrcweir default: 107cdf0e10cSrcweir 108*e78229dfSHerbert Dürr #if OSL_DEBUG_LEVEL > 1 109cdf0e10cSrcweir fprintf(stderr, "Got unrequested XkbAnyEvent %#x/%i\n", 110*e78229dfSHerbert Dürr static_cast<unsigned int>(nXKBType), static_cast<int>(nXKBType) ); 111*e78229dfSHerbert Dürr #endif 112cdf0e10cSrcweir break; 113cdf0e10cSrcweir } 114cdf0e10cSrcweir } 115cdf0e10cSrcweir 116*e78229dfSHerbert Dürr sal_uInt32 SalI18N_KeyboardExtension::LookupKeysymInGroup( sal_uInt32 nKeyCode, 117*e78229dfSHerbert Dürr sal_uInt32 nShiftState, sal_uInt32 nGroup ) const 118cdf0e10cSrcweir { 119cdf0e10cSrcweir nShiftState &= ShiftMask; 120cdf0e10cSrcweir 121*e78229dfSHerbert Dürr KeySym nKeySymbol = XkbKeycodeToKeysym( mpDisplay, nKeyCode, nGroup, nShiftState ); 122cdf0e10cSrcweir return nKeySymbol; 123cdf0e10cSrcweir } 124cdf0e10cSrcweir 125cdf0e10cSrcweir 126