1/* $XFree86: xc/lib/Xxf86misc/XF86Misc.c,v 3.12 2002/11/20 04:04:57 dawes Exp $ */
2
3/*
4 * Copyright (c) 1995, 1996  The XFree86 Project, Inc
5 */
6
7/* THIS IS NOT AN X CONSORTIUM STANDARD */
8
9#define NEED_EVENTS
10#define NEED_REPLIES
11#include <X11/Xlibint.h>
12#include <X11/extensions/xf86mscstr.h>
13#include <X11/extensions/Xext.h>
14#include <X11/extensions/extutil.h>
15
16static XExtensionInfo _xf86misc_info_data;
17static XExtensionInfo *xf86misc_info = &_xf86misc_info_data;
18static char *xf86misc_extension_name = XF86MISCNAME;
19
20#define XF86MiscCheckExtension(dpy,i,val) \
21  XextCheckExtension (dpy, i, xf86misc_extension_name, val)
22
23/*****************************************************************************
24 *                                                                           *
25 *			   private utility routines                          *
26 *                                                                           *
27 *****************************************************************************/
28
29static int close_display(Display *dpy, XExtCodes *codes);
30
31static /* const */ XExtensionHooks xf86misc_extension_hooks = {
32    NULL,				/* create_gc */
33    NULL,				/* copy_gc */
34    NULL,				/* flush_gc */
35    NULL,				/* free_gc */
36    NULL,				/* create_font */
37    NULL,				/* free_font */
38    close_display,			/* close_display */
39    NULL,				/* wire_to_event */
40    NULL,				/* event_to_wire */
41    NULL,				/* error */
42    NULL,				/* error_string */
43};
44
45static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86misc_info,
46				   xf86misc_extension_name,
47				   &xf86misc_extension_hooks,
48				   0, NULL)
49
50static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86misc_info)
51
52
53/*****************************************************************************
54 *                                                                           *
55 *		    public XFree86-Misc Extension routines                *
56 *                                                                           *
57 *****************************************************************************/
58
59Bool XF86MiscQueryExtension (Display *dpy, int *event_basep, int *error_basep)
60{
61    XExtDisplayInfo *info = find_display (dpy);
62
63    if (XextHasExtension(info)) {
64	*event_basep = info->codes->first_event;
65	*error_basep = info->codes->first_error;
66	return True;
67    } else {
68	return False;
69    }
70}
71
72Bool XF86MiscQueryVersion(Display* dpy, int* majorVersion, int* minorVersion)
73{
74    XExtDisplayInfo *info = find_display (dpy);
75    xXF86MiscQueryVersionReply rep;
76    xXF86MiscQueryVersionReq *req;
77
78    XF86MiscCheckExtension (dpy, info, False);
79    LockDisplay(dpy);
80    GetReq(XF86MiscQueryVersion, req);
81    req->reqType = info->codes->major_opcode;
82    req->xf86miscReqType = X_XF86MiscQueryVersion;
83    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
84	UnlockDisplay(dpy);
85	SyncHandle();
86	return False;
87    }
88    *majorVersion = rep.majorVersion;
89    *minorVersion = rep.minorVersion;
90    UnlockDisplay(dpy);
91    SyncHandle();
92    if (*majorVersion > 0 || *minorVersion > 5)
93	XF86MiscSetClientVersion(dpy);
94
95    return True;
96}
97
98Bool
99XF86MiscSetClientVersion(Display *dpy)
100{
101    XExtDisplayInfo *info = find_display(dpy);
102    xXF86MiscSetClientVersionReq *req;
103
104    XF86MiscCheckExtension(dpy, info, False);
105
106    LockDisplay(dpy);
107    GetReq(XF86MiscSetClientVersion, req);
108    req->reqType = info->codes->major_opcode;
109    req->xf86miscReqType = X_XF86MiscSetClientVersion;
110    req->major = XF86MISC_MAJOR_VERSION;
111    req->minor = XF86MISC_MINOR_VERSION;
112    UnlockDisplay(dpy);
113    SyncHandle();
114    return True;
115}
116
117Bool XF86MiscGetMouseSettings(Display* dpy, XF86MiscMouseSettings *mouseinfo)
118{
119    XExtDisplayInfo *info = find_display (dpy);
120    xXF86MiscGetMouseSettingsReply rep;
121    xXF86MiscGetMouseSettingsReq *req;
122
123    XF86MiscCheckExtension (dpy, info, False);
124
125    LockDisplay(dpy);
126    GetReq(XF86MiscGetMouseSettings, req);
127    req->reqType = info->codes->major_opcode;
128    req->xf86miscReqType = X_XF86MiscGetMouseSettings;
129    if (!_XReply(dpy, (xReply *)&rep,
130		(SIZEOF(xXF86MiscGetMouseSettingsReply) - SIZEOF(xReply))>>2,
131		xFalse)) {
132	UnlockDisplay(dpy);
133	SyncHandle();
134	return False;
135    }
136
137    mouseinfo->type = rep.mousetype;
138    mouseinfo->baudrate = rep.baudrate;
139    mouseinfo->samplerate = rep.samplerate;
140    mouseinfo->resolution = rep.resolution;
141    mouseinfo->buttons = rep.buttons;
142    mouseinfo->emulate3buttons = rep.emulate3buttons;
143    mouseinfo->emulate3timeout = rep.emulate3timeout;
144    mouseinfo->chordmiddle = rep.chordmiddle;
145    mouseinfo->flags = rep.flags;
146    if (rep.devnamelen > 0) {
147        if (!(mouseinfo->device = Xcalloc(rep.devnamelen + 1, 1))) {
148            _XEatData(dpy, (rep.devnamelen+3) & ~3);
149            Xfree(mouseinfo->device);
150	    UnlockDisplay(dpy);
151	    SyncHandle();
152            return False;
153        }
154        _XReadPad(dpy, mouseinfo->device, rep.devnamelen);
155    } else
156	mouseinfo->device = NULL;
157
158    UnlockDisplay(dpy);
159    SyncHandle();
160    return True;
161}
162
163Bool XF86MiscGetKbdSettings(Display* dpy, XF86MiscKbdSettings *kbdinfo)
164{
165    XExtDisplayInfo *info = find_display (dpy);
166    xXF86MiscGetKbdSettingsReply rep;
167    xXF86MiscGetKbdSettingsReq *req;
168
169    XF86MiscCheckExtension (dpy, info, False);
170
171    LockDisplay(dpy);
172    GetReq(XF86MiscGetKbdSettings, req);
173    req->reqType = info->codes->major_opcode;
174    req->xf86miscReqType = X_XF86MiscGetKbdSettings;
175    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
176	UnlockDisplay(dpy);
177	SyncHandle();
178	return False;
179    }
180
181    kbdinfo->type = rep.kbdtype;
182    kbdinfo->rate = rep.rate;
183    kbdinfo->delay = rep.delay;
184    kbdinfo->servnumlock = rep.servnumlock;
185
186    UnlockDisplay(dpy);
187    SyncHandle();
188    return True;
189}
190
191Bool XF86MiscSetMouseSettings(Display* dpy, XF86MiscMouseSettings *mouseinfo)
192{
193    XExtDisplayInfo *info = find_display (dpy);
194    xXF86MiscSetMouseSettingsReq *req;
195    int majorVersion, minorVersion;
196
197    XF86MiscCheckExtension (dpy, info, False);
198    XF86MiscQueryVersion(dpy, &majorVersion, &minorVersion);
199
200    LockDisplay(dpy);
201    GetReq(XF86MiscSetMouseSettings, req);
202
203    req->reqType = info->codes->major_opcode;
204    req->xf86miscReqType = X_XF86MiscSetMouseSettings;
205    req->mousetype = mouseinfo->type;
206    req->baudrate = mouseinfo->baudrate;
207    req->samplerate = mouseinfo->samplerate;
208    req->resolution = mouseinfo->resolution;
209    req->buttons = mouseinfo->buttons;
210    req->emulate3buttons = mouseinfo->emulate3buttons;
211    req->emulate3timeout = mouseinfo->emulate3timeout;
212    req->chordmiddle = mouseinfo->chordmiddle;
213    req->flags = mouseinfo->flags;
214    if (majorVersion > 0 || minorVersion > 5) {
215	int len;
216	if ((len = strlen(mouseinfo->device))) {
217	req->devnamelen =  len + 1;
218	len = (req->devnamelen + 3) >> 2;
219	SetReqLen(req,len,len);
220	Data(dpy, mouseinfo->device, req->devnamelen);
221	}
222    }
223
224    UnlockDisplay(dpy);
225    SyncHandle();
226    return True;
227}
228
229Bool XF86MiscSetKbdSettings(Display* dpy, XF86MiscKbdSettings *kbdinfo)
230{
231    XExtDisplayInfo *info = find_display (dpy);
232    xXF86MiscSetKbdSettingsReq *req;
233
234    XF86MiscCheckExtension (dpy, info, False);
235
236    LockDisplay(dpy);
237    GetReq(XF86MiscSetKbdSettings, req);
238    req->reqType = info->codes->major_opcode;
239    req->xf86miscReqType = X_XF86MiscSetKbdSettings;
240    req->kbdtype = kbdinfo->type;
241    req->rate = kbdinfo->rate;
242    req->delay = kbdinfo->delay;
243    req->servnumlock = kbdinfo->servnumlock;
244
245    UnlockDisplay(dpy);
246    SyncHandle();
247    return True;
248}
249
250int XF86MiscSetGrabKeysState(Display* dpy, Bool enable)
251{
252    XExtDisplayInfo *info = find_display (dpy);
253    xXF86MiscSetGrabKeysStateReply rep;
254    xXF86MiscSetGrabKeysStateReq *req;
255
256    XF86MiscCheckExtension (dpy, info, False);
257
258    LockDisplay(dpy);
259    GetReq(XF86MiscSetGrabKeysState, req);
260    req->reqType = info->codes->major_opcode;
261    req->xf86miscReqType = X_XF86MiscSetGrabKeysState;
262    req->enable = enable;
263    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
264	UnlockDisplay(dpy);
265	SyncHandle();
266	return 0;
267    }
268
269    UnlockDisplay(dpy);
270    SyncHandle();
271    return rep.status;
272}
273
274Bool XF86MiscGetFilePaths(Display* dpy, XF86MiscFilePaths *filpaths)
275{
276    XExtDisplayInfo *info = find_display (dpy);
277    xXF86MiscGetFilePathsReply rep;
278    xXF86MiscGetFilePathsReq *req;
279
280    XF86MiscCheckExtension (dpy, info, False);
281
282    LockDisplay(dpy);
283    GetReq(XF86MiscGetFilePaths, req);
284    req->reqType = info->codes->major_opcode;
285    req->xf86miscReqType = X_XF86MiscGetFilePaths;
286    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
287	UnlockDisplay(dpy);
288	SyncHandle();
289	return False;
290    }
291
292    if (rep.configlen) {
293        if (!(filpaths->configfile = Xcalloc(rep.configlen + 1, 1))) {
294            _XEatData(dpy, ((rep.configlen+3) & ~3) + ((rep.modulelen+3) & ~3)
295			    + ((rep.loglen+3) & ~3));
296	    UnlockDisplay(dpy);
297	    SyncHandle();
298            return False;
299        }
300    }
301
302    if (rep.modulelen) {
303        if (!(filpaths->modulepath = Xcalloc(rep.modulelen + 1, 1))) {
304            _XEatData(dpy, ((rep.configlen+3) & ~3) + ((rep.modulelen+3) & ~3)
305			    + ((rep.loglen+3) & ~3));
306            if (filpaths->configfile)
307		    Xfree(filpaths->configfile);
308	    UnlockDisplay(dpy);
309	    SyncHandle();
310            return False;
311        }
312    }
313
314    if (rep.loglen) {
315        if (!(filpaths->logfile = Xcalloc(rep.loglen + 1, 1))) {
316            _XEatData(dpy, ((rep.configlen+3) & ~3) + ((rep.modulelen+3) & ~3)
317			    + ((rep.loglen+3) & ~3));
318            if (filpaths->configfile)
319		    Xfree(filpaths->configfile);
320            if (filpaths->modulepath)
321		    Xfree(filpaths->modulepath);
322	    UnlockDisplay(dpy);
323	    SyncHandle();
324            return False;
325        }
326    }
327
328    if (rep.configlen)
329        _XReadPad(dpy, filpaths->configfile, rep.configlen);
330    else
331	filpaths->configfile = "";
332
333    if (rep.modulelen)
334        _XReadPad(dpy, filpaths->modulepath, rep.modulelen);
335    else
336	filpaths->modulepath = "";
337
338    if (rep.loglen)
339        _XReadPad(dpy, filpaths->logfile, rep.loglen);
340    else
341	filpaths->logfile = "";
342
343    UnlockDisplay(dpy);
344    SyncHandle();
345    return True;
346}
347
348Status XF86MiscPassMessage(Display* dpy, int screen,
349			   const char* msgtype, const char* msgval,
350			   char** retmsg)
351{
352    XExtDisplayInfo *info = find_display (dpy);
353    xXF86MiscPassMessageReply rep;
354    xXF86MiscPassMessageReq *req;
355    int len;
356
357    XF86MiscCheckExtension (dpy, info, False);
358
359    LockDisplay(dpy);
360    GetReq(XF86MiscPassMessage, req);
361    req->reqType = info->codes->major_opcode;
362    req->xf86miscReqType = X_XF86MiscPassMessage;
363    req->screen = screen;
364    if ((len = strlen(msgtype))) {
365	req->typelen =  len + 1;
366	len = (req->typelen + 3) >> 2;
367	SetReqLen(req,len,len);
368	Data(dpy, msgtype, req->typelen);
369    }
370    if ((len = strlen(msgval))) {
371	req->vallen =  len + 1;
372	len = (req->vallen + 3) >> 2;
373	SetReqLen(req,len,len);
374	Data(dpy, msgval, req->vallen);
375    }
376    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
377	UnlockDisplay(dpy);
378	SyncHandle();
379	return BadImplementation;
380    }
381
382    if (rep.mesglen) {
383        if (!(*retmsg = Xcalloc(rep.mesglen + 1, 1))) {
384            _XEatData(dpy, ((rep.mesglen+3) & ~3));
385	    UnlockDisplay(dpy);
386	    SyncHandle();
387            return BadAlloc;
388        }
389        _XReadPad(dpy, *retmsg, rep.mesglen);
390    }
391
392    UnlockDisplay(dpy);
393    SyncHandle();
394    return rep.status;
395}
396
397