mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-12-18 00:11:55 +00:00
9c59fafc3e
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@228 fc73d0e0-1445-4013-8a0c-d673dee63da5
3256 lines
71 KiB
C
3256 lines
71 KiB
C
#include "bothdefs.h"
|
|
|
|
#ifndef NOMEDIA
|
|
|
|
|
|
#include "qux.h"
|
|
#undef strncpy
|
|
|
|
#undef malloc
|
|
#undef free
|
|
|
|
#define free BZ_Free
|
|
#define malloc BZ_Malloc
|
|
|
|
XRequest XRequests [256];
|
|
|
|
#ifdef XBigReqExtensionName
|
|
int X_BigReqCode;
|
|
#endif
|
|
|
|
void XR_MapWindow(xclient_t *cl, xReq *request);
|
|
void XR_UnmapWindow(xclient_t *cl, xReq *request);
|
|
|
|
|
|
#define GXclear 0x0 /* 0 */
|
|
#define GXand 0x1 /* src AND dst */
|
|
#define GXandReverse 0x2 /* src AND NOT dst */
|
|
#define GXcopy 0x3 /* src */
|
|
#define GXandInverted 0x4 /* NOT src AND dst */
|
|
#define GXnoop 0x5 /* dst */
|
|
#define GXxor 0x6 /* src XOR dst */
|
|
#define GXor 0x7 /* src OR dst */
|
|
#define GXnor 0x8 /* NOT src AND NOT dst */
|
|
#define GXequiv 0x9 /* NOT src XOR dst */
|
|
#define GXinvert 0xa /* NOT dst */
|
|
#define GXorReverse 0xb /* src OR NOT dst */
|
|
#define GXcopyInverted 0xc /* NOT src */
|
|
#define GXorInverted 0xd /* NOT src OR dst */
|
|
#define GXnand 0xe /* NOT src OR NOT dst */
|
|
#define GXset 0xf /* 1 */
|
|
|
|
#define GCFunc(src, dst, fnc, out, setval) \
|
|
switch(fnc) \
|
|
{ \
|
|
case GXclear: \
|
|
out = 0; \
|
|
break; \
|
|
case GXand: \
|
|
out = src&dst; \
|
|
break; \
|
|
case GXandReverse: \
|
|
out = src&~dst; \
|
|
break; \
|
|
case GXcopy: \
|
|
out = src; \
|
|
break; \
|
|
case GXandInverted: \
|
|
out = ~src&dst; \
|
|
break; \
|
|
case GXnoop: \
|
|
out = dst; \
|
|
break; \
|
|
case GXxor: \
|
|
out = src^dst; \
|
|
break; \
|
|
case GXor: \
|
|
out = src|dst; \
|
|
break; \
|
|
case GXnor: \
|
|
out = ~src&~dst; \
|
|
break; \
|
|
case GXequiv: \
|
|
out = ~src^dst; \
|
|
break; \
|
|
case GXinvert: \
|
|
out = ~dst; \
|
|
break; \
|
|
case GXorReverse: \
|
|
out = src|~dst; \
|
|
break; \
|
|
case GXcopyInverted: \
|
|
out = ~src; \
|
|
break; \
|
|
case GXorInverted: \
|
|
out = ~src|dst; \
|
|
break; \
|
|
case GXnand: \
|
|
out = ~src|~dst; \
|
|
break; \
|
|
case GXset: \
|
|
out = setval; \
|
|
break; \
|
|
}
|
|
void XW_ClearArea(xwindow_t *wnd, int xp, int yp, int width, int height);
|
|
|
|
void XR_QueryExtension (xclient_t *cl, xReq *request)
|
|
{
|
|
char extname[256];
|
|
xQueryExtensionReply rep;
|
|
xQueryExtensionReq *req = (xQueryExtensionReq *)request;
|
|
|
|
if (req->nbytes > 250)
|
|
req->nbytes = 250;
|
|
strncpy(extname, (char *)(req+1), req->nbytes);
|
|
extname[req->nbytes] = '\0';
|
|
|
|
#ifdef XBigReqExtensionName
|
|
if (X_BigReqCode && !strcmp(extname, XBigReqExtensionName))
|
|
{
|
|
rep.major_opcode = X_BigReqCode;
|
|
rep.present = true;
|
|
rep.first_event = 0;
|
|
rep.first_error = 0;
|
|
}
|
|
else
|
|
#endif
|
|
if (0) {} //for the else
|
|
else
|
|
{
|
|
Con_Printf("Extension %s not supported\n", extname);
|
|
rep.major_opcode = 0;
|
|
rep.present = false;
|
|
rep.first_event = 0;
|
|
rep.first_error = 0;
|
|
}
|
|
|
|
rep.type = X_Reply;
|
|
rep.pad1 = 0;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.pad3 = 0;
|
|
rep.pad4 = 0;
|
|
rep.pad5 = 0;
|
|
rep.pad6 = 0;
|
|
rep.pad7 = 0;
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
|
|
void XW_ExposeWindowRegionInternal(xwindow_t *root, int x, int y, int width, int height)
|
|
{
|
|
int nx,ny,nw,nh;
|
|
xEvent ev;
|
|
if (!root->mapped || root->inputonly)
|
|
return;
|
|
|
|
|
|
ev.u.u.type = VisibilityNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.visibility.window = root->res.id;
|
|
ev.u.visibility.state = VisibilityUnobscured;
|
|
ev.u.visibility.pad1 = 0;
|
|
ev.u.visibility.pad2 = 0;
|
|
ev.u.visibility.pad3 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, root, VisibilityChangeMask);
|
|
|
|
ev.u.u.type = Expose;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.expose.window = root->res.id;
|
|
ev.u.expose.x = x;
|
|
ev.u.expose.y = y;
|
|
ev.u.expose.width = width;
|
|
ev.u.expose.height = height;
|
|
ev.u.expose.count = false; //other expose events following (none - rewrite to group these then send all in one go...)
|
|
ev.u.expose.pad2 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, root, ExposureMask);
|
|
|
|
if (root->buffer && root != rootwindow)
|
|
{
|
|
XW_ClearArea(root, 0, 0, root->width, root->height);
|
|
// free(root->buffer);
|
|
// root->buffer = NULL;
|
|
}
|
|
|
|
for (root = root->child; root; root = root->sibling)
|
|
{
|
|
if (!root->mapped || root->inputonly)
|
|
continue;
|
|
|
|
//subtract the minpos
|
|
nx = x - root->xpos;
|
|
nw = width;
|
|
ny = y - root->ypos;
|
|
nh = height;
|
|
|
|
//cap new minpos to the child window.
|
|
if (nx < 0)
|
|
{
|
|
nw += nx;
|
|
nx = 0;
|
|
}
|
|
if (ny < 0)
|
|
{
|
|
nh += ny;
|
|
ny = 0;
|
|
}
|
|
|
|
//cap new maxpos
|
|
if (nx+nw > x + root->width)
|
|
nw = x+root->width - nx;
|
|
if (ny+nh > y + root->height)
|
|
nh = y+root->height - ny;
|
|
|
|
if (nw > 0 && nh > 0) //make sure some is valid.
|
|
XW_ExposeWindowRegionInternal(root, nx, ny, nw, nh);
|
|
}
|
|
}
|
|
|
|
void XW_ExposeWindow(xwindow_t *root, int x, int y, int width, int height)
|
|
{//we have to go back to the root so we know the exact region, and can expose our sibling's windows.
|
|
while(root)
|
|
{
|
|
x += root->xpos;
|
|
y += root->ypos;
|
|
root = root->parent;
|
|
}
|
|
|
|
XW_ExposeWindowRegionInternal(rootwindow, x, y, width, height);
|
|
}
|
|
|
|
void XR_ListExtensions (xclient_t *cl, xReq *request)
|
|
{
|
|
char buffer[8192];
|
|
xListExtensionsReply *rep = (xListExtensionsReply *)buffer;
|
|
char *out;
|
|
|
|
rep->type = X_Reply;
|
|
rep->nExtensions = 0;
|
|
rep->sequenceNumber = cl->requestnum;
|
|
rep->length = 0;
|
|
rep->pad2 = 0;
|
|
rep->pad3 = 0;
|
|
rep->pad4 = 0;
|
|
rep->pad5 = 0;
|
|
rep->pad6 = 0;
|
|
rep->pad7 = 0;
|
|
|
|
out = (char *)(rep+1);
|
|
|
|
#ifdef XBigReqExtensionName
|
|
rep->nExtensions++;
|
|
strcpy(out, XBigReqExtensionName);
|
|
out+=strlen(out)+1;
|
|
#endif
|
|
|
|
rep->length = (out-(char *)(rep+1) + 3)/4;
|
|
|
|
|
|
X_SendData(cl, rep, sizeof(xListExtensionsReply) + rep->length*4);
|
|
}
|
|
|
|
void XR_GetAtomName (xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq*)request;
|
|
char buffer[8192];
|
|
xGetAtomNameReply *rep = (xGetAtomNameReply*)buffer;
|
|
|
|
xatom_t *xa;
|
|
|
|
if (XS_GetResource(req->id, (void**)&xa) != x_atom)
|
|
{
|
|
X_SendError(cl, BadAtom, req->id, X_GetAtomName, 0);
|
|
return;
|
|
}
|
|
|
|
rep->type = X_Reply;
|
|
rep->pad1 = 0;
|
|
rep->sequenceNumber = cl->requestnum;
|
|
rep->length = (strlen(xa->atomname)+3)/4;
|
|
rep->nameLength = strlen(xa->atomname);
|
|
rep->pad2 = 0;
|
|
rep->pad3 = 0;
|
|
rep->pad4 = 0;
|
|
rep->pad5 = 0;
|
|
rep->pad6 = 0;
|
|
rep->pad7 = 0;
|
|
strcpy((char *)(rep+1), xa->atomname);
|
|
|
|
X_SendData(cl, rep, sizeof(*rep)+rep->length*4);
|
|
}
|
|
|
|
void XR_InternAtom (xclient_t *cl, xReq *request)
|
|
{
|
|
xInternAtomReq *req = (xInternAtomReq*)request;
|
|
xInternAtomReply rep;
|
|
char atomname[1024];
|
|
Atom atom;
|
|
|
|
if (req->nbytes >= sizeof(atomname))
|
|
{ //exceeded that limit then...
|
|
X_SendError(cl, BadImplementation, 0, X_InternAtom, 0);
|
|
return;
|
|
}
|
|
|
|
strncpy(atomname, (char *)(req+1), req->nbytes);
|
|
atomname[req->nbytes] = '\0';
|
|
|
|
atom = XS_FindAtom(atomname);
|
|
if (atom == None && !req->onlyIfExists)
|
|
{
|
|
atom = XS_NewResource();
|
|
XS_CreateAtom(atom, atomname, NULL); //global atom...
|
|
}
|
|
|
|
rep.type = X_Reply;
|
|
rep.pad1 = 0;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.atom = atom;
|
|
rep.pad2 = 0;
|
|
rep.pad3 = 0;
|
|
rep.pad4 = 0;
|
|
rep.pad5 = 0;
|
|
rep.pad6 = 0;
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
void XR_GetProperty (xclient_t *cl, xReq *request)
|
|
{
|
|
xGetPropertyReq *req = (xGetPropertyReq*)request;
|
|
char buffer[8192];
|
|
xwindow_t *wnd;
|
|
int datalen;
|
|
int format;
|
|
int trailing;
|
|
xGetPropertyReply *rep = (xGetPropertyReply*)buffer;
|
|
|
|
if (XS_GetResource(req->window, (void**)&wnd) != x_window)
|
|
{ //wait a minute, That's not a window!!!
|
|
X_SendError(cl, BadWindow, req->window, X_GetProperty, 0);
|
|
return;
|
|
}
|
|
if (XS_GetResource(req->property, (void**)NULL) != x_atom)
|
|
{ //whoops
|
|
X_SendError(cl, BadAtom, req->property, X_GetProperty, 0);
|
|
return;
|
|
}
|
|
|
|
if (req->longLength > sizeof(buffer) - sizeof(req)/4)
|
|
req->longLength = sizeof(buffer) - sizeof(req)/4;
|
|
datalen = XS_GetProperty(wnd, req->property, &rep->propertyType, (char *)(rep+1), req->longLength*4, req->longOffset*4, &trailing, &format);
|
|
|
|
rep->type = X_Reply;
|
|
rep->format = format;
|
|
rep->sequenceNumber = cl->requestnum;
|
|
rep->length = (datalen+3)/4;
|
|
//rep->propertyType = None;
|
|
rep->bytesAfter = trailing;
|
|
if (format)
|
|
rep->nItems = datalen / (format/8);
|
|
else
|
|
rep->nItems = 0;
|
|
rep->pad1 = 0;
|
|
rep->pad2 = 0;
|
|
rep->pad3 = 0;
|
|
|
|
X_SendData(cl, rep, rep->length*4 + sizeof(*rep));
|
|
|
|
if (req->delete)
|
|
{
|
|
xEvent ev;
|
|
|
|
XS_DeleteProperty(wnd, req->property);
|
|
|
|
ev.u.u.type = PropertyNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.property.window = req->window;
|
|
ev.u.property.atom = req->property;
|
|
ev.u.property.time = Sys_DoubleTime()*1000;
|
|
ev.u.property.state = PropertyDelete;
|
|
|
|
ev.u.property.pad1 = 0;
|
|
ev.u.property.pad2 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, PropertyChangeMask);
|
|
}
|
|
}
|
|
|
|
void XR_ListProperties(xclient_t *cl, xReq *request)
|
|
{
|
|
xproperty_t *xp;
|
|
xResourceReq *req = (xResourceReq*)request;
|
|
char buffer[65536];
|
|
xwindow_t *wnd;
|
|
xListPropertiesReply *rep = (xListPropertiesReply*)buffer;
|
|
Atom *out = (Atom *)(rep+1);
|
|
|
|
if (XS_GetResource(req->id, (void**)&wnd) != x_window)
|
|
{ //wait a minute, That's not a window!!!
|
|
X_SendError(cl, BadWindow, req->id, X_GetProperty, 0);
|
|
return;
|
|
}
|
|
|
|
|
|
rep->type = X_Reply;
|
|
rep->sequenceNumber = cl->requestnum;
|
|
rep->length = 0;
|
|
rep->nProperties = 0;
|
|
rep->pad1 = 0;
|
|
rep->pad2 = 0;
|
|
rep->pad3 = 0;
|
|
rep->pad4 = 0;
|
|
rep->pad5 = 0;
|
|
rep->pad6 = 0;
|
|
rep->pad7 = 0;
|
|
|
|
for (xp = wnd->properties; xp; xp = xp->next)
|
|
{
|
|
rep->nProperties++;
|
|
*out = xp->atomid;
|
|
}
|
|
|
|
rep->length = rep->nProperties;
|
|
|
|
X_SendData(cl, rep, rep->length*4 + sizeof(*rep));
|
|
}
|
|
|
|
void XR_ChangeProperty (xclient_t *cl, xReq *request)
|
|
{
|
|
xChangePropertyReq *req = (xChangePropertyReq*)request;
|
|
int len;
|
|
|
|
xatom_t *atom;
|
|
xwindow_t *wnd;
|
|
|
|
if (XS_GetResource(req->window, (void**)&wnd) != x_window)
|
|
{ //wait a minute, That's not a window!!!
|
|
X_SendError(cl, BadWindow, req->window, X_ChangeProperty, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->property, (void**)&atom) != x_atom)
|
|
{
|
|
X_SendError(cl, BadAtom, req->property, X_ChangeProperty, 0);
|
|
return;
|
|
}
|
|
|
|
len = req->nUnits * (req->format/8);
|
|
|
|
if (req->mode == PropModeReplace)
|
|
XS_SetProperty(wnd, req->property, req->type, (char *)(req+1), len, req->format);
|
|
else if (req->mode == PropModePrepend)
|
|
{
|
|
X_SendError(cl, BadImplementation, req->window, X_ChangeProperty, 0);
|
|
return;
|
|
}
|
|
else if (req->mode == PropModeAppend)
|
|
{
|
|
char hugebuffer[65536];
|
|
int trailing;
|
|
int format, datalen;
|
|
Atom proptype;
|
|
|
|
|
|
datalen = XS_GetProperty(wnd, req->property, &proptype, hugebuffer, sizeof(hugebuffer), 0, &trailing, &format);
|
|
if (datalen+len > sizeof(hugebuffer))
|
|
{
|
|
X_SendError(cl, BadImplementation, req->window, X_ChangeProperty, 0);
|
|
return;
|
|
}
|
|
memcpy(hugebuffer + datalen, (char *)(req+1), len);
|
|
|
|
XS_SetProperty(wnd, req->property, proptype, hugebuffer, datalen+len, format);
|
|
}
|
|
|
|
{
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = PropertyNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.property.window = req->window;
|
|
ev.u.property.atom = req->property;
|
|
ev.u.property.time = Sys_DoubleTime()*1000;
|
|
ev.u.property.state = PropertyNewValue;
|
|
|
|
ev.u.property.pad1 = 0;
|
|
ev.u.property.pad2 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, PropertyChangeMask);
|
|
}
|
|
}
|
|
|
|
void XR_DeleteProperty(xclient_t *cl, xReq *request)
|
|
{
|
|
xDeletePropertyReq *req = (xDeletePropertyReq*)request;
|
|
|
|
xwindow_t *wnd;
|
|
|
|
if (XS_GetResource(req->window, (void**)&wnd) != x_window)
|
|
{ //wait a minute, That's not a window!!!
|
|
X_SendError(cl, BadWindow, req->window, X_DeleteProperty, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->property, (void**)NULL) != x_atom)
|
|
{
|
|
X_SendError(cl, BadAtom, req->property, X_DeleteProperty, 0);
|
|
return;
|
|
}
|
|
|
|
XS_DeleteProperty(wnd, req->property);
|
|
|
|
{
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = PropertyNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.property.window = req->window;
|
|
ev.u.property.atom = req->property;
|
|
ev.u.property.time = Sys_DoubleTime()*1000;
|
|
ev.u.property.state = PropertyDelete;
|
|
|
|
ev.u.property.pad1 = 0;
|
|
ev.u.property.pad2 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, PropertyChangeMask);
|
|
}
|
|
}
|
|
|
|
void XR_GetSelectionOwner (xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xGetSelectionOwnerReply reply;
|
|
xatom_t *atom;
|
|
|
|
if (XS_GetResource(req->id, (void**)&atom) != x_atom)
|
|
{
|
|
X_SendError(cl, BadAtom, req->id, X_GetSelectionOwner, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(atom->selectionownerwindowid, (void**)NULL) != x_window) //make sure the window still exists.
|
|
{
|
|
atom->selectionownerwindowid = None;
|
|
}
|
|
|
|
reply.type = X_Reply;
|
|
reply.sequenceNumber = cl->requestnum;
|
|
reply.length = 0;
|
|
reply.owner = atom->selectionownerwindowid;
|
|
reply.pad1 = 0;
|
|
reply.pad2 = 0;
|
|
reply.pad3 = 0;
|
|
reply.pad4 = 0;
|
|
reply.pad5 = 0;
|
|
reply.pad6 = 0;
|
|
|
|
X_SendData(cl, &reply, sizeof(reply));
|
|
}
|
|
void XR_SetSelectionOwner (xclient_t *cl, xReq *request)
|
|
{
|
|
xSetSelectionOwnerReq *req = (xSetSelectionOwnerReq *)request;
|
|
xatom_t *atom;
|
|
xwindow_t *window;
|
|
|
|
if (XS_GetResource(req->selection, (void**)&atom) != x_atom)
|
|
{
|
|
X_SendError(cl, BadAtom, req->selection, X_SetSelectionOwner, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->window, (void**)&window) != x_window) //make sure the window still exists.
|
|
{
|
|
X_SendError(cl, BadWindow, req->window, X_SetSelectionOwner, 0);
|
|
return;
|
|
}
|
|
|
|
if (req->window)
|
|
{
|
|
atom->selectionownerwindowid = req->window;
|
|
atom->selectionownerclient = cl;
|
|
}
|
|
else
|
|
{
|
|
atom->selectionownerwindowid = None;
|
|
atom->selectionownerclient = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
extern int x_windowwithcursor;
|
|
|
|
void XR_GetInputFocus (xclient_t *cl, xReq *request)
|
|
{
|
|
xGetInputFocusReply rep;
|
|
extern xwindow_t *xfocusedwindow;
|
|
|
|
rep.type = X_Reply;
|
|
rep.revertTo = None;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.focus = xfocusedwindow?xfocusedwindow->res.id:None;
|
|
rep.pad1 = 0;
|
|
rep.pad2 = 0;
|
|
rep.pad3 = 0;
|
|
rep.pad4 = 0;
|
|
rep.pad5 = 0;
|
|
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
void XR_SetInputFocus (xclient_t *cl, xReq *request)
|
|
{
|
|
extern xwindow_t *xfocusedwindow;
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xwindow_t *wnd;
|
|
|
|
if (XS_GetResource(req->id, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->id, X_SetInputFocus, 0);
|
|
return;
|
|
}
|
|
|
|
xfocusedwindow = wnd;
|
|
|
|
X_EvalutateFocus(NotifyWhileGrabbed);
|
|
}
|
|
|
|
void XR_QueryBestSize (xclient_t *cl, xReq *request)
|
|
{
|
|
xQueryBestSizeReq *req = (xQueryBestSizeReq *)request;
|
|
xQueryBestSizeReply rep;
|
|
|
|
if (req->class == CursorShape && req->drawable != rootwindow->res.id)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_QueryBestSize, req->class);
|
|
return;
|
|
}
|
|
else if (req->class != CursorShape)
|
|
{
|
|
X_SendError(cl, BadImplementation, req->drawable, X_QueryBestSize, req->class);
|
|
return;
|
|
}
|
|
|
|
rep.type = X_Reply;
|
|
rep.pad1 = 0;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.width = req->width;
|
|
rep.height = req->height;
|
|
rep.pad3 = 0;
|
|
rep.pad4 = 0;
|
|
rep.pad5 = 0;
|
|
rep.pad6 = 0;
|
|
rep.pad7 = 0;
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
void XR_GetGeometry (xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xGetGeometryReply rep;
|
|
xresource_t *drawable;
|
|
|
|
xwindow_t *wnd;
|
|
xpixmap_t *pm;
|
|
|
|
rep.type = X_Reply;
|
|
rep.depth = 24;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.root = 0;
|
|
rep.x = 0;
|
|
rep.y = 0;
|
|
rep.width = 0;
|
|
rep.height = 0;
|
|
rep.borderWidth = 0;
|
|
rep.pad1 = 0;
|
|
rep.pad2 = 0;
|
|
rep.pad3 = 0;
|
|
|
|
switch(XS_GetResource(req->id, (void**)&drawable))
|
|
{
|
|
case x_window:
|
|
wnd = (xwindow_t*)drawable;
|
|
rep.x = wnd->xpos;
|
|
rep.y = wnd->ypos;
|
|
rep.borderWidth = 0; //fixme
|
|
rep.width = wnd->width;
|
|
rep.height = wnd->height;
|
|
rep.root = rootwindow->res.id;
|
|
break;
|
|
case x_pixmap:
|
|
pm = (xpixmap_t*)drawable;
|
|
rep.width = pm->width;
|
|
rep.height = pm->height;
|
|
break;
|
|
default:
|
|
X_SendError(cl, BadDrawable, req->id, X_GetGeometry, 0);
|
|
return;
|
|
}
|
|
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
void XR_CreateWindow (xclient_t *cl, xReq *request)
|
|
{
|
|
xCreateWindowReq *req = (xCreateWindowReq *)request;
|
|
xwindow_t *parent;
|
|
xwindow_t *wnd;
|
|
CARD32 *parameters;
|
|
|
|
if (req->class == InputOnly && req->depth != 0)
|
|
{
|
|
X_SendError(cl, BadMatch, req->wid, X_CreateWindow, 0);
|
|
return;
|
|
}
|
|
if (XS_GetResource(req->wid, (void**)&parent) != x_none)
|
|
{
|
|
X_SendError(cl, BadIDChoice, req->wid, X_CreateWindow, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->parent, (void**)&parent) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->parent, X_CreateWindow, 0);
|
|
return;
|
|
}
|
|
|
|
wnd = XS_CreateWindow(req->wid, cl, parent, req->x, req->y, req->width, req->height);
|
|
|
|
if (req->depth != 0)
|
|
wnd->depth = req->depth;
|
|
else
|
|
wnd->depth = parent->depth;
|
|
|
|
if (req->class == CopyFromParent)
|
|
wnd->inputonly = parent->inputonly;
|
|
else
|
|
wnd->inputonly = (req->class == InputOnly);
|
|
|
|
//FIXME: Depth must be valid
|
|
//FIXME: visual id must be valid.
|
|
|
|
parameters = (CARD32 *)(req+1);
|
|
if (req->mask & CWBackPixmap)
|
|
{
|
|
wnd->backpixmap = NULL;
|
|
if (XS_GetResource(*parameters, (void**)&wnd->backpixmap) != x_pixmap)
|
|
{
|
|
if (*parameters)
|
|
X_SendError(cl, BadPixmap, *parameters, X_CreateWindow, 0);
|
|
}
|
|
else
|
|
wnd->backpixmap->references++;
|
|
parameters++;
|
|
}
|
|
if (req->mask & CWBackPixel)//
|
|
{
|
|
wnd->backpixel = *parameters;
|
|
parameters++;
|
|
}
|
|
if (req->mask & CWBorderPixmap)
|
|
parameters+=0;
|
|
if (req->mask & CWBorderPixel)//
|
|
{
|
|
wnd->borderpixel = *parameters;
|
|
parameters++;
|
|
}
|
|
if (req->mask & CWBitGravity)//
|
|
{
|
|
wnd->bitgravity = *parameters;
|
|
parameters++;
|
|
}
|
|
if (req->mask & CWWinGravity)
|
|
wnd->bitgravity = *parameters++;
|
|
if (req->mask & CWBackingStore)
|
|
parameters++; //ignored
|
|
if (req->mask & CWBackingPlanes)
|
|
parameters+=0;
|
|
if (req->mask & CWBackingPixel)
|
|
parameters+=0;
|
|
if (req->mask & CWOverrideRedirect)
|
|
wnd->overrideredirect = *parameters++;
|
|
else
|
|
wnd->overrideredirect = false;
|
|
if (req->mask & CWSaveUnder)
|
|
parameters++;
|
|
if (req->mask & CWEventMask)//
|
|
{
|
|
xnotificationmask_t *nm;
|
|
nm = malloc(sizeof(xnotificationmask_t));
|
|
nm->client = cl;
|
|
nm->next = NULL;
|
|
nm->mask = *parameters;
|
|
wnd->notificationmask = nm;
|
|
parameters++;
|
|
}
|
|
if (req->mask & CWDontPropagate)
|
|
wnd->donotpropagate = *parameters++;
|
|
if (req->mask & CWColormap)//
|
|
{
|
|
wnd->colormap = *parameters;
|
|
parameters++;
|
|
}
|
|
if (req->mask & CWCursor)
|
|
parameters++;
|
|
|
|
#define CWBackPixmap (1L<<0)
|
|
#define CWBackPixel (1L<<1)
|
|
#define CWBorderPixmap (1L<<2)
|
|
#define CWBorderPixel (1L<<3)
|
|
#define CWBitGravity (1L<<4)
|
|
#define CWWinGravity (1L<<5)
|
|
#define CWBackingStore (1L<<6)
|
|
#define CWBackingPlanes (1L<<7)
|
|
#define CWBackingPixel (1L<<8)
|
|
#define CWOverrideRedirect (1L<<9)
|
|
#define CWSaveUnder (1L<<10)
|
|
#define CWEventMask (1L<<11)
|
|
#define CWDontPropagate (1L<<12)
|
|
#define CWColormap (1L<<13)
|
|
#define CWCursor (1L<<14)
|
|
/*
|
|
CARD8 depth;
|
|
Window wid;
|
|
Window parent;
|
|
INT16 x B16, y B16;
|
|
CARD16 width B16, height B16, borderWidth B16;
|
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
CARD16 c_class B16;
|
|
#else
|
|
CARD16 class B16;
|
|
#endif
|
|
VisualID visual B32;
|
|
CARD32 mask B32;
|
|
*/
|
|
|
|
if (wnd->inputonly)
|
|
return;
|
|
|
|
|
|
{
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = CreateNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.createNotify.parent = wnd->parent->res.id;
|
|
ev.u.createNotify.window = wnd->res.id;
|
|
ev.u.createNotify.x = wnd->xpos;
|
|
ev.u.createNotify.y = wnd->ypos;
|
|
ev.u.createNotify.width = wnd->width;
|
|
ev.u.createNotify.height = wnd->height;
|
|
ev.u.createNotify.borderWidth = req->borderWidth;
|
|
ev.u.createNotify.override = wnd->overrideredirect;
|
|
ev.u.createNotify.bpad = 0;
|
|
|
|
X_SendNotificationMasked (&ev, wnd, SubstructureNotifyMask);
|
|
}
|
|
|
|
/* {
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = MapRequest;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.mapRequest.window = wnd->res.id;
|
|
ev.u.mapRequest.parent = wnd->parent->res.id;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, SubstructureRedirectMask);
|
|
}*/
|
|
/* {
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = GraphicsExpose;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.expose.window = wnd->res.id;
|
|
ev.u.expose.x = 0;
|
|
ev.u.expose.y = 0;
|
|
ev.u.expose.width = wnd->width;
|
|
ev.u.expose.height = wnd->height;
|
|
ev.u.expose.count = 0; //matching expose events after this one
|
|
ev.u.expose.pad2 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, ExposureMask);
|
|
}*/
|
|
}
|
|
|
|
void XR_ChangeWindowAttributes (xclient_t *cl, xReq *request)
|
|
{
|
|
CARD32 *parameters;
|
|
xChangeWindowAttributesReq *req = (xChangeWindowAttributesReq *)request;
|
|
xwindow_t *wnd;
|
|
|
|
if (XS_GetResource(req->window, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->window, X_ChangeWindowAttributes, 0);
|
|
return;
|
|
}
|
|
|
|
parameters = (CARD32 *)(req+1);
|
|
|
|
if (req->valueMask & CWBackPixmap)
|
|
{
|
|
if (wnd->backpixmap)
|
|
wnd->backpixmap->references--;
|
|
wnd->backpixmap = NULL;
|
|
if (XS_GetResource(*parameters, (void**)&wnd->backpixmap) != x_pixmap)
|
|
{
|
|
if (*parameters)
|
|
X_SendError(cl, BadPixmap, *parameters, X_ChangeWindowAttributes, 0);
|
|
}
|
|
else
|
|
wnd->backpixmap->references++;
|
|
parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWBackPixel)
|
|
{
|
|
if (wnd->backpixmap)
|
|
wnd->backpixmap->references--;
|
|
wnd->backpixmap = NULL;
|
|
wnd->backpixel = *parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWBorderPixmap)
|
|
{
|
|
X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0);
|
|
/* wnd->borderpixmap = NULL;
|
|
if (XS_GetResource(*parameters, (void**)&wnd->borderpixmap) != x_pixmap)
|
|
{
|
|
if (*parameters)
|
|
X_SendError(cl, BadPixmap, *parameters, X_ChangeWindowAttributes, 0);
|
|
}
|
|
else
|
|
wnd->backpixmap->references++;
|
|
*/ parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWBorderPixel)
|
|
wnd->borderpixel = *parameters++;
|
|
|
|
if (req->valueMask & CWBitGravity)
|
|
{
|
|
wnd->bitgravity = *parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWWinGravity)
|
|
{
|
|
wnd->wingravity = *parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWBackingStore)
|
|
{
|
|
// X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0);
|
|
parameters++; //ignore
|
|
}
|
|
|
|
if (req->valueMask & CWBackingPlanes)
|
|
{
|
|
X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0);
|
|
parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWBackingPixel)
|
|
{
|
|
X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0);
|
|
parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWOverrideRedirect)
|
|
{
|
|
wnd->overrideredirect = *parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWSaveUnder)
|
|
{
|
|
// X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0);
|
|
parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWEventMask)
|
|
{
|
|
xnotificationmask_t *nm;
|
|
|
|
if (*parameters & (SubstructureRedirectMask | ResizeRedirectMask))
|
|
{ //you're only allowed one client with that one at a time.
|
|
for (nm = wnd->notificationmask; nm; nm = nm->next)
|
|
{
|
|
if (nm->mask & (*parameters))
|
|
if (nm->client != cl)
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
nm = NULL;
|
|
if (nm) //client has this one.
|
|
X_SendError(cl, BadAccess, *parameters, X_ChangeWindowAttributes, CWEventMask);
|
|
else
|
|
{
|
|
for (nm = wnd->notificationmask; nm; nm = nm->next)
|
|
{
|
|
if (nm->client == cl)
|
|
break;
|
|
}
|
|
if (!nm)
|
|
{
|
|
nm = malloc(sizeof(xnotificationmask_t));
|
|
nm->next = wnd->notificationmask;
|
|
wnd->notificationmask = nm;
|
|
nm->client = cl;
|
|
}
|
|
nm->mask = *parameters;
|
|
}
|
|
parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWDontPropagate)
|
|
{
|
|
wnd->donotpropagate = *parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWColormap)
|
|
{
|
|
X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0);
|
|
parameters++;
|
|
}
|
|
|
|
if (req->valueMask & CWCursor)
|
|
{
|
|
// X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0);
|
|
parameters++;
|
|
}
|
|
|
|
xrefreshed=true;
|
|
|
|
if (req->valueMask > CWCursor) //anything else is an error on some implementation's part.
|
|
X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0);
|
|
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
void XR_ConfigureWindow (xclient_t *cl, xReq *request)
|
|
{
|
|
int newx, newy, neww, newh, sibid, newbw;
|
|
xConfigureWindowReq *req = (xConfigureWindowReq *)request;
|
|
xwindow_t *wnd;
|
|
|
|
CARD32 *parm;
|
|
|
|
if (XS_GetResource(req->window, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->window, X_ConfigureWindow, 0);
|
|
return;
|
|
}
|
|
|
|
if (!wnd->parent) //root window.
|
|
{ //can't resize this one.
|
|
X_SendError(cl, BadWindow, req->window, X_ConfigureWindow, 0);
|
|
return;
|
|
}
|
|
|
|
parm = (CARD32 *)(req+1);
|
|
|
|
if (req->mask & CWX)
|
|
newx = *parm++;
|
|
else
|
|
newx=wnd->xpos;
|
|
if (req->mask & CWY)
|
|
newy = *parm++;
|
|
else
|
|
newy=wnd->ypos;
|
|
|
|
if (req->mask & CWWidth)
|
|
neww = *parm++;
|
|
else
|
|
neww=wnd->width;
|
|
|
|
if (wnd->width <= 0)
|
|
wnd->width = 1;
|
|
|
|
if (req->mask & CWHeight)
|
|
newh = *parm++;
|
|
else
|
|
newh=wnd->height;
|
|
|
|
if (req->mask & CWBorderWidth)
|
|
newbw = *parm++;
|
|
else
|
|
newbw = 0;
|
|
if (req->mask & CWSibling)
|
|
sibid = *parm++;
|
|
else
|
|
sibid = 0;
|
|
if (req->mask & CWStackMode)
|
|
*parm++;
|
|
|
|
if (!wnd->overrideredirect && X_NotifcationMaskPresent(wnd, SubstructureRedirectMask, cl))
|
|
{
|
|
xEvent ev;
|
|
|
|
|
|
|
|
ev.u.u.type = ConfigureRequest;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.configureRequest.parent = wnd->parent->res.id;
|
|
ev.u.configureRequest.window = wnd->res.id;
|
|
ev.u.configureRequest.sibling = wnd->sibling?wnd->sibling->res.id:None;
|
|
ev.u.configureRequest.x = newx;
|
|
ev.u.configureRequest.y = newy;
|
|
ev.u.configureRequest.width = neww;
|
|
ev.u.configureRequest.height = newh;
|
|
ev.u.configureRequest.borderWidth = newbw;
|
|
ev.u.configureRequest.valueMask = req->mask;
|
|
ev.u.configureRequest.pad1 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, SubstructureRedirectMask);
|
|
}
|
|
else
|
|
{
|
|
xEvent ev;
|
|
|
|
/* if (wnd->xpos == newx && wnd->ypos == newy)
|
|
{
|
|
ev.u.u.type = ResizeRequest;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.resizeRequest.window = wnd->res.id;
|
|
ev.u.resizeRequest.width = wnd->width;
|
|
ev.u.resizeRequest.height = wnd->height;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, StructureNotifyMask);
|
|
X_SendNotificationMasked(&ev, wnd, SubstructureNotifyMask);
|
|
|
|
return;
|
|
}*/
|
|
|
|
wnd->xpos = newx;
|
|
wnd->ypos = newy;
|
|
|
|
if ((wnd->width != neww || wnd->height != newh) && wnd->buffer)
|
|
{
|
|
free(wnd->buffer);
|
|
wnd->buffer = NULL;
|
|
}
|
|
wnd->width = neww;
|
|
wnd->height = newh;
|
|
|
|
if (wnd->mapped)
|
|
xrefreshed = true;
|
|
|
|
ev.u.u.type = ConfigureNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.configureNotify.event = wnd->res.id;
|
|
ev.u.configureNotify.window = wnd->res.id;
|
|
ev.u.configureNotify.aboveSibling = None;
|
|
ev.u.configureNotify.x = wnd->xpos;
|
|
ev.u.configureNotify.y = wnd->ypos;
|
|
ev.u.configureNotify.width = wnd->width;
|
|
ev.u.configureNotify.height = wnd->height;
|
|
ev.u.configureNotify.borderWidth = 0;
|
|
ev.u.configureNotify.override = wnd->overrideredirect;
|
|
ev.u.configureNotify.bpad = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, StructureNotifyMask);
|
|
X_SendNotificationMasked(&ev, wnd, SubstructureNotifyMask);
|
|
}
|
|
}
|
|
|
|
void XR_ReparentWindow (xclient_t *cl, xReq *request)
|
|
{
|
|
qboolean wasmapped;
|
|
xEvent ev;
|
|
xReparentWindowReq *req = (xReparentWindowReq *)request;
|
|
xwindow_t *wnd, *parent;
|
|
|
|
if (XS_GetResource(req->window, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->window, X_ReparentWindow, 0);
|
|
return;
|
|
}
|
|
if (XS_GetResource(req->parent, (void**)&parent) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->parent, X_ReparentWindow, 0);
|
|
return;
|
|
}
|
|
|
|
if (wnd->mapped)
|
|
{
|
|
XR_UnmapWindow(cl, request);
|
|
wasmapped = true;
|
|
}
|
|
else
|
|
wasmapped = false;
|
|
|
|
ev.u.u.type = ReparentNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.reparent.override = wnd->overrideredirect;
|
|
ev.u.reparent.window = wnd->res.id;
|
|
ev.u.reparent.parent = wnd->res.id;
|
|
ev.u.reparent.x = req->x;
|
|
ev.u.reparent.y = req->y;
|
|
|
|
X_SendNotificationMasked (&ev, wnd, SubstructureNotifyMask);
|
|
|
|
XS_SetParent(wnd, parent);
|
|
wnd->xpos = req->x;
|
|
wnd->ypos = req->y;
|
|
|
|
X_SendNotificationMasked (&ev, wnd, SubstructureNotifyMask); //and again, now that we have the new parent.
|
|
|
|
ev.u.reparent.event = wnd->res.id;
|
|
X_SendNotificationMasked (&ev, wnd, StructureNotifyMask);
|
|
|
|
if (wasmapped)
|
|
XR_MapWindow(cl, request);
|
|
}
|
|
|
|
void XR_DestroyWindow (xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xwindow_t *wnd;
|
|
|
|
if (XS_GetResource(req->id, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->id, X_DestroyWindow, 0);
|
|
return;
|
|
}
|
|
if (!wnd->res.owner) //root window.
|
|
return;
|
|
XS_DestroyResource(&wnd->res);
|
|
}
|
|
void XR_QueryTree (xclient_t *cl, xReq *request)
|
|
{
|
|
char buffer[8192];
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xQueryTreeReply *rep = (xQueryTreeReply*)buffer;
|
|
|
|
xwindow_t *wnd;
|
|
|
|
Window *cwnd;
|
|
|
|
|
|
if (XS_GetResource(req->id, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->id, X_DestroyWindow, 0);
|
|
return;
|
|
}
|
|
|
|
//FIXME: be careful of the count of children overflowing buffer.
|
|
|
|
rep->type = X_Reply;
|
|
rep->pad1 = 0;
|
|
rep->sequenceNumber = cl->requestnum;
|
|
rep->length = 0;
|
|
rep->root = rootwindow->res.id; //we only have one root
|
|
if (wnd->parent)
|
|
rep->parent = wnd->parent->res.id;
|
|
else
|
|
rep->parent = 0;
|
|
rep->nChildren = 0;
|
|
rep->pad2 = 0;
|
|
rep->pad3 = 0;
|
|
rep->pad4 = 0;
|
|
rep->pad5 = 0;
|
|
|
|
cwnd = (Window*)(rep+1);
|
|
|
|
for (wnd = wnd->child ; wnd ; wnd = wnd->sibling)
|
|
{
|
|
*cwnd++ = wnd->res.id;
|
|
rep->nChildren++;
|
|
}
|
|
|
|
rep->length = rep->nChildren;
|
|
|
|
X_SendData(cl, rep, sizeof(*rep)+rep->length*4);
|
|
}
|
|
|
|
void XR_GetWindowAttributes (xclient_t *cl, xReq *request)
|
|
{
|
|
xnotificationmask_t *nm;
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xwindow_t *wnd;
|
|
|
|
xGetWindowAttributesReply rep;
|
|
|
|
if (XS_GetResource(req->id, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->id, X_GetWindowAttributes, 0);
|
|
return;
|
|
}
|
|
|
|
rep.type = X_Reply;
|
|
rep.backingStore = 2;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.visualID = 0x22;
|
|
rep.class = wnd->inputonly;
|
|
rep.bitGravity = wnd->bitgravity;
|
|
rep.winGravity = wnd->wingravity;
|
|
rep.backingBitPlanes = wnd->depth;
|
|
rep.backingPixel = wnd->backpixel;
|
|
rep.saveUnder = 1;
|
|
rep.mapInstalled = !!wnd->buffer;
|
|
rep.mapState = wnd->mapped*2;
|
|
rep.override = wnd->overrideredirect;
|
|
rep.colormap = wnd->colormap;
|
|
rep.yourEventMask = 0;
|
|
rep.allEventMasks = 0;
|
|
for (nm = wnd->notificationmask; nm; nm = nm->next)
|
|
{
|
|
if (nm->client == cl)
|
|
rep.yourEventMask = nm->mask;
|
|
rep.allEventMasks |= nm->mask;
|
|
}
|
|
rep.doNotPropagateMask = wnd->donotpropagate;
|
|
rep.pad = 0;
|
|
|
|
rep.length = (sizeof(xGetWindowAttributesReply) - sizeof(xGenericReply) + 3)/4;
|
|
|
|
X_SendData(cl, &rep, sizeof(xGetWindowAttributesReply));
|
|
}
|
|
|
|
void XR_GetKeyboardMapping (xclient_t *cl, xReq *request)
|
|
{//fixme: send the XK equivelents.
|
|
xGetKeyboardMappingReq *req = (xGetKeyboardMappingReq *)request;
|
|
char buffer[8192];
|
|
xGetKeyboardMappingReply *rep = (xGetKeyboardMappingReply *)buffer;
|
|
int i;
|
|
|
|
rep->type = X_Reply;
|
|
rep->keySymsPerKeyCode = 1;
|
|
rep->sequenceNumber = cl->requestnum;
|
|
rep->length = req->count;
|
|
rep->pad2 = 0;
|
|
rep->pad3 = 0;
|
|
rep->pad4 = 0;
|
|
rep->pad5 = 0;
|
|
rep->pad6 = 0;
|
|
rep->pad7 = 0;
|
|
|
|
for (i = 0; i < req->count; i++)
|
|
{
|
|
switch (req->firstKeyCode+i)
|
|
{
|
|
case ' ': ((int *)(rep+1))[i] = XK_space; break;
|
|
|
|
case K_PGUP: ((int *)(rep+1))[i] = XK_Page_Up; break;
|
|
case K_PGDN: ((int *)(rep+1))[i] = XK_Page_Down; break;
|
|
case K_HOME: ((int *)(rep+1))[i] = XK_Home; break;
|
|
case K_END: ((int *)(rep+1))[i] = XK_End; break;
|
|
|
|
case K_LEFTARROW: ((int *)(rep+1))[i] = XK_Left; break;
|
|
case K_RIGHTARROW: ((int *)(rep+1))[i] = XK_Right; break;
|
|
case K_DOWNARROW: ((int *)(rep+1))[i] = XK_Down; break;
|
|
case K_UPARROW: ((int *)(rep+1))[i] = XK_Up; break;
|
|
|
|
case K_ENTER: ((int *)(rep+1))[i] = XK_Return; break;
|
|
case K_TAB: ((int *)(rep+1))[i] = XK_Tab; break;
|
|
case K_ESCAPE: ((int *)(rep+1))[i] = XK_Escape; break;
|
|
|
|
case K_F1: ((int *)(rep+1))[i] = XK_F1; break;
|
|
case K_F2: ((int *)(rep+1))[i] = XK_F2; break;
|
|
case K_F3: ((int *)(rep+1))[i] = XK_F3; break;
|
|
case K_F4: ((int *)(rep+1))[i] = XK_F4; break;
|
|
case K_F5: ((int *)(rep+1))[i] = XK_F5; break;
|
|
case K_F6: ((int *)(rep+1))[i] = XK_F6; break;
|
|
case K_F7: ((int *)(rep+1))[i] = XK_F7; break;
|
|
case K_F8: ((int *)(rep+1))[i] = XK_F8; break;
|
|
case K_F9: ((int *)(rep+1))[i] = XK_F9; break;
|
|
case K_F10: ((int *)(rep+1))[i] = XK_F10; break;
|
|
case K_F11: ((int *)(rep+1))[i] = XK_F11; break;
|
|
case K_F12: ((int *)(rep+1))[i] = XK_F12; break;
|
|
|
|
case K_BACKSPACE: ((int *)(rep+1))[i] = XK_BackSpace; break;
|
|
case K_DEL: ((int *)(rep+1))[i] = XK_Delete; break;
|
|
case K_INS: ((int *)(rep+1))[i] = XK_Insert; break;
|
|
case K_PAUSE: ((int *)(rep+1))[i] = XK_Pause; break;
|
|
case K_SHIFT: ((int *)(rep+1))[i] = XK_Shift_L; break;
|
|
case K_CTRL: ((int *)(rep+1))[i] = XK_Control_L; break;
|
|
case K_ALT: ((int *)(rep+1))[i] = XK_Alt_L; break;
|
|
|
|
|
|
case K_KP_HOME: ((int *)(rep+1))[i] = XK_Home; break;
|
|
case K_KP_UPARROW: ((int *)(rep+1))[i] = XK_Up; break;
|
|
|
|
|
|
|
|
case K_KP_PGUP: ((int *)(rep+1))[i] = XK_KP_Page_Up; break;
|
|
case K_KP_LEFTARROW: ((int *)(rep+1))[i] = XK_KP_Left; break;
|
|
case K_KP_5: ((int *)(rep+1))[i] = XK_KP_Space; break;
|
|
case K_KP_RIGHTARROW: ((int *)(rep+1))[i] = XK_KP_Right; break;
|
|
case K_KP_END: ((int *)(rep+1))[i] = XK_KP_End; break;
|
|
case K_KP_DOWNARROW: ((int *)(rep+1))[i] = XK_KP_Down; break;
|
|
case K_KP_PGDN: ((int *)(rep+1))[i] = XK_KP_Page_Down; break;
|
|
case K_KP_ENTER: ((int *)(rep+1))[i] = XK_KP_Enter; break;
|
|
case K_KP_INS: ((int *)(rep+1))[i] = XK_KP_Insert; break;
|
|
case K_KP_DEL: ((int *)(rep+1))[i] = XK_KP_Delete; break;
|
|
case K_KP_SLASH: ((int *)(rep+1))[i] = XK_KP_Divide; break;
|
|
case K_KP_MINUS: ((int *)(rep+1))[i] = XK_KP_Subtract; break;
|
|
case K_KP_PLUS: ((int *)(rep+1))[i] = XK_KP_Add; break;
|
|
case K_KP_STAR: ((int *)(rep+1))[i] = XK_KP_Multiply; break;
|
|
case K_KP_EQUALS: ((int *)(rep+1))[i] = XK_KP_Enter; break;
|
|
|
|
default:
|
|
((int *)(rep+1))[i] = req->firstKeyCode+i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
X_SendData(cl, rep, sizeof(*rep)+rep->length*4);
|
|
}
|
|
|
|
void XR_QueryPointer (xclient_t *cl, xReq *request)
|
|
{
|
|
extern int mousecursor_x, mousecursor_y;
|
|
xQueryPointerReply rep;
|
|
|
|
rep.type = X_Reply;
|
|
rep.sameScreen = 1;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.root = rootwindow->res.id;
|
|
rep.child = rootwindow->res.id;
|
|
rep.rootX = mousecursor_x;
|
|
rep.rootY = mousecursor_y;
|
|
rep.winX = mousecursor_x;
|
|
rep.winY = mousecursor_y;
|
|
rep.mask = 0;
|
|
rep.pad1 = 0;
|
|
rep.pad = 0;
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
void XR_ChangeGCInternal(unsigned int mask, xgcontext_t *gc, CARD32 *param)
|
|
{
|
|
if (mask & GCFunction)
|
|
gc->function = *param++;
|
|
if (mask & GCPlaneMask)
|
|
param++;
|
|
if (mask & GCForeground)
|
|
gc->fgcolour = *param++;
|
|
if (mask & GCBackground)
|
|
gc->bgcolour = *param++;
|
|
if (mask & GCLineWidth)
|
|
param++;
|
|
if (mask & GCLineStyle)
|
|
param++;
|
|
if (mask & GCCapStyle)
|
|
param++;
|
|
if (mask & GCJoinStyle)
|
|
param++;
|
|
if (mask & GCFillStyle)
|
|
param++;
|
|
if (mask & GCFillRule)
|
|
param++;
|
|
if (mask & GCTile)
|
|
param++;
|
|
if (mask & GCStipple)
|
|
param++;
|
|
if (mask & GCTileStipXOrigin)
|
|
param++;
|
|
if (mask & GCTileStipYOrigin)
|
|
param++;
|
|
if (mask & GCFont)
|
|
param++;
|
|
if (mask & GCSubwindowMode)
|
|
param++;
|
|
if (mask & GCGraphicsExposures)
|
|
param++;
|
|
if (mask & GCClipXOrigin)
|
|
param++;
|
|
if (mask & GCClipYOrigin)
|
|
param++;
|
|
if (mask & GCClipMask)
|
|
param++;
|
|
if (mask & GCDashOffset)
|
|
param++;
|
|
if (mask & GCDashList)
|
|
param++;
|
|
if (mask & GCArcMode)
|
|
param++;
|
|
}
|
|
void XR_ChangeGC(xclient_t *cl, xReq *request)
|
|
{
|
|
xChangeGCReq *req = (xChangeGCReq *)request;
|
|
xgcontext_t *gc;
|
|
|
|
if (XS_GetResource(req->gc, (void**)&gc) != x_gcontext)
|
|
{
|
|
X_SendError(cl, BadGC, req->gc, X_FreeGC, 0);
|
|
return;
|
|
}
|
|
|
|
XR_ChangeGCInternal(req->mask, gc, (CARD32 *)(req + 1));
|
|
}
|
|
|
|
void XR_CreateGC(xclient_t *cl, xReq *request)
|
|
{
|
|
xCreateGCReq *req = (xCreateGCReq *)request;
|
|
xresource_t *drawable;
|
|
|
|
if (XS_GetResource(req->gc, (void**)&drawable) != x_none)
|
|
{
|
|
// if (req->gc == cl->ridbase&&drawable->owner)
|
|
// XS_DestroyResourcesOfClient(drawable->owner);
|
|
// else
|
|
{
|
|
X_SendError(cl, BadIDChoice, req->gc, X_CreateGC, 0);
|
|
return;
|
|
}
|
|
}
|
|
XS_GetResource(req->drawable, (void**)&drawable);
|
|
/*if (drawable->restype != x_window && drawable->restype != x_gcontext)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_CreateGC, 0);
|
|
return;
|
|
}*/
|
|
|
|
XR_ChangeGCInternal(req->mask, XS_CreateGContext(req->gc, cl, drawable), (CARD32 *)(req + 1));
|
|
}
|
|
|
|
void XR_FreeGC(xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xresource_t *gc;
|
|
if (XS_GetResource(req->id, (void**)&gc) != x_gcontext)
|
|
{
|
|
X_SendError(cl, BadGC, req->id, X_FreeGC, 0);
|
|
return;
|
|
}
|
|
|
|
XS_DestroyResource(gc);
|
|
}
|
|
|
|
void XW_ClearArea(xwindow_t *wnd, int xp, int yp, int width, int height)
|
|
{
|
|
if (!wnd->buffer)
|
|
{
|
|
if (wnd->width*wnd->height<=0)
|
|
wnd->buffer = malloc(1);
|
|
else
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
}
|
|
|
|
if (xp < 0)
|
|
{
|
|
width += xp;
|
|
xp = 0;
|
|
}
|
|
if (xp>wnd->width)
|
|
xp = wnd->width;
|
|
if (yp < 0)
|
|
{
|
|
height += yp;
|
|
xp = 0;
|
|
}
|
|
if (yp>wnd->height)
|
|
yp = wnd->height;
|
|
if (width+xp > wnd->width)
|
|
width = wnd->width - xp;
|
|
if (height+yp > wnd->height)
|
|
height = wnd->height - yp;
|
|
|
|
if (wnd->backpixmap && wnd->backpixmap->width && wnd->backpixmap->height)
|
|
{
|
|
int x, xs;
|
|
int y, ys;
|
|
unsigned int *out;
|
|
unsigned int *in;
|
|
|
|
out = (unsigned int *)wnd->buffer + xp +yp*wnd->width;
|
|
in = (unsigned int *)wnd->backpixmap->data;
|
|
|
|
for (y = 0, ys = 0; y < height; y++)
|
|
{
|
|
for (x = 0; x < width; x+=wnd->backpixmap->width)
|
|
{
|
|
//when do we stop?
|
|
xs = wnd->backpixmap->width;
|
|
if (xs > wnd->width-x)
|
|
xs = wnd->width-x;
|
|
for (; xs > 0; xs--)
|
|
{
|
|
out[x+xs] = in[xs+ys*wnd->backpixmap->width];
|
|
}
|
|
}
|
|
out += wnd->width;
|
|
ys++;
|
|
if (ys >= wnd->backpixmap->height)
|
|
ys = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int x;
|
|
int y;
|
|
unsigned int *out;
|
|
|
|
out = (unsigned int *)wnd->buffer + xp +yp*wnd->width;
|
|
|
|
for (y = yp; y < height; y++)
|
|
{
|
|
for (x = xp; x < width; x++)
|
|
{
|
|
out[x] = wnd->backpixel;
|
|
}
|
|
out+=wnd->width;
|
|
}
|
|
}
|
|
}
|
|
|
|
void XW_CopyArea(unsigned int *dest, int dx, int dy, int dwidth, int dheight, unsigned int *source, int sx, int sy, int swidth, int sheight, int cwidth, int cheight, xgcontext_t *gc)
|
|
{
|
|
int x, y;
|
|
|
|
//tlcap on dest
|
|
if (dx < 0)
|
|
{
|
|
cwidth += dx;
|
|
dx = 0;
|
|
}
|
|
if (dy < 0)
|
|
{
|
|
cheight += dy;
|
|
dy = 0;
|
|
}
|
|
|
|
//tlcap on source
|
|
if (sx < 0)
|
|
{
|
|
cwidth += sx;
|
|
sx = 0;
|
|
}
|
|
if (sy < 0)
|
|
{
|
|
cheight += sy;
|
|
sy = 0;
|
|
}
|
|
|
|
//brcap on dest
|
|
if (cwidth > dwidth - dx)
|
|
cwidth = dwidth - dx;
|
|
|
|
if (cheight > dheight - dy)
|
|
cheight = dheight - dy;
|
|
|
|
//brcap on source
|
|
if (cwidth > swidth - sx)
|
|
cwidth = swidth - sx;
|
|
|
|
if (cheight > sheight - sy)
|
|
cheight = sheight - sy;
|
|
|
|
if (cwidth<=0)
|
|
return;
|
|
if (cheight<=0)
|
|
return;
|
|
|
|
dest += dx+dy*dwidth;
|
|
source += sx+sy*swidth;
|
|
|
|
for (y = 0; y < cheight; y++)
|
|
{
|
|
for (x = 0; x < cwidth;x++)
|
|
{
|
|
GCFunc(gc->fgcolour, dest[x], gc->function, source[x], 0xffffff);
|
|
}
|
|
dest += dwidth;
|
|
source += swidth;
|
|
}
|
|
}
|
|
|
|
void XR_ClearArea(xclient_t *cl, xReq *request)
|
|
{//FIXME: Should be area rather than entire window
|
|
xClearAreaReq *req = (xClearAreaReq *)request;
|
|
xwindow_t *wnd;
|
|
|
|
if (XS_GetResource(req->window, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->window, X_ClearArea, 0);
|
|
return;
|
|
}
|
|
|
|
if (req->x < 0)
|
|
{
|
|
if (req->width)
|
|
req->width += req->x;
|
|
req->x = 0;
|
|
}
|
|
if (req->y < 0)
|
|
{
|
|
if (req->height)
|
|
req->height += req->y;
|
|
req->y = 0;
|
|
}
|
|
|
|
if (!req->width || req->width + req->x > wnd->width)
|
|
{
|
|
if (req->width)
|
|
req->width = wnd->width - req->x;
|
|
req->width = wnd->width - req->x;
|
|
}
|
|
if (!req->height || req->height + req->y > wnd->height)
|
|
{
|
|
if (req->height)
|
|
req->height = wnd->height - req->y;
|
|
req->height = wnd->height - req->y;
|
|
}
|
|
|
|
XW_ClearArea(wnd, req->x, req->y, req->width, req->height);
|
|
|
|
xrefreshed=true;
|
|
}
|
|
|
|
void XR_CopyArea(xclient_t *cl, xReq *request) //from and to pixmap or drawable.
|
|
{
|
|
xCopyAreaReq *req = (xCopyAreaReq *)request;
|
|
|
|
xresource_t *drawable;
|
|
xgcontext_t *gc;
|
|
|
|
|
|
unsigned int *outbuffer;
|
|
unsigned int *inbuffer;
|
|
int inwidth;
|
|
int inheight;
|
|
int outwidth;
|
|
int outheight;
|
|
|
|
if (XS_GetResource(req->gc, (void**)&gc) == x_none)
|
|
{
|
|
X_SendError(cl, BadGC, req->gc, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
|
|
switch (XS_GetResource(req->srcDrawable, (void**)&drawable))
|
|
{
|
|
default:
|
|
X_SendError(cl, BadDrawable, req->srcDrawable, X_PutImage, 0);
|
|
return;
|
|
|
|
case x_window:
|
|
{
|
|
xwindow_t *wnd;
|
|
wnd = (xwindow_t *)drawable;
|
|
if (!wnd->buffer)
|
|
{
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
inwidth = wnd->width;
|
|
inheight = wnd->height;
|
|
inbuffer = (unsigned int *)wnd->buffer;
|
|
}
|
|
break;
|
|
|
|
case x_pixmap:
|
|
{
|
|
xpixmap_t *pm;
|
|
pm = (xpixmap_t *)drawable;
|
|
if (!pm->data)
|
|
{
|
|
pm->data = malloc(pm->width*pm->height*4);
|
|
memset(pm->data, rand(), pm->width*pm->height*4);
|
|
}
|
|
|
|
inwidth = pm->width;
|
|
inheight = pm->height;
|
|
inbuffer = (unsigned int *)pm->data;
|
|
}
|
|
break;
|
|
}
|
|
|
|
switch (XS_GetResource(req->dstDrawable, (void**)&drawable))
|
|
{
|
|
default:
|
|
X_SendError(cl, BadDrawable, req->dstDrawable, X_PutImage, 0);
|
|
return;
|
|
|
|
case x_window:
|
|
{
|
|
xwindow_t *wnd;
|
|
wnd = (xwindow_t *)drawable;
|
|
if (!wnd->buffer)
|
|
{
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
outwidth = wnd->width;
|
|
outheight = wnd->height;
|
|
outbuffer = (unsigned int *)wnd->buffer;
|
|
}
|
|
break;
|
|
|
|
case x_pixmap:
|
|
{
|
|
xpixmap_t *pm;
|
|
pm = (xpixmap_t *)drawable;
|
|
if (!pm->data)
|
|
{
|
|
pm->data = malloc(pm->width*pm->height*4);
|
|
memset(pm->data, rand(), pm->width*pm->height*4);
|
|
}
|
|
|
|
outwidth = pm->width;
|
|
outheight = pm->height;
|
|
outbuffer = (unsigned int *)pm->data;
|
|
}
|
|
break;
|
|
}
|
|
|
|
XW_CopyArea(outbuffer, req->dstX, req->dstY, outwidth, outheight, inbuffer, req->srcX, req->srcY, inwidth, inheight, req->width, req->height, gc);
|
|
|
|
xrefreshed=true;
|
|
}
|
|
|
|
void XR_MapWindow(xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
|
|
xwindow_t *wnd;
|
|
if (XS_GetResource(req->id, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->id, X_MapWindow, 0);
|
|
return;
|
|
}
|
|
|
|
if (wnd->mapped)
|
|
return;
|
|
|
|
if (!wnd->overrideredirect && X_NotifcationMaskPresent(wnd, SubstructureRedirectMask, cl))
|
|
{
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = MapRequest;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.mapNotify.window = wnd->parent->res.id;
|
|
ev.u.mapNotify.window = wnd->res.id;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, SubstructureRedirectMask);
|
|
|
|
return;
|
|
}
|
|
|
|
if (!wnd->buffer)
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
|
|
wnd->mapped = true;
|
|
|
|
{
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = MapNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.mapNotify.window = wnd->res.id;
|
|
ev.u.mapNotify.window = wnd->res.id;
|
|
ev.u.mapNotify.override = wnd->overrideredirect;
|
|
ev.u.mapNotify.pad1 = 0;
|
|
ev.u.mapNotify.pad2 = 0;
|
|
ev.u.mapNotify.pad3 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, StructureNotifyMask);
|
|
X_SendNotificationMasked(&ev, wnd, SubstructureNotifyMask);
|
|
}
|
|
|
|
/* {
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = GraphicsExpose;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.mapNotify.window = wnd->res.id;
|
|
ev.u.mapNotify.override = false;
|
|
ev.u.mapNotify.pad1 = 0;
|
|
ev.u.mapNotify.pad2 = 0;
|
|
ev.u.mapNotify.pad3 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, ExposureMask);
|
|
}*/
|
|
|
|
XW_ExposeWindowRegionInternal(wnd, 0, 0, wnd->width, wnd->height);
|
|
/*
|
|
|
|
while(wnd->mapped)
|
|
{
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = VisibilityNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.visibility.window = wnd->res.id;
|
|
ev.u.visibility.state = 0;
|
|
ev.u.visibility.pad1 = 0;
|
|
ev.u.visibility.pad2 = 0;
|
|
ev.u.visibility.pad3 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, VisibilityChangeMask);
|
|
}
|
|
|
|
{
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = Expose;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.expose.window = wnd->res.id;
|
|
ev.u.expose.x = 0;
|
|
ev.u.expose.y = 0;
|
|
ev.u.expose.width = wnd->width;
|
|
ev.u.expose.height = wnd->height;
|
|
ev.u.expose.count = false; //other expose events following
|
|
ev.u.expose.pad2 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, ExposureMask);
|
|
}*/
|
|
|
|
xrefreshed = true;
|
|
}
|
|
|
|
void XR_UnmapWindow(xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
|
|
xwindow_t *wnd;
|
|
if (XS_GetResource(req->id, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->id, X_UnmapWindow, 0);
|
|
return;
|
|
}
|
|
|
|
if (!wnd->mapped || !wnd->parent)
|
|
return;
|
|
|
|
wnd->mapped = false;
|
|
xrefreshed=true;
|
|
|
|
XW_ExposeWindow(wnd, 0, 0, wnd->width, wnd->height);
|
|
|
|
{
|
|
xEvent ev;
|
|
|
|
ev.u.u.type = UnmapNotify;
|
|
ev.u.u.detail = 0;
|
|
ev.u.u.sequenceNumber = 0;
|
|
ev.u.unmapNotify.event = wnd->res.id;
|
|
ev.u.unmapNotify.window = wnd->res.id;
|
|
ev.u.unmapNotify.fromConfigure = 0;
|
|
ev.u.unmapNotify.pad1 = 0;
|
|
ev.u.unmapNotify.pad2 = 0;
|
|
ev.u.unmapNotify.pad3 = 0;
|
|
|
|
X_SendNotificationMasked(&ev, wnd, StructureNotifyMask);
|
|
X_SendNotificationMasked(&ev, wnd, SubstructureNotifyMask);
|
|
}
|
|
}
|
|
|
|
void XR_MapSubwindows(xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xwindow_t *wnd;
|
|
|
|
if (XS_GetResource(req->id, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->id, X_MapWindow, 0);
|
|
return;
|
|
}
|
|
|
|
for (wnd = wnd->child; wnd; wnd = wnd->sibling)
|
|
{
|
|
req->id = wnd->res.id;
|
|
XR_MapWindow(cl, request);
|
|
}
|
|
}
|
|
|
|
void XR_CreatePixmap(xclient_t *cl, xReq *request)
|
|
{
|
|
xCreatePixmapReq *req = (xCreatePixmapReq *)request;
|
|
|
|
xwindow_t *wnd;
|
|
if (XS_GetResource(req->drawable, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_CreatePixmap, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->pid, (void**)&wnd) != x_none)
|
|
{
|
|
X_SendError(cl, BadIDChoice, req->pid, X_CreatePixmap, 0);
|
|
}
|
|
|
|
XS_CreatePixmap(req->pid, cl, req->width, req->height, 24);
|
|
}
|
|
|
|
void XR_FreePixmap(xclient_t *cl, xReq *request)
|
|
{
|
|
xResourceReq *req = (xResourceReq *)request;
|
|
xresource_t *pm;
|
|
if (XS_GetResource(req->id, (void**)&pm) != x_pixmap)
|
|
{
|
|
X_SendError(cl, BadPixmap, req->id, X_FreePixmap, 0);
|
|
return;
|
|
}
|
|
|
|
XS_DestroyResource(pm);
|
|
}
|
|
|
|
void XR_PutImage(xclient_t *cl, xReq *request)
|
|
{
|
|
unsigned char *out;
|
|
unsigned char *in;
|
|
xPutImageReq *req = (xPutImageReq *)request;
|
|
xresource_t *drawable;
|
|
xgcontext_t *gc;
|
|
int i;
|
|
|
|
int drwidth;
|
|
int drheight;
|
|
int drdepth;
|
|
unsigned char *drbuffer;
|
|
|
|
if (XS_GetResource(req->drawable, (void**)&drawable) == x_none)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->gc, (void**)&gc) == x_none)
|
|
{
|
|
X_SendError(cl, BadGC, req->gc, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
|
|
if (drawable->restype == x_window)
|
|
{
|
|
xwindow_t *wnd;
|
|
wnd = (xwindow_t *)drawable;
|
|
if (!wnd->buffer)
|
|
{
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
drwidth = wnd->width;
|
|
drheight = wnd->height;
|
|
drbuffer = wnd->buffer;
|
|
drdepth = wnd->depth;
|
|
}
|
|
else if (drawable->restype == x_pixmap)
|
|
{
|
|
xpixmap_t *pm;
|
|
pm = (xpixmap_t *)drawable;
|
|
if (!pm->data)
|
|
{
|
|
pm->data = malloc(pm->width*pm->height*4);
|
|
memset(pm->data, rand(), pm->width*pm->height*4);
|
|
}
|
|
|
|
drwidth = pm->width;
|
|
drheight = pm->height;
|
|
drbuffer = pm->data;
|
|
drdepth = pm->depth;
|
|
}
|
|
else
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
xrefreshed = true;
|
|
|
|
if (req->dstX < 0)
|
|
{
|
|
req->width += req->dstX;
|
|
req->dstX = 0;
|
|
}
|
|
if (req->dstY < 0)
|
|
{
|
|
req->height += req->dstY;
|
|
req->dstY = 0;
|
|
}
|
|
|
|
if (req->width > drwidth - req->dstX)
|
|
req->width = drwidth - req->dstX;
|
|
|
|
if (req->height > drheight - req->dstY)
|
|
req->height = drheight - req->dstY;
|
|
|
|
in = (qbyte *)(req+1);
|
|
|
|
if (req->format == ZPixmap && req->leftPad)
|
|
{
|
|
X_SendError(cl, BadMatch, req->drawable, X_PutImage, 0);
|
|
}
|
|
else if (req->format != XYBitmap && req->depth != drdepth)
|
|
{
|
|
// X_SendError(cl, BadMatch, req->drawable, X_PutImage, 0);
|
|
}
|
|
else if (req->format == ZPixmap && req->depth == 24) //32 bit network bandwidth (hideous)
|
|
{
|
|
while(req->height)
|
|
{
|
|
out = drbuffer + (req->dstX + req->dstY*drwidth)*4;
|
|
for (i = 0; i < req->width; i++)
|
|
{
|
|
out[i*4+0] = in[i*4+0];
|
|
out[i*4+1] = in[i*4+1];
|
|
out[i*4+2] = in[i*4+2];
|
|
}
|
|
in += req->width*4;
|
|
|
|
req->height--;
|
|
req->dstY++;
|
|
}
|
|
}
|
|
else if (req->format == XYPixmap)
|
|
{
|
|
|
|
}
|
|
else if (req->format == XYBitmap)
|
|
{ //bitwise image... yuck
|
|
int bnum;
|
|
bnum=0;
|
|
if (req->depth == 1)
|
|
{
|
|
while(req->height)
|
|
{
|
|
bnum += req->leftPad;
|
|
|
|
out = drbuffer + (req->dstX + req->dstY*drwidth)*4;
|
|
for (i = 0; i < req->width; i++)
|
|
{
|
|
if (in[bnum>>8]&(1<<(bnum&7)))
|
|
{
|
|
out[i*4+0] = 0xff;
|
|
out[i*4+1] = 0xff;
|
|
out[i*4+2] = 0xff;
|
|
}
|
|
else
|
|
{
|
|
out[i*4+0] = 0x00;
|
|
out[i*4+1] = 0x00;
|
|
out[i*4+2] = 0x00;
|
|
}
|
|
out[i*4+2] = rand();
|
|
bnum++;
|
|
}
|
|
bnum += req->width;
|
|
|
|
req->height--;
|
|
req->dstY++;
|
|
}
|
|
}
|
|
else
|
|
X_SendError(cl, BadMatch, req->drawable, X_PutImage, 0);
|
|
}
|
|
else
|
|
{
|
|
X_SendError(cl, BadImplementation, req->drawable, X_PutImage, req->format);
|
|
}
|
|
}
|
|
void XR_GetImage(xclient_t *cl, xReq *request)
|
|
{
|
|
unsigned char *out;
|
|
unsigned char *in;
|
|
xGetImageReq *req = (xGetImageReq *)request;
|
|
xresource_t *drawable;
|
|
int i;
|
|
|
|
unsigned int buffer[65535];
|
|
xGetImageReply *rep = (xGetImageReply *)buffer;
|
|
|
|
int drwidth;
|
|
int drheight;
|
|
unsigned char *drbuffer;
|
|
|
|
if (XS_GetResource(req->drawable, (void**)&drawable) == x_none)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
|
|
if (drawable->restype == x_window)
|
|
{
|
|
xwindow_t *wnd;
|
|
wnd = (xwindow_t *)drawable;
|
|
if (!wnd->buffer)
|
|
{
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
drwidth = wnd->width;
|
|
drheight = wnd->height;
|
|
drbuffer = wnd->buffer;
|
|
|
|
rep->visual = 0x22;
|
|
}
|
|
else if (drawable->restype == x_pixmap)
|
|
{
|
|
xpixmap_t *pm;
|
|
pm = (xpixmap_t *)drawable;
|
|
if (!pm->data)
|
|
{
|
|
pm->data = malloc(pm->width*pm->height*4);
|
|
memset(pm->data, rand(), pm->width*pm->height*4);
|
|
}
|
|
|
|
drwidth = pm->width;
|
|
drheight = pm->height;
|
|
drbuffer = pm->data;
|
|
|
|
rep->visual = 0;
|
|
}
|
|
else
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
if (req->x < 0)
|
|
{
|
|
X_SendError(cl, BadValue, req->drawable, X_PutImage, 0);
|
|
return;
|
|
}
|
|
if (req->y < 0)
|
|
{
|
|
X_SendError(cl, BadValue, req->drawable, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
if (req->width > drwidth - req->x)
|
|
{
|
|
X_SendError(cl, BadValue, req->drawable, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
if (req->height > drheight - req->y)
|
|
{
|
|
X_SendError(cl, BadValue, req->drawable, X_PutImage, 0);
|
|
return;
|
|
}
|
|
|
|
out = (qbyte *)(rep+1);
|
|
if (req->format == 2) //32 bit network bandwidth (hideous)
|
|
{
|
|
while(req->height)
|
|
{
|
|
in = drbuffer + (req->x + req->y*drwidth)*4;
|
|
for (i = 0; i < req->width; i++)
|
|
{
|
|
out[i*4+0] = in[i*4+0];
|
|
out[i*4+1] = in[i*4+1];
|
|
out[i*4+2] = in[i*4+2];
|
|
}
|
|
out += req->width*4;
|
|
|
|
req->height--;
|
|
req->y++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
X_SendError(cl, BadImplementation, req->drawable, X_PutImage, req->format);
|
|
return;
|
|
}
|
|
|
|
rep->type = X_Reply;
|
|
rep->sequenceNumber = cl->requestnum;
|
|
rep->length = (out-(qbyte *)(rep+1)+3)/4;
|
|
rep->depth = 24;
|
|
rep->pad3 = 0;
|
|
rep->pad4 = 0;
|
|
rep->pad5 = 0;
|
|
rep->pad6 = 0;
|
|
rep->pad7 = 0;
|
|
|
|
X_SendData(cl, rep, sizeof(*rep)+rep->length*4);
|
|
}
|
|
|
|
void XW_PolyLine(unsigned int *dbuffer, int dwidth, int dheight, int x1, int x2, int y1, int y2, xgcontext_t *gc)
|
|
{
|
|
//FIXME: cap to region.
|
|
int len;
|
|
|
|
int dx, dy;
|
|
|
|
if (x1 < 0)
|
|
return;
|
|
if (x2 < 0)
|
|
return;
|
|
if (y1 < 0)
|
|
return;
|
|
if (y2 < 0)
|
|
return;
|
|
|
|
if (x1 >= dwidth)
|
|
x1 = dwidth-1;
|
|
if (x2 >= dwidth)
|
|
x2 = dwidth-1;
|
|
|
|
if (y1 >= dheight)
|
|
y1 = dheight-1;
|
|
if (y2 >= dheight)
|
|
y2 = dheight-1;
|
|
|
|
dx = (x2 - x1);
|
|
dy = (y2 - y1);
|
|
len = sqrt(dx*dx+dy*dy);
|
|
|
|
if (!len)
|
|
return;
|
|
|
|
x1<<=16;
|
|
y1<<=16;
|
|
dx=(dx<<16)/len;
|
|
dy=(dy<<16)/len;
|
|
|
|
for (; len ; len--)
|
|
{
|
|
GCFunc(gc->fgcolour, dbuffer[(x1>>16)+dwidth*(y1>>16)], gc->function, dbuffer[(x1>>16)+dwidth*(y1>>16)], 0xffffff);
|
|
x1+=dx;
|
|
y1+=dy;
|
|
}
|
|
}
|
|
|
|
void XR_PolyLine(xclient_t *cl, xReq *request)
|
|
{
|
|
xPolyLineReq *req = (xPolyLineReq *)request;
|
|
|
|
xresource_t *drawable;
|
|
xgcontext_t *gc;
|
|
|
|
int pointsleft;
|
|
|
|
int drwidth;
|
|
int drheight;
|
|
unsigned char *drbuffer;
|
|
|
|
INT16 *points;
|
|
points = (INT16 *)(req+1);
|
|
|
|
|
|
|
|
if (XS_GetResource(req->drawable, (void**)&drawable) == x_none)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PolyRectangle, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->gc, (void**)&gc) == x_none)
|
|
{
|
|
X_SendError(cl, BadGC, req->gc, X_PolyRectangle, 0);
|
|
return;
|
|
}
|
|
|
|
if (drawable->restype == x_window)
|
|
{
|
|
xwindow_t *wnd;
|
|
wnd = (xwindow_t *)drawable;
|
|
if (!wnd->buffer)
|
|
{
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
drwidth = wnd->width;
|
|
drheight = wnd->height;
|
|
drbuffer = wnd->buffer;
|
|
}
|
|
else if (drawable->restype == x_pixmap)
|
|
{
|
|
xpixmap_t *pm;
|
|
pm = (xpixmap_t *)drawable;
|
|
if (!pm->data)
|
|
{
|
|
pm->data = malloc(pm->width*pm->height*4);
|
|
memset(pm->data, rand(), pm->width*pm->height*4);
|
|
}
|
|
|
|
drwidth = pm->width;
|
|
drheight = pm->height;
|
|
drbuffer = pm->data;
|
|
}
|
|
else
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PolyRectangle, 0);
|
|
return;
|
|
}
|
|
|
|
xrefreshed = true;
|
|
|
|
if (req->reqType == X_PolySegment)
|
|
{
|
|
for (pointsleft = req->length/2-3; pointsleft>0; pointsleft--)
|
|
{
|
|
XW_PolyLine((unsigned int *)drbuffer, drwidth, drheight, points[0], points[2], points[1], points[3], gc);
|
|
points+=4;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (req->coordMode)
|
|
{
|
|
for(pointsleft = req->length-4; pointsleft>0; pointsleft--)
|
|
{
|
|
points[2] += points[0];
|
|
points[3] += points[1];
|
|
points+=2;
|
|
}
|
|
points = (INT16 *)(req+1);
|
|
}
|
|
|
|
for (pointsleft = req->length-4; pointsleft>0; pointsleft--)
|
|
{
|
|
XW_PolyLine((unsigned int *)drbuffer, drwidth, drheight, points[0], points[2], points[1], points[3], gc);
|
|
points+=2;
|
|
}
|
|
}
|
|
}
|
|
|
|
void XR_PolyRectangle(xclient_t *cl, xReq *request)
|
|
{
|
|
unsigned int *out;
|
|
xPolyRectangleReq *req = (xPolyRectangleReq *)request;
|
|
xresource_t *drawable;
|
|
xgcontext_t *gc;
|
|
int i;
|
|
|
|
short *rect;
|
|
int rectnum;
|
|
|
|
int drwidth;
|
|
int drheight;
|
|
unsigned char *drbuffer;
|
|
|
|
|
|
|
|
if (XS_GetResource(req->drawable, (void**)&drawable) == x_none)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PolyRectangle, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->gc, (void**)&gc) == x_none)
|
|
{
|
|
X_SendError(cl, BadGC, req->gc, X_PolyRectangle, 0);
|
|
return;
|
|
}
|
|
|
|
if (drawable->restype == x_window)
|
|
{
|
|
xwindow_t *wnd;
|
|
wnd = (xwindow_t *)drawable;
|
|
if (!wnd->buffer)
|
|
{
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
drwidth = wnd->width;
|
|
drheight = wnd->height;
|
|
drbuffer = wnd->buffer;
|
|
}
|
|
else if (drawable->restype == x_pixmap)
|
|
{
|
|
xpixmap_t *pm;
|
|
pm = (xpixmap_t *)drawable;
|
|
if (!pm->data)
|
|
{
|
|
pm->data = malloc(pm->width*pm->height*4);
|
|
memset(pm->data, rand(), pm->width*pm->height*4);
|
|
}
|
|
|
|
drwidth = pm->width;
|
|
drheight = pm->height;
|
|
drbuffer = pm->data;
|
|
}
|
|
else
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PolyRectangle, 0);
|
|
return;
|
|
}
|
|
|
|
xrefreshed = true;
|
|
|
|
|
|
rect = (short *)(req+1);
|
|
for (rectnum = req->length/2 - 1; rectnum>0; rectnum--)
|
|
{
|
|
|
|
// Con_Printf("polyrect %i %i %i %i %i\n", req->drawable, rect[0], rect[1], rect[2], rect[3]);
|
|
|
|
if (rect[2] < 0)
|
|
{
|
|
rect[2] *= -1;
|
|
}
|
|
if (rect[3] < 0)
|
|
{
|
|
rect[3] *= -1;
|
|
}
|
|
|
|
if (rect[0] < 0)
|
|
{
|
|
rect[2] += rect[0];
|
|
rect[0] = 0;
|
|
}
|
|
if (rect[0] >= drwidth)
|
|
rect[0] = drwidth-1;
|
|
if (rect[1] < 0)
|
|
{
|
|
rect[3] += rect[1];
|
|
rect[1] = 0;
|
|
}
|
|
if (rect[1] >= drheight)
|
|
rect[1] = drheight-1;
|
|
|
|
if (rect[0] + rect[2] > drwidth)
|
|
rect[2] = drwidth - rect[0];
|
|
if (rect[1] + rect[3] > drheight)
|
|
rect[3] = drheight - rect[1];
|
|
if (request->reqType == X_PolyFillRectangle) //fill
|
|
{
|
|
while(rect[3])
|
|
{
|
|
out = (unsigned int *)drbuffer + (rect[0] + rect[1]*drwidth);
|
|
for (i = 0; i < rect[2]; i++)
|
|
{
|
|
GCFunc(gc->fgcolour, *(char *)&out[i], gc->function, *(char *)&out[i], 0xff);
|
|
}
|
|
|
|
rect[3]--;
|
|
rect[1]++;
|
|
}
|
|
}
|
|
else //outline
|
|
{
|
|
//top
|
|
out = (unsigned int *)drbuffer + (rect[0] + rect[1]*drwidth);
|
|
for (i = 1; i < rect[2]-1; i++)
|
|
{
|
|
GCFunc(gc->fgcolour, out[i], gc->function, out[i], 0xffffff);
|
|
}
|
|
|
|
//bottom
|
|
if (rect[3]-1)
|
|
{
|
|
out = (unsigned int *)drbuffer + (rect[0] + (rect[1]+rect[3]-1)*drwidth);
|
|
for (i = 1; i < rect[2]-1; i++)
|
|
{
|
|
GCFunc(gc->fgcolour, out[i], gc->function, out[i], 0xffffff);
|
|
}
|
|
}
|
|
|
|
//left
|
|
out = (unsigned int *)drbuffer + (rect[0] + rect[1]*drwidth);
|
|
for (i = 0; i < rect[3]; i++)
|
|
{
|
|
GCFunc(gc->fgcolour, out[i*drwidth], gc->function, out[i*drwidth], 0xffffff);
|
|
}
|
|
|
|
//right
|
|
if (rect[2]-1)
|
|
{
|
|
out = (unsigned int *)drbuffer + (rect[0]+rect[2]-1 + rect[1]*drwidth);
|
|
for (i = 0; i < rect[3]; i++)
|
|
{
|
|
GCFunc(gc->fgcolour, out[i*drwidth], gc->function, out[i*drwidth], 0xffffff);
|
|
}
|
|
}
|
|
}
|
|
|
|
rect+=4;
|
|
}
|
|
}
|
|
|
|
void XR_PolyPoint(xclient_t *cl, xReq *request)
|
|
{
|
|
xPolyPointReq *req = (xPolyPointReq *)request;
|
|
|
|
unsigned int *out;
|
|
xresource_t *drawable;
|
|
xgcontext_t *gc;
|
|
|
|
short *point;
|
|
int pointnum;
|
|
|
|
int drwidth;
|
|
int drheight;
|
|
unsigned char *drbuffer;
|
|
|
|
short lastpoint[2];
|
|
|
|
if (XS_GetResource(req->drawable, (void**)&drawable) == x_none)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PolyPoint, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->gc, (void**)&gc) != x_gcontext)
|
|
{
|
|
X_SendError(cl, BadGC, req->gc, X_PolyPoint, 0);
|
|
return;
|
|
}
|
|
|
|
if (drawable->restype == x_window)
|
|
{
|
|
xwindow_t *wnd;
|
|
wnd = (xwindow_t *)drawable;
|
|
if (!wnd->buffer)
|
|
{
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
drwidth = wnd->width;
|
|
drheight = wnd->height;
|
|
drbuffer = wnd->buffer;
|
|
}
|
|
else if (drawable->restype == x_pixmap)
|
|
{
|
|
xpixmap_t *pm;
|
|
pm = (xpixmap_t *)drawable;
|
|
if (!pm->data)
|
|
{
|
|
pm->data = malloc(pm->width*pm->height*4);
|
|
memset(pm->data, rand(), pm->width*pm->height*4);
|
|
}
|
|
|
|
drwidth = pm->width;
|
|
drheight = pm->height;
|
|
drbuffer = pm->data;
|
|
}
|
|
else
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, X_PolyPoint, 0);
|
|
return;
|
|
}
|
|
|
|
point = (short*)(req+1);
|
|
|
|
if (req->coordMode) //relative
|
|
{
|
|
lastpoint[0] = 0; //do the absolute stuff
|
|
lastpoint[1] = 0;
|
|
for (pointnum = 1; pointnum>0; pointnum--)
|
|
{
|
|
lastpoint[0] += point[0]; //do the absolute stuff
|
|
lastpoint[1] += point[1];
|
|
|
|
out = (unsigned int *)drbuffer + lastpoint[0] + lastpoint[1]*drwidth;
|
|
GCFunc(gc->fgcolour, *out, gc->function, *out, 0xffffff);
|
|
point+=2;
|
|
}
|
|
|
|
}
|
|
else //absolute
|
|
{
|
|
for (pointnum = req->length-1; pointnum>0; pointnum--)
|
|
{
|
|
if (!(point[0] < 0 || point[1] < 0 || point[0] >= drwidth || point[1] >= drheight))
|
|
{
|
|
out = (unsigned int *)drbuffer + point[0] + point[1]*drwidth;
|
|
GCFunc(gc->fgcolour, *out, gc->function, *out, 0xffffff);
|
|
}
|
|
|
|
point+=2;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Draw_CharToDrawable (int num, unsigned int *drawable, int x, int y, int width, int height, xgcontext_t *gc)
|
|
{
|
|
int row, col;
|
|
qbyte *source;
|
|
int drawline;
|
|
int i;
|
|
|
|
int s, e;
|
|
|
|
s = 0;
|
|
e = 8;
|
|
if (x<0)
|
|
s = s - x;
|
|
|
|
if (x > width - e)
|
|
e = width - x;
|
|
|
|
if (s > e)
|
|
return;
|
|
if (y >= height)
|
|
return;
|
|
if (y < -8)
|
|
return;
|
|
if (!draw_chars)
|
|
return;
|
|
|
|
if (y <= 0)
|
|
drawable += x;
|
|
else
|
|
drawable += (width*y) + x;
|
|
|
|
|
|
row = num>>4;
|
|
col = num&15;
|
|
source = draw_chars + (row<<10) + (col<<3);
|
|
if (y < 0)
|
|
source -= 128*y;
|
|
|
|
drawline = height-y;
|
|
if (drawline > 8)
|
|
drawline = 8;
|
|
|
|
if (y < 0)
|
|
drawline += y;
|
|
|
|
while (drawline--)
|
|
{
|
|
for (i=s ; i<e ; i++)
|
|
if (source[i] != 255 && source[i])
|
|
// GCFunc(gc->fgcolour, drawable[i], gc->function, drawable[i], d_8to24rgbtable[source[i]]);
|
|
drawable[i] = gc->fgcolour;//d_8to24rgbtable[source[i]];
|
|
source += 128;
|
|
drawable += width;
|
|
}
|
|
|
|
}
|
|
|
|
void XR_PolyText(xclient_t *cl, xReq *request)
|
|
{
|
|
unsigned char *str;
|
|
|
|
xPolyTextReq *req = (xPolyTextReq*)request;
|
|
|
|
xresource_t *drawable;
|
|
xgcontext_t *gc;
|
|
|
|
|
|
int drwidth;
|
|
int drheight;
|
|
unsigned char *drbuffer;
|
|
|
|
short charnum;
|
|
short numchars;
|
|
|
|
int xpos, ypos;
|
|
|
|
if (XS_GetResource(req->drawable, (void**)&drawable) == x_none)
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, req->reqType, 0);
|
|
return;
|
|
}
|
|
|
|
if (XS_GetResource(req->gc, (void**)&gc) != x_gcontext)
|
|
{
|
|
X_SendError(cl, BadGC, req->gc, req->reqType, 0);
|
|
return;
|
|
}
|
|
|
|
if (drawable->restype == x_window)
|
|
{
|
|
xwindow_t *wnd;
|
|
wnd = (xwindow_t *)drawable;
|
|
if (!wnd->buffer)
|
|
{
|
|
wnd->buffer = malloc(wnd->width*wnd->height*4);
|
|
XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height);
|
|
}
|
|
|
|
drwidth = wnd->width;
|
|
drheight = wnd->height;
|
|
drbuffer = wnd->buffer;
|
|
}
|
|
else if (drawable->restype == x_pixmap)
|
|
{
|
|
xpixmap_t *pm;
|
|
pm = (xpixmap_t *)drawable;
|
|
if (!pm->data)
|
|
{
|
|
pm->data = malloc(pm->width*pm->height*4);
|
|
memset(pm->data, rand(), pm->width*pm->height*4);
|
|
}
|
|
|
|
drwidth = pm->width;
|
|
drheight = pm->height;
|
|
drbuffer = pm->data;
|
|
}
|
|
else
|
|
{
|
|
X_SendError(cl, BadDrawable, req->drawable, req->reqType, 0);
|
|
return;
|
|
}
|
|
|
|
xrefreshed = true;
|
|
|
|
xpos = req->x;
|
|
ypos = req->y-4;
|
|
|
|
str = (char*)(req+1);
|
|
|
|
if (req->reqType == X_ImageText16 || req->reqType == X_ImageText8)
|
|
{
|
|
while(1)
|
|
{
|
|
charnum = 0;
|
|
if (req->reqType == X_ImageText16)
|
|
charnum |= (*str++)<<8;
|
|
charnum |= *str++;
|
|
if (!charnum)
|
|
return;
|
|
|
|
Draw_CharToDrawable(charnum, (unsigned int *)drbuffer, xpos, ypos, drwidth, drheight, gc);
|
|
|
|
xpos += 8;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
numchars = *(short*) str;
|
|
str+=2;
|
|
while(1)
|
|
{
|
|
charnum = 0;
|
|
if (req->reqType == X_PolyText16)
|
|
charnum |= (*str++)<<8;
|
|
charnum |= *str++;
|
|
if (!numchars--)
|
|
return;
|
|
|
|
Draw_CharToDrawable(charnum, (unsigned int *)drbuffer, xpos, ypos, drwidth, drheight, gc);
|
|
|
|
xpos += 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
void XR_OpenFont(xclient_t *cl, xReq *request) //basically ignored. We only support one font...
|
|
{
|
|
xOpenFontReq *req = (xOpenFontReq *)request;
|
|
char *name;
|
|
|
|
name = (char *)(req+1);
|
|
|
|
}
|
|
|
|
void XR_ListFonts(xclient_t *cl, xReq *request) //basically ignored. We only support one font...
|
|
{
|
|
// xListFontsReq *req = (xListFontsReq *)request;
|
|
int buffer[256];
|
|
xListFontsReply *reply = (xListFontsReply *)buffer;
|
|
|
|
reply->type = X_Reply;
|
|
reply->sequenceNumber = cl->requestnum;
|
|
reply->length = 0;
|
|
reply->nFonts = 0;
|
|
|
|
X_SendData(cl, reply, sizeof(xGenericReply)+reply->length*4);
|
|
}
|
|
|
|
void XR_QueryFont(xclient_t *cl, xReq *request) //basically ignored. We only support one font...
|
|
{
|
|
// xResourceReq *req = (xResourceReq *)request;
|
|
char buffer[8192];
|
|
xQueryFontReply *rep = (xQueryFontReply *)buffer;
|
|
|
|
rep->type = X_Reply;
|
|
rep->pad1 = 0;
|
|
rep->sequenceNumber = cl->requestnum;
|
|
rep->length = 0; /* definitely > 0, even if "nCharInfos" is 0 */
|
|
|
|
rep->minBounds.leftSideBearing = 0;
|
|
rep->minBounds.rightSideBearing = 0;
|
|
rep->minBounds.characterWidth = 8;
|
|
rep->minBounds.ascent = 4;
|
|
rep->minBounds.descent = 4;
|
|
rep->minBounds.attributes = 0;
|
|
|
|
#ifndef WORD64
|
|
rep->walign1 = 0;
|
|
#endif
|
|
rep->maxBounds.leftSideBearing = 0;
|
|
rep->maxBounds.rightSideBearing = 0;
|
|
rep->maxBounds.characterWidth = 8;
|
|
rep->maxBounds.ascent = 4;
|
|
rep->maxBounds.descent = 4;
|
|
rep->maxBounds.attributes = 0;
|
|
#ifndef WORD64
|
|
rep->walign2 = 0;
|
|
#endif
|
|
rep->minCharOrByte2 = 0;
|
|
rep->maxCharOrByte2 = 0;
|
|
rep->defaultChar = 0;
|
|
rep->nFontProps = 0; /* followed by this many xFontProp structures */
|
|
rep->drawDirection = 0;
|
|
rep->minByte1 = 0;
|
|
rep->maxByte1 = 0;
|
|
rep->allCharsExist = 1;
|
|
rep->fontAscent = 4;
|
|
rep->fontDescent = 4;
|
|
rep->nCharInfos = 0; /* followed by this many xCharInfo structures */
|
|
|
|
rep->length = ((sizeof(xQueryFontReply) - sizeof(xGenericReply)) + rep->nFontProps*sizeof(xFontProp) + rep->nCharInfos*sizeof(xCharInfo))/4;
|
|
|
|
X_SendData(cl, rep, sizeof(xGenericReply)+rep->length*4);
|
|
}
|
|
|
|
//esentually just throw it back at them.
|
|
void XR_AllocColor(xclient_t *cl, xReq *request)
|
|
{
|
|
xAllocColorReq *req = (xAllocColorReq *)request;
|
|
xAllocColorReply rep;
|
|
|
|
rep.type = X_Reply;
|
|
rep.pad1 = 0;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.red = req->red;
|
|
rep.green = req->green;
|
|
rep.blue = req->blue;
|
|
rep.pad2 = 0;
|
|
rep.pixel = ((req->blue>>8)<<16) | ((req->green>>8)<<8) | (req->red>>8);
|
|
rep.pad3 = 0;
|
|
rep.pad4 = 0;
|
|
rep.pad5 = 0;
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
void XR_LookupColor(xclient_t *cl, xReq *request)
|
|
{
|
|
typedef struct {
|
|
char *name;
|
|
float r, g, b;
|
|
} colour_t;
|
|
char colourname[256];
|
|
colour_t *c, colour[] = {
|
|
{"black", 0,0,0},
|
|
{"grey", 0.5,0.5,0.5},
|
|
{"gray", 0.5,0.5,0.5}, //wmaker uses this one. humour it.
|
|
{"gray90", 0.9,0.9,0.9},
|
|
{"gray80", 0.8,0.8,0.8},
|
|
{"gray70", 0.7,0.7,0.7},
|
|
{"gray60", 0.6,0.6,0.6},
|
|
{"gray50", 0.5,0.5,0.5},
|
|
{"gray40", 0.4,0.4,0.4},
|
|
{"gray30", 0.3,0.3,0.3},
|
|
{"gray20", 0.2,0.2,0.2},
|
|
{"gray10", 0.1,0.1,0.1},
|
|
{"grey10", 0.1,0.1,0.1},
|
|
{"white", 1,1,1},
|
|
{"red", 1,0,0},
|
|
{"green", 0,1,0},
|
|
{"blue", 0,0,1},
|
|
{"blue4", 0,0,0.4},
|
|
{NULL}
|
|
};
|
|
|
|
xLookupColorReq *req = (xLookupColorReq *)request;
|
|
xLookupColorReply rep;
|
|
|
|
strncpy(colourname, (char *)(req+1), req->nbytes);
|
|
colourname[req->nbytes] = '\0';
|
|
|
|
for (c = colour; c->name; c++)
|
|
{
|
|
if (!stricmp(c->name, colourname))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!c->name)
|
|
{
|
|
X_SendError(cl, BadName, 0, X_LookupColor, 0);
|
|
return;
|
|
}
|
|
|
|
|
|
rep.type = X_Reply;
|
|
rep.pad1 = 0;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.exactRed = c->r*0xffff;
|
|
rep.exactGreen = c->g*0xffff;
|
|
rep.exactBlue = c->b*0xffff;
|
|
rep.screenRed = rep.exactRed;
|
|
rep.screenGreen = rep.exactGreen;
|
|
rep.screenBlue = rep.exactBlue;
|
|
rep.pad3 = 0;
|
|
rep.pad4 = 0;
|
|
rep.pad5 = 0;
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
//get's keyboard status stuff.
|
|
void XR_GetKeyboardControl(xclient_t *cl, xReq *request)
|
|
{
|
|
xGetKeyboardControlReply rep;
|
|
|
|
rep.type = X_Reply;
|
|
rep.globalAutoRepeat = false;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 5;
|
|
rep.ledMask = 0;
|
|
rep.keyClickPercent = 0;
|
|
rep.bellPercent = 0;
|
|
rep.bellPitch = 0;
|
|
rep.bellDuration = 0;
|
|
rep.pad = 0;
|
|
memset(rep.map, 0, sizeof(rep.map)); //per key map
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
|
|
void XR_WarpPointer(xclient_t *cl, xReq *request)
|
|
{
|
|
// xWarpPointerReq *req = (xWarpPointerReq *)request;
|
|
// req->m
|
|
}
|
|
|
|
#ifdef XBigReqExtensionName
|
|
void XR_BigReq(xclient_t *cl, xReq *request)
|
|
{
|
|
xBigReqEnableReply rep;
|
|
|
|
rep.type = X_Reply;
|
|
rep.pad0 = 0;
|
|
rep.sequenceNumber = cl->requestnum;
|
|
rep.length = 0;
|
|
rep.max_request_size = 65535*1000;
|
|
rep.pad1 = 0;
|
|
rep.pad2 = 0;
|
|
rep.pad3 = 0;
|
|
rep.pad4 = 0;
|
|
rep.pad5 = 0;
|
|
|
|
X_SendData(cl, &rep, sizeof(rep));
|
|
}
|
|
#endif
|
|
|
|
#define MAXREQUESTSIZE 65535
|
|
|
|
//cl -> cl protocol
|
|
void XR_SendEvent (xclient_t *cl, xReq *request)
|
|
{
|
|
int count;
|
|
xSendEventReq *req = (xSendEventReq *)request;
|
|
xwindow_t *wnd;
|
|
|
|
if (XS_GetResource(req->destination, (void**)&wnd) != x_window)
|
|
{
|
|
X_SendError(cl, BadWindow, req->destination, X_SendEvent, 0);
|
|
return;
|
|
}
|
|
|
|
if (!req->eventMask) //goes to owner.
|
|
{
|
|
req->event.u.u.sequenceNumber = cl->requestnum;
|
|
X_SendData(wnd->res.owner, &req->event, sizeof(req->event));
|
|
}
|
|
else
|
|
{
|
|
xnotificationmask_t *nm;
|
|
count = 0;
|
|
while(!count)
|
|
{
|
|
for (nm = wnd->notificationmask; nm; nm = nm->next)
|
|
{
|
|
if (!(nm->mask & req->eventMask))
|
|
continue;
|
|
cl = nm->client;
|
|
|
|
if (cl->stillinitialising)
|
|
continue;
|
|
|
|
count++;
|
|
|
|
if (cl->tobedropped)
|
|
continue;
|
|
if (cl->outbufferlen > MAXREQUESTSIZE*4)
|
|
{
|
|
cl->tobedropped = true;
|
|
continue;
|
|
}
|
|
|
|
req->event.u.u.sequenceNumber = cl->requestnum;
|
|
X_SendData(cl, &req->event, sizeof(xEvent));
|
|
}
|
|
if (req->propagate)
|
|
wnd = wnd->parent;
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void XR_GrabServer (xclient_t *cl, xReq *request)
|
|
{
|
|
xgrabbedclient = cl;
|
|
}
|
|
void XR_UngrabServer (xclient_t *cl, xReq *request)
|
|
{
|
|
xgrabbedclient = NULL;
|
|
}
|
|
|
|
xclient_t *xpointergrabclient;
|
|
xwindow_t *xpgrabbedwindow;
|
|
xwindow_t *xpconfinewindow;
|
|
void XR_GrabPointer (xclient_t *cl, xReq *request)
|
|
{
|
|
xGrabPointerReq *req = (xGrabPointerReq *)request;
|
|
xGrabPointerReply reply;
|
|
|
|
reply.type = X_Reply;
|
|
reply.status = 0;
|
|
reply.sequenceNumber = cl->requestnum;
|
|
reply.length = 0;
|
|
reply.pad1 = 0;
|
|
reply.pad2 = 0;
|
|
reply.pad3 = 0;
|
|
reply.pad4 = 0;
|
|
reply.pad5 = 0;
|
|
reply.pad6 = 0;
|
|
|
|
if (xpointergrabclient && xpointergrabclient != cl)
|
|
{ //you can't have it.
|
|
// if (pointerstatus == Frozen)
|
|
// reply.status = GrabFrozen;
|
|
// else
|
|
reply.status = AlreadyGrabbed;
|
|
X_SendData(cl, &reply, sizeof(reply));
|
|
return;
|
|
}
|
|
|
|
xpointergrabclient = cl;
|
|
XS_GetResource(req->grabWindow, (void**)&xpgrabbedwindow);
|
|
XS_GetResource(req->confineTo, (void**)&xpconfinewindow);
|
|
|
|
X_EvalutateCursorOwner(NotifyGrab);
|
|
|
|
|
|
reply.status = GrabSuccess;
|
|
X_SendData(cl, &reply, sizeof(reply));
|
|
}
|
|
void XR_UngrabPointer (xclient_t *cl, xReq *request)
|
|
{
|
|
xpointergrabclient = NULL;
|
|
xpgrabbedwindow = NULL;
|
|
xpconfinewindow = NULL;
|
|
|
|
X_EvalutateCursorOwner(NotifyUngrab);
|
|
}
|
|
|
|
void XR_NoOperation (xclient_t *cl, xReq *request)
|
|
{
|
|
}
|
|
|
|
void X_InitRequests(void)
|
|
{
|
|
int ExtentionCode = X_NoOperation+1;
|
|
|
|
memset(XRequests, 0, sizeof(XRequests));
|
|
|
|
XRequests[X_QueryExtension] = XR_QueryExtension;
|
|
XRequests[X_ListExtensions] = XR_ListExtensions;
|
|
XRequests[X_GetProperty] = XR_GetProperty;
|
|
XRequests[X_ChangeProperty] = XR_ChangeProperty;
|
|
XRequests[X_DeleteProperty] = XR_DeleteProperty;
|
|
XRequests[X_ListProperties] = XR_ListProperties;
|
|
XRequests[X_SetInputFocus] = XR_SetInputFocus;
|
|
XRequests[X_GetInputFocus] = XR_GetInputFocus;
|
|
XRequests[X_QueryBestSize] = XR_QueryBestSize;
|
|
XRequests[X_CreateWindow] = XR_CreateWindow;
|
|
XRequests[X_DestroyWindow] = XR_DestroyWindow;
|
|
XRequests[X_QueryTree] = XR_QueryTree;
|
|
XRequests[X_ChangeWindowAttributes] = XR_ChangeWindowAttributes;
|
|
XRequests[X_GetWindowAttributes] = XR_GetWindowAttributes;
|
|
XRequests[X_CreateGC] = XR_CreateGC;
|
|
XRequests[X_ChangeGC] = XR_ChangeGC;
|
|
XRequests[X_FreeGC] = XR_FreeGC;
|
|
XRequests[X_CreatePixmap] = XR_CreatePixmap;
|
|
XRequests[X_FreePixmap] = XR_FreePixmap;
|
|
XRequests[X_MapWindow] = XR_MapWindow;
|
|
XRequests[X_MapSubwindows] = XR_MapSubwindows;
|
|
XRequests[X_UnmapWindow] = XR_UnmapWindow;
|
|
XRequests[X_ClearArea] = XR_ClearArea;
|
|
XRequests[X_CopyArea] = XR_CopyArea;
|
|
XRequests[X_InternAtom] = XR_InternAtom;
|
|
XRequests[X_GetAtomName] = XR_GetAtomName;
|
|
XRequests[X_PutImage] = XR_PutImage;
|
|
XRequests[X_GetImage] = XR_GetImage;
|
|
XRequests[X_PolyRectangle] = XR_PolyRectangle;
|
|
XRequests[X_PolyFillRectangle] = XR_PolyRectangle;
|
|
XRequests[X_PolyPoint] = XR_PolyPoint;
|
|
XRequests[X_PolyLine] = XR_PolyLine;
|
|
XRequests[X_PolySegment] = XR_PolyLine;
|
|
XRequests[X_QueryPointer] = XR_QueryPointer;
|
|
XRequests[X_GetKeyboardMapping] = XR_GetKeyboardMapping;
|
|
XRequests[X_GetKeyboardControl] = XR_GetKeyboardControl;
|
|
XRequests[X_AllocColor] = XR_AllocColor;
|
|
XRequests[X_LookupColor] = XR_LookupColor;
|
|
XRequests[X_GetGeometry] = XR_GetGeometry;
|
|
|
|
XRequests[X_WarpPointer] = XR_WarpPointer;
|
|
|
|
XRequests[X_ListFonts] = XR_ListFonts;
|
|
XRequests[X_OpenFont] = XR_OpenFont;
|
|
XRequests[X_QueryFont] = XR_QueryFont;
|
|
XRequests[X_PolyText8] = XR_PolyText;
|
|
XRequests[X_PolyText16] = XR_PolyText;
|
|
XRequests[X_ImageText8] = XR_PolyText;
|
|
XRequests[X_ImageText16] = XR_PolyText;
|
|
|
|
XRequests[X_ConfigureWindow] = XR_ConfigureWindow;
|
|
XRequests[X_ReparentWindow] = XR_ReparentWindow;
|
|
|
|
XRequests[X_GrabServer] = XR_GrabServer;
|
|
XRequests[X_UngrabServer] = XR_UngrabServer;
|
|
XRequests[X_GrabPointer] = XR_GrabPointer;
|
|
XRequests[X_UngrabPointer] = XR_UngrabPointer;
|
|
|
|
|
|
XRequests[X_SendEvent] = XR_SendEvent;
|
|
|
|
XRequests[X_GetSelectionOwner] = XR_GetSelectionOwner;
|
|
XRequests[X_SetSelectionOwner] = XR_SetSelectionOwner;
|
|
|
|
XRequests[X_GrabKey] = XR_NoOperation;
|
|
XRequests[X_AllowEvents] = XR_NoOperation;
|
|
XRequests[X_FillPoly] = XR_PolyLine;
|
|
XRequests[X_NoOperation] = XR_NoOperation;
|
|
|
|
#ifdef XBigReqExtensionName
|
|
X_BigReqCode=ExtentionCode++;
|
|
XRequests[X_BigReqCode] = XR_BigReq;
|
|
#endif
|
|
}
|
|
|
|
#endif
|