diff --git a/plugins/plugin.c b/plugins/plugin.c index 969c1bc6d..c81ee8837 100644 --- a/plugins/plugin.c +++ b/plugins/plugin.c @@ -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) diff --git a/plugins/plugin.h b/plugins/plugin.h index 41518fdef..4b6259040 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -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; diff --git a/plugins/qvm_api.c b/plugins/qvm_api.c index 62a3f8f86..66a0e25bb 100644 --- a/plugins/qvm_api.c +++ b/plugins/qvm_api.c @@ -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; diff --git a/plugins/xsv/m_x.c b/plugins/xsv/m_x.c index 2469e1fa5..8dd9c6efb 100644 --- a/plugins/xsv/m_x.c +++ b/plugins/xsv/m_x.c @@ -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"); diff --git a/plugins/xsv/qux.h b/plugins/xsv/qux.h index 1237b7207..560845693 100644 --- a/plugins/xsv/qux.h +++ b/plugins/xsv/qux.h @@ -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 diff --git a/plugins/xsv/x_reqs.c b/plugins/xsv/x_reqs.c index 0bf5a08e1..719a7c4f4 100644 --- a/plugins/xsv/x_reqs.c +++ b/plugins/xsv/x_reqs.c @@ -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 diff --git a/plugins/xsv/x_res.c b/plugins/xsv/x_res.c index 891dcdece..39c8d4bbd 100644 --- a/plugins/xsv/x_res.c +++ b/plugins/xsv/x_res.c @@ -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);