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 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 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* 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 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 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 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