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