imInsClbk.c revision b4ee4795
1/****************************************************************** 2 3 Copyright 1993, 1994 by Sony Corporation 4 5Permission to use, copy, modify, distribute, and sell this software 6and its documentation for any purpose is hereby granted without fee, 7provided that the above copyright notice appear in all copies and 8that both that copyright notice and this permission notice appear 9in supporting documentation, and that the name of Sony Corporation 10 not be used in advertising or publicity pertaining to distribution 11 of the software without specific, written prior permission. 12Sony Corporation makes no representations about the suitability of 13 this software for any purpose. It is provided "as is" without 14 express or implied warranty. 15 16SONY CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 20USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22PERFORMANCE OF THIS SOFTWARE. 23 24 Author: Makoto Wakamatsu Sony Corporation 25 makoto@sm.sony.co.jp 26 27******************************************************************/ 28 29#ifdef HAVE_CONFIG_H 30#include <config.h> 31#endif 32#include <X11/Xatom.h> 33#define NEED_EVENTS 34#include "Xlibint.h" 35#include "Xlcint.h" 36#include "XlcPublic.h" 37#include "Ximint.h" 38 39 40typedef struct _XimInstCallback { 41 Bool call; 42 Bool destroy; 43 Display *display; 44 XLCd lcd; 45 char name[XIM_MAXLCNAMELEN]; 46 char *modifiers; 47 XrmDatabase rdb; 48 char *res_name; 49 char *res_class; 50 XIDProc callback; 51 XPointer client_data; 52 struct _XimInstCallback *next; 53} XimInstCallbackRec, *XimInstCallback; 54 55 56Private XimInstCallback callback_list = NULL; 57Private Bool lock = False; 58 59 60Private void 61MakeLocale( XLCd lcd, char locale[] ) 62{ 63 char *language, *territory, *codeset; 64 65 _XGetLCValues( lcd, XlcNLanguage, &language, XlcNTerritory, &territory, 66 XlcNCodeset, &codeset, NULL ); 67 68 strcpy( locale, language ); 69 if( territory && *territory ) { 70 strcat( locale, "_" ); 71 strcat( locale, territory ); 72 } 73 if( codeset && *codeset ) { 74 strcat( locale, "." ); 75 strcat( locale, codeset ); 76 } 77} 78 79 80Private Bool 81_XimFilterPropertyNotify( 82 Display *display, 83 Window window, 84 XEvent *event, 85 XPointer client_data) 86{ 87 Atom ims, actual_type, *atoms; 88 int actual_format; 89 unsigned long nitems, bytes_after; 90 int ii; 91 XIM xim; 92 Bool flag = False; 93 XimInstCallback icb, picb, tmp; 94 95 if( (ims = XInternAtom( display, XIM_SERVERS, True )) == None || 96 event->xproperty.atom != ims || 97 event->xproperty.state == PropertyDelete ) 98 return( False ); 99 100 if( XGetWindowProperty( display, RootWindow(display, 0), ims, 0L, 1000000L, 101 False, XA_ATOM, &actual_type, &actual_format, 102 &nitems, &bytes_after, (unsigned char **)&atoms ) 103 != Success ) { 104 return( False ); 105 } 106 if( actual_type != XA_ATOM || actual_format != 32 ) { 107 XFree( atoms ); 108 return( False ); 109 } 110 111 lock = True; 112 for( ii = 0; ii < nitems; ii++, atoms ) { 113 if(XGetSelectionOwner (display, atoms[ii])) { 114 for( icb = callback_list; icb; icb = icb->next ) { 115 if( !icb->call && !icb->destroy ) { 116 xim = (*icb->lcd->methods->open_im)( icb->lcd, display, 117 icb->rdb, 118 icb->res_name, 119 icb->res_class ); 120 if( xim ) { 121 xim->methods->close( (XIM)xim ); 122 flag = True; 123 icb->call = True; 124 icb->callback( icb->display, icb->client_data, NULL ); 125 } 126 } 127 } 128 break; 129 } 130 } 131 XFree( atoms ); 132 133 for( icb = callback_list, picb = NULL; icb; ) { 134 if( icb->destroy ) { 135 if( picb ) 136 picb->next = icb->next; 137 else 138 callback_list = icb->next; 139 tmp = icb; 140 icb = icb->next; 141 XFree( tmp ); 142 } 143 else { 144 picb = icb; 145 icb = icb->next; 146 } 147 } 148 lock = False; 149 150 return( flag ); 151} 152 153 154Public Bool 155_XimRegisterIMInstantiateCallback( 156 XLCd lcd, 157 Display *display, 158 XrmDatabase rdb, 159 char *res_name, 160 char *res_class, 161 XIDProc callback, 162 XPointer client_data) 163{ 164 XimInstCallback icb, tmp; 165 XIM xim; 166 Window root; 167 XWindowAttributes attr; 168 169 if( lock ) 170 return( False ); 171 172 icb = (XimInstCallback)Xmalloc(sizeof(XimInstCallbackRec)); 173 if( !icb ) 174 return( False ); 175 icb->call = icb->destroy = False; 176 icb->display = display; 177 icb->lcd = lcd; 178 MakeLocale( lcd, icb->name ); 179 icb->modifiers = lcd->core->modifiers; /* XXXXX */ 180 icb->rdb = rdb; 181 icb->res_name = res_name; 182 icb->res_class = res_class; 183 icb->callback = callback; 184 icb->client_data = client_data; 185 icb->next = NULL; 186 187 if( !callback_list ) 188 callback_list = icb; 189 else { 190 for( tmp = callback_list; tmp->next; tmp = tmp->next ); 191 tmp->next = icb; 192 } 193 194 xim = (*lcd->methods->open_im)( lcd, display, rdb, res_name, res_class ); 195 196 if( icb == callback_list ) { 197 root = RootWindow( display, 0 ); 198 XGetWindowAttributes( display, root, &attr ); 199 _XRegisterFilterByType( display, root, PropertyNotify, PropertyNotify, 200 _XimFilterPropertyNotify, (XPointer)NULL ); 201 XSelectInput( display, root, 202 attr.your_event_mask | PropertyChangeMask ); 203 } 204 205 if( xim ) { 206 lock = True; 207 xim->methods->close( (XIM)xim ); 208 lock = False; 209 icb->call = True; 210 callback( display, client_data, NULL ); 211 } 212 213 return( True ); 214} 215 216 217Public Bool 218_XimUnRegisterIMInstantiateCallback( 219 XLCd lcd, 220 Display *display, 221 XrmDatabase rdb, 222 char *res_name, 223 char *res_class, 224 XIDProc callback, 225 XPointer client_data) 226{ 227 char locale[XIM_MAXLCNAMELEN]; 228 XimInstCallback icb, picb; 229 230 if( !callback_list ) 231 return( False ); 232 233 MakeLocale( lcd, locale ); 234 235 for( icb = callback_list, picb = NULL; icb; picb = icb, icb = icb->next ) { 236 if( !strcmp( locale, icb->name ) && 237 (lcd->core->modifiers == icb->modifiers || /* XXXXX */ 238 (lcd->core->modifiers && icb->modifiers && 239 !strcmp( lcd->core->modifiers, icb->modifiers ))) && 240 rdb == icb->rdb && /* XXXXX */ 241 ((res_name == NULL && icb->res_name == NULL) || 242 (res_name != NULL && icb->res_name != NULL && 243 !strcmp( res_name, icb->res_name ))) && 244 ((res_class == NULL && icb->res_class == NULL) || 245 (res_class != NULL && icb->res_class != NULL && 246 !strcmp( res_class, icb->res_class ))) && 247 (callback == icb->callback) && 248 (client_data == icb->client_data) && /* XXXXX */ 249 !icb->destroy ) { 250 if( lock ) 251 icb->destroy = True; 252 else { 253 if( !picb ) { 254 callback_list = icb->next; 255 _XUnregisterFilter( display, RootWindow(display, 0), 256 _XimFilterPropertyNotify, 257 (XPointer)NULL ); 258 } 259 else 260 picb->next = icb->next; 261 _XCloseLC( icb->lcd ); 262 XFree( icb ); 263 } 264 return( True ); 265 } 266 } 267 return( False ); 268} 269 270 271Public void 272_XimResetIMInstantiateCallback(Xim xim) 273{ 274 char locale[XIM_MAXLCNAMELEN]; 275 XimInstCallback icb; 276 XLCd lcd = xim->core.lcd; 277 278 if( !callback_list && lock ) 279 return; 280 281 MakeLocale( lcd, locale ); 282 283 for( icb = callback_list; icb; icb = icb->next ) 284 if( !strcmp( locale, icb->name ) && 285 (lcd->core->modifiers == icb->modifiers || 286 (lcd->core->modifiers && icb->modifiers && 287 !strcmp( lcd->core->modifiers, icb->modifiers ))) ) 288 icb->call = False; 289} 290