aboutsummaryrefslogtreecommitdiffstats
path: root/x11
diff options
context:
space:
mode:
authorkiri <kiri@FreeBSD.org>2002-12-24 09:18:49 +0800
committerkiri <kiri@FreeBSD.org>2002-12-24 09:18:49 +0800
commitddfa19f40000e4bf0f721f2df6130ead894a146f (patch)
tree4c2725a762865dfa8f78cbe1e42a7bbf329a5f1c /x11
parentfec3a9b29df2023f2f87c97b80c20de030b38c9e (diff)
downloadfreebsd-ports-gnome-ddfa19f40000e4bf0f721f2df6130ead894a146f.tar.gz
freebsd-ports-gnome-ddfa19f40000e4bf0f721f2df6130ead894a146f.tar.zst
freebsd-ports-gnome-ddfa19f40000e4bf0f721f2df6130ead894a146f.zip
Add XIM patch to files/patch-XlcDL.c
Diffstat (limited to 'x11')
-rw-r--r--x11/XFree86-4-libraries/files/patch-XlcDL.c433
1 files changed, 433 insertions, 0 deletions
diff --git a/x11/XFree86-4-libraries/files/patch-XlcDL.c b/x11/XFree86-4-libraries/files/patch-XlcDL.c
index 5b1d42898ac5..4a13cc704955 100644
--- a/x11/XFree86-4-libraries/files/patch-XlcDL.c
+++ b/x11/XFree86-4-libraries/files/patch-XlcDL.c
@@ -13,3 +13,436 @@
#endif /* defined(__sparcv9) */
#endif /* _LP64 */
+@@ -83,6 +83,7 @@
+ char *im_register;
+ char *im_unregister;
+ int dl_release;
++ unsigned int refcount;
+ #if defined(hpux)
+ shl_t dl_module;
+ #else
+@@ -214,6 +215,7 @@
+ xi18n_objects_list[lc_count].open = strdup(args[2]);
+ xi18n_objects_list[lc_count].dl_release = XI18N_DLREL;
+ xi18n_objects_list[lc_count].locale_name = strdup(lc_name);
++ xi18n_objects_list[lc_count].refcount = 0;
+ xi18n_objects_list[lc_count].dl_module = (void*)NULL;
+ if (n == 5) {
+ xi18n_objects_list[lc_count].im_register = strdup(args[3]);
+@@ -290,6 +292,85 @@
+ return path;
+ }
+
++/* We reference count dlopen() and dlclose() of modules; unfortunately,
++ * since XCloseIM, XCloseOM, XlcClose aren't wrapped, but directly
++ * call the close method of the object, we leak a reference count every
++ * time we open then close a module. Fixing this would require
++ * either creating proxy objects or hooks for close_im/close_om
++ * in XLCd
++ */
++static Bool
++open_object (object, lc_dir)
++ XI18NObjectsList object;
++ char *lc_dir;
++{
++ char *path;
++
++ if (object->refcount == 0) {
++ path = __lc_path(object->dl_name, lc_dir);
++#if defined(hpux)
++ object->dl_module = shl_load(path, BIND_DEFERRED, 0L);
++#else
++ object->dl_module = dlopen(path, RTLD_LAZY);
++#endif
++ Xfree(path);
++
++ if (!object->dl_module)
++ return False;
++ }
++
++ object->refcount++;
++ return True;
++}
++
++static void *
++fetch_symbol (object, symbol)
++ XI18NObjectsList object;
++ char *symbol;
++{
++ void *result = NULL;
++#if defined(hpux)
++ int getsyms_cnt, i;
++ struct shl_symbol *symbols;
++#endif
++
++#if defined(hpux)
++ getsyms_cnt = shl_getsymbols(object->dl_module, TYPE_PROCEDURE,
++ EXPORT_SYMBOLS, malloc, &symbols);
++
++ for(i=0; i<getsyms_cnt; i++) {
++ if(!strcmp(symbols[i].name, symbol)) {
++ result = symbols[i].value;
++ break;
++ }
++ }
++
++ if(getsyms_cnt > 0) {
++ free(symbols);
++ }
++#else
++ result = (XLCd(*)())try_both_dlsym(object->dl_module, symbol);
++#endif
++
++ return result;
++}
++
++static void
++close_object (object)
++ XI18NObjectsList object;
++{
++ object->refcount--;
++ if (object->refcount == 0)
++ {
++#if defined(hpux)
++ shl_unload(object->dl_module);
++#else
++ dlclose(object->dl_module);
++#endif
++ object->dl_module = NULL;
++ }
++}
++
+ XLCd
+ #if NeedFunctionPrototypes
+ _XlcDynamicLoad(const char *lc_name)
+@@ -300,14 +381,9 @@
+ {
+ XLCd lcd = (XLCd)NULL;
+ XLCd (*lc_loader)() = (XLCd(*)())NULL;
+- char *path;
+ int count;
+ XI18NObjectsList objects_list;
+ char lc_dir[BUFSIZE];
+-#if defined(hpux)
+- int getsyms_cnt, i;
+- struct shl_symbol *symbols;
+-#endif
+
+ if (lc_name == NULL) return (XLCd)NULL;
+
+@@ -321,47 +397,17 @@
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XLC_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+- if (!objects_list->dl_module) {
+- path = __lc_path(objects_list->dl_name, lc_dir);
+- if (!path)
+- continue;
+-#if defined(hpux)
+- objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
+-#else
+- objects_list->dl_module = dlopen(path, RTLD_LAZY);
+-#endif
+- Xfree(path);
+- if (!objects_list->dl_module) continue;
+- }
+-#if defined(hpux)
+- getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
+- EXPORT_SYMBOLS, malloc, &symbols);
+-
+- for(i=0; i<getsyms_cnt; i++) {
+- if(!strcmp(symbols[i].name, objects_list->open)) {
+- lc_loader = symbols[i].value;
+- break;
+- }
+- }
++ if (!open_object (objects_list, lc_dir))
++ continue;
+
+- if(getsyms_cnt > 0) {
+- free(symbols);
+- }
+-#else
+- lc_loader = (XLCd(*)())try_both_dlsym(objects_list->dl_module,
+- objects_list->open);
+-#endif
++ lc_loader = (XLCd(*)())fetch_symbol (objects_list, objects_list->open);
+ if (!lc_loader) continue;
+ lcd = (*lc_loader)(lc_name);
+ if (lcd != (XLCd)NULL) {
+ break;
+ }
+-#if defined(hpux)
+- shl_unload(objects_list->dl_module);
+-#else
+- dlclose(objects_list->dl_module);
+-#endif
+- objects_list->dl_module = NULL;
++
++ close_object (objects_list);
+ }
+ return (XLCd)lcd;
+ }
+@@ -379,16 +425,11 @@
+ #endif
+ {
+ XIM im = (XIM)NULL;
+- char *path;
+ char lc_dir[BUFSIZE];
+ char *lc_name;
+ XIM (*im_openIM)() = (XIM(*)())NULL;
+ int count;
+ XI18NObjectsList objects_list = xi18n_objects_list;
+-#if defined(hpux)
+- int getsyms_cnt, i;
+- struct shl_symbol *symbols;
+-#endif
+
+ lc_name = lcd->core->name;
+
+@@ -398,48 +439,18 @@
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XIM_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+- if (!objects_list->dl_module) {
+- path = __lc_path(objects_list->dl_name, lc_dir);
+- if (!path)
+- continue;
+-#if defined(hpux)
+- objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
+-#else
+- objects_list->dl_module = dlopen(path, RTLD_LAZY);
+-#endif
+- Xfree(path);
+- if (!objects_list->dl_module) continue;
+- }
+-#if defined(hpux)
+- getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
+- EXPORT_SYMBOLS, malloc, &symbols);
+
+- for(i=0; i<getsyms_cnt; i++) {
+- if(!strcmp(symbols[i].name, objects_list->open)) {
+- im_openIM = symbols[i].value;
+- break;
+- }
+- }
++ if (!open_object (objects_list, lc_dir))
++ continue;
+
+- if(getsyms_cnt > 0) {
+- free(symbols);
+- }
+-#else
+- im_openIM = (XIM(*)())try_both_dlsym(objects_list->dl_module,
+- objects_list->open);
++ im_openIM = (XIM(*)())fetch_symbol(objects_list, objects_list->open);
+ if (!im_openIM) continue;
+-#endif
+ im = (*im_openIM)(lcd, display, rdb, res_name, res_class);
+ if (im != (XIM)NULL) {
+ break;
+ }
+- im_openIM = 0;
+-#if defined(hpux)
+- shl_unload(objects_list->dl_module);
+-#else
+- dlclose(objects_list->dl_module);
+-#endif
+- objects_list->dl_module = NULL;
++
++ close_object (objects_list);
+ }
+ return (XIM)im;
+ }
+@@ -455,7 +466,6 @@
+ XIMProc callback;
+ XPointer *client_data;
+ {
+- char *path;
+ char lc_dir[BUFSIZE];
+ char *lc_name;
+ Bool (*im_registerIM)() = (Bool(*)())NULL;
+@@ -475,49 +485,18 @@
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XIM_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+- if (!objects_list->dl_module) {
+- path = __lc_path(objects_list->dl_name, lc_dir);
+- if (!path)
+- continue;
+-#if defined(hpux)
+- objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
+-#else
+- objects_list->dl_module = dlopen(path, RTLD_LAZY);
+-#endif
+- Xfree(path);
+- if (!objects_list->dl_module) continue;
+- }
+-#if defined(hpux)
+- getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
+- EXPORT_SYMBOLS, malloc, &symbols);
+-
+- for(i=0; i<getsyms_cnt; i++) {
+- if(!strcmp(symbols[i].name, objects_list->open)) {
+- im_registerIM = symbols[i].value;
+- break;
+- }
+- }
+
+- if(getsyms_cnt > 0) {
+- free(symbols);
+- }
+-#else
+- im_registerIM = (Bool(*)())try_both_dlsym(objects_list->dl_module,
+- objects_list->im_register);
++ if (!open_object (objects_list, lc_dir))
++ continue;
++ im_registerIM = (Bool(*)())fetch_symbol(objects_list,
++ objects_list->im_register);
+ if (!im_registerIM) continue;
+-#endif
+ ret_flag = (*im_registerIM)(lcd, display, rdb,
+ res_name, res_class,
+ callback, client_data);
+ if (ret_flag) break;
+
+- im_registerIM = 0;
+-#if defined(hpux)
+- shl_unload(objects_list->dl_module);
+-#else
+- dlclose(objects_list->dl_module);
+-#endif
+- objects_list->dl_module = NULL;
++ close_object (objects_list);
+ }
+ return (Bool)ret_flag;
+ }
+@@ -533,7 +512,6 @@
+ XIMProc callback;
+ XPointer *client_data;
+ {
+- char *path;
+ char lc_dir[BUFSIZE];
+ char *lc_name;
+ Bool (*im_unregisterIM)() = (Bool(*)())NULL;
+@@ -552,50 +530,21 @@
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XIM_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+- if (!objects_list->dl_module) {
+- path = __lc_path(objects_list->dl_name, lc_dir);
+- if (!path)
+- continue;
+-#if defined(hpux)
+- objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
+-#else
+- objects_list->dl_module = dlopen(path, RTLD_LAZY);
+-#endif
+- Xfree(path);
+- if (!objects_list->dl_module) continue;
+- }
+-#if defined(hpux)
+- getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
+- EXPORT_SYMBOLS, malloc, &symbols);
+
+- for(i=0; i<getsyms_cnt; i++) {
+- if(!strcmp(symbols[i].name, objects_list->open)) {
+- im_unregisterIM = symbols[i].value;
+- break;
+- }
+- }
++ if (!objects_list->refcount) /* Must already be opened */
++ continue;
+
+- if(getsyms_cnt > 0) {
+- free(symbols);
+- }
+-#else
+- im_unregisterIM = (Bool(*)())try_both_dlsym(objects_list->dl_module,
+- objects_list->im_unregister);
++ im_unregisterIM = (Bool(*)())fetch_symbol(objects_list,
++ objects_list->im_unregister);
+
+ if (!im_unregisterIM) continue;
+-#endif
+ ret_flag = (*im_unregisterIM)(lcd, display, rdb,
+ res_name, res_class,
+ callback, client_data);
+- if (ret_flag) break;
+-
+- im_unregisterIM = 0;
+-#if defined(hpux)
+- shl_unload(objects_list->dl_module);
+-#else
+- dlclose(objects_list->dl_module);
+-#endif
+- objects_list->dl_module = NULL;
++ if (ret_flag) {
++ close_object (objects_list); /* opened in RegisterIMInstantiateCallback */
++ break;
++ }
+ }
+ return (Bool)ret_flag;
+ }
+@@ -631,7 +580,6 @@
+ {
+ XOM om = (XOM)NULL;
+ int count;
+- char *path;
+ char lc_dir[BUFSIZE];
+ char *lc_name;
+ XOM (*om_openOM)() = (XOM(*)())NULL;
+@@ -649,48 +597,16 @@
+ for (; count-- > 0; objects_list++) {
+ if (objects_list->type != XOM_OBJECT ||
+ strcmp(objects_list->locale_name, lc_name)) continue;
+- if (!objects_list->dl_module) {
+- path = __lc_path(objects_list->dl_name, lc_dir);
+- if (!path)
+- continue;
+-#if defined(hpux)
+- objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
+-#else
+- objects_list->dl_module = dlopen(path, RTLD_LAZY);
+-#endif
+- Xfree(path);
+- if (!objects_list->dl_module) continue;
+- }
+-#if defined(hpux)
+- getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
+- EXPORT_SYMBOLS, malloc, &symbols);
+-
+- for(i=0; i<getsyms_cnt; i++) {
+- if(!strcmp(symbols[i].name, objects_list->open)) {
+- om_openOM = symbols[i].value;
+- break;
+- }
+- }
+-
+- if(getsyms_cnt > 0) {
+- free(symbols);
+- }
+-#else
+- om_openOM = (XOM(*)())try_both_dlsym(objects_list->dl_module,
+- objects_list->open);
++ if (!open_object (objects_list, lc_dir))
++ continue;
++
++ om_openOM = (XOM(*)())fetch_symbol(objects_list, objects_list->open);
+ if (!om_openOM) continue;
+-#endif
+ om = (*om_openOM)(lcd, display, rdb, res_name, res_class);
+ if (om != (XOM)NULL) {
+ break;
+ }
+- om_openOM = 0;
+-#if defined(hpux)
+- shl_unload(objects_list->dl_module);
+-#else
+- dlclose(objects_list->dl_module);
+-#endif
+- objects_list->dl_module = NULL;
++ close_object(objects_list);
+ }
+ return (XOM)om;
+ }