/***************************************************************************** xdwapi.c - implementation of the xdesktopwaves API Copyright (C) 2004 Oliver Hamann (olha@users.sourceforge.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *****************************************************************************/ #include #include #include #include #include #include #include #include "xdwapi.h" typedef struct { Display * display; Window root; Atom XDESKTOPWAVES_WINDOW_ID; Atom XDESKTOPWAVES_COMMAND_MESSAGE; Atom XDESKTOPWAVES_WINDOW_INTERACTION; } xdwApiContextImp; xdwApiContext xdwApiOpen(Display * display) { xdwApiContextImp * imp; imp=(xdwApiContextImp*)malloc(sizeof(xdwApiContextImp)); imp->display=display; imp->root=DefaultRootWindow(display); imp->XDESKTOPWAVES_WINDOW_ID=XInternAtom( display,"XDESKTOPWAVES_WINDOW_ID",False ); imp->XDESKTOPWAVES_COMMAND_MESSAGE=XInternAtom( display,"XDESKTOPWAVES_COMMAND_MESSAGE",False ); imp->XDESKTOPWAVES_WINDOW_INTERACTION=XInternAtom( display,"XDESKTOPWAVES_WINDOW_INTERACTION",False ); return (xdwApiContext)imp; } void xdwApiClose(xdwApiContext context) { free((xdwApiContextImp*)context); } volatile Bool xdwApiGotXError; static int xdwApiTmpXErrHandler(Display * display, XErrorEvent * errorEvent) { xdwApiGotXError=True; return 0; } static Bool xdwApiSendCommand(xdwApiContext context, int argCount, ...) { xdwApiContextImp * imp; int (*originalXErrorHandler)(Display *, XErrorEvent *); Atom type; Status st; Window win; XEvent event; va_list ap; unsigned char * data; char * name; unsigned long len, rem; int i, frmt, ret; /* Get window id of xdesktopwaves. */ imp=(xdwApiContextImp*)context; data=NULL; ret=XGetWindowProperty( imp->display,imp->root,imp->XDESKTOPWAVES_WINDOW_ID,0,1,False, XA_WINDOW,&type,&frmt,&len,&rem,&data ); if (ret!=Success || type!=XA_WINDOW || frmt!=32 || len!=1 || rem!=0) { if (data) XFree(data); return False; } win=*(Window*)data; if (data) XFree(data); if (win==None) return False; /* Prepare client message to be sent. */ memset(&event,0,sizeof(event)); event.xclient.type=ClientMessage; event.xclient.display=imp->display; event.xclient.window=win; event.xclient.message_type=imp->XDESKTOPWAVES_COMMAND_MESSAGE; event.xclient.format=16; va_start(ap,argCount); for (i=0; idisplay,False); xdwApiGotXError=False; originalXErrorHandler=XSetErrorHandler(xdwApiTmpXErrHandler); name=NULL; st=XFetchName(imp->display,win,&name); if (st && (!name || strcmp(name,"xdesktopwaves")!=0)) st=0; if (name) XFree(name); if (st) st=XSendEvent(imp->display,win,False,0,&event); XSync(imp->display,False); XSetErrorHandler(originalXErrorHandler); if (xdwApiGotXError) st=0; return st ? True : False; } Bool xdwApiPing(xdwApiContext context) { return xdwApiSendCommand(context,1,0); } Bool xdwApiClear(xdwApiContext context) { return xdwApiSendCommand(context,1,1); } Bool xdwApiSetRain(xdwApiContext context, int intensity) { return xdwApiSendCommand(context,2,2,intensity); } Bool xdwApiSetStorm(xdwApiContext context, int intensity) { return xdwApiSendCommand(context,2,3,intensity); } Bool xdwApiPutRaindrop(xdwApiContext context, int x, int y, int volume) { return xdwApiSendCommand(context,4,4,x,y,volume); } static int xdwApiGenGhostId() { static int seed=0; int id; seed=seed*1375117+3370481; id=(getpid()*2873451)^(time(NULL)*11876973)^seed; if (!id) id=1; return id; } int xdwApiPutGhostRect(xdwApiContext context, int milliSecs, int removeId, int x, int y, int width, int height) { int ghostId; Bool success; ghostId=xdwApiGenGhostId(); success=xdwApiSendCommand( context, 10, 5, ghostId>>16, ghostId&0xffff, removeId>>16, removeId&0xffff, milliSecs, x, y, width, height ); return success ? ghostId : 0; } int xdwApiPutGhostCircle(xdwApiContext context, int milliSecs, int removeId, int x, int y, int radius) { int ghostId; Bool success; ghostId=xdwApiGenGhostId(); success=xdwApiSendCommand( context, 9, 6, ghostId>>16, ghostId&0xffff, removeId>>16, removeId&0xffff, milliSecs, x, y, radius ); return success ? ghostId : 0; } void xdwApiSetWavesByWindow(xdwApiContext context, Window window, Bool wavesByWindow) { xdwApiContextImp * imp; unsigned card32; imp=(xdwApiContextImp*)context; card32=wavesByWindow ? 1 : 0; XChangeProperty( imp->display, window, imp->XDESKTOPWAVES_WINDOW_INTERACTION, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&card32, 1 ); } void xdwApiDefaultWavesByWindow(xdwApiContext context, Window window) { xdwApiContextImp * imp; imp=(xdwApiContextImp*)context; XDeleteProperty( imp->display, window, imp->XDESKTOPWAVES_WINDOW_INTERACTION ); }