1 /******************************************************************
2 
3          Copyright 1994, 1995 by Sun Microsystems, Inc.
4          Copyright 1993, 1994 by Hewlett-Packard Company
5 
6 Permission to use, copy, modify, distribute, and sell this software
7 and its documentation for any purpose is hereby granted without fee,
8 provided that the above copyright notice appear in all copies and
9 that both that copyright notice and this permission notice appear
10 in supporting documentation, and that the name of Sun Microsystems, Inc.
11 and Hewlett-Packard not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior permission.
13 Sun Microsystems, Inc. and Hewlett-Packard make no representations about
14 the suitability of this software for any purpose.  It is provided "as is"
15 without express or implied warranty.
16 
17 SUN MICROSYSTEMS INC. AND HEWLETT-PACKARD COMPANY DISCLAIMS ALL
18 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20 SUN MICROSYSTEMS, INC. AND HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY
21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
22 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
23 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
24 IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 
26   Author: Hidetoshi Tajima(tajima@Eng.Sun.COM) Sun Microsystems, Inc.
27 
28 ******************************************************************/
29 #include <X11/Xlib.h>
30 #include <X11/Ximd/IMdkit.h>
31 #include <X11/Ximd/Xi18n.h>
32 #include "IC.h"
33 #include <stdio.h>
34 
35 static IC *ic_list = (IC *)NULL;
36 static IC *free_list = (IC *)NULL;
37 
38 static IC
NewIC()39 *NewIC()
40 {
41     static CARD16 icid = 0;
42     IC *rec;
43 
44     if (free_list != NULL) {
45 	rec = free_list;
46 	free_list = free_list->next;
47     } else {
48 	rec = (IC *)malloc(sizeof(IC));
49     }
50     memset(rec, 0, sizeof(IC));
51     rec->id = ++icid;
52 
53     rec->next = ic_list;
54     ic_list = rec;
55     return rec;
56 }
57 
58 IC
FindIC(icid)59 *FindIC(icid)
60 CARD16 icid;
61 {
62     IC *rec = ic_list;
63 
64     while (rec != NULL) {
65 	if (rec->id == icid)
66 	  return rec;
67 	rec = rec->next;
68     }
69 
70     return NULL;
71 }
72 
73 static void
DeleteIC(icid)74 DeleteIC(icid)
75 CARD16 icid;
76 {
77     IC *rec, *last;
78 
79     last = NULL;
80     for (rec = ic_list; rec != NULL; last = rec, rec = rec->next) {
81         if (rec->id == icid) {
82           if (last != NULL)
83             last->next = rec->next;
84           else
85             ic_list = rec->next;
86 
87           rec->next = free_list;
88           free_list = rec;
89           return;
90 	}
91     }
92     return;
93 }
94 
Is(char * attr,XICAttribute * attr_list)95 static int Is(char *attr, XICAttribute *attr_list) {
96 	return !strcmp(attr, attr_list->name);
97 }
98 
99 static void
StoreIC(rec,call_data)100 StoreIC(rec, call_data)
101 IC *rec;
102 IMChangeICStruct *call_data;
103 {
104 	XICAttribute *ic_attr = call_data->ic_attr;
105 	XICAttribute *pre_attr = call_data->preedit_attr;
106 	XICAttribute *sts_attr = call_data->status_attr;
107 	register int i;
108 
109 	for (i = 0; i < (int)call_data->ic_attr_num; i++, ic_attr++) {
110 		if (Is (XNInputStyle, ic_attr))
111 		    rec->input_style = *(INT32*)ic_attr->value;
112 
113 		else if (Is (XNClientWindow, ic_attr))
114 		    rec->client_win = *(Window*)ic_attr->value;
115 
116 		else if (Is (XNFocusWindow, ic_attr))
117 		    rec->focus_win = *(Window*)ic_attr->value;
118 
119 		else
120 		    fprintf(stderr, "Unknown attr: %s\n", ic_attr->name);
121 	}
122 
123 	for (i = 0; i < (int)call_data->preedit_attr_num; i++, pre_attr++) {
124 		if (Is (XNArea, pre_attr))
125 		    rec->pre_attr.area = *(XRectangle*)pre_attr->value;
126 
127 		else if (Is (XNAreaNeeded, pre_attr))
128 		    rec->pre_attr.area_needed = *(XRectangle*)pre_attr->value;
129 
130 		else if (Is (XNSpotLocation, pre_attr))
131 		    rec->pre_attr.spot_location = *(XPoint*)pre_attr->value;
132 
133 		else if (Is (XNColormap, pre_attr))
134 		    rec->pre_attr.cmap = *(Colormap*)pre_attr->value;
135 
136 		else if (Is (XNStdColormap, pre_attr))
137 		    rec->pre_attr.cmap = *(Colormap*)pre_attr->value;
138 
139 		else if (Is (XNForeground, pre_attr))
140 		    rec->pre_attr.foreground = *(CARD32*)pre_attr->value;
141 
142 		else if (Is (XNBackground, pre_attr))
143 		    rec->pre_attr.background = *(CARD32*)pre_attr->value;
144 
145 		else if (Is (XNBackgroundPixmap, pre_attr))
146 		    rec->pre_attr.bg_pixmap = *(Pixmap*)pre_attr->value;
147 
148 		else if (Is (XNFontSet, pre_attr)) {
149 			int str_length = strlen(pre_attr->value);
150 
151 			if (rec->pre_attr.base_font != NULL) {
152 				if (Is (rec->pre_attr.base_font, pre_attr))
153 					continue;
154 				XFree(rec->pre_attr.base_font);
155 			}
156 			rec->pre_attr.base_font = malloc(str_length + 1);
157 			strcpy(rec->pre_attr.base_font, pre_attr->value);
158 
159 		} else if (Is (XNLineSpace, pre_attr))
160 			    rec->pre_attr.line_space = *(CARD32*)pre_attr->value;
161 
162 		else if (Is (XNCursor, pre_attr))
163 		    rec->pre_attr.cursor = *(Cursor*)pre_attr->value;
164 
165 		else
166 		    fprintf(stderr, "Unknown attr: %s\n", ic_attr->name);
167 	}
168 
169 	for (i = 0; i < (int)call_data->status_attr_num; i++, sts_attr++) {
170 		if (Is (XNArea, sts_attr))
171 		    rec->sts_attr.area = *(XRectangle*)sts_attr->value;
172 
173 		else if (Is (XNAreaNeeded, sts_attr))
174 		    rec->sts_attr.area_needed = *(XRectangle*)sts_attr->value;
175 
176 		else if (Is (XNColormap, sts_attr))
177 		    rec->sts_attr.cmap = *(Colormap*)sts_attr->value;
178 
179 		else if (Is (XNStdColormap, sts_attr))
180 		    rec->sts_attr.cmap = *(Colormap*)sts_attr->value;
181 
182 		else if (Is (XNForeground, sts_attr))
183 		    rec->sts_attr.foreground = *(CARD32*)sts_attr->value;
184 
185 		else if (Is (XNBackground, sts_attr))
186 		    rec->sts_attr.background = *(CARD32*)sts_attr->value;
187 
188 		else if (Is (XNBackgroundPixmap, sts_attr))
189 		    rec->sts_attr.bg_pixmap = *(Pixmap*)sts_attr->value;
190 
191 		else if (Is (XNFontSet, sts_attr)) {
192 			int str_length = strlen(sts_attr->value);
193 
194 			if (rec->sts_attr.base_font != NULL) {
195 				if (Is (rec->sts_attr.base_font, sts_attr))
196 					continue;
197 				XFree(rec->sts_attr.base_font);
198 			}
199 			rec->sts_attr.base_font = malloc(str_length + 1);
200 			strcpy(rec->sts_attr.base_font, sts_attr->value);
201 
202 		} else if (Is (XNLineSpace, sts_attr))
203 			    rec->sts_attr.line_space= *(CARD32*)sts_attr->value;
204 
205 		else if (Is (XNCursor, sts_attr))
206 
207 		    rec->sts_attr.cursor = *(Cursor*)sts_attr->value;
208 
209 		else
210 		    fprintf(stderr, "Unknown attr: %s\n", ic_attr->name);
211 	}
212 
213 }
214 
215 void
CreateIC(call_data)216 CreateIC(call_data)
217 IMChangeICStruct *call_data;
218 {
219     IC *rec;
220 
221     rec = NewIC();
222     if (rec == NULL)
223       return;
224     StoreIC(rec, call_data);
225     call_data->icid = rec->id;
226     return;
227 }
228 
229 void
DestroyIC(call_data)230 DestroyIC(call_data)
231 IMChangeICStruct *call_data;
232 {
233     DeleteIC(call_data->icid);
234     return;
235 }
236 
237 void
SetIC(call_data)238 SetIC(call_data)
239 IMChangeICStruct *call_data;
240 {
241     IC *rec = FindIC(call_data->icid);
242 
243     if (rec == NULL)
244       return;
245     StoreIC(rec, call_data);
246     return;
247 }
248 
249 void
GetIC(call_data)250 GetIC(call_data)
251 IMChangeICStruct *call_data;
252 {
253     XICAttribute *ic_attr = call_data->ic_attr;
254     XICAttribute *pre_attr = call_data->preedit_attr;
255     XICAttribute *sts_attr = call_data->status_attr;
256     register int i;
257     IC *rec = FindIC(call_data->icid);
258 
259     if (rec == NULL)
260       return;
261     for (i = 0; i < (int)call_data->ic_attr_num; i++, ic_attr++) {
262 	if (Is (XNFilterEvents, ic_attr)) {
263 	    ic_attr->value = (void *)malloc(sizeof(CARD32));
264 	    *(CARD32*)ic_attr->value = KeyPressMask|KeyReleaseMask;
265 	    ic_attr->value_length = sizeof(CARD32);
266 	}
267     }
268 
269     /* preedit attributes */
270     for (i = 0; i < (int)call_data->preedit_attr_num; i++, pre_attr++) {
271 	if (Is (XNArea, pre_attr)) {
272 	    pre_attr->value = (void *)malloc(sizeof(XRectangle));
273 	    *(XRectangle*)pre_attr->value = rec->pre_attr.area;
274 	    pre_attr->value_length = sizeof(XRectangle);
275 
276 	} else if (Is (XNAreaNeeded, pre_attr)) {
277 	    pre_attr->value = (void *)malloc(sizeof(XRectangle));
278 	    *(XRectangle*)pre_attr->value = rec->pre_attr.area_needed;
279 	    pre_attr->value_length = sizeof(XRectangle);
280 
281 	} else if (Is (XNSpotLocation, pre_attr)) {
282 	    pre_attr->value = (void *)malloc(sizeof(XPoint));
283 	    *(XPoint*)pre_attr->value = rec->pre_attr.spot_location;
284 	    pre_attr->value_length = sizeof(XPoint);
285 
286 	} else if (Is (XNFontSet, pre_attr)) {
287 	    CARD16 base_len = (CARD16)strlen(rec->pre_attr.base_font);
288 	    int total_len = sizeof(CARD16) + (CARD16)base_len;
289 	    char *p;
290 
291 	    pre_attr->value = (void *)malloc(total_len);
292 	    p = (char *)pre_attr->value;
293 	    memmove(p, &base_len, sizeof(CARD16));
294 	    p += sizeof(CARD16);
295 	    strncpy(p, rec->pre_attr.base_font, base_len);
296 	    pre_attr->value_length = total_len;
297 
298 	} else if (Is (XNForeground, pre_attr)) {
299 	    pre_attr->value = (void *)malloc(sizeof(long));
300 	    *(long*)pre_attr->value = rec->pre_attr.foreground;
301 	    pre_attr->value_length = sizeof(long);
302 
303 	} else if (Is (XNBackground, pre_attr)) {
304 	    pre_attr->value = (void *)malloc(sizeof(long));
305 	    *(long*)pre_attr->value = rec->pre_attr.background;
306 	    pre_attr->value_length = sizeof(long);
307 
308 	} else if (Is (XNLineSpace, pre_attr)) {
309 	    pre_attr->value = (void *)malloc(sizeof(long));
310 #if 0
311 	    *(long*)pre_attr->value = rec->pre_attr.line_space;
312 #endif
313 	    *(long*)pre_attr->value = 18;
314 	    pre_attr->value_length = sizeof(long);
315 	}
316     }
317 
318     /* status attributes */
319     for (i = 0; i < (int)call_data->status_attr_num; i++, sts_attr++) {
320 	if (Is (XNArea, sts_attr)) {
321 	    sts_attr->value = (void *)malloc(sizeof(XRectangle));
322 	    *(XRectangle*)sts_attr->value = rec->sts_attr.area;
323 	    sts_attr->value_length = sizeof(XRectangle);
324 
325 	} else if (Is (XNAreaNeeded, sts_attr)) {
326 	    sts_attr->value = (void *)malloc(sizeof(XRectangle));
327 	    *(XRectangle*)sts_attr->value = rec->sts_attr.area_needed;
328 	    sts_attr->value_length = sizeof(XRectangle);
329 
330 	} else if (Is (XNFontSet, sts_attr)) {
331 	    CARD16 base_len = (CARD16)strlen(rec->sts_attr.base_font);
332 	    int total_len = sizeof(CARD16) + (CARD16)base_len;
333 	    char *p;
334 
335 	    sts_attr->value = (void *)malloc(total_len);
336 	    p = (char *)sts_attr->value;
337 	    memmove(p, &base_len, sizeof(CARD16));
338 	    p += sizeof(CARD16);
339 	    strncpy(p, rec->sts_attr.base_font, base_len);
340 	    sts_attr->value_length = total_len;
341 
342 	} else if (Is (XNForeground, sts_attr)) {
343 	    sts_attr->value = (void *)malloc(sizeof(long));
344 	    *(long*)sts_attr->value = rec->sts_attr.foreground;
345 	    sts_attr->value_length = sizeof(long);
346 
347 	} else if (Is (XNBackground, sts_attr)) {
348 	    sts_attr->value = (void *)malloc(sizeof(long));
349 	    *(long*)sts_attr->value = rec->sts_attr.background;
350 	    sts_attr->value_length = sizeof(long);
351 
352 	} else if (Is (XNLineSpace, sts_attr)) {
353 	    sts_attr->value = (void *)malloc(sizeof(long));
354 #if 0
355 	    *(long*)sts_attr->value = rec->sts_attr.line_space;
356 #endif
357 	    *(long*)sts_attr->value = 18;
358 	    sts_attr->value_length = sizeof(long);
359 	}
360     }
361 }
362