Back to index

im-sdk  12.3.91
iiimpDL.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 #ifdef HAVE_CONFIG_H
00043 #include <config.h>
00044 #endif
00045 
00046 #include <unistd.h>
00047 #include <dlfcn.h>
00048 #include "iiimpDL.h"
00049 #include <sys/types.h>
00050 #include <dirent.h>
00051 #include "genutil.h"
00052 #include "Xlcint.h"
00053 
00054 #ifdef _LP64
00055 #if defined(__sparcv9)
00056 #define       _MACH64_NAME         "sparcv9"
00057 #define       _MACH64_NAME_LEN     (sizeof (_MACH64_NAME) - 1)
00058 #endif /* defined(__sparcv9) */
00059 #endif /* _LP64 */
00060 
00061 static XIMStyles *GetInputStyles(char*, void *);
00062 static void* GetProc(void*, const char*);
00063 
00064 static char*
00065 lc_path(const char *dl_name, const char *lc_dir) {
00066   char *path;
00067   size_t len;
00068 
00069 #ifdef _MACH64_NAME
00070   len = (lc_dir ? strlen(lc_dir) : 0 ) +
00071     (dl_name ? strlen(dl_name) : 0) + _MACH64_NAME_LEN + 10;
00072   path = Xmalloc(len + 1);
00073 
00074   strcpy(path, lc_dir); strcat(path, "/");
00075   strcat(path, _MACH64_NAME); strcat(path, "/");
00076   strcat(path, dl_name); strcat(path, ".so");
00077 #else
00078   len = (lc_dir ? strlen(lc_dir) : 0 ) +
00079     (dl_name ? strlen(dl_name) : 0) + 10;
00080   path = Xmalloc(len + 1);
00081 
00082   strcpy(path, lc_dir); strcat(path, "/");
00083   strcat(path, dl_name); strcat(path, ".so");
00084 #endif
00085   return path;
00086 }
00087 
00088 static XIMStyles*
00089 GetInputStyles(char *lc_name, void *module) {
00090   XIMStyles* (*get_styles)() = (XIMStyles*(*)())NULL;
00091   XIMStyles *values = (XIMStyles*)NULL;
00092 
00093   get_styles = (XIMStyles*(*)())dlsym(module, "GetInputStyles");
00094 
00095   values = (*get_styles)(lc_name);
00096 
00097   return values;
00098 }
00099 
00100 static void*
00101 GetProc(void *module, const char *name) {
00102   void *proc;
00103 
00104   proc = (void*)dlsym(module, name);
00105   return proc;
00106 }
00107 
00108 #ifndef XLOCALEDIR
00109 #define XLOCALEDIR IIIMLIBDIR "/modules"
00110 #endif
00111 
00112 static const char*
00113 has_so_suffix (const char *str)
00114 {
00115   int str_len;
00116   int suffix_len;
00117   
00118   if (str == NULL)
00119     return NULL;
00120 
00121   str_len = strlen (str);
00122   suffix_len = strlen (".so");
00123 
00124   if (str_len < suffix_len)
00125     return False;
00126 
00127   return ((strcmp (str + str_len - suffix_len, ".so") == 0)? str : 0);
00128          
00129 }
00130 
00131 /* Public functions */
00132 XIMDLRec*
00133 OpenDynamicObject(XLCd lcd) {
00134   void *module = NULL;
00135   XIMDLRec *dl_object = (XIMDLRec*)NULL;
00136   DIR *dir = NULL;
00137   struct dirent *entry;
00138   char *lc_name = lcd->core->name;
00139   char *filename;
00140   const size_t xlclocaledir_len = strlen (XLOCALEDIR);
00141 
00142   dir = opendir (XLOCALEDIR);
00143   if (dir == NULL)
00144     return NULL;
00145 
00146   while ((entry = readdir (dir)))
00147     {
00148       while (entry
00149             && (0 == strcmp (entry->d_name, ".") ||
00150                0 == strcmp (entry->d_name, "..")))
00151        entry = readdir (dir);
00152       if (entry && (filename = has_so_suffix (entry->d_name)) != NULL)
00153        {
00154          size_t len = xlclocaledir_len + strlen (filename) + 2;
00155          char *path = Xmalloc (len);
00156          strcpy (path, XLOCALEDIR);
00157          strcat (path, "/");
00158          strcat (path, filename);
00159          module = dlopen((char*)path, RTLD_LAZY);
00160          XFree (path);
00161          if (module)
00162            {
00163              dl_object = (XIMDLRec*)Xmalloc(sizeof(XIMDLRec));
00164              dl_object->dl_module = module;
00165              dl_object->styles = GetInputStyles(lc_name, module);
00166              dl_object->change_status =
00167               (ChangeStatusProc)GetProc(module,
00168                                      "ChangeStatus");
00169              dl_object->change_preedit =
00170               (ChangePreeditProc)GetProc(module,
00171                                       "ChangePreedit");
00172              dl_object->change_lookup =
00173               (ChangeLookupProc)GetProc(module,
00174                                      "ChangeLookup");
00175              dl_object->register_forwardevent =
00176               (RegisterForwardEventProc)GetProc(module,
00177                                             "RegisterForwardEvent");
00178            }
00179        }
00180       if (dl_object)
00181        break;
00182     }
00183 
00184   if (dir)
00185     closedir(dir);
00186 
00187   return dl_object;
00188 }
00189 
00190 void
00191 CloseDynamicObject(XIMDLRec *dl_object) {
00192   if (dl_object->styles) Xfree(dl_object->styles);
00193   dlclose(dl_object->dl_module);
00194   return;
00195 }