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 struct XIMArg
28 {
29 char *name;
30 char *value;
31 };
32
33 #if defined(SOLARIS) && !defined(__GNUC__)
34 #include <varargs.h>
35 #else
36 #include <stdarg.h>
37 #endif
38 #include <sal/alloca.h>
39
40 #include <string.h>
41 #include <dlfcn.h>
42
43 #include <X11/Xlib.h>
44 #include <X11/Xlibint.h>
45 #include "unx/XIM.h"
46
47 #define XIIIMP_LIB "xiiimp.so.2"
48
49 #ifdef SOLARIS
50 #define XIIIMP_PATH "/usr/openwin/lib/locale/common/" XIIIMP_LIB
51 #else /* Linux */
52 #define XIIIMP_PATH "/usr/lib/im/" XIIIMP_LIB
53 #endif
54
55 extern "C" {
56 typedef XIM (*OpenFunction)(Display*, XrmDatabase, char*, char*, XIMArg*);
57 }
58
59 /* global variables */
60 static void *g_dlmodule = 0;
61 static OpenFunction g_open_im = (OpenFunction)NULL;
62
63 /* utility function to transform vararg list into an array of XIMArg */
64
65 int
XvaCountArgs(XIMArg * pInArgs)66 XvaCountArgs( XIMArg *pInArgs )
67 {
68 int nArgs = 0;
69 char *pName, *pValue;
70
71 while ( (pName = pInArgs->name) != NULL )
72 {
73 pValue = pInArgs->value;
74
75 if ( strcmp(pName, XNVaNestedList) == 0 )
76 {
77 nArgs += XvaCountArgs( (XIMArg*)pValue );
78 }
79 else
80 {
81 nArgs += 1;
82 }
83 pInArgs++;
84 }
85
86 return nArgs;
87 }
88
89 int
XvaCountArgs(va_list pInArgs)90 XvaCountArgs( va_list pInArgs )
91 {
92 int nArgs = 0;
93 char *pName, *pValue;
94
95 while ( (pName = va_arg(pInArgs, char*)) != NULL)
96 {
97 pValue = va_arg(pInArgs, char*);
98
99 if ( strcmp(pName, XNVaNestedList) == 0 )
100 {
101 nArgs += XvaCountArgs( (XIMArg*)pValue );
102 }
103 else
104 {
105 nArgs += 1;
106 }
107 }
108
109 return nArgs;
110 }
111
112 XIMArg*
XvaGetArgs(XIMArg * pInArgs,XIMArg * pOutArgs)113 XvaGetArgs( XIMArg *pInArgs, XIMArg *pOutArgs )
114 {
115 char *pName, *pValue;
116
117 while ( (pName = pInArgs->name) != NULL )
118 {
119 pValue = pInArgs->value;
120
121 if ( strcmp(pName, XNVaNestedList) == 0 )
122 {
123 pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs );
124 }
125 else
126 {
127 pOutArgs->name = pName;
128 pOutArgs->value = pValue;
129 pOutArgs++;
130 }
131 pInArgs++;
132 }
133
134 return pOutArgs;
135 }
136
137 void
XvaGetArgs(va_list pInArgs,XIMArg * pOutArgs)138 XvaGetArgs( va_list pInArgs, XIMArg *pOutArgs )
139 {
140 char *pName, *pValue;
141
142 while ((pName = va_arg(pInArgs, char*)) != NULL)
143 {
144 pValue = va_arg(pInArgs, char*);
145
146 if ( strcmp(pName, XNVaNestedList) == 0 )
147 {
148 pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs );
149 }
150 else
151 {
152 pOutArgs->name = pName;
153 pOutArgs->value = pValue;
154 pOutArgs++;
155 }
156 }
157
158 pOutArgs->name = NULL;
159 pOutArgs->value = NULL;
160 }
161
162
163 /* Puplic functions */
164
165 #ifdef __cplusplus
166 extern "C"
167 #endif
168 XIM
XvaOpenIM(Display * display,XrmDatabase rdb,char * res_name,char * res_class,...)169 XvaOpenIM(Display *display, XrmDatabase rdb,
170 char *res_name, char *res_class, ...)
171 {
172 XIM xim = (XIM)0;
173 va_list variable;
174 int total_count = 0;
175
176 /*
177 * so count the stuff dangling here
178 */
179
180 #if defined(SOLARIS) && !defined(__GNUC__)
181 va_start(variable);
182 #else
183 va_start(variable, res_class);
184 #endif
185 total_count = XvaCountArgs(variable);
186 va_end(variable);
187
188 if (total_count > 0)
189 {
190 /* call a new open IM method */
191
192 XIMArg* args = (XIMArg*)alloca( (total_count + 1) * sizeof(XIMArg) );
193
194 /*
195 * now package it up so we can set it along
196 */
197 #if defined(SOLARIS) && !defined(__GNUC__)
198 va_start(variable);
199 #else
200 va_start(variable, res_class);
201 #endif
202 XvaGetArgs( variable, args );
203 va_end(variable);
204
205 if (!g_dlmodule)
206 {
207 g_dlmodule = dlopen(XIIIMP_LIB, RTLD_LAZY);
208 if(!g_dlmodule)
209 {
210 g_dlmodule = dlopen(XIIIMP_PATH, RTLD_LAZY);
211 if (!g_dlmodule)
212 goto legacy_XIM;
213 }
214 g_open_im = (OpenFunction)(long)dlsym(g_dlmodule, "__XOpenIM");
215 if (!g_open_im)
216 goto legacy_XIM;
217
218 xim = (*g_open_im)(display, (XrmDatabase)rdb,
219 (char*)res_name, (char *)res_class, (XIMArg*)args);
220 }
221 else
222 {
223 goto legacy_XIM;
224 }
225 }
226
227 // in #if to prevent warning "warning: label 'legacy_XIM' defined but not used"
228 legacy_XIM:
229
230 if (!xim)
231 xim = XOpenIM(display, rdb, res_name, res_class);
232
233 return xim;
234 }
235
236 /*
237 * Close the connection to the input manager, and free the XIM structure
238 */
239
XvaCloseIM(XIM)240 Status XvaCloseIM(XIM)
241 {
242 Status s = False;
243
244 if (!g_dlmodule)
245 {
246 /* assuming one XvaOpenIM call */
247 dlclose(g_dlmodule);
248 g_dlmodule = (void*)0;
249 g_open_im = (OpenFunction)NULL;
250 s = True;
251 }
252 return (s);
253 }
254
255
256
257