xref: /AOO41X/main/vcl/unx/generic/app/i18n_xkb.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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 
28 #include <stdio.h>
29 
30 #include "unx/saldisp.hxx"
31 #include "unx/saldata.hxx"
32 #include "unx/i18n_xkb.hxx"
33 
34 SalI18N_KeyboardExtension::SalI18N_KeyboardExtension( Display*
35 #if __XKeyboardExtension__
36 pDisplay
37 #endif
38 )
39     : mbUseExtension( (sal_Bool)__XKeyboardExtension__ ),
40       mnDefaultGroup( 0 )
41 {
42     #if __XKeyboardExtension__
43 
44     mpDisplay = pDisplay;
45 
46     // allow user to set the default keyboard group idx or to disable the usage
47     // of x keyboard extension at all:
48     //      setenv SAL_XKEYBOARDGROUP       disables keyboard extension
49     //      setenv SAL_XKEYBOARDGROUP 2     sets the keyboard group index to 2
50     // keyboard group index must be in [1,4], may be specified in hex or decimal
51     static char *pUseKeyboardExtension = getenv( "SAL_XKEYBOARDGROUP" );
52     if ( pUseKeyboardExtension != NULL )
53     {
54         mbUseExtension = pUseKeyboardExtension[0] != '\0' ;
55         if ( mbUseExtension )
56             mnDefaultGroup = strtol( pUseKeyboardExtension, NULL, 0 );
57         if ( mnDefaultGroup > XkbMaxKbdGroup )
58             mnDefaultGroup = 0;
59     }
60 
61     // query XServer support for XKB Extension,
62     // do not call XQueryExtension() / XInitExtension() due to possible version
63     // clashes !
64     if ( mbUseExtension )
65     {
66         int nMajorExtOpcode;
67         int nExtMajorVersion = XkbMajorVersion;
68         int nExtMinorVersion = XkbMinorVersion;
69 
70         mbUseExtension = (sal_Bool)XkbQueryExtension( mpDisplay,
71             &nMajorExtOpcode, (int*)&mnEventBase, (int*)&mnErrorBase,
72             &nExtMajorVersion, &nExtMinorVersion );
73     }
74 
75     // query notification for changes of the keyboard group
76     if ( mbUseExtension )
77     {
78         #define XkbGroupMask (  XkbGroupStateMask | XkbGroupBaseMask \
79                               | XkbGroupLatchMask | XkbGroupLockMask )
80 
81         mbUseExtension = XkbSelectEventDetails( mpDisplay,
82             XkbUseCoreKbd, XkbStateNotify, XkbGroupMask, XkbGroupMask );
83     }
84 
85     // query initial keyboard group
86     if ( mbUseExtension )
87     {
88         XkbStateRec aStateRecord;
89         XkbGetState( mpDisplay, XkbUseCoreKbd, &aStateRecord );
90         mnGroup = aStateRecord.group;
91     }
92 
93     #endif // __XKeyboardExtension__
94 }
95 
96 void
97 SalI18N_KeyboardExtension::Dispatch( XEvent*
98 #if __XKeyboardExtension__
99 pEvent
100 #endif
101 )
102 {
103     #if __XKeyboardExtension__
104 
105     // must the event be handled?
106     if (   !mbUseExtension
107         || (pEvent->type != mnEventBase) )
108         return;
109 
110     // only handle state notify events for now, and only interested
111     // in group details
112     sal_uInt32 nXKBType = ((XkbAnyEvent*)pEvent)->xkb_type;
113     switch ( nXKBType )
114     {
115         case XkbStateNotify:
116 
117             mnGroup = ((XkbStateNotifyEvent*)pEvent)->group;
118             break;
119 
120         default:
121 
122             #if OSL_DEBUG_LEVEL > 1
123             fprintf(stderr, "Got unrequested XkbAnyEvent %#x/%i\n",
124                     static_cast<unsigned int>(nXKBType), static_cast<int>(nXKBType) );
125             #endif
126             break;
127     }
128     #endif // __XKeyboardExtension__
129 }
130 
131 #if __XKeyboardExtension__
132 sal_uInt32
133 SalI18N_KeyboardExtension::LookupKeysymInGroup( sal_uInt32 nKeyCode,
134                                                 sal_uInt32 nShiftState,
135                                                 sal_uInt32 nGroup ) const
136 #else
137 sal_uInt32
138 SalI18N_KeyboardExtension::LookupKeysymInGroup( sal_uInt32,sal_uInt32,sal_uInt32 ) const
139 #endif
140 {
141     #if __XKeyboardExtension__
142 
143     if ( !mbUseExtension )
144         return NoSymbol;
145 
146     nShiftState &= ShiftMask;
147 
148     KeySym      nKeySymbol;
149     nKeySymbol = XkbKeycodeToKeysym( mpDisplay, nKeyCode, nGroup, nShiftState );
150     return nKeySymbol;
151 
152     #else
153 
154     return NoSymbol;
155 
156     #endif // __XKeyboardExtension__
157 }
158 
159 
160