xref: /trunk/main/vcl/unx/generic/app/i18n_xkb.cxx (revision c82f2877)
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