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