| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_vcl.hxx" |
| |
| |
| #include <stdio.h> |
| |
| #include "unx/saldisp.hxx" |
| #include "unx/saldata.hxx" |
| #include "unx/i18n_xkb.hxx" |
| |
| SalI18N_KeyboardExtension::SalI18N_KeyboardExtension( Display* pDisplay) |
| : mbUseExtension( true ) |
| , mnDefaultGroup( 0 ) |
| { |
| mpDisplay = pDisplay; |
| |
| // allow user to set the default keyboard group idx or to disable the usage |
| // of x keyboard extension at all: |
| // setenv SAL_XKEYBOARDGROUP disables keyboard extension |
| // setenv SAL_XKEYBOARDGROUP 2 sets the keyboard group index to 2 |
| // keyboard group index must be in [1,4], may be specified in hex or decimal |
| static char *pUseKeyboardExtension = getenv( "SAL_XKEYBOARDGROUP" ); |
| if ( pUseKeyboardExtension != NULL ) |
| { |
| mbUseExtension = pUseKeyboardExtension[0] != '\0' ; |
| if ( mbUseExtension ) |
| mnDefaultGroup = strtol( pUseKeyboardExtension, NULL, 0 ); |
| if ( mnDefaultGroup > XkbMaxKbdGroup ) |
| mnDefaultGroup = 0; |
| } |
| |
| // query XServer support for XKB Extension, |
| // do not call XQueryExtension() / XInitExtension() due to possible version |
| // clashes ! |
| if ( mbUseExtension ) |
| { |
| int nMajorExtOpcode; |
| int nExtMajorVersion = XkbMajorVersion; |
| int nExtMinorVersion = XkbMinorVersion; |
| |
| mbUseExtension = (sal_Bool)XkbQueryExtension( mpDisplay, |
| &nMajorExtOpcode, (int*)&mnEventBase, (int*)&mnErrorBase, |
| &nExtMajorVersion, &nExtMinorVersion ); |
| } |
| |
| // query notification for changes of the keyboard group |
| if ( mbUseExtension ) |
| { |
| #define XkbGroupMask ( XkbGroupStateMask | XkbGroupBaseMask \ |
| | XkbGroupLatchMask | XkbGroupLockMask ) |
| |
| mbUseExtension = XkbSelectEventDetails( mpDisplay, |
| XkbUseCoreKbd, XkbStateNotify, XkbGroupMask, XkbGroupMask ); |
| } |
| |
| // query initial keyboard group |
| if ( mbUseExtension ) |
| { |
| XkbStateRec aStateRecord; |
| XkbGetState( mpDisplay, XkbUseCoreKbd, &aStateRecord ); |
| mnGroup = aStateRecord.group; |
| } |
| } |
| |
| void |
| SalI18N_KeyboardExtension::Dispatch( XEvent* pEvent) |
| { |
| // must the event be handled? |
| if ( !mbUseExtension |
| || (pEvent->type != mnEventBase) ) |
| return; |
| |
| // only handle state notify events for now, and only interested |
| // in group details |
| sal_uInt32 nXKBType = ((XkbAnyEvent*)pEvent)->xkb_type; |
| switch ( nXKBType ) |
| { |
| case XkbStateNotify: |
| |
| mnGroup = ((XkbStateNotifyEvent*)pEvent)->group; |
| break; |
| |
| default: |
| |
| #if OSL_DEBUG_LEVEL > 1 |
| fprintf(stderr, "Got unrequested XkbAnyEvent %#x/%i\n", |
| static_cast<unsigned int>(nXKBType), static_cast<int>(nXKBType) ); |
| #endif |
| break; |
| } |
| } |
| |
| sal_uInt32 SalI18N_KeyboardExtension::LookupKeysymInGroup( sal_uInt32 nKeyCode, |
| sal_uInt32 nShiftState, sal_uInt32 nGroup ) const |
| { |
| nShiftState &= ShiftMask; |
| |
| KeySym nKeySymbol = XkbKeycodeToKeysym( mpDisplay, nKeyCode, nGroup, nShiftState ); |
| return nKeySymbol; |
| } |
| |
| |