#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "Xfixesint.h"
XFixesExtInfo XFixesExtensionInfo;
char XFixesExtensionName[] = XFIXES_NAME;
static int
XFixesCloseDisplay (Display *dpy, XExtCodes *codes);
static Bool
XFixesWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
static Status
XFixesEventToWire(Display *dpy, XEvent *event, xEvent *wire);
static XFixesExtDisplayInfo *
XFixesExtAddDisplay (XFixesExtInfo *extinfo,
Display *dpy,
char *ext_name)
{
XFixesExtDisplayInfo *info;
int ev;
info = (XFixesExtDisplayInfo *) Xmalloc (sizeof (XFixesExtDisplayInfo));
if (!info) return NULL;
info->display = dpy;
info->codes = XInitExtension (dpy, ext_name);
if (info->codes) {
xXFixesQueryVersionReply rep;
xXFixesQueryVersionReq *req;
XESetCloseDisplay (dpy, info->codes->extension,
XFixesCloseDisplay);
for (ev = info->codes->first_event;
ev < info->codes->first_event + XFixesNumberEvents;
ev++)
{
XESetWireToEvent (dpy, ev, XFixesWireToEvent);
XESetEventToWire (dpy, ev, XFixesEventToWire);
}
LockDisplay (dpy);
GetReq (XFixesQueryVersion, req);
req->reqType = info->codes->major_opcode;
req->xfixesReqType = X_XFixesQueryVersion;
req->majorVersion = XFIXES_MAJOR;
req->minorVersion = XFIXES_MINOR;
if (!_XReply (dpy, (xReply *) &rep, 0, xTrue))
{
UnlockDisplay (dpy);
SyncHandle ();
Xfree(info);
return 0;
}
info->major_version = rep.majorVersion;
info->minor_version = rep.minorVersion;
UnlockDisplay (dpy);
} else {
XExtCodes *codes = XAddExtension(dpy);
if (!codes) {
XFree(info);
return NULL;
}
XESetCloseDisplay (dpy, codes->extension, XFixesCloseDisplay);
}
_XLockMutex(_Xglobal_lock);
info->next = extinfo->head;
extinfo->head = info;
extinfo->cur = info;
extinfo->ndisplays++;
_XUnlockMutex(_Xglobal_lock);
return info;
}
static int
XFixesExtRemoveDisplay (XFixesExtInfo *extinfo, Display *dpy)
{
XFixesExtDisplayInfo *info, *prev;
_XLockMutex(_Xglobal_lock);
prev = NULL;
for (info = extinfo->head; info; info = info->next) {
if (info->display == dpy) break;
prev = info;
}
if (!info) {
_XUnlockMutex(_Xglobal_lock);
return 0;
}
if (prev)
prev->next = info->next;
else
extinfo->head = info->next;
extinfo->ndisplays--;
if (info == extinfo->cur) extinfo->cur = NULL;
_XUnlockMutex(_Xglobal_lock);
Xfree ((char *) info);
return 1;
}
static XFixesExtDisplayInfo *
XFixesExtFindDisplay (XFixesExtInfo *extinfo,
Display *dpy)
{
XFixesExtDisplayInfo *info;
if ((info = extinfo->cur) && info->display == dpy)
return info;
_XLockMutex(_Xglobal_lock);
for (info = extinfo->head; info; info = info->next) {
if (info->display == dpy) {
extinfo->cur = info;
_XUnlockMutex(_Xglobal_lock);
return info;
}
}
_XUnlockMutex(_Xglobal_lock);
return NULL;
}
XFixesExtDisplayInfo *
XFixesFindDisplay (Display *dpy)
{
XFixesExtDisplayInfo *info;
info = XFixesExtFindDisplay (&XFixesExtensionInfo, dpy);
if (!info)
info = XFixesExtAddDisplay (&XFixesExtensionInfo, dpy,
XFixesExtensionName);
return info;
}
static int
XFixesCloseDisplay (Display *dpy, XExtCodes *codes)
{
return XFixesExtRemoveDisplay (&XFixesExtensionInfo, dpy);
}
static Bool
XFixesWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
XFixesExtDisplayInfo *info = XFixesFindDisplay(dpy);
XFixesCheckExtension(dpy, info, False);
switch ((wire->u.u.type & 0x7F) - info->codes->first_event)
{
case XFixesSelectionNotify: {
XFixesSelectionNotifyEvent *aevent;
xXFixesSelectionNotifyEvent *awire;
awire = (xXFixesSelectionNotifyEvent *) wire;
aevent = (XFixesSelectionNotifyEvent *) event;
aevent->type = awire->type & 0x7F;
aevent->subtype = awire->subtype;
aevent->serial = _XSetLastRequestRead(dpy,
(xGenericReply *) wire);
aevent->send_event = (awire->type & 0x80) != 0;
aevent->display = dpy;
aevent->window = awire->window;
aevent->owner = awire->owner;
aevent->selection = awire->selection;
aevent->timestamp = awire->timestamp;
aevent->selection_timestamp = awire->selectionTimestamp;
return True;
}
case XFixesCursorNotify: {
XFixesCursorNotifyEvent *aevent;
xXFixesCursorNotifyEvent *awire;
awire = (xXFixesCursorNotifyEvent *) wire;
aevent = (XFixesCursorNotifyEvent *) event;
aevent->type = awire->type & 0x7F;
aevent->subtype = awire->subtype;
aevent->serial = _XSetLastRequestRead(dpy,
(xGenericReply *) wire);
aevent->send_event = (awire->type & 0x80) != 0;
aevent->display = dpy;
aevent->window = awire->window;
aevent->cursor_serial = awire->cursorSerial;
aevent->timestamp = awire->timestamp;
aevent->cursor_name = awire->name;
return True;
}
}
return False;
}
static Status
XFixesEventToWire(Display *dpy, XEvent *event, xEvent *wire)
{
XFixesExtDisplayInfo *info = XFixesFindDisplay(dpy);
XFixesCheckExtension(dpy, info, False);
switch ((event->type & 0x7F) - info->codes->first_event)
{
case XFixesSelectionNotify: {
XFixesSelectionNotifyEvent *aevent;
xXFixesSelectionNotifyEvent *awire;
awire = (xXFixesSelectionNotifyEvent *) wire;
aevent = (XFixesSelectionNotifyEvent *) event;
awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
awire->subtype = aevent->subtype;
awire->window = aevent->window;
awire->owner = aevent->owner;
awire->selection = aevent->selection;
awire->timestamp = aevent->timestamp;
awire->selectionTimestamp = aevent->selection_timestamp;
return True;
}
case XFixesCursorNotify: {
XFixesCursorNotifyEvent *aevent;
xXFixesCursorNotifyEvent *awire;
awire = (xXFixesCursorNotifyEvent *) wire;
aevent = (XFixesCursorNotifyEvent *) event;
awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
awire->subtype = aevent->subtype;
awire->window = aevent->window;
awire->timestamp = aevent->timestamp;
awire->cursorSerial = aevent->cursor_serial;
awire->name = aevent->cursor_name;
}
}
return False;
}
Bool
XFixesQueryExtension (Display *dpy, int *event_basep, int *error_basep)
{
XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
if (XFixesHasExtension(info))
{
*event_basep = info->codes->first_event;
*error_basep = info->codes->first_error;
return True;
}
else
return False;
}
Status
XFixesQueryVersion (Display *dpy,
int *major_versionp,
int *minor_versionp)
{
XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
XFixesCheckExtension (dpy, info, 0);
*major_versionp = info->major_version;
*minor_versionp = info->minor_version;
return 1;
}
int
XFixesVersion (void)
{
return XFIXES_VERSION;
}