1*c82f2877SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*c82f2877SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*c82f2877SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*c82f2877SAndrew Rist * distributed with this work for additional information
6*c82f2877SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*c82f2877SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*c82f2877SAndrew Rist * "License"); you may not use this file except in compliance
9*c82f2877SAndrew Rist * with the License. You may obtain a copy of the License at
10*c82f2877SAndrew Rist *
11*c82f2877SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*c82f2877SAndrew Rist *
13*c82f2877SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*c82f2877SAndrew Rist * software distributed under the License is distributed on an
15*c82f2877SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*c82f2877SAndrew Rist * KIND, either express or implied. See the License for the
17*c82f2877SAndrew Rist * specific language governing permissions and limitations
18*c82f2877SAndrew Rist * under the License.
19*c82f2877SAndrew Rist *
20*c82f2877SAndrew Rist *************************************************************/
21*c82f2877SAndrew Rist
22*c82f2877SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir struct XIMArg
28cdf0e10cSrcweir {
29cdf0e10cSrcweir char *name;
30cdf0e10cSrcweir char *value;
31cdf0e10cSrcweir };
32cdf0e10cSrcweir
33cdf0e10cSrcweir #if defined(SOLARIS) && !defined(__GNUC__)
34cdf0e10cSrcweir #include <varargs.h>
35cdf0e10cSrcweir #else
36cdf0e10cSrcweir #include <stdarg.h>
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir #include <sal/alloca.h>
39cdf0e10cSrcweir
40cdf0e10cSrcweir #include <string.h>
41cdf0e10cSrcweir #include <dlfcn.h>
42cdf0e10cSrcweir
43cdf0e10cSrcweir #include <X11/Xlib.h>
44cdf0e10cSrcweir #include <X11/Xlibint.h>
45cdf0e10cSrcweir #include "unx/XIM.h"
46cdf0e10cSrcweir
47cdf0e10cSrcweir #define XIIIMP_LIB "xiiimp.so.2"
48cdf0e10cSrcweir
49cdf0e10cSrcweir #ifdef SOLARIS
50cdf0e10cSrcweir #define XIIIMP_PATH "/usr/openwin/lib/locale/common/" XIIIMP_LIB
51cdf0e10cSrcweir #else /* Linux */
52cdf0e10cSrcweir #define XIIIMP_PATH "/usr/lib/im/" XIIIMP_LIB
53cdf0e10cSrcweir #endif
54cdf0e10cSrcweir
55cdf0e10cSrcweir extern "C" {
56cdf0e10cSrcweir typedef XIM (*OpenFunction)(Display*, XrmDatabase, char*, char*, XIMArg*);
57cdf0e10cSrcweir }
58cdf0e10cSrcweir
59cdf0e10cSrcweir /* global variables */
60cdf0e10cSrcweir static void *g_dlmodule = 0;
61cdf0e10cSrcweir static OpenFunction g_open_im = (OpenFunction)NULL;
62cdf0e10cSrcweir
63cdf0e10cSrcweir /* utility function to transform vararg list into an array of XIMArg */
64cdf0e10cSrcweir
65cdf0e10cSrcweir int
XvaCountArgs(XIMArg * pInArgs)66cdf0e10cSrcweir XvaCountArgs( XIMArg *pInArgs )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir int nArgs = 0;
69cdf0e10cSrcweir char *pName, *pValue;
70cdf0e10cSrcweir
71cdf0e10cSrcweir while ( (pName = pInArgs->name) != NULL )
72cdf0e10cSrcweir {
73cdf0e10cSrcweir pValue = pInArgs->value;
74cdf0e10cSrcweir
75cdf0e10cSrcweir if ( strcmp(pName, XNVaNestedList) == 0 )
76cdf0e10cSrcweir {
77cdf0e10cSrcweir nArgs += XvaCountArgs( (XIMArg*)pValue );
78cdf0e10cSrcweir }
79cdf0e10cSrcweir else
80cdf0e10cSrcweir {
81cdf0e10cSrcweir nArgs += 1;
82cdf0e10cSrcweir }
83cdf0e10cSrcweir pInArgs++;
84cdf0e10cSrcweir }
85cdf0e10cSrcweir
86cdf0e10cSrcweir return nArgs;
87cdf0e10cSrcweir }
88cdf0e10cSrcweir
89cdf0e10cSrcweir int
XvaCountArgs(va_list pInArgs)90cdf0e10cSrcweir XvaCountArgs( va_list pInArgs )
91cdf0e10cSrcweir {
92cdf0e10cSrcweir int nArgs = 0;
93cdf0e10cSrcweir char *pName, *pValue;
94cdf0e10cSrcweir
95cdf0e10cSrcweir while ( (pName = va_arg(pInArgs, char*)) != NULL)
96cdf0e10cSrcweir {
97cdf0e10cSrcweir pValue = va_arg(pInArgs, char*);
98cdf0e10cSrcweir
99cdf0e10cSrcweir if ( strcmp(pName, XNVaNestedList) == 0 )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir nArgs += XvaCountArgs( (XIMArg*)pValue );
102cdf0e10cSrcweir }
103cdf0e10cSrcweir else
104cdf0e10cSrcweir {
105cdf0e10cSrcweir nArgs += 1;
106cdf0e10cSrcweir }
107cdf0e10cSrcweir }
108cdf0e10cSrcweir
109cdf0e10cSrcweir return nArgs;
110cdf0e10cSrcweir }
111cdf0e10cSrcweir
112cdf0e10cSrcweir XIMArg*
XvaGetArgs(XIMArg * pInArgs,XIMArg * pOutArgs)113cdf0e10cSrcweir XvaGetArgs( XIMArg *pInArgs, XIMArg *pOutArgs )
114cdf0e10cSrcweir {
115cdf0e10cSrcweir char *pName, *pValue;
116cdf0e10cSrcweir
117cdf0e10cSrcweir while ( (pName = pInArgs->name) != NULL )
118cdf0e10cSrcweir {
119cdf0e10cSrcweir pValue = pInArgs->value;
120cdf0e10cSrcweir
121cdf0e10cSrcweir if ( strcmp(pName, XNVaNestedList) == 0 )
122cdf0e10cSrcweir {
123cdf0e10cSrcweir pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs );
124cdf0e10cSrcweir }
125cdf0e10cSrcweir else
126cdf0e10cSrcweir {
127cdf0e10cSrcweir pOutArgs->name = pName;
128cdf0e10cSrcweir pOutArgs->value = pValue;
129cdf0e10cSrcweir pOutArgs++;
130cdf0e10cSrcweir }
131cdf0e10cSrcweir pInArgs++;
132cdf0e10cSrcweir }
133cdf0e10cSrcweir
134cdf0e10cSrcweir return pOutArgs;
135cdf0e10cSrcweir }
136cdf0e10cSrcweir
137cdf0e10cSrcweir void
XvaGetArgs(va_list pInArgs,XIMArg * pOutArgs)138cdf0e10cSrcweir XvaGetArgs( va_list pInArgs, XIMArg *pOutArgs )
139cdf0e10cSrcweir {
140cdf0e10cSrcweir char *pName, *pValue;
141cdf0e10cSrcweir
142cdf0e10cSrcweir while ((pName = va_arg(pInArgs, char*)) != NULL)
143cdf0e10cSrcweir {
144cdf0e10cSrcweir pValue = va_arg(pInArgs, char*);
145cdf0e10cSrcweir
146cdf0e10cSrcweir if ( strcmp(pName, XNVaNestedList) == 0 )
147cdf0e10cSrcweir {
148cdf0e10cSrcweir pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs );
149cdf0e10cSrcweir }
150cdf0e10cSrcweir else
151cdf0e10cSrcweir {
152cdf0e10cSrcweir pOutArgs->name = pName;
153cdf0e10cSrcweir pOutArgs->value = pValue;
154cdf0e10cSrcweir pOutArgs++;
155cdf0e10cSrcweir }
156cdf0e10cSrcweir }
157cdf0e10cSrcweir
158cdf0e10cSrcweir pOutArgs->name = NULL;
159cdf0e10cSrcweir pOutArgs->value = NULL;
160cdf0e10cSrcweir }
161cdf0e10cSrcweir
162cdf0e10cSrcweir
163cdf0e10cSrcweir /* Puplic functions */
164cdf0e10cSrcweir
165cdf0e10cSrcweir #ifdef __cplusplus
166cdf0e10cSrcweir extern "C"
167cdf0e10cSrcweir #endif
168cdf0e10cSrcweir XIM
XvaOpenIM(Display * display,XrmDatabase rdb,char * res_name,char * res_class,...)169cdf0e10cSrcweir XvaOpenIM(Display *display, XrmDatabase rdb,
170cdf0e10cSrcweir char *res_name, char *res_class, ...)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir XIM xim = (XIM)0;
173cdf0e10cSrcweir va_list variable;
174cdf0e10cSrcweir int total_count = 0;
175cdf0e10cSrcweir
176cdf0e10cSrcweir /*
177cdf0e10cSrcweir * so count the stuff dangling here
178cdf0e10cSrcweir */
179cdf0e10cSrcweir
180cdf0e10cSrcweir #if defined(SOLARIS) && !defined(__GNUC__)
181cdf0e10cSrcweir va_start(variable);
182cdf0e10cSrcweir #else
183cdf0e10cSrcweir va_start(variable, res_class);
184cdf0e10cSrcweir #endif
185cdf0e10cSrcweir total_count = XvaCountArgs(variable);
186cdf0e10cSrcweir va_end(variable);
187cdf0e10cSrcweir
188cdf0e10cSrcweir if (total_count > 0)
189cdf0e10cSrcweir {
190cdf0e10cSrcweir /* call a new open IM method */
191cdf0e10cSrcweir
192cdf0e10cSrcweir XIMArg* args = (XIMArg*)alloca( (total_count + 1) * sizeof(XIMArg) );
193cdf0e10cSrcweir
194cdf0e10cSrcweir /*
195cdf0e10cSrcweir * now package it up so we can set it along
196cdf0e10cSrcweir */
197cdf0e10cSrcweir #if defined(SOLARIS) && !defined(__GNUC__)
198cdf0e10cSrcweir va_start(variable);
199cdf0e10cSrcweir #else
200cdf0e10cSrcweir va_start(variable, res_class);
201cdf0e10cSrcweir #endif
202cdf0e10cSrcweir XvaGetArgs( variable, args );
203cdf0e10cSrcweir va_end(variable);
204cdf0e10cSrcweir
205cdf0e10cSrcweir if (!g_dlmodule)
206cdf0e10cSrcweir {
207cdf0e10cSrcweir g_dlmodule = dlopen(XIIIMP_LIB, RTLD_LAZY);
208cdf0e10cSrcweir if(!g_dlmodule)
209cdf0e10cSrcweir {
210cdf0e10cSrcweir g_dlmodule = dlopen(XIIIMP_PATH, RTLD_LAZY);
211cdf0e10cSrcweir if (!g_dlmodule)
212cdf0e10cSrcweir goto legacy_XIM;
213cdf0e10cSrcweir }
214cdf0e10cSrcweir g_open_im = (OpenFunction)(long)dlsym(g_dlmodule, "__XOpenIM");
215cdf0e10cSrcweir if (!g_open_im)
216cdf0e10cSrcweir goto legacy_XIM;
217cdf0e10cSrcweir
218cdf0e10cSrcweir xim = (*g_open_im)(display, (XrmDatabase)rdb,
219cdf0e10cSrcweir (char*)res_name, (char *)res_class, (XIMArg*)args);
220cdf0e10cSrcweir }
221cdf0e10cSrcweir else
222cdf0e10cSrcweir {
223cdf0e10cSrcweir goto legacy_XIM;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir // in #if to prevent warning "warning: label 'legacy_XIM' defined but not used"
228cdf0e10cSrcweir legacy_XIM:
229cdf0e10cSrcweir
230cdf0e10cSrcweir if (!xim)
231cdf0e10cSrcweir xim = XOpenIM(display, rdb, res_name, res_class);
232cdf0e10cSrcweir
233cdf0e10cSrcweir return xim;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir
236cdf0e10cSrcweir /*
237cdf0e10cSrcweir * Close the connection to the input manager, and free the XIM structure
238cdf0e10cSrcweir */
239cdf0e10cSrcweir
XvaCloseIM(XIM)240cdf0e10cSrcweir Status XvaCloseIM(XIM)
241cdf0e10cSrcweir {
242cdf0e10cSrcweir Status s = False;
243cdf0e10cSrcweir
244cdf0e10cSrcweir if (!g_dlmodule)
245cdf0e10cSrcweir {
246cdf0e10cSrcweir /* assuming one XvaOpenIM call */
247cdf0e10cSrcweir dlclose(g_dlmodule);
248cdf0e10cSrcweir g_dlmodule = (void*)0;
249cdf0e10cSrcweir g_open_im = (OpenFunction)NULL;
250cdf0e10cSrcweir s = True;
251cdf0e10cSrcweir }
252cdf0e10cSrcweir return (s);
253cdf0e10cSrcweir }
254cdf0e10cSrcweir
255cdf0e10cSrcweir
256cdf0e10cSrcweir
257