xref: /trunk/main/vcl/unx/generic/app/i18n_wrp.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 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