File: cli_xcin.c

package info (click to toggle)
rxvt 1%3A2.4.5-16
  • links: PTS
  • area: main
  • in suites: slink
  • size: 1,128 kB
  • ctags: 1,296
  • sloc: ansic: 12,852; makefile: 521; sh: 411
file content (145 lines) | stat: -rw-r--r-- 3,355 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
	Copyright (C) 1994,1995	Edward Der-Hua Liu, Hsin-Chu, Taiwan
*/

#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include "state.h"
#include "protocol.h"

static void p_err(char *fmt,...)
{
  va_list args;
  
  va_start(args, fmt);
  fprintf(stderr,"%s:", "cli_xcin:");
  vfprintf(stderr, fmt, args);
  va_end(args);
  fprintf(stderr,"\n");
  exit(-1);
} 


static Atom xcin_atom=0;
static Window xcin_win=None;
static InmdState inmdstate;
#define ENDIAN_TEST() (*(int *)"\x11\x22\x33\x44"==0x11223344)
char my_endian;

static connect_xcin(Display *display)
{
Window twin;
xcin_atom=XInternAtom(display, XCIN_ATOM,False);
my_endian=ENDIAN_TEST();  /* if == 11223344, it is big-endian */

xcin_win=XGetSelectionOwner(display,xcin_atom);
return xcin_win;
}

void send_FocusIn(Display *display, Window window)
{
	XClientMessageEvent event;
	XEvent erreve;
	char *tmp=event.data.b;

	if (connect_xcin(display)==None) return;
/* Ensure xcin exists, or the process will be hanged */
	event.type=ClientMessage;
	event.window=window;
	event.message_type=xcin_atom;
	event.format=8;
	
	tmp[0]=tmp[1]=tmp[2]=0xff;
	tmp[3]=CLI_FOCUS_IN;
	memcpy(&tmp[4],&inmdstate, sizeof(inmdstate));
	XSendEvent(display, xcin_win, False, 0, (XEvent *)&event);
}

void send_FocusOut(Display *display, Window window)
{
	XClientMessageEvent event;
	XEvent erreve;
	char *tmp=event.data.b;

	if (connect_xcin(display)==None) return;
/* Ensure xcin exists, or the process will be hanged */
	event.type=ClientMessage;
	event.window=window;
	event.message_type=xcin_atom;
	event.format=8;
	
	tmp[0]=tmp[1]=tmp[2]=0xff;
	tmp[3]=CLI_FOCUS_OUT;
	memcpy(&tmp[4],&inmdstate, sizeof(inmdstate));
	XSendEvent(display, xcin_win, False, 0, (XEvent *)&event);
}

static void big_little(char *i)
{
char t;
t=*i; *i=*(i+3); *(i+3)=t;
t=*(i+1); *(i+1)=*(i+2); *(i+2)=t;
}
static read_keys(Display *display, char *buf)
{
	Atom actual_type;
	int actual_format,i;
	u_long nitems,bytes_after;
	char *ttt, *cp;
	XCIN_RES res;
	int ofs;
 
	cp=(char *)&res;
	ofs=0;
	do { 
	if (XGetWindowProperty(display,xcin_win,xcin_atom,
		ofs/4,(sizeof(XCIN_RES)+3)/4,
		True, AnyPropertyType, &actual_type,&actual_format,
		&nitems,&bytes_after,(unsigned char **)&ttt) != Success)
			puts("err property");
		memcpy((char *)(&res)+(ofs & ~0x3), ttt, nitems);
		XFree(ttt);
		ofs=(ofs & ~0x3) + nitems;
	} while ((!nitems && !ofs) || bytes_after>0);
	if (my_endian) {
		big_little((char *)&res.len);
		big_little((char *)&res.status);
	}
	memcpy(buf,res.tkey, res.len);
	inmdstate=res.inmdstate;
	buf[res.len]=0;
 
	return  res.status;
}

#include <X11/Xutil.h>

static XComposeStatus compose_status = {NULL, 0};

send_key(Display *display, Window win, XKeyEvent *eve, char *buf)
{
XClientMessageEvent event;
XEvent erreve;
char *tmp=event.data.b;
u_char tttt[8];
KeySym keysym;
int count;

if (xcin_win==None && connect_xcin(display)==None)
	return K_REJECT;
if ((xcin_win=XGetSelectionOwner(display,xcin_atom))==None)
	return K_REJECT;

event.type=ClientMessage;
event.window=win;
event.message_type=xcin_atom;
event.format=32;
count = XLookupString (eve, tttt, sizeof(tmp), (KeySym *)tmp, &compose_status);
memcpy(&tmp[4],&eve->state,4);
XSendEvent(display, xcin_win, False, 0, (XEvent *)&event);
XSync(display,False);
return (read_keys(display, buf));
}