Small update for the X11 server/plugin, for the luls. This update moves the x11 server from a menu and into a media decoder, allowing it to be specified in shaders and played on walls etc (muh_bad or whatever).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4025 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-04-23 05:07:40 +00:00
parent 3da350a3ed
commit 8fa45f2c65
7 changed files with 836 additions and 359 deletions

View file

@ -44,6 +44,12 @@ BUILTINR(funcptr_t, Plug_GetEngineFunction, (char *funcname));
BUILTINR(int, Plug_ExportToEngine, (char *funcname, int expnum));
#undef ARGNAMES
#ifndef Q3_VM
#define ARGNAMES ,funcname,func
BUILTINR(qboolean, Plug_ExportNative, (char *funcname, void *func));
#undef ARGNAMES
#endif
#define ARGNAMES ,text
BUILTIN(void, Con_Print, (char *text)); //on to main console.
#undef ARGNAMES
@ -170,10 +176,6 @@ BUILTIN(void, Draw_Colour4f, (float r, float g, float b, float a));
BUILTIN(void, SCR_CenterPrint, (char *s));
#undef ARGNAMES
#define ARGNAMES ,src,srcwidth,srcheight,x,y,width,height
BUILTIN(void, Media_ShowFrameRGBA_32, (void *src, int srcwidth, int srcheight, int x, int y, int width, int height));
#undef ARGNAMES
#define ARGNAMES ,mnum
BUILTIN(void, Menu_Control, (int mnum));
#undef ARGNAMES
@ -286,6 +288,9 @@ void Plug_InitStandardBuiltins(void)
CHECKBUILTIN(Con_Print);
CHECKBUILTIN(Plug_ExportToEngine);
#ifndef Q3_VM
CHECKBUILTIN(Plug_ExportNative);
#endif
CHECKBUILTIN(Sys_Error);
CHECKBUILTIN(ReadInputBuffer);
@ -353,8 +358,6 @@ void Plug_InitStandardBuiltins(void)
CHECKBUILTIN(Draw_Colour4f);
CHECKBUILTIN(SCR_CenterPrint);
CHECKBUILTIN(Media_ShowFrameRGBA_32);
CHECKBUILTIN(GetPluginName);
//sub consoles (optional)

View file

@ -71,7 +71,7 @@ extern int (*plugin_syscall)( int arg, ... );
#ifdef _WIN32
void strlcpy(char *d, const char *s, int n);
int snprintf(char *buffer, int maxlen, char *format, ...);
int snprintf(char *buffer, size_t maxlen, const char *format, ...);
#endif
#endif
@ -103,6 +103,9 @@ typedef struct {
//Basic builtins:
EBUILTIN(funcptr_t, Plug_GetEngineFunction, (char *funcname)); //set up in vmMain, use this to get all other builtins
#ifndef Q3_VM
EBUILTIN(qboolean, Plug_ExportNative, (char *funcname, void *func)); //set up in vmMain, use this to get all other builtins
#endif
EBUILTIN(void, Con_Print, (char *text)); //on to main console.
EBUILTIN(void, Con_SubPrint, (char *subname, char *text)); //on to sub console.
@ -143,7 +146,6 @@ EBUILTIN(void, Menu_Control, (int mnum));
#define MENU_CLEAR 0
#define MENU_GRAB 1
EBUILTIN(int, Key_GetKeyCode, (char *keyname));
EBUILTIN(void, Media_ShowFrameRGBA_32, (void *src, int srcwidth, int srcheight, int x, int y, int width, int height));
EBUILTIN(qhandle_t, Draw_LoadImage, (char *name, qboolean iswadimage)); //wad image is ONLY for loading out of q1 gfx.wad
EBUILTIN(int, Draw_Image, (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t image));
@ -175,7 +177,7 @@ EBUILTIN(void, Net_Close, (qhandle_t socket));
#if defined(_WIN32) || defined(Q3_VM)
int vsnprintf(char *buffer, int maxlen, char *format, va_list vargs);
int vsnprintf(char *buffer, size_t maxlen, const char *format, va_list vargs);
#endif
#ifdef Q3_VM
@ -214,7 +216,7 @@ void Q_strncpyz(char *d, const char *s, int n);
//
// qvm_api.c
//
int vsnprintf(char *buffer, int maxlen, char *format, va_list vargs);
int vsnprintf(char *buffer, size_t maxlen, const char *format, va_list vargs);
typedef struct {
char *name;

View file

@ -10,7 +10,7 @@ this is a fairly basic implementation.
don't expect it to do much.
You can probably get a better version from somewhere.
*/
int vsnprintf(char *buffer, int maxlen, char *format, va_list vargs)
int vsnprintf(char *buffer, size_t maxlen, const char *format, va_list vargs)
{
int tokens=0;
char *string;
@ -316,7 +316,7 @@ Con_Printf("%i bytes left\n", maxlen);
{*buffer++='\0';return tokens;}
}
int snprintf(char *buffer, int maxlen, char *format, ...)
int snprintf(char *buffer, size_t maxlen, const char *format, ...)
{
int p;
va_list argptr;

View file

@ -1,19 +1,21 @@
//network interface
#include "../plugin.h"
#include "../engine.h"
#include "qux.h"
int mousecursor_x, mousecursor_y;
static xclient_t *xclients;
static int xlistensocket=-1;
static qhandle_t xlistensocket=NULL;
xwindow_t *xfocusedwindow;
qboolean xrefreshed;
xclient_t *xgrabbedclient; //clients can ask the server to ignore other clients
extern xwindow_t *xpgrabbedwindow;
#define MAXREQUESTSIZE 65535
@ -426,9 +428,9 @@ void X_SendIntialResponse(xclient_t *cl)
visualtype->class = TrueColor;
visualtype->bitsPerRGB = 24;
visualtype->colormapEntries = 256;
visualtype->redMask = 0x0000ff;
visualtype->redMask = 0xff0000;
visualtype->greenMask = 0x00ff00;
visualtype->blueMask = 0xff0000;
visualtype->blueMask = 0x0000ff;
visualtype->pad = 0;
visualtype++;
@ -470,12 +472,12 @@ qboolean XWindows_TendToClient(xclient_t *cl) //true says drop
cl->inbuffer = newbuffer;
}
len = cl->inbuffermaxlen - cl->inbufferlen;
Con_Printf("recving\n");
//Con_Printf("recving\n");
len = Net_Recv(cl->socket, cl->inbuffer + cl->inbufferlen, len);
Con_Printf("recved %i\n", len);
//Con_Printf("recved %i\n", len);
if (len == 0) //connection was closed. bummer.
{
Con_Printf("Closed\n");
//Con_Printf("Closed\n");
return true;
}
if (len > 0)
@ -551,7 +553,7 @@ nextmessage:
}
else if (inlen >= sizeof(xReq))
{
int rlen;
unsigned int rlen;
xReq *req;
req = (xReq *)input;
@ -754,16 +756,16 @@ void X_RunClient(void *parm)
void XWindows_TendToClients(void)
{
xclient_t *cl, *prev=NULL;
int newclient;
qhandle_t newclient;
#ifndef MULTITHREADWIN32
unsigned int _true = 1;
unsigned int _false = 0;
#endif
if (xlistensocket != -1)
if (xlistensocket != NULL)
{
newclient = Net_Accept(xlistensocket, NULL, 0);
if (newclient != -1)
if ((int)newclient != -1)
{
cl = malloc(sizeof(xclient_t));
memset(cl, 0, sizeof(xclient_t));
@ -830,11 +832,12 @@ void XWindows_Startup(void) //initialise the server socket and do any initial se
Cmd_Argv(1, buffer, sizeof(buffer));
port += atoi(buffer);
if (xlistensocket == -1)
if (xlistensocket == NULL)
{
xlistensocket = Net_TCPListen(NULL, port, 3);
if (xlistensocket < 0)
if ((int)xlistensocket < 0)
{
xlistensocket = NULL;
Con_Printf("Failed to create tcp listen socket\n");
return;
}
@ -889,7 +892,30 @@ void XWindows_RefreshWindow(xwindow_t *wnd)
{
if (wnd->buffer)// && x_windowwithfocus != wnd->res.id)
/*if (x_windowwithcursor == wnd->res.id)
{
for (; y < maxy; y++)
{
x = xpos + wnd->xpos;
maxx = x + wnd->width;
if (x < xpos+wnd->xpos)
{
x = xpos+wnd->xpos;
}
if (x < 0)
x = 0;
if (maxx > xscreenwidth)
maxx = xscreenwidth;
out = (unsigned int *)xscreen + (x+(y*xscreenwidth));
for (; x < maxx; x++)
{
*out++ = ((rand()&0xff)<<16)|((rand()&0xff)<<8)|(rand() & 0xff);
}
}
}
else */if (wnd->buffer)// && x_windowwithfocus != wnd->res.id)
{
for (; y < maxy; y++)
{
@ -933,7 +959,6 @@ void XWindows_RefreshWindow(xwindow_t *wnd)
maxx = xscreenwidth;
out = (unsigned int *)xscreen + (x+(y*xscreenwidth));
for (; x < maxx; x++)
{
*out++ = wnd->backpixel;
@ -1007,11 +1032,246 @@ void XWindows_Init(void)
int x_mousex;
int x_mousey;
int x_mousestate;
int x_windowwithcursor;
int x_windowwithfocus;
int mousestate;
void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
{
xEvent ev;
#define MAX_WINDOW_CHAIN 64
int od, nd;
int d, i;
xwindow_t *ow;
xwindow_t *nw = ew;
xwindow_t *oc[MAX_WINDOW_CHAIN];
xwindow_t *nc[MAX_WINDOW_CHAIN];
unsigned int curtime = Sys_Milliseconds();
if (!nw)
nw = rootwindow;
/*its already got it*/
if (nw->res.id == x_windowwithcursor)
return;
if (XS_GetResource(x_windowwithcursor, (void**)&ow) != x_window)
return;
//build the window chains into a simple list
od = 0;
while(ow && od < MAX_WINDOW_CHAIN)
{
oc[od++] = ow;
ow = ow->parent;
}
nd = 0;
while(nw && nd < MAX_WINDOW_CHAIN)
{
nc[nd++] = nw;
nw = nw->parent;
}
//both chains have the root at the end
//walk from the parent (last) window up to the top. if they diverge then we have the relevent common ancestor
for (d = 0; d < nd && d < od; )
{
d++;
if (nc[nd-d] != oc[od-d])
break;
}
nd -= d;
od -= d;
if (!nd)
{
/*moved to a parent*/
//LeaveNotify with detail Inferior is generated on A.
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyInferior;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = oc[0]->res.id;
ev.u.enterLeave.child = None;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - oc[0]->xpos;
ev.u.enterLeave.eventY = my - oc[0]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, oc[0], LeaveWindowMask);
//EnterNotify with detail Virtual is generated on each window between A and B exclusive (in that order).
for (i = od-1; i > 0; i--)
{
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyVirtual;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = oc[i]->res.id;
ev.u.enterLeave.child = oc[i-1]->res.id;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - oc[i]->xpos;
ev.u.enterLeave.eventY = my - oc[i]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, oc[i], EnterWindowMask);
}
//EnterNotify with detail Ancestor is generated on B.
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyInferior;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = nc[0]->res.id;
ev.u.enterLeave.child = None;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - nc[0]->xpos;
ev.u.enterLeave.eventY = my - nc[0]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, nc[0], EnterWindowMask);
}
else if (!od)
{
/*moved to a child*/
//LeaveNotify with detail Ancestor is generated on A.
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyAncestor;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = oc[0]->res.id;
ev.u.enterLeave.child = None;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - oc[0]->xpos;
ev.u.enterLeave.eventY = my - oc[0]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, oc[0], LeaveWindowMask);
//LeaveNotify with detail Virtual is generated on each window between A and B exclusive (in that order).
for (i = 1; i < nd; i++)
{
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyVirtual;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = nc[i]->res.id;
ev.u.enterLeave.child = nc[i-1]->res.id;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - nc[i]->xpos;
ev.u.enterLeave.eventY = my - nc[i]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, nc[i], LeaveWindowMask);
}
//EnterNotify with detail Inferior is generated on B.
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyInferior;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = nc[0]->res.id;
ev.u.enterLeave.child = None;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - nc[0]->xpos;
ev.u.enterLeave.eventY = my - nc[0]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, nc[0], EnterWindowMask);
}
else
{
/*moved up then down*/
//LeaveNotify with detail Nonlinear is generated on A.
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyNonlinear;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = oc[0]->res.id;
ev.u.enterLeave.child = None;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - oc[0]->xpos;
ev.u.enterLeave.eventY = my - oc[0]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, oc[0], LeaveWindowMask);
//LeaveNotify with detail NonlinearVirtual is generated on each window between A and C exclusive (in that order).
for (i = 1; i < nd; i++)
{
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyNonlinearVirtual;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = nc[i]->res.id;
ev.u.enterLeave.child = nc[i-1]->res.id;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - nc[i]->xpos;
ev.u.enterLeave.eventY = my - nc[i]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, nc[i], LeaveWindowMask);
}
//EnterNotify with detail NonlinearVirtual is generated on each window between C and B exclusive (in that order).
for (i = od-1; i > 0; i--)
{
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyNonlinearVirtual;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = oc[i]->res.id;
ev.u.enterLeave.child = oc[i-1]->res.id;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - oc[i]->xpos;
ev.u.enterLeave.eventY = my - oc[i]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, oc[i], EnterWindowMask);
}
//EnterNotify with detail Nonlinear is generated on B.
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyNonlinear;
ev.u.enterLeave.time = Sys_Milliseconds();
ev.u.enterLeave.root = rootwindow->res.id;
ev.u.enterLeave.event = nc[0]->res.id;
ev.u.enterLeave.child = None;
ev.u.enterLeave.rootX = mx;
ev.u.enterLeave.rootY = my;
ev.u.enterLeave.eventX = mx - nc[0]->xpos;
ev.u.enterLeave.eventY = my - nc[0]->ypos;
ev.u.enterLeave.state = mousestate;
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen;
X_SendInputNotification(&ev, nc[0], EnterWindowMask);
}
}
void X_EvalutateCursorOwner(int movemode)
{
xEvent ev;
@ -1024,8 +1284,8 @@ void X_EvalutateCursorOwner(int movemode)
{
extern int mousecursor_x, mousecursor_y;
mx = mousecursor_x * ((float)rootwindow->width/vid.width);
my = mousecursor_y * ((float)rootwindow->height/vid.height);
mx = mousecursor_x;
my = mousecursor_y;
}
if (mx >= xscreenwidth)
mx = xscreenwidth-1;
@ -1083,235 +1343,68 @@ void X_EvalutateCursorOwner(int movemode)
}
}
if (mx != x_mousex || my != x_mousey || x_windowwithcursor != cursorowner->res.id)
if (mx != x_mousex || my != x_mousey || x_mousestate != mousestate || x_windowwithcursor != cursorowner->res.id)
{
int mask = 0;
// extern qboolean keydown[256];
// Con_Printf("move %i %i\n", mx, my);
ev.u.u.detail = 0;
ev.u.u.sequenceNumber = 0;
ev.u.keyButtonPointer.time = Sys_Milliseconds();
ev.u.keyButtonPointer.root = rootwindow->res.id;
ev.u.keyButtonPointer.child = None;
ev.u.keyButtonPointer.rootX = mx;
ev.u.keyButtonPointer.rootY = my;
ev.u.keyButtonPointer.state = mousestate;
if (cursorowner->res.id != x_windowwithcursor) //changed window
X_MoveCursorWindow(cursorowner, mx, my, movemode);
x_windowwithcursor = cursorowner->res.id;
if (mx != x_mousex || my != x_mousey)
{
xwindow_t *a,*b;
int d1,d2;
if (XS_GetResource(x_windowwithcursor, (void**)&wnd) != x_window)
wnd = rootwindow;
x_windowwithcursor = cursorowner->res.id;
//count how deep the windows are
for (a = wnd,d1=0; a; a = a->parent)
d1++;
for (b = cursorowner,d2=0; b; b = b->parent)
d2++;
a = wnd;
b = cursorowner;
if (d1>d2)
{
while(d1>d2) //a is too deep
{
a = a->parent;
d1--;
}
}
if (mousestate)
mask |= ButtonMotionMask;
else
{
while(d2>d1)
{
b = b->parent;
d2--;
}
}
while(a != b) //find the common ancestor.
{
a = a->parent;
b = b->parent;
}
ev.u.enterLeave.mode = movemode;
ev.u.enterLeave.flags = ELFlagSameScreen; /* sameScreen and focus booleans, packed together */
//the cursor moved from a to b via:
// if (!a) //changed screen...
// {
// } else
if (a != wnd && b != cursorowner)
{ //changed via a common root, indirectly.
//o LeaveNotify with detail Nonlinear is generated on A.
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyNonlinear;
ev.u.keyButtonPointer.child = wnd->res.id;
X_SendInputNotification(&ev, wnd, LeaveWindowMask);
//o LeaveNotify with detail NonlinearVirtual is generated
// on each window between A and C exclusive (in that
// order).
for (a = wnd->parent; a != b; a = a->parent)
{
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyNonlinearVirtual;
ev.u.keyButtonPointer.child = a->res.id;
X_SendInputNotification(&ev, a, LeaveWindowMask);
}
//o EnterNotify with detail NonlinearVirtual is generated
// on each window between C and B exclusive (in that
// order).
for (; b != cursorowner; )
{
for (a = cursorowner; ; a = a->parent) //we need to go through the children.
{
if (a->parent == b)
{
b = a;
break;
}
}
if (b == cursorowner)
break;
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyNonlinearVirtual;
ev.u.keyButtonPointer.child = a->res.id;
X_SendInputNotification(&ev, a, EnterWindowMask);
}
//o EnterNotify with detail Nonlinear is generated on B.
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyNonlinear;
ev.u.keyButtonPointer.child = cursorowner->res.id;
X_SendInputNotification(&ev, cursorowner, EnterWindowMask);
}
else if (a == wnd)
{ //b is a child of a
//o LeaveNotify with detail Inferior is generated on A.
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyInferior;
ev.u.keyButtonPointer.child = wnd->res.id;
X_SendInputNotification(&ev, wnd, LeaveWindowMask);
//o EnterNotify with detail Virtual is generated on each
// window between A and B exclusive (in that order).
if (wnd != cursorowner)
for (b = wnd; ; )
{
for (a = cursorowner; ; a = a->parent) //we need to go through the children.
{
if (a->parent == b)
{
b = a;
break;
}
}
if (b == cursorowner)
break;
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyVirtual;
ev.u.keyButtonPointer.child = b->res.id;
X_SendInputNotification(&ev, b, EnterWindowMask);
}
//o EnterNotify with detail Ancestor is generated on B.
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyAncestor;
ev.u.keyButtonPointer.child = cursorowner->res.id;
X_SendInputNotification(&ev, cursorowner, EnterWindowMask);
}
else// if (b == cursorowner)
{ //a is a child of b
//o LeaveNotify with detail Ancestor is generated on A.
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyAncestor;
ev.u.keyButtonPointer.child = wnd->res.id;
X_SendInputNotification(&ev, wnd, LeaveWindowMask);
//o LeaveNotify with detail Virtual is generated on each
// window between A and B exclusive (in that order).
for (b = wnd; ; )
{
b = b->parent;
if (b == cursorowner)
break;
ev.u.u.type = LeaveNotify;
ev.u.u.detail = NotifyVirtual;
ev.u.keyButtonPointer.child = b->res.id;
X_SendInputNotification(&ev, b, LeaveWindowMask);
}
//o EnterNotify with detail Inferior is generated on B.
ev.u.u.type = EnterNotify;
ev.u.u.detail = NotifyInferior;
ev.u.keyButtonPointer.child = cursorowner->res.id;
X_SendInputNotification(&ev, cursorowner, EnterWindowMask);
}
{
char title[1024];
Atom type;
int extrabytes;
int format;
while(cursorowner)
{
title[XS_GetProperty(cursorowner, 39, &type, title, sizeof(title), 0, &extrabytes, &format)] = '\0';
if (*title)
break;
cursorowner = cursorowner->parent;
}
Con_Printf("Entered \"%s\"\n", title);
}
}
{ //same window
ev.u.keyButtonPointer.child = x_windowwithcursor;
if (XS_GetResource(x_windowwithcursor, (void**)&wnd) == x_window)
{ //cursor still in the same child.
int mask = PointerMotionMask;
if (mousestate)
mask |= ButtonMotionMask;
if (mousestate & Button1Mask)
mask |= Button1MotionMask;
if (mousestate & Button2Mask)
mask |= Button2MotionMask;
if (mousestate & Button3Mask)
mask |= Button3MotionMask;
if (mousestate & Button4Mask)
mask |= Button4MotionMask;
if (mousestate & Button5Mask)
mask |= Button5MotionMask;
ev.u.u.type = MotionNotify;
X_SendInputNotification(&ev, wnd, mask);
}
mask |= PointerMotionMask;
}
if ((mousestate^x_mousestate) & Button1Mask)
mask |= Button1MotionMask;
if ((mousestate^x_mousestate) & Button2Mask)
mask |= Button2MotionMask;
if ((mousestate^x_mousestate) & Button3Mask)
mask |= Button3MotionMask;
if ((mousestate^x_mousestate) & Button4Mask)
mask |= Button4MotionMask;
if ((mousestate^x_mousestate) & Button5Mask)
mask |= Button5MotionMask;
x_mousex = mx;
x_mousey = my;
x_mousestate = mousestate;
for (; cursorowner && mask; cursorowner = cursorowner->parent)
{ //same window
if (cursorowner->notificationmasks & mask)
{
ev.u.keyButtonPointer.child = x_windowwithcursor;
/* #define ButtonPress 4
#define ButtonRelease 5
#define MotionNotify 6
*/
ev.u.u.type = MotionNotify;
ev.u.u.detail = 0;
ev.u.u.sequenceNumber = 0;
ev.u.keyButtonPointer.time = Sys_Milliseconds();
ev.u.keyButtonPointer.root = rootwindow->res.id;
ev.u.keyButtonPointer.event = cursorowner->res.id;
ev.u.keyButtonPointer.child = (x_windowwithcursor == cursorowner->res.id)?None:x_windowwithcursor;
ev.u.keyButtonPointer.rootX = mx;
ev.u.keyButtonPointer.rootY = my;
ev.u.keyButtonPointer.eventX = mx - cursorowner->xpos;
ev.u.keyButtonPointer.eventY = my - cursorowner->ypos;
ev.u.keyButtonPointer.state = mousestate;
ev.u.keyButtonPointer.sameScreen= true;
X_SendNotificationMasked(&ev, cursorowner, cursorowner->notificationmasks&mask);
mask &= ~cursorowner->notificationmasks;
}
}
}
}
@ -1572,7 +1665,7 @@ void XWindows_Draw(void)
// XW_ExposeWindow(rootwindow, 0, 0, rootwindow->width, rootwindow->height);
// XWindows_DrawWindowTree(rootwindow, 0, 0);
if (xrefreshed)
// if (xrefreshed)
{
XWindows_RefreshWindow(rootwindow);
xrefreshed = false;
@ -1586,7 +1679,6 @@ void XWindows_Draw(void)
}
XWindows_TendToClients();
Media_ShowFrameRGBA_32 (xscreen, xscreenwidth, xscreenheight, 0, 0, vid.width, vid.height);
// Con_DrawNotify();
@ -1594,19 +1686,19 @@ void XWindows_Draw(void)
XS_CheckResourceSentinals();
}
void XWindows_Key(int key)
void XWindows_KeyDown(int key)
{
XS_CheckResourceSentinals();
if (!key) //hrm
return;
/*
if (key == 'q' || (key == K_BACKSPACE && ctrldown && altdown)) //kill off the server
{ //explicit kill
Menu_Control(MENU_CLEAR);
return;
}
*/
if (key == K_CTRL)
ctrldown = true;
if (key == K_ALT)
@ -1677,7 +1769,7 @@ void XWindows_Key(int key)
// Con_Printf("key %i, %i %i\n", key, x_mousex, x_mousey);
if (xpointergrabclient)
if (0)//xpointergrabclient)
{
ev.u.keyButtonPointer.event = ev.u.keyButtonPointer.child;
ev.u.keyButtonPointer.eventX = ev.u.keyButtonPointer.rootX;
@ -1811,14 +1903,12 @@ int Plug_MenuEvent(int *args)
XWindows_Draw();
break;
case 1: //keydown
XWindows_Key(args[1]);
XWindows_KeyDown(args[1]);
break;
case 2: //keyup
XWindows_Keyup(args[1]);
break;
case 3: //menu closed (this is called even if we change it).
Net_Close(xlistensocket);
xlistensocket = -1;
break;
}
@ -1837,15 +1927,110 @@ int Plug_ExecuteCommand(int *args)
return 0;
}
int Plug_Tick(int *args)
{
XWindows_TendToClients();
return 0;
}
static void *XWindows_Create(char *medianame) //initialise the server socket and do any initial setup as required.
{
if (!strcmp(medianame, "x11"))
{
XWindows_Startup();
return xscreen;
}
return NULL;
}
qbyte *XWindows_DisplayFrame(void *ctx, qboolean nosound, enum uploadfmt *fmt, int *width, int *height)
{
XWindows_Draw();
*fmt = TF_BGRX32;
*width = xscreenwidth;
*height = xscreenheight;
return xscreen;
}
static void XWindows_Shutdown(void *ctx)
{
Net_Close(xlistensocket);
xlistensocket = NULL;
}
static qboolean XWindows_SetSize (void *ctx, int width, int height)
{
qbyte *ns;
if (width < 64 || height < 64 || width > 2048 || height > 2048)
return false;
ns = realloc(xscreen, width*4*height);
if (ns)
{
xscreen = ns;
xscreenwidth = width;
xscreenheight = height;
//FIXME: resize root window + send notify
return true;
}
return false;
}
static void XWindows_GetSize (void *ctx, int *width, int *height) //retrieves the screen-space size
{
*width = xscreenwidth;
*height = xscreenheight;
}
static void XWindows_CursorMove (void *ctx, float posx, float posy)
{
mousecursor_x = (int)(posx * xscreenwidth);
mousecursor_y = (int)(posy * xscreenheight);
}
static void XWindows_Key (void *ctx, int code, int unicode, int isup)
{
if (isup)
XWindows_Keyup(code);
else
XWindows_KeyDown(code);
}
media_decoder_funcs_t decoderfuncs =
{
XWindows_Create,
XWindows_DisplayFrame,
NULL,//doneframe
XWindows_Shutdown,
NULL,//rewind
XWindows_CursorMove,
XWindows_Key,
XWindows_SetSize,
XWindows_GetSize,
NULL//changestream
};
int Plug_Init(int *args)
{
if (!Plug_Export("ExecuteCommand", Plug_ExecuteCommand) ||
!Plug_Export("MenuEvent", Plug_MenuEvent))
!Plug_Export("MenuEvent", Plug_MenuEvent) ||
!Plug_Export("Tick", Plug_Tick))
{
Con_Printf("XServer plugin failed\n");
return false;
}
if (!Plug_ExportNative("Media_VideoDecoder", &decoderfuncs))
{
Con_Printf("XServer plugin failed: Engine doesn't support media decoder plugins\n");
return false;
}
Con_Printf("XServer plugin started\n");
Cmd_AddCommand("startx");

View file

@ -26,7 +26,8 @@
#include "keysymdef.h"
typedef struct xclient_s {
int socket;
int closedownmode;
qhandle_t socket;
int inbufferlen;
int outbufferlen;
int inbuffermaxlen;
@ -84,9 +85,9 @@ typedef struct xpixmap_s {
} xpixmap_t;
typedef struct xatom_s {
xresource_t res;
char atomname[1];
int selectionownerwindowid;
xclient_t *selectionownerclient;
char atomname[1]; //must be last
} xatom_t;
typedef struct xwindow_s {
xresource_t res;
@ -117,6 +118,7 @@ typedef struct xwindow_s {
xproperty_t *properties;
xnotificationmask_t *notificationmask;
unsigned int notificationmasks;
} xwindow_t;
typedef struct xfont_s

View file

@ -91,9 +91,9 @@ void XR_QueryExtension (xclient_t *cl, xReq *request)
xQueryExtensionReply rep;
xQueryExtensionReq *req = (xQueryExtensionReq *)request;
if (req->nbytes > 250)
req->nbytes = 250;
strncpy(extname, (char *)(req+1), req->nbytes);
if (req->nbytes > sizeof(extname)-1)
req->nbytes = sizeof(extname)-1;
memcpy(extname, (char *)(req+1), req->nbytes);
extname[req->nbytes] = '\0';
#ifdef XBigReqExtensionName
@ -244,6 +244,23 @@ void XR_ListExtensions (xclient_t *cl, xReq *request)
X_SendData(cl, rep, sizeof(xListExtensionsReply) + rep->length*4);
}
void XR_SetCloseDownMode(xclient_t *cl, xReq *request)
{
xSetCloseDownModeReq *req = (xSetCloseDownModeReq*)request;
switch(req->mode)
{
case DestroyAll:
case RetainPermanent:
case RetainTemporary:
break;
default:
X_SendError(cl, BadValue, req->mode, X_SetCloseDownMode, 0);
return;
}
cl->closedownmode = req->mode;
}
void XR_GetAtomName (xclient_t *cl, xReq *request)
{
xResourceReq *req = (xResourceReq*)request;
@ -789,6 +806,10 @@ void XR_CreateWindow (xclient_t *cl, xReq *request)
nm->mask = *parameters;
wnd->notificationmask = nm;
parameters++;
wnd->notificationmasks = 0;
for (nm = wnd->notificationmask; nm; nm = nm->next)
wnd->notificationmasks |= nm->mask;
}
if (req->mask & CWDontPropagate)
wnd->donotpropagate = *parameters++;
@ -1007,6 +1028,10 @@ void XR_ChangeWindowAttributes (xclient_t *cl, xReq *request)
nm->client = cl;
}
nm->mask = *parameters;
wnd->notificationmasks = 0;
for (nm = wnd->notificationmask; nm; nm = nm->next)
wnd->notificationmasks |= nm->mask;
}
parameters++;
}
@ -1432,6 +1457,30 @@ void XR_QueryPointer (xclient_t *cl, xReq *request)
X_SendData(cl, &rep, sizeof(rep));
}
void XR_CreateCursor (xclient_t *cl, xReq *request)
{
xCreateCursorReq *req = (xCreateCursorReq *)request;
// X_SendError(cl, BadImplementation, 0, req->reqType, 0);
}
void XR_CreateGlyphCursor (xclient_t *cl, xReq *request)
{
xCreateGlyphCursorReq *req = (xCreateGlyphCursorReq *)request;
// char buffer[8192];
// xGetKeyboardMappingReply *rep = (xGetKeyboardMappingReply *)buffer;
// X_SendError(cl, BadImplementation, 0, req->reqType, 0);
// X_SendError(cl, BadAlloc, req->id, X_DestroyWindow, 0);
// X_SendError(cl, BadFont, req->id, X_DestroyWindow, 0);
// X_SendError(cl, BadValue, req->id, X_DestroyWindow, 0);
}
void XR_FreeCursor (xclient_t *cl, xReq *request)
{
// X_SendError(cl, BadImplementation, 0, req->reqType, 0);
// X_SendError(cl, BadValue, req->id, X_DestroyWindow, 0);
}
void XR_ChangeGCInternal(unsigned int mask, xgcontext_t *gc, CARD32 *param)
{
if (mask & GCFunction)
@ -1784,6 +1833,9 @@ void XR_ClearArea(xclient_t *cl, xReq *request)
XW_ClearArea(wnd, req->x, req->y, req->width, req->height);
if (req->exposures)
XW_ExposeWindowRegionInternal(wnd, req->x, req->y, req->width, req->height);
xrefreshed=true;
}
@ -1804,7 +1856,7 @@ void XR_CopyArea(xclient_t *cl, xReq *request) //from and to pixmap or drawable.
if (XS_GetResource(req->gc, (void**)&gc) == x_none)
{
X_SendError(cl, BadGC, req->gc, X_PutImage, 0);
X_SendError(cl, BadGC, req->gc, X_CopyArea, 0);
return;
}
@ -1812,7 +1864,7 @@ void XR_CopyArea(xclient_t *cl, xReq *request) //from and to pixmap or drawable.
switch (XS_GetResource(req->srcDrawable, (void**)&drawable))
{
default:
X_SendError(cl, BadDrawable, req->srcDrawable, X_PutImage, 0);
X_SendError(cl, BadDrawable, req->srcDrawable, X_CopyArea, 0);
return;
case x_window:
@ -1851,7 +1903,7 @@ void XR_CopyArea(xclient_t *cl, xReq *request) //from and to pixmap or drawable.
switch (XS_GetResource(req->dstDrawable, (void**)&drawable))
{
default:
X_SendError(cl, BadDrawable, req->dstDrawable, X_PutImage, 0);
X_SendError(cl, BadDrawable, req->dstDrawable, X_CopyArea, 0);
return;
case x_window:
@ -1903,8 +1955,8 @@ void XR_MapWindow(xclient_t *cl, xReq *request)
return;
}
if (wnd->mapped)
return;
// if (wnd->mapped)
// return;
if (!wnd->overrideredirect && X_NotifcationMaskPresent(wnd, SubstructureRedirectMask, cl))
{
@ -1913,8 +1965,8 @@ void XR_MapWindow(xclient_t *cl, xReq *request)
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;
ev.u.mapRequest.parent = wnd->parent->res.id;
ev.u.mapRequest.window = wnd->res.id;
X_SendNotificationMasked(&ev, wnd, SubstructureRedirectMask);
@ -1932,7 +1984,7 @@ void XR_MapWindow(xclient_t *cl, xReq *request)
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.event = wnd->res.id;
ev.u.mapNotify.window = wnd->res.id;
ev.u.mapNotify.override = wnd->overrideredirect;
ev.u.mapNotify.pad1 = 0;
@ -2056,19 +2108,32 @@ void XR_CreatePixmap(xclient_t *cl, xReq *request)
{
xCreatePixmapReq *req = (xCreatePixmapReq *)request;
xwindow_t *wnd;
if (XS_GetResource(req->drawable, (void**)&wnd) != x_window)
xresource_t *res;
xpixmap_t *newpix;
switch(XS_GetResource(req->drawable, (void**)&res))
{
case x_window:
case x_pixmap:
break;
default:
X_SendError(cl, BadDrawable, req->drawable, X_CreatePixmap, 0);
return;
}
if (XS_GetResource(req->pid, (void**)&wnd) != x_none)
//depth must be one of the depths supported by the drawable's root window
if (req->depth != 24 && req->depth != 32)
{
// X_SendError(cl, BadValue, req->depth, X_CreatePixmap, 0);
// return;
}
req->depth = 24;
if (XS_GetResource(req->pid, (void**)&newpix) != x_none)
{
X_SendError(cl, BadIDChoice, req->pid, X_CreatePixmap, 0);
}
XS_CreatePixmap(req->pid, cl, req->width, req->height, 24);
XS_CreatePixmap(req->pid, cl, req->width, req->height, req->depth);
}
void XR_FreePixmap(xclient_t *cl, xReq *request)
@ -2168,38 +2233,17 @@ void XR_PutImage(xclient_t *cl, xReq *request)
in = (qbyte *)(req+1);
if (req->format == ZPixmap && req->leftPad)
//my own bugs...
if (req->leftPad != 0)
{
X_SendError(cl, BadMatch, req->drawable, X_PutImage, 0);
X_SendError(cl, BadImplementation, req->drawable, X_PutImage, req->format);
return;
}
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
if (req->format == XYBitmap)
{ //bitmaps are just a 'mask' specifying which pixels get foreground and which get background.
int bnum;
unsigned int *o4;
bnum=0;
if (req->depth == 1)
{
@ -2208,21 +2252,13 @@ void XR_PutImage(xclient_t *cl, xReq *request)
bnum += req->leftPad;
out = drbuffer + (req->dstX + req->dstY*drwidth)*4;
o4 = (unsigned int*)out;
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;
}
o4[i] = gc->fgcolour;
else
{
out[i*4+0] = 0x00;
out[i*4+1] = 0x00;
out[i*4+2] = 0x00;
}
out[i*4+2] = rand();
o4[i] = gc->bgcolour;
bnum++;
}
bnum += req->width;
@ -2234,6 +2270,83 @@ void XR_PutImage(xclient_t *cl, xReq *request)
else
X_SendError(cl, BadMatch, req->drawable, X_PutImage, 0);
}
else if (req->depth != drdepth) /*depth must match*/
{
X_SendError(cl, BadMatch, req->drawable, X_PutImage, 0);
}
else if (req->format == ZPixmap) //32 bit network bandwidth (hideous)
{
if (req->leftPad != 0)
{
X_SendError(cl, BadMatch, req->drawable, X_PutImage, 0);
return;
}
if (req->depth == 1)
{
unsigned int *o4;
int bnum = 0;
while(req->height)
{
out = drbuffer + (req->dstX + req->dstY*drwidth)*4;
o4 = (unsigned int*)out;
for (i = 0; i < req->width; i++, bnum++)
{
if (in[bnum>>8]&(1<<(bnum&7)))
o4[i] = 0xffffff;
else
o4[i] = 0;
}
req->height--;
req->dstY++;
}
}
else
{
while(req->height)
{
unsigned int *i4, *o4;
out = drbuffer + (req->dstX + req->dstY*drwidth)*4;
i4 = (unsigned int*)in;
o4 = (unsigned int*)out;
for (i = 0; i < req->width; i++)
{
o4[i] = i4[i];
}
/* 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)
{
while(req->height)
{
unsigned int *o4;
out = drbuffer + (req->dstX + req->dstY*drwidth)*4;
o4 = (unsigned int*)out;
for (i = 0; i < req->width; i++)
{
if (in[i>>3] & (1u<<(i&7)))
o4[i] = rand();
else
o4[i] = rand();
}
in += (req->width+7)/8;
req->height--;
req->dstY++;
}
}
else
{
X_SendError(cl, BadImplementation, req->drawable, X_PutImage, req->format);
@ -2256,7 +2369,7 @@ void XR_GetImage(xclient_t *cl, xReq *request)
if (XS_GetResource(req->drawable, (void**)&drawable) == x_none)
{
X_SendError(cl, BadDrawable, req->drawable, X_PutImage, 0);
X_SendError(cl, BadDrawable, req->drawable, X_GetImage, 0);
return;
}
@ -2295,30 +2408,30 @@ void XR_GetImage(xclient_t *cl, xReq *request)
}
else
{
X_SendError(cl, BadDrawable, req->drawable, X_PutImage, 0);
X_SendError(cl, BadDrawable, req->drawable, X_GetImage, 0);
return;
}
if (req->x < 0)
{
X_SendError(cl, BadValue, req->drawable, X_PutImage, 0);
X_SendError(cl, BadValue, req->drawable, X_GetImage, 0);
return;
}
if (req->y < 0)
{
X_SendError(cl, BadValue, req->drawable, X_PutImage, 0);
X_SendError(cl, BadValue, req->drawable, X_GetImage, 0);
return;
}
if (req->width > drwidth - req->x)
{
X_SendError(cl, BadValue, req->drawable, X_PutImage, 0);
X_SendError(cl, BadValue, req->drawable, X_GetImage, 0);
return;
}
if (req->height > drheight - req->y)
{
X_SendError(cl, BadValue, req->drawable, X_PutImage, 0);
X_SendError(cl, BadValue, req->drawable, X_GetImage, 0);
return;
}
@ -2342,7 +2455,7 @@ void XR_GetImage(xclient_t *cl, xReq *request)
}
else
{
X_SendError(cl, BadImplementation, req->drawable, X_PutImage, req->format);
X_SendError(cl, BadImplementation, req->drawable, X_GetImage, req->format);
return;
}
@ -2387,7 +2500,7 @@ void XW_PolyLine(unsigned int *dbuffer, int dwidth, int dheight, int x1, int x2,
dx = (x2 - x1);
dy = (y2 - y1);
len = sqrt(dx*dx+dy*dy);
len = (int)sqrt(dx*dx+dy*dy);
if (!len)
return;
@ -2417,6 +2530,7 @@ void XR_PolyLine(xclient_t *cl, xReq *request)
int drwidth;
int drheight;
unsigned char *drbuffer;
INT16 start[2], end[2];
INT16 *points;
points = (INT16 *)(req+1);
@ -2481,21 +2595,121 @@ void XR_PolyLine(xclient_t *cl, xReq *request)
}
else
{
/*if (req->coordMode)
{
for(pointsleft = req->length-3; pointsleft>0; pointsleft--)
{
points[2] += points[0];
points[3] += points[1];
points+=2;
}
points = (INT16 *)(req+1);
}*/
end[0] = 0;
end[1] = 0;
for (pointsleft = req->length-3; pointsleft>0; pointsleft--)
for (pointsleft = req->length-3; pointsleft>0; pointsleft-=2)
{
XW_PolyLine((unsigned int *)drbuffer, drwidth, drheight, points[0], points[2], points[1], points[3], gc);
if (req->coordMode == 1/*Previous*/)
{
start[0] = end[0] + points[0];
start[1] = end[1] + points[1];
end[0] = start[0] + points[2];
end[1] = start[1] + points[3];
}
else
{
start[0] = points[0];
start[1] = points[1];
end[0] = points[2];
end[1] = points[3];
}
XW_PolyLine((unsigned int *)drbuffer, drwidth, drheight, start[0], end[0], start[1], end[1], gc);
points+=4;
}
}
}
void XR_FillPoly(xclient_t *cl, xReq *request)
{
xFillPolyReq *req = (xFillPolyReq *)request;
INT16 *points = (INT16*)(req+1);
int numpoints = req->length-4;
xresource_t *drawable;
xgcontext_t *gc;
int drwidth;
int drheight;
unsigned char *drbuffer;
INT16 start[2], end[2];
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;
{
start[0] = points[(numpoints*2)-2];
start[1] = points[(numpoints*2)-1];
while (numpoints-->0)
{
if (req->coordMode == 1/*Previous*/)
{
end[0] = start[0] + points[0];
end[1] = start[1] + points[1];
}
else
{
end[0] = points[0];
end[1] = points[1];
}
points+=2;
// XW_PolyLine((unsigned int *)drbuffer, drwidth, drheight, start[0], start[1], end[0], end[1], gc);
points++;
start[0] = end[0];
start[1] = end[1];
}
}
}
@ -3017,6 +3231,7 @@ void XR_AllocColor(xclient_t *cl, xReq *request)
{
xAllocColorReq *req = (xAllocColorReq *)request;
xAllocColorReply rep;
unsigned char rgb[3] = {req->red>>8, req->green>>8, req->blue>>8};
rep.type = X_Reply;
rep.pad1 = 0;
@ -3026,7 +3241,7 @@ void XR_AllocColor(xclient_t *cl, xReq *request)
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.pixel = (rgb[0]<<16) | (rgb[1]<<8) | (rgb[2]);
rep.pad3 = 0;
rep.pad4 = 0;
rep.pad5 = 0;
@ -3043,35 +3258,40 @@ void XR_LookupColor(xclient_t *cl, xReq *request)
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},
{"grey", 0.5f,0.5f,0.5f},
{"gray", 0.5f,0.5f,0.5f}, //wmaker uses this one. humour it.
{"gray90", 0.9f,0.9f,0.9f},
{"gray80", 0.8f,0.8f,0.8f},
{"gray70", 0.7f,0.7f,0.7f},
{"gray60", 0.6f,0.6f,0.6f},
{"gray50", 0.5f,0.5f,0.5f},
{"gray40", 0.4f,0.4f,0.4f},
{"gray30", 0.3f,0.3f,0.3f},
{"gray20", 0.2f,0.2f,0.2f},
{"gray10", 0.1f,0.1f,0.1f},
{"grey10", 0.1f,0.1f,0.1f},
{"white", 1,1,1},
{"red", 1,0,0},
{"green", 0,1,0},
{"blue", 0,0,1},
{"blue4", 0,0,0.4},
{"blue4", 0,0,0.4f},
{NULL}
};
xLookupColorReq *req = (xLookupColorReq *)request;
xLookupColorReply rep;
strncpy(colourname, (char *)(req+1), req->nbytes);
if (req->nbytes >= sizeof(colourname))
{
X_SendError(cl, BadName, 0, X_LookupColor, 0);
return;
}
memcpy(colourname, (char *)(req+1), req->nbytes);
colourname[req->nbytes] = '\0';
for (c = colour; c->name; c++)
{
if (!stricmp(c->name, colourname))
if (!strcasecmp(c->name, colourname))
{
break;
}
@ -3088,9 +3308,9 @@ void XR_LookupColor(xclient_t *cl, xReq *request)
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.exactRed = (unsigned short)(c->r*0xffffu);
rep.exactGreen = (unsigned short)(c->g*0xffffu);
rep.exactBlue = (unsigned short)(c->b*0xffffu);
rep.screenRed = rep.exactRed;
rep.screenGreen = rep.exactGreen;
rep.screenBlue = rep.exactBlue;
@ -3215,6 +3435,8 @@ void XR_UngrabServer (xclient_t *cl, xReq *request)
xclient_t *xpointergrabclient;
xwindow_t *xpgrabbedwindow;
xwindow_t *xpconfinewindow;
unsigned int xpointergrabmask;
CARD32 xpointergrabcursor;
void XR_GrabPointer (xclient_t *cl, xReq *request)
{
xGrabPointerReq *req = (xGrabPointerReq *)request;
@ -3244,6 +3466,9 @@ void XR_GrabPointer (xclient_t *cl, xReq *request)
xpointergrabclient = cl;
XS_GetResource(req->grabWindow, (void**)&xpgrabbedwindow);
XS_GetResource(req->confineTo, (void**)&xpconfinewindow);
xpointergrabmask = req->eventMask;
xpointergrabcursor = req->cursor;
// xpointergrabtime = req->time;
X_EvalutateCursorOwner(NotifyGrab);
@ -3251,6 +3476,19 @@ void XR_GrabPointer (xclient_t *cl, xReq *request)
reply.status = GrabSuccess;
X_SendData(cl, &reply, sizeof(reply));
}
void XR_ChangeActivePointerGrab (xclient_t *cl, xReq *request)
{
xChangeActivePointerGrabReq *req = (xChangeActivePointerGrabReq *)request;
if (xpointergrabclient != cl)
{ //its not yours to change
return;
}
xpointergrabmask = req->eventMask;
xpointergrabcursor = req->cursor;
// xpointergrabtime = req->time;
}
void XR_UngrabPointer (xclient_t *cl, xReq *request)
{
xpointergrabclient = NULL;
@ -3271,7 +3509,8 @@ void X_InitRequests(void)
memset(XRequests, 0, sizeof(XRequests));
XRequests[X_QueryExtension] = XR_QueryExtension;
XRequests[X_ListExtensions] = XR_ListExtensions;
XRequests[X_ListExtensions] = XR_ListExtensions;
XRequests[X_SetCloseDownMode] = XR_SetCloseDownMode;
XRequests[X_GetProperty] = XR_GetProperty;
XRequests[X_ChangeProperty] = XR_ChangeProperty;
XRequests[X_DeleteProperty] = XR_DeleteProperty;
@ -3310,6 +3549,9 @@ void X_InitRequests(void)
XRequests[X_AllocColor] = XR_AllocColor;
XRequests[X_LookupColor] = XR_LookupColor;
XRequests[X_GetGeometry] = XR_GetGeometry;
XRequests[X_CreateCursor] = XR_CreateCursor;
XRequests[X_CreateGlyphCursor] = XR_CreateGlyphCursor;
XRequests[X_FreeCursor] = XR_FreeCursor;
XRequests[X_WarpPointer] = XR_WarpPointer;
@ -3327,6 +3569,7 @@ void X_InitRequests(void)
XRequests[X_GrabServer] = XR_GrabServer;
XRequests[X_UngrabServer] = XR_UngrabServer;
XRequests[X_GrabPointer] = XR_GrabPointer;
XRequests[X_ChangeActivePointerGrab] = XR_ChangeActivePointerGrab;
XRequests[X_UngrabPointer] = XR_UngrabPointer;
@ -3337,7 +3580,7 @@ void X_InitRequests(void)
XRequests[X_GrabKey] = XR_NoOperation;
XRequests[X_AllowEvents] = XR_NoOperation;
XRequests[X_FillPoly] = XR_PolyLine;
XRequests[X_FillPoly] = XR_FillPoly;
XRequests[X_NoOperation] = XR_NoOperation;
#ifdef XBigReqExtensionName

View file

@ -207,11 +207,12 @@ void XS_LinkResource(xresource_t *res)
xatom_t *XS_CreateAtom(Atom atomid, char *name, xclient_t *owner)
{
xatom_t *at;
at = malloc(sizeof(xatom_t)+strlen(name));
int nlen = strlen(name);
at = malloc(sizeof(xatom_t)+nlen);
at->res.owner = owner;
at->res.restype = x_atom;
at->res.id = atomid;
strcpy(at->atomname, name);
memcpy(at->atomname, name, nlen+1);
XS_LinkResource(&at->res);
@ -344,8 +345,21 @@ void XS_SetParent(xwindow_t *wnd, xwindow_t *parent)
XS_ClearParent(wnd);
if (parent)
{
wnd->sibling = parent->child;
parent->child = wnd;
if (!parent->child)
parent->child = wnd;
else
{
xwindow_t *sib;
sib = parent->child;
while(sib->sibling)
{
sib = sib->sibling;
}
sib->sibling = wnd;
wnd->sibling = NULL;
}
// wnd->sibling = parent->child;
// parent->child = wnd;
}
wnd->parent = parent;
@ -398,8 +412,28 @@ xgcontext_t *XS_CreateGContext(int id, xclient_t *owner, xresource_t *drawable)
newgc->res.restype = x_gcontext;
newgc->function = GXcopy;
newgc->bgcolour = 0xffffff;
// newgc->planemask = ~0;
newgc->bgcolour = 1;
newgc->fgcolour = 0;
// newgc->line_width = 0;
// newgc->line_style = linesolid;
// newgc->cap_style = capbutt;
// newgc->join_style = joinmitter;
// newgc->fill_style = fillsolid;
// newgc->fill_rule = evenoddrule;
// newgc->arc_mode = arcpieslice;
// newgc->tile = somepixmap;
// newgc->stipple somepixmap;
// newgc->ts_x_origin = 0;
// newgc->ts_y_origin = 0;
// newgc->font = 0;
// newgc->subwindow_mode = clipbychildren;
// newgc->graphics_exposures = true;
// newgc->clip_x_origin = 0;
// newgc->clip_y_origin = 0;
// newgc->clip_mask = None;
// newgc->dash_offset = 0;
// newgc->dashes = 4;
XS_LinkResource(&newgc->res);
@ -409,9 +443,16 @@ xgcontext_t *XS_CreateGContext(int id, xclient_t *owner, xresource_t *drawable)
xpixmap_t *XS_CreatePixmap(int id, xclient_t *owner, int width, int height, int depth)
{
xpixmap_t *newpm;
int i;
unsigned char *c;
newpm = malloc(sizeof(xpixmap_t) + (width*height*4));
memset(newpm, 0, sizeof(xpixmap_t));
for(i = 0, c = (char*)(newpm+1); i < width*height*4; i++)
{
c[i] = rand();
}
newpm->res.id = id;
newpm->res.owner = owner;
newpm->res.restype = x_pixmap;
@ -531,6 +572,7 @@ void XS_CreateInitialResources(void)
resources = NULL;
/*these are the 'always created' atoms*/
XS_CreateAtom(baseres++, "PRIMARY", NULL);
XS_CreateAtom(baseres++, "SECONDARY", NULL);
XS_CreateAtom(baseres++, "ARC", NULL);