1
0
Fork 0
forked from fte/fteqw
fteqw/engine/qux/x_res.c
Spoike 9ae7e2621d SOFTWARE RENDERING IS BROKEN: DO NOT USE ASM VERSION.
Lots of changes.
CSQC should be functional, but is still tied to debug builds. It WILL have some bugs still, hopefully I'll be able to clean them up better if people test it a bit.
Precompiled headers are working properly now. Compile times are now much quicker in msvc. This takes most of the files this commit.
Restructured how client commands work. They're buffered outside the network message, some multithreaded code is in. It needs a bit of testing before it's active.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@885 fc73d0e0-1445-4013-8a0c-d673dee63da5
2005-02-28 07:16:19 +00:00

563 lines
12 KiB
C

#include "quakedef.h"
#ifndef NOMEDIA
#include "qux.h"
#include "hash.h"
void *Hash_AddKey2(hashtable_t *table, int key, void *data, bucket_t *buck); //fixme; move to hash.h
void Hash_RemoveKey(hashtable_t *table, int key);
#undef malloc
#undef free
#define free BZ_Free
#define malloc BZ_Malloc
hashtable_t restable;
bucket_t *resbuckets[1357]; //strange number to help the hashing.
xwindow_t *rootwindow;
xresource_t *resources;
qbyte *xscreen;
short xscreenwidth;
short xscreenheight;
int baseres;
void XS_ClearParent(xwindow_t *wnd);
int XS_GetResource(int id, void **data)
{
xresource_t *res;
if (id < 0)
return x_none;
res = Hash_GetKey(&restable, id);
if (res)
{
if (data)
*data = res;
return res->restype;
}
return x_none;
}
Atom XS_FindAtom(char *name)
{
xresource_t *res;
for (res = resources; res; res = res->next)
{
if (res->restype == x_atom)
{
if (!strcmp(((xatom_t*)res)->atomname, name))
return res->id;
}
}
return None;
}
void XS_CheckResourceSentinals(void)
{
/* xresource_t *res;
for (res = resources; res; res = res->next)
{
if (res->restype == x_window)
{
if (((xwindow_t*)res)->buffer)
BZ_CheckSentinals(((xwindow_t*)res)->buffer);
}
}
*/
}
void XS_DestroyResource(xresource_t *res)
{
qboolean nofree = false;
if (res->restype == x_pixmap)
{
xpixmap_t *pm = (xpixmap_t *)res;
if (pm->references)
nofree = true;
if (!pm->linked)
return;
pm->linked = false;
}
if (res->restype == x_window)
{
extern xwindow_t *xfocusedwindow, *xpgrabbedwindow;
xwindow_t *wnd = (xwindow_t *)res;
while(wnd->child)
XS_DestroyResource((xresource_t *)(wnd->child));
if (xfocusedwindow == wnd)
xfocusedwindow = wnd->parent;
if (xpgrabbedwindow == wnd)
xpgrabbedwindow = wnd->parent;
if (wnd->mapped)
{
XW_ExposeWindow(wnd, 0, 0, wnd->width, wnd->height);
}
{
xEvent ev;
xrefreshed = true;
ev.u.u.type = DestroyNotify;
ev.u.u.detail = 0;
ev.u.u.sequenceNumber = 0;
ev.u.destroyNotify.event = wnd->res.id; //should be the window that has the recieve attribute.
ev.u.destroyNotify.window = wnd->res.id;
X_SendNotificationMasked (&ev, wnd, StructureNotifyMask);
X_SendNotificationMasked (&ev, wnd, SubstructureNotifyMask);
}
XS_ClearParent(wnd);
}
if (!res->prev)
{
resources = res->next;
if (res->next)
res->next->prev = NULL;
}
else
{
res->prev->next = res->next;
res->next->prev = res->prev;
}
// XS_FindAtom("");
Hash_RemoveKey(&restable, res->id);
if (!nofree)
free(res);
// XS_FindAtom("");
}
void XS_DestroyResourcesOfClient(xclient_t *cl)
{
xresource_t *res;
xnotificationmask_t *nm, *nm2;
if (xgrabbedclient == cl)
xgrabbedclient = NULL;
if (xpointergrabclient == cl)
xpointergrabclient = NULL;
for (res = resources; res;)
{
if (res->restype == x_window)
{ //clear the event masks
nm = ((xwindow_t *)res)->notificationmask;
if (nm)
{
if (nm->client == cl)
{
((xwindow_t *)res)->notificationmask = nm->next;
free(nm);
}
else
{
for (; nm->next; nm = nm->next)
{
if (nm->next->client == cl || !cl)
{
nm2 = nm->next;
nm->next = nm->next->next;
free(nm2);
break;
}
}
}
}
}
if (res->owner == cl)
{
XS_DestroyResource(res);
res = resources; //evil!!!
continue;
}
res = res->next;
}
}
void XS_LinkResource(xresource_t *res)
{
res->next = resources;
resources = res;
res->prev = NULL;
if (res->next)
res->next->prev = res;
Hash_AddKey2(&restable, res->id, res, malloc(sizeof(bucket_t)));
}
xatom_t *XS_CreateAtom(Atom atomid, char *name, xclient_t *owner)
{
xatom_t *at;
at = malloc(sizeof(xatom_t)+strlen(name));
at->res.owner = owner;
at->res.restype = x_atom;
at->res.id = atomid;
strcpy(at->atomname, name);
XS_LinkResource(&at->res);
return at;
}
void XS_ClearParent(xwindow_t *wnd)
{
xwindow_t *sib;
xwindow_t *parent = wnd->parent;
if (!parent)
return;
wnd->parent = NULL;
if (parent->child == wnd)
{
parent->child = wnd->sibling;
return;
}
for (sib = parent->child; sib; sib = sib->sibling)
{
if (sib->sibling == wnd)
{
sib->sibling = wnd->sibling;
return;
}
}
}
int XS_GetProperty(xwindow_t *wnd, Atom atomid, Atom *atomtype, char *output, int maxlen, int offset, int *extrabytes, int *format)
{
xproperty_t *xp;
for (xp = wnd->properties; xp; xp = xp->next)
{
if (xp->atomid == atomid)
{
if (maxlen > xp->datalen - offset)
maxlen = xp->datalen - offset;
memcpy(output, xp->data + offset, maxlen);
if (maxlen < 0)
maxlen = 0;
*extrabytes = xp->datalen - maxlen - offset;
*format = xp->format;
*atomtype = xp->type;
if (*extrabytes < 0)
*extrabytes = 0;
return maxlen;
}
}
*format = 0;
*extrabytes = 0;
*atomtype = None;
return 0;
}
void XS_DeleteProperty(xwindow_t *wnd, Atom atomid)
{
xproperty_t *xp, *prev = NULL;
for (xp = wnd->properties; xp; xp = xp->next)
{
if (xp->atomid == atomid)
{
if (prev)
prev->next = xp->next;
else
wnd->properties = xp->next;
free(xp);
return;
}
prev = xp;
}
}
void XS_SetProperty(xwindow_t *wnd, Atom atomid, Atom atomtype, char *data, int datalen, int format)
{
xproperty_t *prop;
XS_DeleteProperty(wnd, atomid);
prop = malloc(sizeof(xproperty_t) + datalen);
prop->atomid = atomid;
prop->format = format;
prop->type = atomtype;
memcpy(prop->data, data, datalen);
prop->data[datalen] = '\0';
prop->datalen = datalen;
prop->next = wnd->properties;
wnd->properties = prop;
}
void XS_RaiseWindow(xwindow_t *wnd)
{
xwindow_t *bigger;
if (!wnd->parent)
return;
bigger = wnd->parent->child;
if (bigger == wnd)
{
wnd->parent->child = wnd->sibling;
bigger = wnd->sibling;
if (!bigger)
{
wnd->parent->child = wnd;
//ah well, it was worth a try
return;
}
}
else
{
while(bigger->sibling != wnd)
bigger = bigger->sibling;
bigger->sibling = wnd->sibling; //unlink
}
while(bigger->sibling)
bigger = bigger->sibling;
bigger->sibling = wnd;
wnd->sibling = NULL;
}
void XS_SetParent(xwindow_t *wnd, xwindow_t *parent)
{
XS_ClearParent(wnd);
if (parent)
{
wnd->sibling = parent->child;
parent->child = wnd;
}
wnd->parent = parent;
XS_RaiseWindow(wnd);
}
xwindow_t *XS_CreateWindow(int wid, xclient_t *owner, xwindow_t *parent, short x, short y, short width, short height)
{
xwindow_t *neww;
neww = malloc(sizeof(xwindow_t));
memset(neww, 0, sizeof(xwindow_t));
neww->res.id = wid;
neww->res.owner = owner;
neww->res.restype = x_window;
if (width < 0)
{
width*=-1;
x-=width;
}
if (height < 0)
{
height*=-1;
x-=height;
}
neww->xpos = (CARD16)x;
neww->ypos = (CARD16)y;
neww->width = width;
neww->height = height;
neww->buffer = NULL;
XS_SetParent(neww, parent);
XS_LinkResource(&neww->res);
XS_CheckResourceSentinals();
return neww;
}
xgcontext_t *XS_CreateGContext(int id, xclient_t *owner, xresource_t *drawable)
{
xgcontext_t *newgc;
newgc = malloc(sizeof(xgcontext_t));
memset(newgc, 0, sizeof(xgcontext_t));
newgc->res.id = id;
newgc->res.owner = owner;
newgc->res.restype = x_gcontext;
newgc->function = GXcopy;
newgc->bgcolour = 0xffffff;
newgc->fgcolour = 0;
XS_LinkResource(&newgc->res);
return newgc;
}
xpixmap_t *XS_CreatePixmap(int id, xclient_t *owner, int width, int height, int depth)
{
xpixmap_t *newpm;
newpm = malloc(sizeof(xpixmap_t) + (width*height*4));
memset(newpm, 0, sizeof(xpixmap_t));
newpm->res.id = id;
newpm->res.owner = owner;
newpm->res.restype = x_pixmap;
if (id>0)
{
newpm->linked=true; //destroyed when last reference AND this are cleared
XS_LinkResource(&newpm->res);
}
newpm->data = (qbyte*)(newpm+1);
newpm->width = width;
newpm->height = height;
newpm->depth = depth;
return newpm;
}
int XS_NewResource (void)
{
return baseres++;
}
void XS_CreateInitialResources(void)
{
static xpixmap_t pm;
static unsigned int rawpm[8*9] = {
0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
0x000000, 0x000000, 0xffffff, 0x000000, 0xffffff, 0x000000, 0x000000, 0x000000,
0x000000, 0xffffff, 0x000000, 0x000000, 0x000000, 0xffffff, 0x000000, 0x000000,
0xffffff, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xffffff, 0x000000,
0xffffff, 0x000000, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff, 0x000000,
0xffffff, 0x000000, 0x000000, 0xffffff, 0x000000, 0x000000, 0xffffff, 0x000000,
0x000000, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0x000000,
0x000000, 0x000000, 0x000000, 0xffffff, 0x000000, 0x000000, 0x000000, 0x000000,
0x000000, 0x000000, 0x000000, 0xffffff, 0x000000, 0x000000, 0x000000, 0x000000};
if (baseres)
return;
baseres=1;
xscreenwidth = 640;
xscreenheight = 480;
xscreen = realloc(xscreen, xscreenwidth*4 * xscreenheight);
XS_CheckResourceSentinals();
XS_DestroyResourcesOfClient(NULL);
memset(resbuckets, 0, sizeof(resbuckets));
Hash_InitTable(&restable, sizeof(resbuckets)/sizeof(resbuckets[0]), resbuckets);
resources = NULL;
XS_CreateAtom(baseres++, "PRIMARY", NULL);
XS_CreateAtom(baseres++, "SECONDARY", NULL);
XS_CreateAtom(baseres++, "ARC", NULL);
XS_CreateAtom(baseres++, "ATOM", NULL);
XS_CreateAtom(baseres++, "BITMAP", NULL);
XS_CreateAtom(baseres++, "CARDINAL", NULL);
XS_CreateAtom(baseres++, "COLORMAP", NULL);
XS_CreateAtom(baseres++, "CURSOR", NULL);
XS_CreateAtom(baseres++, "CUT_BUFFER0", NULL);
XS_CreateAtom(baseres++, "CUT_BUFFER1", NULL);
XS_CreateAtom(baseres++, "CUT_BUFFER2", NULL);
XS_CreateAtom(baseres++, "CUT_BUFFER3", NULL);
XS_CreateAtom(baseres++, "CUT_BUFFER4", NULL);
XS_CreateAtom(baseres++, "CUT_BUFFER5", NULL);
XS_CreateAtom(baseres++, "CUT_BUFFER6", NULL);
XS_CreateAtom(baseres++, "CUT_BUFFER7", NULL);
XS_CreateAtom(baseres++, "DRAWABLE", NULL);
XS_CreateAtom(baseres++, "FONT", NULL);
XS_CreateAtom(baseres++, "INTEGER", NULL);
XS_CreateAtom(baseres++, "PIXMAP", NULL);
XS_CreateAtom(baseres++, "POINT", NULL);
XS_CreateAtom(baseres++, "RECTANGLE", NULL);
XS_CreateAtom(baseres++, "RESOURCE_MANAGER", NULL);
XS_CreateAtom(baseres++, "RGB_COLOR_MAP", NULL);
XS_CreateAtom(baseres++, "RGB_BEST_MAP", NULL);
XS_CreateAtom(baseres++, "RGB_BLUE_MAP", NULL);
XS_CreateAtom(baseres++, "RGB_DEFAULT_MAP", NULL);
XS_CreateAtom(baseres++, "RGB_GRAY_MAP", NULL);
XS_CreateAtom(baseres++, "RGB_GREEN_MAP", NULL);
XS_CreateAtom(baseres++, "RGB_RED_MAP", NULL);
XS_CreateAtom(baseres++, "STRING", NULL);
XS_CreateAtom(baseres++, "VISUALID", NULL);
XS_CreateAtom(baseres++, "WINDOW", NULL);
XS_CreateAtom(baseres++, "WM_COMMAND", NULL);
XS_CreateAtom(baseres++, "WM_HINTS", NULL);
XS_CreateAtom(baseres++, "WM_CLIENT_MACHINE", NULL);
XS_CreateAtom(baseres++, "WM_ICON_NAME", NULL);
XS_CreateAtom(baseres++, "WM_ICON_SIZE", NULL);
XS_CreateAtom(baseres++, "WM_NAME", NULL);
XS_CreateAtom(baseres++, "WM_NORMAL_HINTS", NULL);
XS_CreateAtom(baseres++, "WM_SIZE_HINTS", NULL);
XS_CreateAtom(baseres++, "WM_ZOOM_HINTS", NULL);
XS_CreateAtom(baseres++, "MIN_SPACE", NULL);
XS_CreateAtom(baseres++, "NORM_SPACE", NULL);
XS_CreateAtom(baseres++, "MAX_SPACE", NULL);
XS_CreateAtom(baseres++, "END_SPACE", NULL);
XS_CreateAtom(baseres++, "SUPERSCRIPT_X", NULL);
XS_CreateAtom(baseres++, "SUPERSCRIPT_Y", NULL);
XS_CreateAtom(baseres++, "SUBSCRIPT_X", NULL);
XS_CreateAtom(baseres++, "SUBSCRIPT_Y", NULL);
XS_CreateAtom(baseres++, "UNDERLINE_POSITION", NULL);
XS_CreateAtom(baseres++, "UNDERLINE_THICKNESS", NULL);
XS_CreateAtom(baseres++, "STRIKEOUT_ASCENT", NULL);
XS_CreateAtom(baseres++, "STRIKEOUT_DESCENT", NULL);
XS_CreateAtom(baseres++, "ITALIC_ANGLE", NULL);
XS_CreateAtom(baseres++, "X_HEIGHT", NULL);
XS_CreateAtom(baseres++, "QUAD_WIDTH", NULL);
XS_CreateAtom(baseres++, "WEIGHT", NULL);
XS_CreateAtom(baseres++, "POINT_SIZE", NULL);
XS_CreateAtom(baseres++, "RESOLUTION", NULL);
XS_CreateAtom(baseres++, "COPYRIGHT", NULL);
XS_CreateAtom(baseres++, "NOTICE", NULL);
XS_CreateAtom(baseres++, "FONT_NAME", NULL);
XS_CreateAtom(baseres++, "FAMILY_NAME", NULL);
XS_CreateAtom(baseres++, "FULL_NAME", NULL);
XS_CreateAtom(baseres++, "CAP_HEIGHT", NULL);
XS_CreateAtom(baseres++, "WM_CLASS", NULL);
XS_CreateAtom(baseres++, "WM_TRANSIENT_FOR", NULL);
rootwindow = XS_CreateWindow(baseres++, NULL, NULL, 0, 0, xscreenwidth, xscreenheight);
rootwindow->mapped = true;
XS_CheckResourceSentinals();
memset(&pm, 0, sizeof(pm));
pm.linked = true;
pm.data = (qbyte *)rawpm;
pm.depth = 24;
pm.width = 8;
pm.height = 9;
pm.references = 2;
pm.res.restype = x_pixmap;
rootwindow->backpixmap = &pm;
XW_ClearArea(rootwindow, 0, 0, rootwindow->width, rootwindow->height);
XS_CheckResourceSentinals();
xrefreshed = true;
}
#endif