Home | History | Annotate | Line # | Download | only in ximcp
      1 /******************************************************************
      2 
      3            Copyright 1992, 1993, 1994 by FUJITSU LIMITED
      4 
      5 Permission to use, copy, modify, distribute, and sell this software
      6 and its documentation for any purpose is hereby granted without fee,
      7 provided that the above copyright notice appear in all copies and
      8 that both that copyright notice and this permission notice appear
      9 in supporting documentation, and that the name of FUJITSU LIMITED
     10 not be used in advertising or publicity pertaining to distribution
     11 of the software without specific, written prior permission.
     12 FUJITSU LIMITED makes no representations about the suitability of
     13 this software for any purpose.
     14 It is provided "as is" without express or implied warranty.
     15 
     16 FUJITSU LIMITED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     18 EVENT SHALL FUJITSU LIMITED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     19 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
     20 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
     21 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     22 PERFORMANCE OF THIS SOFTWARE.
     23 
     24   Author: Takashi Fujiwara     FUJITSU LIMITED
     25                                fujiwara (at) a80.tech.yk.fujitsu.co.jp
     26 
     27 ******************************************************************/
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include <config.h>
     31 #endif
     32 #include <X11/Xatom.h>
     33 #include "Xlibint.h"
     34 #include "Xlcint.h"
     35 #include "Ximint.h"
     36 
     37 /*
     38  * index of extensions
     39  */
     40 
     41 #define	XIM_EXT_SET_EVENT_MASK_IDX	0
     42 #ifdef EXT_FORWARD
     43 #define	XIM_EXT_FORWARD_KEYEVENT_IDX	1
     44 #endif
     45 #ifdef EXT_MOVE
     46 #define	XIM_EXT_MOVE_IDX		2
     47 #endif
     48 
     49 typedef struct	_XIM_QueryExtRec {
     50     Bool	 is_support;
     51     const char	*name;
     52     int		 name_len;
     53     CARD16	 major_opcode;
     54     CARD16	 minor_opcode;
     55     int		 idx;
     56 } XIM_QueryExtRec;
     57 
     58 static XIM_QueryExtRec	extensions[] = {
     59 	{False, "XIM_EXT_SET_EVENT_MASK", 0, 0, 0,
     60 					XIM_EXT_SET_EVENT_MASK_IDX},
     61 #ifdef EXT_FORWARD
     62 	{False, "XIM_EXT_FORWARD_KEYEVENT", 0, 0, 0,
     63 					XIM_EXT_FORWARD_KEYEVENT_IDX},
     64 #endif
     65 #ifdef EXT_MOVE
     66 	{False, "XIM_EXT_MOVE", 0, 0, 0, XIM_EXT_MOVE_IDX},
     67 #endif
     68 	{False, NULL, 0, 0, 0, 0}		/* dummy */
     69 };
     70 
     71 static int
     72 _XimIsSupportExt(
     73     int		 idx)
     74 {
     75     register int i;
     76     int		 n = XIMNumber(extensions) - 1;
     77 
     78     for (i = 0; i < n; i++) {
     79 	if (extensions[i].idx == idx) {
     80 	    if (extensions[i].is_support)
     81 		return i;
     82 	    else
     83 		break;
     84 	}
     85     }
     86     return -1;
     87 }
     88 
     89 static Bool
     90 _XimProcExtSetEventMask(
     91     Xim		 im,
     92     Xic		 ic,
     93     XPointer	 buf)
     94 {
     95     EVENTMASK	*buf_l = (EVENTMASK *)buf;
     96     EVENTMASK	 select_mask = _XimGetWindowEventmask(ic);
     97 
     98     ic->private.proto.filter_event_mask      = buf_l[0];
     99     ic->private.proto.intercept_event_mask   = buf_l[1];
    100     ic->private.proto.select_event_mask      = buf_l[2];
    101     ic->private.proto.forward_event_mask     = buf_l[3];
    102     ic->private.proto.synchronous_event_mask = buf_l[4];
    103 
    104     select_mask &= ~ic->private.proto.intercept_event_mask;
    105 						/* deselected event mask */
    106     select_mask |= ic->private.proto.select_event_mask;
    107 						/* selected event mask */
    108     XSelectInput(im->core.display, ic->core.focus_window, select_mask);
    109     _XimReregisterFilter(ic);
    110 
    111     if (!(_XimProcSyncReply(im, ic)))
    112 	return False;
    113     return True;
    114 }
    115 
    116 static Bool
    117 _XimExtSetEventMaskCallback(
    118     Xim		 xim,
    119     INT16	 len,
    120     XPointer	 data,
    121     XPointer	 call_data)
    122 {
    123     CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
    124     XIMID	 imid = buf_s[0];
    125     XICID	 icid = buf_s[1];
    126     Xim		 im = (Xim)call_data;
    127     Xic		 ic;
    128 
    129     if ((imid == im->private.proto.imid)
    130      && (ic = _XimICOfXICID(im, icid))) {
    131 	(void)_XimProcExtSetEventMask(im, ic, (XPointer)&buf_s[2]);
    132 	return True;
    133     }
    134     return False;
    135 }
    136 
    137 #ifdef EXT_FORWARD
    138 static Bool
    139 _XimProcExtForwardKeyEvent(
    140     Xim		 im,
    141     Xic		 ic,
    142     XPointer	 buf)
    143 {
    144     CARD8	*buf_b = (CARD8 *)buf;
    145     CARD16	*buf_s = (CARD16 *)buf;
    146     CARD32	*buf_l = (CARD32 *)buf;
    147     XEvent	 ev;
    148     XKeyEvent	*kev = (XKeyEvent *)&ev;
    149 
    150     bzero(&ev, sizeof(XEvent));
    151     kev->send_event	= False;
    152     kev->display	= im->core.display;
    153     kev->serial		= buf_s[1];		/* sequence number */
    154     kev->type		= buf_b[4] & 0x7f;	/* xEvent.u.u.type */
    155     kev->keycode	= buf_b[5];		/* Keycode */
    156     kev->state		= buf_s[3];		/* state */
    157     kev->time		= buf_l[2];		/* time */
    158 
    159     XPutBackEvent(im->core.display, &ev);
    160 
    161     _XimRespSyncReply(ic, buf_s[0]);
    162     MARK_FABRICATED(im);
    163 
    164     return True;
    165 }
    166 
    167 static Bool
    168 _XimExtForwardKeyEventCallback(
    169     Xim		 xim,
    170     INT16	 len,
    171     XPointer	 data,
    172     XPointer	 call_data)
    173 {
    174     CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
    175     XIMID	 imid = buf_s[0];
    176     XICID	 icid = buf_s[1];
    177     Xim		 im = (Xim)call_data;
    178     Xic		 ic;
    179 
    180     if ((imid == im->private.proto.imid)
    181      && (ic = _XimICOfXICID(im, icid))) {
    182 	(void)_XimProcExtForwardKeyEvent(im, ic, (XPointer)&buf_s[2]);
    183 	return True;
    184     }
    185     return False;
    186 }
    187 
    188 static Bool
    189 _XimExtForwardKeyEventCheck(
    190     Xim          im,
    191     INT16        len,
    192     XPointer	 data,
    193     XPointer     arg)
    194 {
    195     Xic		 ic  = (Xic)arg;
    196     CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
    197     CARD8	 major_opcode = *((CARD8 *)data);
    198     CARD8	 minor_opcode = *((CARD8 *)data + 1);
    199     XIMID	 imid = buf_s[0];
    200     XICID	 icid = buf_s[1];
    201 
    202     if ((major_opcode == XIM_SYNC_REPLY)
    203      && (minor_opcode == 0)
    204      && (imid == im->private.proto.imid)
    205      && (icid == ic->private.proto.icid))
    206     if ((major_opcode == XIM_ERROR)
    207      && (minor_opcode == 0)
    208      && (buf_s[2] & XIM_IMID_VALID)
    209      && (imid == im->private.proto.imid)
    210      && (buf_s[2] & XIM_ICID_VALID)
    211      && (icid == ic->private.proto.icid))
    212 	return True;
    213     return False;
    214 }
    215 
    216 Bool
    217 _XimExtForwardKeyEvent(
    218     Xic		 ic,
    219     XKeyEvent	*ev,
    220     Bool	 sync)
    221 {
    222     Xim		 im = (Xim) ic->core.im;
    223     CARD32	 buf32[BUFSIZE/4];
    224     CARD8	*buf = (CARD8 *)buf32;
    225     CARD8	*buf_b = &buf[XIM_HEADER_SIZE];
    226     CARD16	*buf_s = (CARD16 *)buf_b;
    227     CARD32	*buf_l = (CARD32 *)buf_b;
    228     CARD32	 reply32[BUFSIZE/4];
    229     char	*reply = (char *)reply32;
    230     XPointer	preply;
    231     int		buf_size;
    232     int		ret_code;
    233     INT16	len;
    234     int		idx;
    235 
    236     if ((idx = _XimIsSupportExt(XIM_EXT_FORWARD_KEYEVENT_IDX)) < 0)
    237 	return False;
    238 
    239     buf_s[0] = im->private.proto.imid;		/* imid */
    240     buf_s[1] = ic->private.proto.icid;		/* icid */
    241     buf_s[2] = sync ? XimSYNCHRONUS : 0;	/* flag */
    242     buf_s[3] = (CARD16)(((XAnyEvent *)ev)->serial & ((unsigned long) 0xffff));
    243 						/* sequence number */
    244     buf_b[8] = ev->type;			/* xEvent.u.u.type */
    245     buf_b[9] = ev->keycode;			/* keycode */
    246     buf_s[5] = ev->state;			/* state */
    247     buf_l[3] = ev->time;			/* time */
    248     len = sizeof(CARD16)			/* sizeof imid */
    249 	+ sizeof(CARD16)			/* sizeof icid */
    250 	+ sizeof(BITMASK16)			/* sizeof flag */
    251 	+ sizeof(CARD16)			/* sizeof sequence number */
    252 	+ sizeof(BYTE)				/* sizeof xEvent.u.u.type */
    253 	+ sizeof(BYTE)				/* sizeof keycode */
    254 	+ sizeof(CARD16)			/* sizeof state */
    255 	+ sizeof(CARD32);			/* sizeof time */
    256 
    257     _XimSetHeader((XPointer)buf,
    258 		extensions[idx].major_opcode,
    259 		extensions[idx].minor_opcode, &len);
    260     if (!(_XimWrite(im, len, (XPointer)buf)))
    261 	return False;
    262     _XimFlush(im);
    263     if (sync) {
    264     	buf_size = BUFSIZE;
    265     	ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
    266     				_XimExtForwardKeyEventCheck, (XPointer)ic);
    267     	if(ret_code == XIM_TRUE) {
    268     	    preply = reply;
    269     	} else if(ret_code == XIM_OVERFLOW) {
    270     	    if(len <= 0) {
    271     		preply = reply;
    272     	    } else {
    273     		buf_sizex = len;
    274 		preply = Xmalloc(buf_size);
    275     		ret_code = _XimRead(im, &len, preply, buf_size,
    276     				_XimExtForwardKeyEventCheck, (XPointer)ic);
    277     		if(ret_code != XIM_TRUE) {
    278 		    Xfree(preply);
    279     		    return False;
    280 		}
    281     	    }
    282     	} else
    283 	    return False;
    284     	buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
    285     	if (*((CARD8 *)preply) == XIM_ERROR) {
    286 	    _XimProcError(im, 0, (XPointer)&buf_s[3]);
    287     	    if(reply != preply)
    288     		Xfree(preply);
    289 	    return False;
    290 	}
    291     	if(reply != preply)
    292     	    Xfree(preply);
    293     }
    294     return True;
    295 }
    296 #endif /* EXT_FORWARD */
    297 
    298 static int
    299 _XimCheckExtensionListSize(void)
    300 {
    301     register int i;
    302     int		 len;
    303     int		 total = 0;
    304     int		 n = XIMNumber(extensions) - 1;
    305 
    306     for (i = 0; i < n; i++) {
    307 	len = strlen(extensions[i].name);
    308 	extensions[i].name_len = len;
    309 	len += sizeof(BYTE);
    310 	total += len;
    311     }
    312     return total;
    313 }
    314 
    315 static void
    316 _XimSetExtensionList(
    317     CARD8	*buf)
    318 {
    319     register int i;
    320     int		 len;
    321     int		 n = XIMNumber(extensions) - 1;
    322 
    323     for (i = 0; i < n; i++) {
    324 	len = extensions[i].name_len;
    325 	buf[0] = (BYTE)len;
    326 	(void)strcpy((char *)&buf[1], extensions[i].name);
    327 	len += sizeof(BYTE);
    328 	buf += len;
    329     }
    330     return;
    331 }
    332 
    333 static unsigned int
    334 _XimCountNumberOfExtension(
    335     INT16	 total,
    336     CARD8	*ext)
    337 {
    338     unsigned int n;
    339     INT16	 len;
    340     INT16	 min_len = sizeof(CARD8)
    341 			 + sizeof(CARD8)
    342 			 + sizeof(INT16);
    343 
    344     n = 0;
    345     while (total > min_len) {
    346 	len = *((INT16 *)(&ext[2]));
    347 	len += (min_len + XIM_PAD(len));
    348 	total -= len;
    349 	ext += len;
    350 	n++;
    351     }
    352     return n;
    353 }
    354 
    355 static Bool
    356 _XimParseExtensionList(
    357     Xim			 im,
    358     CARD16		*data)
    359 {
    360     int			 num = XIMNumber(extensions) - 1;
    361     unsigned int	 n;
    362     CARD8		*buf;
    363     register int	 i;
    364     register int	 j;
    365     INT16		 len;
    366 
    367     if (!(n = _XimCountNumberOfExtension(data[0], (CARD8 *)&data[1])))
    368 	return True;
    369 
    370     buf = (CARD8 *)&data[1];
    371     for (i = 0; i < n; i++) {
    372 	len = *((INT16 *)(&buf[2]));
    373 	for (j = 0; j < num; j++) {
    374 	    if (!(strncmp(extensions[j].name, (char *)&buf[4], len))) {
    375 		extensions[j].major_opcode = buf[0];
    376 		extensions[j].minor_opcode = buf[1];
    377 		extensions[j].is_support   = True;
    378 		break;
    379 	    }
    380 	}
    381 	len += sizeof(CARD8)		/* sizeof major_opcode */
    382 	     + sizeof(CARD8)		/* sizeof minor_opcode */
    383 	     + sizeof(INT16)		/* sizeof length */
    384 	     + XIM_PAD(len);		/* sizeof pad */
    385 	buf += len;
    386     }
    387 
    388     return True;
    389 }
    390 
    391 static Bool
    392 _XimQueryExtensionCheck(
    393     Xim          im,
    394     INT16        len,
    395     XPointer	 data,
    396     XPointer     arg)
    397 {
    398     CARD16	*buf_s = (CARD16 *)((CARD8 *)data + XIM_HEADER_SIZE);
    399     CARD8	 major_opcode = *((CARD8 *)data);
    400     CARD8	 minor_opcode = *((CARD8 *)data + 1);
    401     XIMID	 imid = buf_s[0];
    402 
    403     if ((major_opcode == XIM_QUERY_EXTENSION_REPLY)
    404      && (minor_opcode == 0)
    405      && (imid == im->private.proto.imid))
    406 	return True;
    407     if ((major_opcode == XIM_ERROR)
    408      && (minor_opcode == 0)
    409      && (buf_s[2] & XIM_IMID_VALID)
    410      && (imid == im->private.proto.imid))
    411 	return True;
    412     return False;
    413 }
    414 
    415 Bool
    416 _XimExtension(
    417     Xim		 im)
    418 {
    419     CARD8	*buf;
    420     CARD16	*buf_s;
    421     int		 buf_len;
    422     INT16	 len;
    423     CARD32	 reply32[BUFSIZE/4];
    424     char	*reply = (char *)reply32;
    425     XPointer	 preply;
    426     int		 buf_size;
    427     int		 ret_code;
    428     int		 idx;
    429 
    430     if (!(len = _XimCheckExtensionListSize()))
    431 	return True;
    432 
    433     buf_len = XIM_HEADER_SIZE
    434 	    + sizeof(CARD16)
    435 	    + sizeof(INT16)
    436 	    + len
    437 	    + XIM_PAD(len);
    438 
    439     if (!(buf = Xmalloc(buf_len)))
    440 	return False;
    441     buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
    442 
    443     buf_s[0] = im->private.proto.imid;	/* imid */
    444     buf_s[1] = len;			/* length of Extensions */
    445     _XimSetExtensionList((CARD8 *)&buf_s[2]);
    446 					/* extensions supported */
    447     XIM_SET_PAD(&buf_s[2], len);	/* pad */
    448     len += sizeof(CARD16)		/* sizeof imid */
    449 	 + sizeof(INT16);		/* sizeof length of extensions */
    450 
    451     _XimSetHeader((XPointer)buf, XIM_QUERY_EXTENSION, 0, &len);
    452     if (!(_XimWrite(im, len, (XPointer)buf))) {
    453         XFree(buf);
    454 	return False;
    455     }
    456     XFree(buf);
    457     _XimFlush(im);
    458     buf_size = BUFSIZE;
    459     ret_code = _XimRead(im, &len, (XPointer)reply, buf_size,
    460     					_XimQueryExtensionCheck, 0);
    461     if(ret_code == XIM_TRUE) {
    462     	preply = reply;
    463     } else if(ret_code == XIM_OVERFLOW) {
    464     	if(len <= 0) {
    465     	    preply = reply;
    466     	} else {
    467     	    buf_size = len;
    468 	    preply = Xmalloc(buf_size);
    469     	    ret_code = _XimRead(im, &len, preply, buf_size,
    470     					_XimQueryExtensionCheck, 0);
    471     	    if(ret_code != XIM_TRUE) {
    472 		Xfree(preply);
    473     		return False;
    474 	    }
    475     	}
    476     } else
    477 	return False;
    478     buf_s = (CARD16 *)((char *)preply + XIM_HEADER_SIZE);
    479     if (*((CARD8 *)preply) == XIM_ERROR) {
    480 	_XimProcError(im, 0, (XPointer)&buf_s[3]);
    481     	if(reply != preply)
    482     	    Xfree(preply);
    483 	return False;
    484     }
    485 
    486     if (!(_XimParseExtensionList(im, &buf_s[1]))) {
    487     	if(reply != preply)
    488     	    Xfree(preply);
    489 	return False;
    490     }
    491     if(reply != preply)
    492     	Xfree(preply);
    493 
    494     if ((idx = _XimIsSupportExt(XIM_EXT_SET_EVENT_MASK_IDX)) >= 0)
    495 	_XimRegProtoIntrCallback(im,
    496 	 	extensions[idx].major_opcode,
    497 	 	extensions[idx].minor_opcode,
    498 		_XimExtSetEventMaskCallback, (XPointer)im);
    499 #ifdef EXT_FORWARD
    500     if ((idx = _XimIsSupportExt(XIM_EXT_FORWARD_KEYEVENT_IDX)) >= 0)
    501 	_XimRegProtoIntrCallback(im,
    502 		extensions[idx].major_opcode,
    503 		extensions[idx].minor_opcode,
    504 		_XimExtForwardKeyEventCallback, (XPointer)im);
    505 #endif
    506 
    507     return True;
    508 }
    509 
    510 #ifdef EXT_MOVE
    511 /* flag of ExtenArgCheck */
    512 #define	EXT_XNSPOTLOCATION	(1L<<0)
    513 
    514 /* macro for ExtenArgCheck */
    515 #define SET_EXT_XNSPOTLOCATION(flag) (flag |= EXT_XNSPOTLOCATION)
    516 #define IS_EXT_XNSPOTLOCATION(flag)  (flag & EXT_XNSPOTLOCATION)
    517 
    518 /* length of XPoint attribute */
    519 #define	XIM_Xpoint_length	12
    520 
    521 static Bool
    522 _XimExtMove(
    523     Xim		 im,
    524     Xic		 ic,
    525     CARD16	 x,
    526     CARD16	 y)
    527 {
    528     CARD32	 buf32[BUFSIZE/4];
    529     CARD8	*buf = (CARD8 *)buf32;
    530     CARD16	*buf_s = (CARD16 *)&buf[XIM_HEADER_SIZE];
    531     INT16	 len;
    532     int		idx;
    533 
    534     if ((idx = _XimIsSupportExt(XIM_EXT_MOVE_IDX)) < 0)
    535 	return False;
    536 
    537     buf_s[0] = im->private.proto.imid;	/* imid */
    538     buf_s[1] = ic->private.proto.icid;	/* icid */
    539     buf_s[2] = x;			/* X */
    540     buf_s[3] = y;			/* Y */
    541     len = sizeof(CARD16)		/* sizeof imid */
    542 	+ sizeof(CARD16)		/* sizeof icid */
    543 	+ sizeof(INT16)			/* sizeof X */
    544 	+ sizeof(INT16);		/* sizeof Y */
    545 
    546     _XimSetHeader((XPointer)buf, extensions[idx].major_opcode,
    547 			extensions[idx].minor_opcode, &len);
    548     if (!(_XimWrite(im, len, (XPointer)buf)))
    549 	return False;
    550     _XimFlush(im);
    551     return True;
    552 }
    553 
    554 BITMASK32
    555 _XimExtenArgCheck(
    556     XIMArg	*arg)
    557 {
    558     CARD32	flag = 0L;
    559     if (!strcmp(arg->name, XNSpotLocation))
    560 	SET_EXT_XNSPOTLOCATION(flag);
    561     return flag;
    562 }
    563 
    564 Bool
    565 _XimExtenMove(
    566     Xim		 im,
    567     Xic		 ic,
    568     CARD32	 flag,
    569     CARD16	*buf,
    570     INT16	 length)
    571 {
    572     if ((IS_EXT_XNSPOTLOCATION(flag)) && (length == XIM_Xpoint_length))
    573 	return _XimExtMove(im, ic, buf[4], buf[5]);
    574     return False;
    575 }
    576 #endif /* EXT_MOVE */
    577