Logo Search packages:      
Sourcecode: xdesktopwaves version File versions  Download package

xdwapi.c

/*****************************************************************************
   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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <X11/Xatom.h>
#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; i<argCount && i<10; i++) {
            event.xclient.data.s[i]=(short)va_arg(ap,int);
      }
      va_end(ap);

      /* Send the message, but check for the window name first. */
      XSync(imp->display,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
      );
}

Generated by  Doxygen 1.6.0   Back to index