1 /* # skkinput (Simple Kana-Kanji Input)
2 *
3 * This file is part of skkinput.
4 * Copyright (C) 2002
5 * Takashi SAKAMOTO (PXG01715@nifty.ne.jp)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with skkinput; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 #include "AfxWin.h"
22 #include "local.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <X11/X.h>
27 #include <X11/Xlib.h>
28 #include <X11/Xatom.h>
29 #include <X11/IntrinsicP.h>
30 #include <X11/StringDefs.h>
31 #include <X11/Shell.h>
32 #include "XIMServerP.h"
33 #include "XIMProtocol.h"
34 #include "lispyevent.h"
35
36 #define offset(field) XtOffsetOf(XIMServerRec, ximServer.field)
37 #define goffset(field) XtOffsetOf(WidgetRec, core.field)
38
39 static XtResource srXIMServerResources [] = {
40 { XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension),
41 goffset (width), XtRImmediate, (XtPointer) 1, },
42 { XtNheight, XtCHeight, XtRDimension, sizeof (Dimension),
43 goffset (height), XtRImmediate, (XtPointer) 1, },
44 { XtNmappedWhenManaged, XtCMappedWhenManaged, XtRBoolean, sizeof (Boolean),
45 goffset (mapped_when_managed), XtRImmediate, (XtPointer)False, },
46 { XtNlispMachine, XtCLispMachine, XtRPointer, sizeof (XtPointer),
47 offset (m_pLispMachine), XtRImmediate, (XtPointer) 0, },
48 { XtNsupportedLocales, XtCSupportedLocales,
49 XtRString, sizeof (String),
50 offset (m_strLocales), XtRImmediate,
51 (XtPointer) "ja_JP.SJIS,ja_JP.eucJP,ja_JP.EUC,ja_JP,japanese,japan,ja", },
52 { XtNconversionStartKeys, XtCConversionStartKeys,
53 XtRString, sizeof (String),
54 offset (m_strConvStartKeys), XtRImmediate,
55 (XtPointer) "[S-space], [S-kp-space]", },
56 { XtNdestroyCallback, XtCCallback,
57 XtRCallback, sizeof (XtCallbackList),
58 offset (m_lstCbkDestroy), XtRCallback, (XtPointer) NULL, },
59 } ;
60
61 #undef offset
62 #undef goffset
63
64 static void ximServer_onInitialize (Widget, Widget, ArgList, Cardinal*) ;
65 static void ximServer_onRealize (Widget, XtValueMask*, XSetWindowAttributes*) ;
66 static Boolean ximServer_onSetValues (Widget, Widget, Widget, ArgList, Cardinal*) ;
67 static void ximServer_onDestroy (Widget) ;
68
69 static void ximServer_onClientMessage (Widget, XEvent*, String*, Cardinal*) ;
70 static void ximServer_onSelectionRequest (Widget, XEvent*, String*, Cardinal*) ;
71 static void ximServer_onSelectionClear (Widget, XEvent*, String*, Cardinal*) ;
72 static void ximServer_onClientDestroy (Widget, XtPointer, XtPointer) ;
73
74 static Boolean ximServer_setServerProfile (Widget) ;
75 static Boolean ximServer_parseConversionStartKey (Widget) ;
76
77 static Widget ximServer_newClient (Widget, Window) ;
78 static Widget ximServer_findClient (Widget, Window) ;
79 static void ximServer_removeClient (Widget, Widget) ;
80 static void ximServer_destroyAllClient (Widget) ;
81 static Boolean ximServer_isValidWindow (Display*, Window) ;
82
83 static XtActionsRec srXIMServerActionsTable [] = {
84 { "client-message", ximServer_onClientMessage, },
85 { "selection-request", ximServer_onSelectionRequest, },
86 { "selection-clear", ximServer_onSelectionClear, },
87 } ;
88
89 static char sstrXIMServerTranslations [] =
90 "<Message>: client-message()\n\
91 <SelReq>: selection-request()\n\
92 <SelClr>: selection-clear()" ;
93
94 XIMServerClassRec ximServerClassRec = {
95 { /* core fields */
96 /* superclass */ &widgetClassRec,
97 /* class_name */ "XIMServer",
98 /* size */ sizeof (XIMServerRec),
99 /* class_initialize */ NULL,
100 /* class_part_initialize*/ NULL,
101 /* class_inited */ FALSE,
102 /* initialize */ ximServer_onInitialize,
103 /* initialize_hook */ NULL,
104 /* realize */ ximServer_onRealize,
105 /* actions */ srXIMServerActionsTable,
106 /* num_actions */ XtNumber (srXIMServerActionsTable),
107 /* resources */ srXIMServerResources,
108 /* num_resources */ XtNumber (srXIMServerResources),
109 /* xrm_class */ NULLQUARK,
110 /* compress_motion */ TRUE,
111 /* compress_exposure */ TRUE,
112 /* compress_enterleave */ TRUE,
113 /* visible_interest */ FALSE,
114 /* destroy */ ximServer_onDestroy,
115 /* resize */ NULL,
116 /* expose */ NULL,
117 /* set_values */ ximServer_onSetValues,
118 /* set_values_hook */ NULL,
119 /* set_values_almost */ XtInheritSetValuesAlmost,
120 /* get_values_hook */ NULL,
121 /* accept_focus */ NULL,
122 /* version */ XtVersion,
123 /* callback_private */ NULL,
124 /* tm_table */ sstrXIMServerTranslations,
125 /* query_geometry */ XtInheritQueryGeometry,
126 }, {
127 /* dummy */ 0,
128 }
129 } ;
130
131 WidgetClass ximServerWidgetClass = (WidgetClass)&ximServerClassRec ;
132
133
134 void
ximServer_onInitialize(register Widget greq,register Widget gnew,register ArgList args,register Cardinal * num_args)135 ximServer_onInitialize (
136 register Widget greq,
137 register Widget gnew,
138 register ArgList args,
139 register Cardinal* num_args)
140 {
141 register XIMServerWidget wgThis = (XIMServerWidget) gnew ;
142 register Display* pDisplay = XtDisplay (gnew) ;
143
144 #if defined (DEBUG)
145 fprintf (stderr, "ximServer_onInitizlize (%p)\n", wgThis) ;
146 #endif
147 TVarbuffer_Initialize (&wgThis->ximServer.m_vbufClient, sizeof (Widget)) ;
148 #define MakeAtom(s) XInternAtom(pDisplay,s,False)
149 wgThis->ximServer.m_atServer = MakeAtom ("@server=" XIM_SERVER_NAME) ;
150 wgThis->ximServer.m_atCompoundText = MakeAtom ("COMPOUND_TEXT") ;
151 wgThis->ximServer.m_atLocales = MakeAtom ("LOCALES") ;
152 wgThis->ximServer.m_atTransport = MakeAtom ("TRANSPORT") ;
153 wgThis->ximServer.m_atXConnect = MakeAtom ("_XIM_XCONNECT") ;
154 wgThis->ximServer.m_atSkkComm = MakeAtom ("_SKKINPUT_COMM") ;
155 #undef MakeAtom
156 wgThis->ximServer.m_lstHotKeyTrigger = NULL ;
157 wgThis->ximServer.m_nHotKeyTrigger = 0 ;
158 return ;
159 }
160
161 void
ximServer_onRealize(register Widget gw,register XtValueMask * pValueMask,register XSetWindowAttributes * pXSWA)162 ximServer_onRealize (
163 register Widget gw,
164 register XtValueMask* pValueMask,
165 register XSetWindowAttributes* pXSWA)
166 {
167 register Display* pDisplay = XtDisplay (gw) ;
168 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
169 register CoreWidgetClass super = (CoreWidgetClass) XtClass (gw)->core_class.superclass ;
170
171 (*super->core_class.realize)(gw, pValueMask, pXSWA) ;
172
173 XSetSelectionOwner (pDisplay, wgThis->ximServer.m_atServer, XtWindow (gw), CurrentTime) ;
174 if (XGetSelectionOwner (pDisplay, wgThis->ximServer.m_atServer) != XtWindow (gw)) {
175 #if defined (DEBUG)
176 fprintf (stderr, "ximServer_onRealize() : failed.\n") ;
177 #endif
178 XtDestroyWidget (gw) ;
179 return ;
180 }
181 ximServer_setServerProfile (gw) ;
182 ximServer_parseConversionStartKey (gw) ;
183 #if defined (DEBUG)
184 fprintf (stderr, "ximServer_onRealize() : done.\n") ;
185 #endif
186 return ;
187 }
188
189 Boolean
ximServer_onSetValues(register Widget gwCurrent,register Widget gwRequest,register Widget gwNeww,register ArgList args,register Cardinal * num_args)190 ximServer_onSetValues (
191 register Widget gwCurrent,
192 register Widget gwRequest,
193 register Widget gwNeww,
194 register ArgList args,
195 register Cardinal* num_args)
196 {
197 return False ;
198 }
199
200 void
ximServer_onDestroy(register Widget gw)201 ximServer_onDestroy (
202 register Widget gw)
203 {
204 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
205
206 #if defined (DEBUG)
207 fprintf (stderr, "ximServer_onDestroy (%p)\n", gw) ;
208 #endif
209 XtCallCallbacks (gw, XtNdestroyCallback, 0) ;
210 ximServer_destroyAllClient (gw) ;
211
212 if (wgThis->ximServer.m_lstHotKeyTrigger != NULL) {
213 FREE (wgThis->ximServer.m_lstHotKeyTrigger) ;
214 wgThis->ximServer.m_lstHotKeyTrigger = NULL ;
215 }
216 return ;
217 }
218
219 void
ximServer_onSelectionClear(register Widget gw,register XEvent * pXEvent,register String * params,register Cardinal * num_params)220 ximServer_onSelectionClear (
221 register Widget gw,
222 register XEvent* pXEvent,
223 register String* params,
224 register Cardinal* num_params)
225 {
226 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
227 register XSelectionClearEvent* pEvent = &pXEvent->xselectionclear ;
228
229 #if defined (DEBUG)
230 fprintf (stderr, "ximServer_onSelectionClear ()\n") ;
231 #endif
232 if (pEvent->selection != wgThis->ximServer.m_atServer)
233 return ;
234
235 XtDestroyWidget (gw) ;
236 return ;
237 }
238
239 void
ximServer_onSelectionRequest(register Widget gw,register XEvent * pXEvent,register String * params,register Cardinal * num_params)240 ximServer_onSelectionRequest (
241 register Widget gw,
242 register XEvent* pXEvent,
243 register String* params,
244 register Cardinal* num_params)
245 {
246 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
247 register XSelectionRequestEvent* pEvent = &pXEvent->xselectionrequest ;
248 register Display* pDisplay = XtDisplay (gw) ;
249 register unsigned char* pValue ;
250 register int iLength ;
251 register int iFormat ;
252 XEvent xev ;
253 Atom atTarget ;
254 Atom atTargets [2] ;
255
256 #if defined (DEBUG)
257 {
258 char* pSelection = XGetAtomName (pDisplay, pEvent->selection) ;
259 char* pAtomName = XGetAtomName (pDisplay, pEvent->target) ;
260
261 fprintf (stderr, "ximServer_onSelectionRequest: ") ;
262 if (pSelection != NULL) {
263 fprintf (stderr, "Selection: \"%s\", ", pSelection) ;
264 XFree (pSelection) ;
265 }
266 if (pAtomName != NULL) {
267 fprintf (stderr, "Target: \"%s\"\n", pAtomName) ;
268 XFree (pAtomName) ;
269 }
270 }
271 #endif
272 if (pEvent->selection != wgThis->ximServer.m_atServer)
273 return ;
274
275 pValue = NULL ;
276 iLength = 0 ;
277 if (pEvent->target == XInternAtom (pDisplay, "TARGETS", False)){
278 atTargets [0] = wgThis->ximServer.m_atLocales ;
279 atTargets [1] = wgThis->ximServer.m_atTransport ;
280 pValue = (unsigned char*)&atTargets ;
281 iLength = 2 ;
282 iFormat = 32 ;
283 atTarget = XA_ATOM ;
284 } else if (pEvent->target == wgThis->ximServer.m_atLocales){
285 static char* sstrLocales = NULL ;
286 static int snstrLocales ;
287
288 if (sstrLocales == NULL) {
289 static const char sstrAtLocal [] = "@locale=" ;
290 register int nNeed ;
291 nNeed = strlen (wgThis->ximServer.m_strLocales) + NELEMENTS (sstrAtLocal) + 1 ;
292 sstrLocales = MALLOC (nNeed + 1) ;
293 assert (sstrLocales != NULL) ;
294 strcpy (sstrLocales, sstrAtLocal) ;
295 strcat (sstrLocales, wgThis->ximServer.m_strLocales) ;
296 snstrLocales = strlen (sstrLocales) ;
297 }
298 pValue = sstrLocales ;
299 iLength = snstrLocales ;
300 iFormat = 8 ;
301 atTarget = pEvent->target ;
302 } else if (pEvent->target == wgThis->ximServer.m_atTransport){
303 static char rchTransport [] = "@transport=X/" ;
304 pValue = rchTransport ;
305 iLength = NELEMENTS (rchTransport) ;
306 iFormat = 8 ;
307 atTarget = pEvent->target ;
308 } else {
309 #if defined (DEBUG)
310 fprintf (stderr, "ximServer_onSelectionRequest: invalid request\n") ;
311 #endif
312 return ;
313 }
314 if (pValue == NULL || iLength <= 0)
315 return ;
316
317 XChangeProperty (pDisplay, pEvent->requestor, pEvent->property, atTarget, iFormat, PropModeReplace, pValue, iLength) ;
318 xev.xselection.type = SelectionNotify ;
319 xev.xselection.selection = pEvent->selection ;
320 xev.xselection.target = atTarget ;
321 xev.xselection.property = pEvent->property ;
322 xev.xselection.requestor = pEvent->requestor ;
323 xev.xselection.send_event = True ;
324 xev.xselection.time = CurrentTime ;
325 xev.xselection.display = pDisplay ;
326 XSendEvent (pDisplay, pEvent->requestor, False, 0L, &xev) ;
327 return ;
328 }
329
330 void
ximServer_onClientMessage(register Widget gw,register XEvent * pXEvent,register String * params,register Cardinal * num_params)331 ximServer_onClientMessage (
332 register Widget gw,
333 register XEvent* pXEvent,
334 register String* params,
335 register Cardinal* num_params)
336 {
337 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
338 register XClientMessageEvent* pEvent = (XClientMessageEvent*)&pXEvent->xclient ;
339 register Widget wgClient ;
340 register Window wndClient ;
341 XEvent xev ;
342
343 if (pEvent->display != XtDisplay (gw) ||
344 pEvent->window != XtWindow (gw) ||
345 pEvent->message_type != wgThis->ximServer.m_atXConnect ||
346 pEvent->format != 32)
347 return ;
348
349 wndClient = (Window) pEvent->data.l [0] ;
350 if (!ximServer_isValidWindow (XtDisplay (gw), wndClient)) {
351 return ;
352 }
353 wgClient = ximServer_findClient (gw, wndClient) ;
354 if (wgClient == NULL) {
355 wgClient = ximServer_newClient (gw, wndClient) ;
356 }
357 assert (wgClient != NULL) ;
358 xev.xclient.type = ClientMessage ;
359 xev.xclient.window = wndClient ;
360 xev.xclient.message_type = wgThis->ximServer.m_atXConnect ;
361 xev.xclient.format = 32 ;
362 xev.xclient.data.l [0] = XtWindow (wgClient) ;
363 xev.xclient.data.l [1] = XIM_SERVERMAJOR_TRANSPORT_VERSION ;
364 xev.xclient.data.l [2] = XIM_SERVERMINOR_TRANSPORT_VERSION ;
365 xev.xclient.data.l [3] = XTRANSPORT_DIVIDING_SIZE ;
366 XSendEvent (XtDisplay (gw), wndClient, False, NoEventMask, &xev) ;
367 return ;
368 }
369
370 void
ximServer_onClientDestroy(register Widget gw,register XtPointer closure,register XtPointer call_data)371 ximServer_onClientDestroy (
372 register Widget gw,
373 register XtPointer closure,
374 register XtPointer call_data)
375 {
376 register Widget wgServer = (Widget) closure ;
377
378 #if defined (DEBUG)
379 fprintf (stderr, "ximServer_removeClient (%p, %p)\n", wgServer, call_data) ;
380 #endif
381 ximServer_removeClient (wgServer, call_data) ;
382 return ;
383 }
384
385 Boolean
ximServer_setServerProfile(register Widget gw)386 ximServer_setServerProfile (
387 register Widget gw)
388 {
389 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
390 register Display* pDisplay ;
391 register Atom atServers ;
392 register Atom atServer ;
393 register int iOperation ;
394 register Boolean fNoRegistration ;
395 unsigned long lData ;
396
397 assert (gw != NULL) ;
398
399 pDisplay = XtDisplay (gw) ;
400 atServers = XInternAtom (pDisplay, "XIM_SERVERS", False) ;
401 atServer = wgThis->ximServer.m_atServer ;
402 iOperation = PropModePrepend ;
403 fNoRegistration = False ;
404
405 {
406 Atom atType ;
407 int iFormat ;
408 unsigned long ulItems ;
409 unsigned long ulBytesAfter ;
410 unsigned char* pValue ;
411
412 /* �ޤ�������°�������ꤵ��Ƥ��뤫�ɤ������ɤࡣ*/
413 if (XGetWindowProperty (pDisplay, DefaultRootWindow (pDisplay), atServers, 0L, 1024L, False, AnyPropertyType, &atType, &iFormat, &ulItems, &ulBytesAfter, &pValue) == Success){
414 if (atType != XA_ATOM || iFormat != 32){
415 iOperation = PropModeReplace ;
416 } else {
417 Atom* pAtom = (Atom*)pValue ;
418 while (ulItems > 0){
419 if (*pAtom == wgThis->ximServer.m_atServer){
420 fNoRegistration = True ;
421 break ;
422 }
423 pAtom ++ ;
424 ulItems -- ;
425 }
426 }
427 if (pValue)
428 XFree (pValue) ;
429 }
430 }
431 lData = wgThis->ximServer.m_atServer ;
432 if (!fNoRegistration){
433 XChangeProperty (pDisplay, DefaultRootWindow (pDisplay), atServers, XA_ATOM, 32, iOperation, (unsigned char *)&lData, 1) ;
434 } else {
435 XChangeProperty (pDisplay, DefaultRootWindow (pDisplay), atServers, XA_ATOM, 32, PropModeAppend, (unsigned char*)&lData, 0) ;
436 }
437 return True ;
438 }
439
440 Boolean
ximServer_parseConversionStartKey(register Widget gw)441 ximServer_parseConversionStartKey (
442 register Widget gw)
443 {
444 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
445 register Display* pDisplay ;
446 const char* pString ;
447 int nString ;
448 KeySym rKeysym [2] ;
449 unsigned int ruState [2] ;
450 TVarbuffer vbufHotKey ;
451 register int nHotKey, nRetval ;
452 register XIMHotKeyTrigger* pHotKey ;
453 register Boolean fRetval = False ;
454
455 assert (wgThis->ximServer.m_lstHotKeyTrigger == NULL) ;
456
457 pDisplay = XtDisplay (gw) ;
458 pString = wgThis->ximServer.m_strConvStartKeys ;
459 if (pString == NULL)
460 return False ;
461
462 if (TFAILED (TVarbuffer_Initialize (&vbufHotKey, sizeof (XIMHotKeyTrigger))))
463 return False ;
464
465 nString = strlen (pString) ;
466 while (nString > 0) {
467 nRetval = string2keysymlist (pDisplay, &pString, &nString, rKeysym, ruState, 2) ;
468 if (nRetval < 0)
469 break ;
470
471 if (nRetval == 1) {
472 XIMHotKeyTrigger hotkey ;
473
474 hotkey.keysym = rKeysym [0] ;
475 hotkey.modifier = ruState [0] ;
476 hotkey.modifier_mask = ruState [0] ;
477 #if defined (DEBUG)
478 fprintf (stderr, "XIMHotKeyTrigger(%lx, %x)\n",
479 hotkey.keysym,
480 hotkey.modifier) ;
481 #endif
482 if (TFAILED (TVarbuffer_Add (&vbufHotKey, &hotkey, 1)))
483 goto error ;
484 }
485
486 if (nString > 0 && *pString == ',') {
487 pString ++ ;
488 nString -- ;
489 }
490 }
491
492 nHotKey = TVarbuffer_GetUsage (&vbufHotKey) ;
493 if (nHotKey > 0) {
494 register XIMHotKeyTrigger* pSrc ;
495 register int nSize ;
496
497 nSize = sizeof (XIMHotKeyTrigger) * nHotKey ;
498 pSrc = TVarbuffer_GetBuffer (&vbufHotKey) ;
499 pHotKey = MALLOC (nSize) ;
500 if (pHotKey != NULL) {
501 memcpy (pHotKey, pSrc, sizeof (XIMHotKeyTrigger) * nHotKey) ;
502 fRetval = True ;
503 }
504 } else {
505 pHotKey = NULL ;
506 fRetval = True ;
507 }
508 if (fRetval) {
509 wgThis->ximServer.m_lstHotKeyTrigger = pHotKey ;
510 wgThis->ximServer.m_nHotKeyTrigger = nHotKey ;
511 }
512
513 error:
514 TVarbuffer_Uninitialize (&vbufHotKey) ;
515 return fRetval ;
516 }
517
518 Widget
ximServer_newClient(register Widget gw,register Window wndClient)519 ximServer_newClient (
520 register Widget gw,
521 register Window wndClient)
522 {
523 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
524 Widget wgClient ;
525 Arg rArg [8] ;
526 register int nArg ;
527
528 nArg = 0 ;
529 XtSetArg (rArg [nArg], XtNmappedWhenManaged, False) ; nArg ++ ;
530 XtSetArg (rArg [nArg], XtNclientWindow, wndClient) ; nArg ++ ;
531 XtSetArg (rArg [nArg], XtNprotocolWidget, gw) ; nArg ++ ;
532 wgClient = XtCreateWidget ("ximClient", ximClientWidgetClass, gw, rArg, nArg) ;
533 if (wgClient == NULL)
534 return NULL ;
535 if (TFAILED (TVarbuffer_Add (&wgThis->ximServer.m_vbufClient, &wgClient, 1))) {
536 XtDestroyWidget (wgClient) ;
537 return NULL ;
538 }
539 XtAddCallback (wgClient, XtNdestroyCallback, ximServer_onClientDestroy, gw) ;
540 XtRealizeWidget (wgClient) ;
541 return wgClient ;
542 }
543
544 void
ximServer_removeClient(register Widget gw,register Widget gwClient)545 ximServer_removeClient (
546 register Widget gw,
547 register Widget gwClient)
548 {
549 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
550 register Widget* pClient ;
551 register Widget* pLast ;
552 register int i, nClient ;
553
554 pClient = TVarbuffer_GetBuffer (&wgThis->ximServer.m_vbufClient) ;
555 nClient = TVarbuffer_GetUsage (&wgThis->ximServer.m_vbufClient) ;
556 pLast = pClient + nClient - 1 ;
557 for (i = 0 ; i < nClient ; i ++) {
558 if (*pClient == gwClient) {
559 if (pClient != pLast)
560 *pClient = *pLast ;
561 TVarbuffer_Sub (&wgThis->ximServer.m_vbufClient, 1) ;
562 XtRemoveAllCallbacks (gwClient, XtNdestroyCallback) ;
563 return ;
564 }
565 pClient ++ ;
566 }
567 return ;
568 }
569
570 Widget
ximServer_findClient(register Widget gw,register Window wndClient)571 ximServer_findClient (
572 register Widget gw,
573 register Window wndClient)
574 {
575 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
576 register Widget* pClient ;
577 register int nClient ;
578
579 pClient = TVarbuffer_GetBuffer (&wgThis->ximServer.m_vbufClient) ;
580 nClient = TVarbuffer_GetUsage (&wgThis->ximServer.m_vbufClient) ;
581 while (nClient -- > 0) {
582 if (XtWindow (*pClient) == wndClient)
583 return *pClient ;
584 pClient ++ ;
585 }
586 return NULL ;
587 }
588
589 void
ximServer_destroyAllClient(register Widget gw)590 ximServer_destroyAllClient (
591 register Widget gw)
592 {
593 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
594 register Widget* pClient ;
595 register int nClient ;
596
597 pClient = TVarbuffer_GetBuffer (&wgThis->ximServer.m_vbufClient) ;
598 nClient = TVarbuffer_GetUsage (&wgThis->ximServer.m_vbufClient) ;
599
600 /* remoteClient ���ƤӽФ���ʤ��褦��դ��롣*/
601 while (nClient -- > 0) {
602 XtRemoveAllCallbacks (*pClient, XtNdestroyCallback) ;
603 XtDestroyWidget (*pClient ++) ;
604 }
605 TVarbuffer_Uninitialize (&wgThis->ximServer.m_vbufClient) ;
606 return ;
607 }
608
609 Boolean
ximServer_isValidWindow(register Display * pDisplay,register Window wnd)610 ximServer_isValidWindow (
611 register Display* pDisplay,
612 register Window wnd)
613 {
614 XWindowAttributes xwa ;
615
616 /* ������ XError ����ٻߤ�Ƥ����Ƥ��顢XGetWindowAttributes ���ơ�
617 * �����֤��ͤ롣���� XErrorHandler �������ʬ���ʤ��ġ�
618 */
619 return XGetWindowAttributes (pDisplay, wnd, &xwa) ;
620 }
621
622 int
XIMServer_GetConversionStartKey(register Widget gw,register const XIMHotKeyTrigger ** ppHotKey)623 XIMServer_GetConversionStartKey (
624 register Widget gw,
625 register const XIMHotKeyTrigger** ppHotKey)
626 {
627 register XIMServerWidget wgThis = (XIMServerWidget) gw ;
628
629 assert (gw != NULL) ;
630
631 if (XtClass (gw) != ximServerWidgetClass)
632 return 0 ;
633
634 if (ppHotKey != NULL)
635 *ppHotKey = wgThis->ximServer.m_lstHotKeyTrigger ;
636
637 return wgThis->ximServer.m_nHotKeyTrigger ;
638 }
639
640