xref: /aoo42x/main/vcl/unx/generic/app/i18n_wrp.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 struct XIMArg
32 {
33     char *name;
34     char *value;
35 };
36 
37 #if defined(SOLARIS) && !defined(__GNUC__)
38 #include <varargs.h>
39 #else
40 #include <stdarg.h>
41 #endif
42 #include <sal/alloca.h>
43 
44 #include <string.h>
45 #include <dlfcn.h>
46 
47 #include <X11/Xlib.h>
48 #include <X11/Xlibint.h>
49 #include "unx/XIM.h"
50 
51 #define XIIIMP_LIB		 "xiiimp.so.2"
52 
53 #ifdef SOLARIS
54 #define XIIIMP_PATH     "/usr/openwin/lib/locale/common/" XIIIMP_LIB
55 #else /* Linux */
56 #define XIIIMP_PATH     "/usr/lib/im/" XIIIMP_LIB
57 #endif
58 
59 extern "C" {
60 typedef XIM (*OpenFunction)(Display*, XrmDatabase, char*, char*, XIMArg*);
61 }
62 
63 /* global variables */
64 static void *g_dlmodule = 0;
65 static OpenFunction g_open_im = (OpenFunction)NULL;
66 
67 /* utility function to transform vararg list into an array of XIMArg */
68 
69 int
70 XvaCountArgs( XIMArg *pInArgs )
71 {
72 	int nArgs = 0;
73 	char *pName, *pValue;
74 
75 	while ( (pName = pInArgs->name) != NULL )
76 	{
77 		pValue = pInArgs->value;
78 
79 		if ( strcmp(pName, XNVaNestedList) == 0 )
80 		{
81 			nArgs += XvaCountArgs( (XIMArg*)pValue );
82 		}
83 		else
84 		{
85 			nArgs += 1;
86 		}
87 		pInArgs++;
88 	}
89 
90 	return nArgs;
91 }
92 
93 int
94 XvaCountArgs( va_list pInArgs )
95 {
96 	int nArgs = 0;
97 	char *pName, *pValue;
98 
99 	while ( (pName = va_arg(pInArgs, char*)) != NULL)
100     {
101 		pValue = va_arg(pInArgs, char*);
102 
103 		if ( strcmp(pName, XNVaNestedList) == 0 )
104 		{
105 			nArgs += XvaCountArgs( (XIMArg*)pValue );
106 		}
107 		else
108 		{
109 			nArgs += 1;
110 		}
111 	}
112 
113 	return nArgs;
114 }
115 
116 XIMArg*
117 XvaGetArgs( XIMArg *pInArgs, XIMArg *pOutArgs )
118 {
119 	char *pName, *pValue;
120 
121 	while ( (pName = pInArgs->name) != NULL )
122 	{
123 		pValue = pInArgs->value;
124 
125 		if ( strcmp(pName, XNVaNestedList) == 0 )
126 		{
127 			pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs );
128 		}
129 		else
130 		{
131 			pOutArgs->name  = pName;
132 			pOutArgs->value = pValue;
133 			pOutArgs++;
134 		}
135 		pInArgs++;
136 	}
137 
138 	return pOutArgs;
139 }
140 
141 void
142 XvaGetArgs( va_list pInArgs, XIMArg *pOutArgs )
143 {
144 	char *pName, *pValue;
145 
146 	while ((pName = va_arg(pInArgs, char*)) != NULL)
147     {
148 		pValue = va_arg(pInArgs, char*);
149 
150 		if ( strcmp(pName, XNVaNestedList) == 0 )
151 		{
152 			pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs );
153 		}
154 		else
155 		{
156 			pOutArgs->name  = pName;
157 			pOutArgs->value = pValue;
158 			pOutArgs++;
159 		}
160 	}
161 
162 	pOutArgs->name  = NULL;
163 	pOutArgs->value = NULL;
164 }
165 
166 
167 /* Puplic functions */
168 
169 #ifdef __cplusplus
170 extern "C"
171 #endif
172 XIM
173 XvaOpenIM(Display *display, XrmDatabase rdb,
174 		char *res_name, char *res_class, ...)
175 {
176   	XIM xim = (XIM)0;
177   	va_list variable;
178   	int total_count = 0;
179 
180   	/*
181    	 * so count the stuff dangling here
182      */
183 
184 #if defined(SOLARIS) && !defined(__GNUC__)
185   	va_start(variable);
186 #else
187 	va_start(variable, res_class);
188 #endif
189   	total_count = XvaCountArgs(variable);
190   	va_end(variable);
191 
192   	if (total_count > 0)
193 	{
194 		/* call a new open IM method */
195 
196     	XIMArg* args = (XIMArg*)alloca( (total_count + 1) * sizeof(XIMArg) );
197 
198     	/*
199      	 * now package it up so we can set it along
200      	 */
201 #if defined(SOLARIS) && !defined(__GNUC__)
202     	va_start(variable);
203 #else
204     	va_start(variable, res_class);
205 #endif
206 		XvaGetArgs( variable, args );
207     	va_end(variable);
208 
209     	if (!g_dlmodule)
210 		{
211             g_dlmodule = dlopen(XIIIMP_LIB, RTLD_LAZY);
212             if(!g_dlmodule)
213             {
214                 g_dlmodule = dlopen(XIIIMP_PATH, RTLD_LAZY);
215                 if (!g_dlmodule)
216                     goto legacy_XIM;
217             }
218       		g_open_im = (OpenFunction)(long)dlsym(g_dlmodule, "__XOpenIM");
219       		if (!g_open_im)
220 				goto legacy_XIM;
221 
222       		xim = (*g_open_im)(display, (XrmDatabase)rdb,
223 				  (char*)res_name, (char *)res_class, (XIMArg*)args);
224     	}
225 		else
226 		{
227       		goto legacy_XIM;
228     	}
229   	}
230 
231 // in #if to prevent warning "warning: label 'legacy_XIM' defined but not used"
232  	legacy_XIM:
233 
234 	if (!xim)
235     	xim = XOpenIM(display, rdb, res_name, res_class);
236 
237 	return xim;
238 }
239 
240 /*
241  * Close the connection to the input manager, and free the XIM structure
242  */
243 
244 Status XvaCloseIM(XIM)
245 {
246   	Status s = False;
247 
248 	if (!g_dlmodule)
249 	{
250 		/* assuming one XvaOpenIM call */
251     	dlclose(g_dlmodule);
252    	 	g_dlmodule = (void*)0;
253     	g_open_im = (OpenFunction)NULL;
254         s = True;
255   	}
256 	return (s);
257 }
258 
259 
260 
261