/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" struct XIMArg { char *name; char *value; }; #if defined(SOLARIS) && !defined(__GNUC__) #include #else #include #endif #include #include #include #include #include #include "unx/XIM.h" #define XIIIMP_LIB "xiiimp.so.2" #ifdef SOLARIS #define XIIIMP_PATH "/usr/openwin/lib/locale/common/" XIIIMP_LIB #else /* Linux */ #define XIIIMP_PATH "/usr/lib/im/" XIIIMP_LIB #endif extern "C" { typedef XIM (*OpenFunction)(Display*, XrmDatabase, char*, char*, XIMArg*); } /* global variables */ static void *g_dlmodule = 0; static OpenFunction g_open_im = (OpenFunction)NULL; /* utility function to transform vararg list into an array of XIMArg */ int XvaCountArgs( XIMArg *pInArgs ) { int nArgs = 0; char *pName, *pValue; while ( (pName = pInArgs->name) != NULL ) { pValue = pInArgs->value; if ( strcmp(pName, XNVaNestedList) == 0 ) { nArgs += XvaCountArgs( (XIMArg*)pValue ); } else { nArgs += 1; } pInArgs++; } return nArgs; } int XvaCountArgs( va_list pInArgs ) { int nArgs = 0; char *pName, *pValue; while ( (pName = va_arg(pInArgs, char*)) != NULL) { pValue = va_arg(pInArgs, char*); if ( strcmp(pName, XNVaNestedList) == 0 ) { nArgs += XvaCountArgs( (XIMArg*)pValue ); } else { nArgs += 1; } } return nArgs; } XIMArg* XvaGetArgs( XIMArg *pInArgs, XIMArg *pOutArgs ) { char *pName, *pValue; while ( (pName = pInArgs->name) != NULL ) { pValue = pInArgs->value; if ( strcmp(pName, XNVaNestedList) == 0 ) { pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs ); } else { pOutArgs->name = pName; pOutArgs->value = pValue; pOutArgs++; } pInArgs++; } return pOutArgs; } void XvaGetArgs( va_list pInArgs, XIMArg *pOutArgs ) { char *pName, *pValue; while ((pName = va_arg(pInArgs, char*)) != NULL) { pValue = va_arg(pInArgs, char*); if ( strcmp(pName, XNVaNestedList) == 0 ) { pOutArgs = XvaGetArgs( (XIMArg*)pValue, pOutArgs ); } else { pOutArgs->name = pName; pOutArgs->value = pValue; pOutArgs++; } } pOutArgs->name = NULL; pOutArgs->value = NULL; } /* Puplic functions */ #ifdef __cplusplus extern "C" #endif XIM XvaOpenIM(Display *display, XrmDatabase rdb, char *res_name, char *res_class, ...) { XIM xim = (XIM)0; va_list variable; int total_count = 0; /* * so count the stuff dangling here */ #if defined(SOLARIS) && !defined(__GNUC__) va_start(variable); #else va_start(variable, res_class); #endif total_count = XvaCountArgs(variable); va_end(variable); if (total_count > 0) { /* call a new open IM method */ XIMArg* args = (XIMArg*)alloca( (total_count + 1) * sizeof(XIMArg) ); /* * now package it up so we can set it along */ #if defined(SOLARIS) && !defined(__GNUC__) va_start(variable); #else va_start(variable, res_class); #endif XvaGetArgs( variable, args ); va_end(variable); if (!g_dlmodule) { g_dlmodule = dlopen(XIIIMP_LIB, RTLD_LAZY); if(!g_dlmodule) { g_dlmodule = dlopen(XIIIMP_PATH, RTLD_LAZY); if (!g_dlmodule) goto legacy_XIM; } g_open_im = (OpenFunction)(long)dlsym(g_dlmodule, "__XOpenIM"); if (!g_open_im) goto legacy_XIM; xim = (*g_open_im)(display, (XrmDatabase)rdb, (char*)res_name, (char *)res_class, (XIMArg*)args); } else { goto legacy_XIM; } } // in #if to prevent warning "warning: label 'legacy_XIM' defined but not used" legacy_XIM: if (!xim) xim = XOpenIM(display, rdb, res_name, res_class); return xim; } /* * Close the connection to the input manager, and free the XIM structure */ Status XvaCloseIM(XIM) { Status s = False; if (!g_dlmodule) { /* assuming one XvaOpenIM call */ dlclose(g_dlmodule); g_dlmodule = (void*)0; g_open_im = (OpenFunction)NULL; s = True; } return (s); }