OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [gfx/] [mw/] [v2_0/] [src/] [nanox/] [srvevent.c] - Diff between revs 27 and 174

Only display areas with differences | Details | Blame | View Log

Rev 27 Rev 174
/*
/*
 * Copyright (c) 2000 Greg Haerr <greg@censoft.com>
 * Copyright (c) 2000 Greg Haerr <greg@censoft.com>
 * Copyright (c) 1991 David I. Bell
 * Copyright (c) 1991 David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 * provided that this copyright notice remains intact.
 *
 *
 * Graphics server event routines for windows.
 * Graphics server event routines for windows.
 */
 */
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include "serv.h"
#include "serv.h"
 
 
#ifndef __ECOS
#ifndef __ECOS
/* readable error strings*/
/* readable error strings*/
char *nxErrorStrings[] = {
char *nxErrorStrings[] = {
        GR_ERROR_STRINGS
        GR_ERROR_STRINGS
};
};
#endif
#endif
 
 
#if NONETWORK
#if NONETWORK
/* [copied from client.c]
/* [copied from client.c]
 * The following is the user defined function for handling errors.
 * The following is the user defined function for handling errors.
 * If this is not set, then the default action is to close the connection
 * If this is not set, then the default action is to close the connection
 * to the server, describe the error, and then exit.  This error function
 * to the server, describe the error, and then exit.  This error function
 * will only be called when the client asks for events.
 * will only be called when the client asks for events.
 */
 */
static GR_FNCALLBACKEVENT ErrorFunc = GrDefaultErrorHandler;
static GR_FNCALLBACKEVENT ErrorFunc = GrDefaultErrorHandler;
 
 
/*
/*
 * The default error handler which is called when the server
 * The default error handler which is called when the server
 * reports an error event and the client hasn't set a handler for error events.
 * reports an error event and the client hasn't set a handler for error events.
 */
 */
void
void
GrDefaultErrorHandler(GR_EVENT *ep)
GrDefaultErrorHandler(GR_EVENT *ep)
{
{
        if (ep->type == GR_EVENT_TYPE_ERROR) {
        if (ep->type == GR_EVENT_TYPE_ERROR) {
                EPRINTF("nxclient: Error (%s) ", ep->error.name);
                EPRINTF("nxclient: Error (%s) ", ep->error.name);
                EPRINTF(nxErrorStrings[ep->error.code], ep->error.id);
                EPRINTF(nxErrorStrings[ep->error.code], ep->error.id);
                GrClose();
                GrClose();
                exit(1);
                exit(1);
        }
        }
}
}
 
 
/*
/*
 * Set an error handling routine, which will be called on any errors from
 * Set an error handling routine, which will be called on any errors from
 * the server (when events are asked for by the client).  If zero is given,
 * the server (when events are asked for by the client).  If zero is given,
 * then errors will be returned as regular events.
 * then errors will be returned as regular events.
 * Returns the previous error handler.
 * Returns the previous error handler.
 */
 */
GR_FNCALLBACKEVENT
GR_FNCALLBACKEVENT
GrSetErrorHandler(GR_FNCALLBACKEVENT fncb)
GrSetErrorHandler(GR_FNCALLBACKEVENT fncb)
{
{
        GR_FNCALLBACKEVENT orig = ErrorFunc;
        GR_FNCALLBACKEVENT orig = ErrorFunc;
 
 
        ErrorFunc = fncb;
        ErrorFunc = fncb;
        return orig;
        return orig;
}
}
#endif /* NONETWORK*/
#endif /* NONETWORK*/
 
 
/*
/*
 * Generate an error from a graphics function.
 * Generate an error from a graphics function.
 * This creates a special event which describes the error.
 * This creates a special event which describes the error.
 * Only one error event at a time can be saved for delivery to a client.
 * Only one error event at a time can be saved for delivery to a client.
 * This is ok since there are usually lots of redundant errors generated
 * This is ok since there are usually lots of redundant errors generated
 * before the client can notice, errors occurs after the fact, and clients
 * before the client can notice, errors occurs after the fact, and clients
 * can't do much about them except complain and die.  The error is saved
 * can't do much about them except complain and die.  The error is saved
 * specially so that memory problems cannot occur.
 * specially so that memory problems cannot occur.
 */
 */
void GsError(GR_ERROR code, GR_ID id)
void GsError(GR_ERROR code, GR_ID id)
{
{
        GR_EVENT_ERROR  *ep;            /* event to describe error */
        GR_EVENT_ERROR  *ep;            /* event to describe error */
 
 
        EPRINTF("nano-X: GsError ");
        EPRINTF("nano-X: GsError ");
        if(curfunc)
        if(curfunc)
                EPRINTF("(%s) ", curfunc);
                EPRINTF("(%s) ", curfunc);
        EPRINTF(nxErrorStrings[code], id);
        EPRINTF(nxErrorStrings[code], id);
 
 
        /* if no clients, nothing to report*/
        /* if no clients, nothing to report*/
        if (!curclient)
        if (!curclient)
                return;
                return;
 
 
        /* queue the error event regardless of GrSelectEvents*/
        /* queue the error event regardless of GrSelectEvents*/
        ep = (GR_EVENT_ERROR *)GsAllocEvent(curclient);
        ep = (GR_EVENT_ERROR *)GsAllocEvent(curclient);
        ep->type = GR_EVENT_TYPE_ERROR;
        ep->type = GR_EVENT_TYPE_ERROR;
        ep->name[0] = 0;
        ep->name[0] = 0;
        if(curfunc) {
        if(curfunc) {
                strncpy(ep->name, curfunc, sizeof(GR_FUNC_NAME));
                strncpy(ep->name, curfunc, sizeof(GR_FUNC_NAME));
                ep->name[sizeof(GR_FUNC_NAME)-1] = '\0';
                ep->name[sizeof(GR_FUNC_NAME)-1] = '\0';
        }
        }
        ep->code = code;
        ep->code = code;
        ep->id = id;
        ep->id = id;
}
}
 
 
/*
/*
 * Allocate an event to be passed back to the specified client.
 * Allocate an event to be passed back to the specified client.
 * The event is already chained onto the event queue, and only
 * The event is already chained onto the event queue, and only
 * needs filling out.  Returns NULL with an error generated if
 * needs filling out.  Returns NULL with an error generated if
 * the event cannot be allocated.
 * the event cannot be allocated.
 */
 */
GR_EVENT *GsAllocEvent(GR_CLIENT *client)
GR_EVENT *GsAllocEvent(GR_CLIENT *client)
{
{
        GR_EVENT_LIST   *elp;           /* current element list */
        GR_EVENT_LIST   *elp;           /* current element list */
        GR_CLIENT       *oldcurclient;  /* old current client */
        GR_CLIENT       *oldcurclient;  /* old current client */
 
 
        /*
        /*
         * Get a new event structure from the free list, or else
         * Get a new event structure from the free list, or else
         * allocate it using malloc.
         * allocate it using malloc.
         */
         */
        elp = eventfree;
        elp = eventfree;
        if (elp)
        if (elp)
                eventfree = elp->next;
                eventfree = elp->next;
        else {
        else {
                elp = (GR_EVENT_LIST *) malloc(sizeof(GR_EVENT_LIST));
                elp = (GR_EVENT_LIST *) malloc(sizeof(GR_EVENT_LIST));
                if (elp == NULL) {
                if (elp == NULL) {
                        oldcurclient = curclient;
                        oldcurclient = curclient;
                        curclient = client;
                        curclient = client;
                        GsError(GR_ERROR_MALLOC_FAILED, 0);
                        GsError(GR_ERROR_MALLOC_FAILED, 0);
                        curclient = oldcurclient;
                        curclient = oldcurclient;
                        return NULL;
                        return NULL;
                }
                }
        }
        }
 
 
        /*
        /*
         * Add the event to the end of the event list.
         * Add the event to the end of the event list.
         */
         */
        if (client->eventhead)
        if (client->eventhead)
                client->eventtail->next = elp;
                client->eventtail->next = elp;
        else
        else
                client->eventhead = elp;
                client->eventhead = elp;
        client->eventtail = elp;
        client->eventtail = elp;
        elp->next = NULL;
        elp->next = NULL;
        elp->event.type = GR_EVENT_TYPE_NONE;
        elp->event.type = GR_EVENT_TYPE_NONE;
 
 
        return &elp->event;
        return &elp->event;
}
}
 
 
/*
/*
 * Update mouse status and issue events on it if necessary.
 * Update mouse status and issue events on it if necessary.
 * This function doesn't block, but is normally only called when
 * This function doesn't block, but is normally only called when
 * there is known to be some data waiting to be read from the mouse.
 * there is known to be some data waiting to be read from the mouse.
 */
 */
GR_BOOL GsCheckMouseEvent(void)
GR_BOOL GsCheckMouseEvent(void)
{
{
        GR_COORD        rootx;          /* latest mouse x position */
        GR_COORD        rootx;          /* latest mouse x position */
        GR_COORD        rooty;          /* latest mouse y position */
        GR_COORD        rooty;          /* latest mouse y position */
        int             newbuttons;     /* latest buttons */
        int             newbuttons;     /* latest buttons */
        int             mousestatus;    /* latest mouse status */
        int             mousestatus;    /* latest mouse status */
 
 
        /* Read the latest mouse status: */
        /* Read the latest mouse status: */
        mousestatus = GdReadMouse(&rootx, &rooty, &newbuttons);
        mousestatus = GdReadMouse(&rootx, &rooty, &newbuttons);
        if(mousestatus < 0) {
        if(mousestatus < 0) {
                GsError(GR_ERROR_MOUSE_ERROR, 0);
                GsError(GR_ERROR_MOUSE_ERROR, 0);
                return FALSE;
                return FALSE;
        } else if(mousestatus) {        /* Deliver events as appropriate: */
        } else if(mousestatus) {        /* Deliver events as appropriate: */
                GsHandleMouseStatus(rootx, rooty, newbuttons);
                GsHandleMouseStatus(rootx, rooty, newbuttons);
 
 
                /* possibly reset portrait mode based on mouse position*/
                /* possibly reset portrait mode based on mouse position*/
                if (autoportrait)
                if (autoportrait)
                        GsSetPortraitModeFromXY(rootx, rooty);
                        GsSetPortraitModeFromXY(rootx, rooty);
                return TRUE;
                return TRUE;
        }
        }
        return FALSE;
        return FALSE;
}
}
 
 
/*
/*
 * Update keyboard status and issue events on it if necessary.
 * Update keyboard status and issue events on it if necessary.
 * This function doesn't block, but is normally only called when
 * This function doesn't block, but is normally only called when
 * there is known to be some data waiting to be read from the keyboard.
 * there is known to be some data waiting to be read from the keyboard.
 */
 */
GR_BOOL GsCheckKeyboardEvent(void)
GR_BOOL GsCheckKeyboardEvent(void)
{
{
        MWKEY           mwkey;          /* latest character */
        MWKEY           mwkey;          /* latest character */
        MWKEYMOD        modifiers;      /* latest modifiers */
        MWKEYMOD        modifiers;      /* latest modifiers */
        MWSCANCODE      scancode;
        MWSCANCODE      scancode;
        int             keystatus;      /* latest keyboard status */
        int             keystatus;      /* latest keyboard status */
 
 
        /* Read the latest keyboard status: */
        /* Read the latest keyboard status: */
        keystatus = GdReadKeyboard(&mwkey, &modifiers, &scancode);
        keystatus = GdReadKeyboard(&mwkey, &modifiers, &scancode);
 
 
        if(keystatus < 0) {
        if(keystatus < 0) {
                if(keystatus == -2)     /* special case return code*/
                if(keystatus == -2)     /* special case return code*/
                        GsTerminate();
                        GsTerminate();
                GsError(GR_ERROR_KEYBOARD_ERROR, 0);
                GsError(GR_ERROR_KEYBOARD_ERROR, 0);
                return FALSE;
                return FALSE;
        } else if(keystatus) {          /* Deliver events as appropriate: */
        } else if(keystatus) {          /* Deliver events as appropriate: */
                switch (mwkey) {
                switch (mwkey) {
                case MWKEY_QUIT:
                case MWKEY_QUIT:
                        GsTerminate();
                        GsTerminate();
                        /* no return*/
                        /* no return*/
                case MWKEY_REDRAW:
                case MWKEY_REDRAW:
                        GsRedrawScreen();
                        GsRedrawScreen();
                        break;
                        break;
                case MWKEY_PRINT:
                case MWKEY_PRINT:
                        if (keystatus == 1)
                        if (keystatus == 1)
                                GdCaptureScreen("screen.bmp");
                                GdCaptureScreen("screen.bmp");
                        break;
                        break;
                }
                }
                GsDeliverKeyboardEvent(0,
                GsDeliverKeyboardEvent(0,
                        (keystatus==1?
                        (keystatus==1?
                        GR_EVENT_TYPE_KEY_DOWN: GR_EVENT_TYPE_KEY_UP),
                        GR_EVENT_TYPE_KEY_DOWN: GR_EVENT_TYPE_KEY_UP),
                        mwkey, modifiers, scancode);
                        mwkey, modifiers, scancode);
                return TRUE;
                return TRUE;
        }
        }
        return FALSE;
        return FALSE;
}
}
 
 
/*
/*
 * Handle all mouse events.  These are mouse enter, mouse exit, mouse
 * Handle all mouse events.  These are mouse enter, mouse exit, mouse
 * motion, mouse position, button down, and button up.  This also moves
 * motion, mouse position, button down, and button up.  This also moves
 * the cursor to the new mouse position and changes it shape if needed.
 * the cursor to the new mouse position and changes it shape if needed.
 */
 */
void GsHandleMouseStatus(GR_COORD newx, GR_COORD newy, int newbuttons)
void GsHandleMouseStatus(GR_COORD newx, GR_COORD newy, int newbuttons)
{
{
        int      changebuttons; /* buttons that have changed */
        int      changebuttons; /* buttons that have changed */
        MWKEYMOD modifiers;     /* latest modifiers */
        MWKEYMOD modifiers;     /* latest modifiers */
 
 
        GdGetModifierInfo(NULL, &modifiers); /* Read kbd modifiers */
        GdGetModifierInfo(NULL, &modifiers); /* Read kbd modifiers */
 
 
        /*
        /*
         * First, if the mouse has moved, then position the cursor to the
         * First, if the mouse has moved, then position the cursor to the
         * new location, which will send mouse enter, mouse exit, focus in,
         * new location, which will send mouse enter, mouse exit, focus in,
         * and focus out events if needed.  Check here for mouse motion and
         * and focus out events if needed.  Check here for mouse motion and
         * mouse position events.  Flush the device queue to make sure the
         * mouse position events.  Flush the device queue to make sure the
         * new cursor location is quickly seen by the user.
         * new cursor location is quickly seen by the user.
         */
         */
        if ((newx != cursorx) || (newy != cursory)) {
        if ((newx != cursorx) || (newy != cursory)) {
                GsResetScreenSaver();
                GsResetScreenSaver();
                GrMoveCursor(newx, newy);
                GrMoveCursor(newx, newy);
                GsDeliverMotionEvent(GR_EVENT_TYPE_MOUSE_MOTION,
                GsDeliverMotionEvent(GR_EVENT_TYPE_MOUSE_MOTION,
                        newbuttons, modifiers);
                        newbuttons, modifiers);
                GsDeliverMotionEvent(GR_EVENT_TYPE_MOUSE_POSITION,
                GsDeliverMotionEvent(GR_EVENT_TYPE_MOUSE_POSITION,
                        newbuttons, modifiers);
                        newbuttons, modifiers);
        }
        }
 
 
        /*
        /*
         * Next, generate a button up event if any buttons have been released.
         * Next, generate a button up event if any buttons have been released.
         */
         */
        changebuttons = (curbuttons & ~newbuttons);
        changebuttons = (curbuttons & ~newbuttons);
        if (changebuttons) {
        if (changebuttons) {
                GsResetScreenSaver();
                GsResetScreenSaver();
                GsDeliverButtonEvent(GR_EVENT_TYPE_BUTTON_UP,
                GsDeliverButtonEvent(GR_EVENT_TYPE_BUTTON_UP,
                        newbuttons, changebuttons, modifiers);
                        newbuttons, changebuttons, modifiers);
        }
        }
 
 
        /*
        /*
         * Finally, generate a button down event if any buttons have been
         * Finally, generate a button down event if any buttons have been
         * pressed.
         * pressed.
         */
         */
        changebuttons = (~curbuttons & newbuttons);
        changebuttons = (~curbuttons & newbuttons);
        if (changebuttons) {
        if (changebuttons) {
                GsResetScreenSaver();
                GsResetScreenSaver();
                GsDeliverButtonEvent(GR_EVENT_TYPE_BUTTON_DOWN,
                GsDeliverButtonEvent(GR_EVENT_TYPE_BUTTON_DOWN,
                        newbuttons, changebuttons, modifiers);
                        newbuttons, changebuttons, modifiers);
        }
        }
 
 
        curbuttons = newbuttons;
        curbuttons = newbuttons;
}
}
 
 
/*
/*
 * Deliver a mouse button event to the clients which have selected for it.
 * Deliver a mouse button event to the clients which have selected for it.
 * Each client can only be delivered one instance of the event.  The window
 * Each client can only be delivered one instance of the event.  The window
 * the event is delivered for is either the smallest one containing the
 * the event is delivered for is either the smallest one containing the
 * mouse coordinates, or else one of its direct ancestors.  The lowest
 * mouse coordinates, or else one of its direct ancestors.  The lowest
 * window in that tree which has enabled for the event gets it.  This scan
 * window in that tree which has enabled for the event gets it.  This scan
 * is done independently for each client.  If a window with the correct
 * is done independently for each client.  If a window with the correct
 * noprop mask is reached, or if no window selects for the event, then the
 * noprop mask is reached, or if no window selects for the event, then the
 * event is discarded for that client.  Special case: for the first client
 * event is discarded for that client.  Special case: for the first client
 * that is enabled for both button down and button up events in a window,
 * that is enabled for both button down and button up events in a window,
 * then the pointer is implicitly grabbed by that window when a button is
 * then the pointer is implicitly grabbed by that window when a button is
 * pressed down in that window.  The grabbing remains until all buttons are
 * pressed down in that window.  The grabbing remains until all buttons are
 * released.  While the pointer is grabbed, no other clients or windows can
 * released.  While the pointer is grabbed, no other clients or windows can
 * receive button down or up events.
 * receive button down or up events.
 */
 */
void GsDeliverButtonEvent(GR_EVENT_TYPE type, int buttons, int changebuttons,
void GsDeliverButtonEvent(GR_EVENT_TYPE type, int buttons, int changebuttons,
                        int modifiers)
                        int modifiers)
{
{
        GR_EVENT_BUTTON *ep;            /* mouse button event */
        GR_EVENT_BUTTON *ep;            /* mouse button event */
        GR_WINDOW       *wp;            /* current window */
        GR_WINDOW       *wp;            /* current window */
        GR_EVENT_CLIENT *ecp;           /* current event client */
        GR_EVENT_CLIENT *ecp;           /* current event client */
        GR_CLIENT       *client;        /* current client */
        GR_CLIENT       *client;        /* current client */
        GR_WINDOW_ID    subwid;         /* subwindow id event is for */
        GR_WINDOW_ID    subwid;         /* subwindow id event is for */
        GR_EVENT_MASK   eventmask;      /* event mask */
        GR_EVENT_MASK   eventmask;      /* event mask */
        GR_EVENT_MASK   tempmask;       /* to get around compiler bug */
        GR_EVENT_MASK   tempmask;       /* to get around compiler bug */
 
 
        eventmask = GR_EVENTMASK(type);
        eventmask = GR_EVENTMASK(type);
        if (eventmask == 0)
        if (eventmask == 0)
                return;
                return;
 
 
        /*
        /*
         * If the pointer is implicitly grabbed, then the only window
         * If the pointer is implicitly grabbed, then the only window
         * which can receive button events is that window.  Otherwise
         * which can receive button events is that window.  Otherwise
         * the window the pointer is in gets the events.  Determine the
         * the window the pointer is in gets the events.  Determine the
         * subwindow by seeing if it is a child of the grabbed button.
         * subwindow by seeing if it is a child of the grabbed button.
         */
         */
        wp = mousewp;
        wp = mousewp;
        subwid = wp->id;
        subwid = wp->id;
 
 
        if (grabbuttonwp) {
        if (grabbuttonwp) {
                while ((wp != rootwp) && (wp != grabbuttonwp))
                while ((wp != rootwp) && (wp != grabbuttonwp))
                        wp = wp->parent;
                        wp = wp->parent;
#if 0
#if 0
                if (wp != grabbuttonwp)
                if (wp != grabbuttonwp)
                        subwid = grabbuttonwp->id;
                        subwid = grabbuttonwp->id;
#endif
#endif
                wp = grabbuttonwp;
                wp = grabbuttonwp;
        }
        }
 
 
        for (;;) {
        for (;;) {
                for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                        if ((ecp->eventmask & eventmask) == 0)
                        if ((ecp->eventmask & eventmask) == 0)
                                continue;
                                continue;
 
 
                        client = ecp->client;
                        client = ecp->client;
 
 
                        /*
                        /*
                         * If this is a button down, the buttons are not
                         * If this is a button down, the buttons are not
                         * yet grabbed, and this client is enabled for both
                         * yet grabbed, and this client is enabled for both
                         * button down and button up events, then implicitly
                         * button down and button up events, then implicitly
                         * grab the window for him.
                         * grab the window for him.
                         */
                         */
                        if ((type == GR_EVENT_TYPE_BUTTON_DOWN)
                        if ((type == GR_EVENT_TYPE_BUTTON_DOWN)
                                && (grabbuttonwp == NULL))
                                && (grabbuttonwp == NULL))
                        {
                        {
                                tempmask = GR_EVENT_MASK_BUTTON_UP;
                                tempmask = GR_EVENT_MASK_BUTTON_UP;
                                if (ecp->eventmask & tempmask) {
                                if (ecp->eventmask & tempmask) {
/*DPRINTF("nano-X: implicit grab on window %d\n", wp->id);*/
/*DPRINTF("nano-X: implicit grab on window %d\n", wp->id);*/
                                        grabbuttonwp = wp;
                                        grabbuttonwp = wp;
                                }
                                }
                        }
                        }
 
 
                        ep = (GR_EVENT_BUTTON *) GsAllocEvent(client);
                        ep = (GR_EVENT_BUTTON *) GsAllocEvent(client);
                        if (ep == NULL)
                        if (ep == NULL)
                                continue;
                                continue;
 
 
                        ep->type = type;
                        ep->type = type;
                        ep->wid = wp->id;
                        ep->wid = wp->id;
                        ep->subwid = subwid;
                        ep->subwid = subwid;
                        ep->rootx = cursorx;
                        ep->rootx = cursorx;
                        ep->rooty = cursory;
                        ep->rooty = cursory;
                        ep->x = cursorx - wp->x;
                        ep->x = cursorx - wp->x;
                        ep->y = cursory - wp->y;
                        ep->y = cursory - wp->y;
                        ep->buttons = buttons;
                        ep->buttons = buttons;
                        ep->changebuttons = changebuttons;
                        ep->changebuttons = changebuttons;
                        ep->modifiers = modifiers;
                        ep->modifiers = modifiers;
                        ep->time = GsGetTickCount();
                        ep->time = GsGetTickCount();
                }
                }
 
 
                /*
                /*
                 * Events do not propagate if the window was grabbed.
                 * Events do not propagate if the window was grabbed.
                 * Also release the grab if the buttons are now all released,
                 * Also release the grab if the buttons are now all released,
                 * which can cause various events.
                 * which can cause various events.
                 */
                 */
                if (grabbuttonwp) {
                if (grabbuttonwp) {
                        if (buttons == 0) {
                        if (buttons == 0) {
                                grabbuttonwp = NULL;
                                grabbuttonwp = NULL;
                                GrMoveCursor(cursorx, cursory);
                                GrMoveCursor(cursorx, cursory);
                        }
                        }
                        return;
                        return;
                }
                }
 
 
                if ((wp == rootwp) || (wp->nopropmask & eventmask))
                if ((wp == rootwp) || (wp->nopropmask & eventmask))
                        return;
                        return;
 
 
                wp = wp->parent;
                wp = wp->parent;
        }
        }
}
}
 
 
/*
/*
 * Deliver a mouse motion event to the clients which have selected for it.
 * Deliver a mouse motion event to the clients which have selected for it.
 * Each client can only be delivered one instance of the event.  The window
 * Each client can only be delivered one instance of the event.  The window
 * the event is delivered for is either the smallest one containing the
 * the event is delivered for is either the smallest one containing the
 * mouse coordinates, or else one of its direct ancestors.  The lowest
 * mouse coordinates, or else one of its direct ancestors.  The lowest
 * window in that tree which has enabled for the event gets it.  This scan
 * window in that tree which has enabled for the event gets it.  This scan
 * is done independently for each client.  If a window with the correct
 * is done independently for each client.  If a window with the correct
 * noprop mask is reached, or if no window selects for the event, then the
 * noprop mask is reached, or if no window selects for the event, then the
 * event is discarded for that client.  Special case: If the event type is
 * event is discarded for that client.  Special case: If the event type is
 * GR_EVENT_TYPE_MOUSE_POSITION, then only the last such event is queued for
 * GR_EVENT_TYPE_MOUSE_POSITION, then only the last such event is queued for
 * any single client to reduce events.  If the mouse is implicitly grabbed,
 * any single client to reduce events.  If the mouse is implicitly grabbed,
 * then only the grabbing window receives the events, and continues to do
 * then only the grabbing window receives the events, and continues to do
 * so even if the mouse is currently outside of the grabbing window.
 * so even if the mouse is currently outside of the grabbing window.
 */
 */
void GsDeliverMotionEvent(GR_EVENT_TYPE type, int buttons, MWKEYMOD modifiers)
void GsDeliverMotionEvent(GR_EVENT_TYPE type, int buttons, MWKEYMOD modifiers)
{
{
        GR_EVENT_MOUSE  *ep;            /* mouse motion event */
        GR_EVENT_MOUSE  *ep;            /* mouse motion event */
        GR_WINDOW       *wp;            /* current window */
        GR_WINDOW       *wp;            /* current window */
        GR_EVENT_CLIENT *ecp;           /* current event client */
        GR_EVENT_CLIENT *ecp;           /* current event client */
        GR_CLIENT       *client;        /* current client */
        GR_CLIENT       *client;        /* current client */
        GR_WINDOW_ID    subwid;         /* subwindow id event is for */
        GR_WINDOW_ID    subwid;         /* subwindow id event is for */
        GR_EVENT_MASK   eventmask;      /* event mask */
        GR_EVENT_MASK   eventmask;      /* event mask */
 
 
        eventmask = GR_EVENTMASK(type);
        eventmask = GR_EVENTMASK(type);
        if (eventmask == 0)
        if (eventmask == 0)
                return;
                return;
 
 
        wp = mousewp;
        wp = mousewp;
        subwid = wp->id;
        subwid = wp->id;
 
 
        if (grabbuttonwp) {
        if (grabbuttonwp) {
                while ((wp != rootwp) && (wp != grabbuttonwp))
                while ((wp != rootwp) && (wp != grabbuttonwp))
                        wp = wp->parent;
                        wp = wp->parent;
#if 0
#if 0
                if (wp != grabbuttonwp)
                if (wp != grabbuttonwp)
                        subwid = grabbuttonwp->id;
                        subwid = grabbuttonwp->id;
#endif
#endif
                wp = grabbuttonwp;
                wp = grabbuttonwp;
        }
        }
 
 
        for (;;) {
        for (;;) {
                for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                        if ((ecp->eventmask & eventmask) == 0)
                        if ((ecp->eventmask & eventmask) == 0)
                                continue;
                                continue;
 
 
                        client = ecp->client;
                        client = ecp->client;
 
 
                        /*
                        /*
                         * If the event is for just the latest position,
                         * If the event is for just the latest position,
                         * then search the event queue for an existing
                         * then search the event queue for an existing
                         * event of this type (if any), and free it.
                         * event of this type (if any), and free it.
                         */
                         */
                        if (type == GR_EVENT_TYPE_MOUSE_POSITION)
                        if (type == GR_EVENT_TYPE_MOUSE_POSITION)
                                GsFreePositionEvent(client, wp->id, subwid);
                                GsFreePositionEvent(client, wp->id, subwid);
 
 
                        ep = (GR_EVENT_MOUSE *) GsAllocEvent(client);
                        ep = (GR_EVENT_MOUSE *) GsAllocEvent(client);
                        if (ep == NULL)
                        if (ep == NULL)
                                continue;
                                continue;
 
 
                        ep->type = type;
                        ep->type = type;
                        ep->wid = wp->id;
                        ep->wid = wp->id;
                        ep->subwid = subwid;
                        ep->subwid = subwid;
                        ep->rootx = cursorx;
                        ep->rootx = cursorx;
                        ep->rooty = cursory;
                        ep->rooty = cursory;
                        ep->x = cursorx - wp->x;
                        ep->x = cursorx - wp->x;
                        ep->y = cursory - wp->y;
                        ep->y = cursory - wp->y;
                        ep->buttons = buttons;
                        ep->buttons = buttons;
                        ep->modifiers = modifiers;
                        ep->modifiers = modifiers;
                }
                }
 
 
                if ((wp == rootwp) || grabbuttonwp ||
                if ((wp == rootwp) || grabbuttonwp ||
                        (wp->nopropmask & eventmask))
                        (wp->nopropmask & eventmask))
                                return;
                                return;
 
 
                wp = wp->parent;
                wp = wp->parent;
        }
        }
}
}
 
 
/*
/*
 * Deliver a keyboard event to one of the clients which have selected for it.
 * Deliver a keyboard event to one of the clients which have selected for it.
 * Only the first client found gets the event (no duplicates are sent).  The
 * Only the first client found gets the event (no duplicates are sent).  The
 * window the event is delivered to is either the smallest one containing
 * window the event is delivered to is either the smallest one containing
 * the mouse coordinates, or else one of its direct ancestors (if such a
 * the mouse coordinates, or else one of its direct ancestors (if such a
 * window is a descendant of the focus window), or else just the focus window.
 * window is a descendant of the focus window), or else just the focus window.
 * The lowest window in that tree which has enabled for the event gets it.
 * The lowest window in that tree which has enabled for the event gets it.
 * If a window with the correct noprop mask is reached, or if no window selects
 * If a window with the correct noprop mask is reached, or if no window selects
 * for the event, then the event is discarded.
 * for the event, then the event is discarded.
 */
 */
void GsDeliverKeyboardEvent(GR_WINDOW_ID wid, GR_EVENT_TYPE type,
void GsDeliverKeyboardEvent(GR_WINDOW_ID wid, GR_EVENT_TYPE type,
        GR_KEY keyvalue, GR_KEYMOD modifiers, GR_SCANCODE scancode)
        GR_KEY keyvalue, GR_KEYMOD modifiers, GR_SCANCODE scancode)
{
{
        GR_EVENT_KEYSTROKE      *ep;            /* keystroke event */
        GR_EVENT_KEYSTROKE      *ep;            /* keystroke event */
        GR_WINDOW               *wp;            /* current window */
        GR_WINDOW               *wp;            /* current window */
        GR_WINDOW               *tempwp;        /* temporary window pointer */
        GR_WINDOW               *tempwp;        /* temporary window pointer */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_WINDOW_ID            subwid;         /* subwindow id event is for */
        GR_WINDOW_ID            subwid;         /* subwindow id event is for */
        GR_EVENT_MASK           eventmask;      /* event mask */
        GR_EVENT_MASK           eventmask;      /* event mask */
        GR_WINDOW               *kwp;
        GR_WINDOW               *kwp;
 
 
        eventmask = GR_EVENTMASK(type);
        eventmask = GR_EVENTMASK(type);
        if (eventmask == 0)
        if (eventmask == 0)
                return;
                return;
 
 
        GsResetScreenSaver();
        GsResetScreenSaver();
 
 
        /* if window id passed, use it, otherwise focus window*/
        /* if window id passed, use it, otherwise focus window*/
        if (wid) {
        if (wid) {
                kwp = GsFindWindow(wid);
                kwp = GsFindWindow(wid);
                if (!kwp)
                if (!kwp)
                        return;
                        return;
        } else
        } else
                kwp = focuswp;
                kwp = focuswp;
        wp = mousewp;
        wp = mousewp;
        subwid = wp->id;
        subwid = wp->id;
 
 
        /*
        /*
         * See if the actual window the pointer is in is a descendant of
         * See if the actual window the pointer is in is a descendant of
         * the focus window.  If not, then ignore it, and force the input
         * the focus window.  If not, then ignore it, and force the input
         * into the focus window itself.
         * into the focus window itself.
         */
         */
        tempwp = wp;
        tempwp = wp;
        while ((tempwp != kwp) && (tempwp != rootwp))
        while ((tempwp != kwp) && (tempwp != rootwp))
                tempwp = tempwp->parent;
                tempwp = tempwp->parent;
 
 
        if (tempwp != kwp) {
        if (tempwp != kwp) {
                wp = kwp;
                wp = kwp;
                subwid = wp->id;
                subwid = wp->id;
        }
        }
 
 
        /*
        /*
         * Now walk upwards looking for the first window which will accept
         * Now walk upwards looking for the first window which will accept
         * the keyboard event.  However, do not go beyond the focus window,
         * the keyboard event.  However, do not go beyond the focus window,
         * and only give the event to one client.
         * and only give the event to one client.
         */
         */
        for (;;) {
        for (;;) {
                for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                        if ((ecp->eventmask & eventmask) == 0)
                        if ((ecp->eventmask & eventmask) == 0)
                                continue;
                                continue;
 
 
                        ep = (GR_EVENT_KEYSTROKE *) GsAllocEvent(ecp->client);
                        ep = (GR_EVENT_KEYSTROKE *) GsAllocEvent(ecp->client);
                        if (ep == NULL)
                        if (ep == NULL)
                                return;
                                return;
 
 
                        ep->type = type;
                        ep->type = type;
                        ep->wid = wp->id;
                        ep->wid = wp->id;
                        ep->subwid = subwid;
                        ep->subwid = subwid;
                        ep->rootx = cursorx;
                        ep->rootx = cursorx;
                        ep->rooty = cursory;
                        ep->rooty = cursory;
                        ep->x = cursorx - wp->x;
                        ep->x = cursorx - wp->x;
                        ep->y = cursory - wp->y;
                        ep->y = cursory - wp->y;
                        ep->buttons = curbuttons;
                        ep->buttons = curbuttons;
                        ep->modifiers = modifiers;
                        ep->modifiers = modifiers;
                        ep->ch = keyvalue;
                        ep->ch = keyvalue;
                        ep->scancode = scancode;
                        ep->scancode = scancode;
                        return;                 /* only one client gets it */
                        return;                 /* only one client gets it */
                }
                }
 
 
                if ((wp == rootwp) || (wp == kwp) ||
                if ((wp == rootwp) || (wp == kwp) ||
                        (wp->nopropmask & eventmask))
                        (wp->nopropmask & eventmask))
                                return;
                                return;
 
 
                wp = wp->parent;
                wp = wp->parent;
        }
        }
}
}
 
 
/*
/*
 * Try to deliver a exposure event to the clients which have selected for it.
 * Try to deliver a exposure event to the clients which have selected for it.
 * This does not send exposure events for unmapped or input-only windows.
 * This does not send exposure events for unmapped or input-only windows.
 * Exposure events do not propagate upwards.
 * Exposure events do not propagate upwards.
 */
 */
void
void
GsDeliverExposureEvent(GR_WINDOW *wp, GR_COORD x, GR_COORD y,
GsDeliverExposureEvent(GR_WINDOW *wp, GR_COORD x, GR_COORD y,
        GR_SIZE width, GR_SIZE height)
        GR_SIZE width, GR_SIZE height)
{
{
        GR_EVENT_EXPOSURE       *ep;            /* exposure event */
        GR_EVENT_EXPOSURE       *ep;            /* exposure event */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
 
 
        if (wp->unmapcount || !wp->output)
        if (wp->unmapcount || !wp->output)
                return;
                return;
 
 
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                if ((ecp->eventmask & GR_EVENT_MASK_EXPOSURE) == 0)
                if ((ecp->eventmask & GR_EVENT_MASK_EXPOSURE) == 0)
                        continue;
                        continue;
 
 
                GsFreeExposureEvent(ecp->client, wp->id, x, y, width, height);
                GsFreeExposureEvent(ecp->client, wp->id, x, y, width, height);
 
 
                ep = (GR_EVENT_EXPOSURE *) GsAllocEvent(ecp->client);
                ep = (GR_EVENT_EXPOSURE *) GsAllocEvent(ecp->client);
                if (ep == NULL)
                if (ep == NULL)
                        continue;
                        continue;
 
 
                ep->type = GR_EVENT_TYPE_EXPOSURE;
                ep->type = GR_EVENT_TYPE_EXPOSURE;
                ep->wid = wp->id;
                ep->wid = wp->id;
                ep->x = x;
                ep->x = x;
                ep->y = y;
                ep->y = y;
                ep->width = width;
                ep->width = width;
                ep->height = height;
                ep->height = height;
        }
        }
}
}
 
 
/*
/*
 * Search for an enclosed expose event in the specified client's
 * Search for an enclosed expose event in the specified client's
 * event queue, and remove it.  This is used to prevent multiple expose
 * event queue, and remove it.  This is used to prevent multiple expose
 * events from being delivered, thus providing a more pleasing visual
 * events from being delivered, thus providing a more pleasing visual
 * redraw effect than if the events were all sent.
 * redraw effect than if the events were all sent.
 */
 */
void
void
GsFreeExposureEvent(GR_CLIENT *client, GR_WINDOW_ID wid, GR_COORD x,
GsFreeExposureEvent(GR_CLIENT *client, GR_WINDOW_ID wid, GR_COORD x,
        GR_COORD y, GR_SIZE width, GR_SIZE height)
        GR_COORD y, GR_SIZE width, GR_SIZE height)
{
{
        GR_EVENT_LIST   *elp;           /* current element list */
        GR_EVENT_LIST   *elp;           /* current element list */
        GR_EVENT_LIST   *prevelp;       /* previous element list */
        GR_EVENT_LIST   *prevelp;       /* previous element list */
 
 
        prevelp = NULL;
        prevelp = NULL;
        for (elp = client->eventhead; elp; prevelp = elp, elp = elp->next) {
        for (elp = client->eventhead; elp; prevelp = elp, elp = elp->next) {
                if (elp->event.type != GR_EVENT_TYPE_EXPOSURE ||
                if (elp->event.type != GR_EVENT_TYPE_EXPOSURE ||
                    elp->event.exposure.wid != wid)
                    elp->event.exposure.wid != wid)
                        continue;
                        continue;
                if (elp->event.exposure.x < x || elp->event.exposure.y < y ||
                if (elp->event.exposure.x < x || elp->event.exposure.y < y ||
                    elp->event.exposure.x+elp->event.exposure.width > x+width ||
                    elp->event.exposure.x+elp->event.exposure.width > x+width ||
                    elp->event.exposure.y+elp->event.exposure.height > y+height)
                    elp->event.exposure.y+elp->event.exposure.height > y+height)
                        continue;
                        continue;
 
 
                /*
                /*
                 * Found one, remove it and put it back on the free list.
                 * Found one, remove it and put it back on the free list.
                 */
                 */
                if (prevelp)
                if (prevelp)
                        prevelp->next = elp->next;
                        prevelp->next = elp->next;
                else
                else
                        client->eventhead = elp->next;
                        client->eventhead = elp->next;
                if (client->eventtail == elp)
                if (client->eventtail == elp)
                        client->eventtail = prevelp;
                        client->eventtail = prevelp;
 
 
                elp->next = eventfree;
                elp->next = eventfree;
                eventfree = elp;
                eventfree = elp;
                return;
                return;
        }
        }
}
}
 
 
/*
/*
 * Try to deliver an update event to the clients which have selected for it.
 * Try to deliver an update event to the clients which have selected for it.
 */
 */
void GsDeliverUpdateEvent(GR_WINDOW *wp, GR_UPDATE_TYPE utype, GR_COORD x,
void GsDeliverUpdateEvent(GR_WINDOW *wp, GR_UPDATE_TYPE utype, GR_COORD x,
                        GR_COORD y, GR_SIZE width, GR_SIZE height)
                        GR_COORD y, GR_SIZE width, GR_SIZE height)
{
{
        GR_EVENT_MASK           cmask = GR_EVENT_MASK_UPDATE;
        GR_EVENT_MASK           cmask = GR_EVENT_MASK_UPDATE;
        GR_EVENT_UPDATE         *ep;            /* update event */
        GR_EVENT_UPDATE         *ep;            /* update event */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_WINDOW_ID            id = wp->id;
        GR_WINDOW_ID            id = wp->id;
        int                     lcount = 0;
        int                     lcount = 0;
 
 
        /* adjust reported x,y to be parent-relative*/
        /* adjust reported x,y to be parent-relative*/
        if (wp->parent) {
        if (wp->parent) {
                x -= wp->parent->x;
                x -= wp->parent->x;
                y -= wp->parent->y;
                y -= wp->parent->y;
        }
        }
 
 
update_again:
update_again:
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                if ((ecp->eventmask & cmask) == 0)
                if ((ecp->eventmask & cmask) == 0)
                        continue;
                        continue;
 
 
                ep = (GR_EVENT_UPDATE *) GsAllocEvent(ecp->client);
                ep = (GR_EVENT_UPDATE *) GsAllocEvent(ecp->client);
                if (ep == NULL)
                if (ep == NULL)
                        continue;
                        continue;
 
 
                ep->type = lcount?
                ep->type = lcount?
                        GR_EVENT_TYPE_CHLD_UPDATE: GR_EVENT_TYPE_UPDATE;
                        GR_EVENT_TYPE_CHLD_UPDATE: GR_EVENT_TYPE_UPDATE;
                ep->utype = utype;
                ep->utype = utype;
                ep->wid = wp->id;       /* GrSelectEvents window id*/
                ep->wid = wp->id;       /* GrSelectEvents window id*/
                ep->subwid = id;        /* update window id*/
                ep->subwid = id;        /* update window id*/
                ep->x = x;
                ep->x = x;
                ep->y = y;
                ep->y = y;
                ep->width = width;
                ep->width = width;
                ep->height = height;
                ep->height = height;
        }
        }
 
 
        /* If we are currently checking the window updated, go back and
        /* If we are currently checking the window updated, go back and
         * check its parent too */
         * check its parent too */
        if (!lcount++) {
        if (!lcount++) {
                wp = wp->parent;
                wp = wp->parent;
                /* check for NULL on root window id*/
                /* check for NULL on root window id*/
                if (wp == NULL)
                if (wp == NULL)
                        return;
                        return;
                cmask = GR_EVENT_MASK_CHLD_UPDATE;
                cmask = GR_EVENT_MASK_CHLD_UPDATE;
                goto update_again;
                goto update_again;
        }
        }
}
}
 
 
/*
/*
 * Try to deliver a general event such as focus in, focus out, mouse enter,
 * Try to deliver a general event such as focus in, focus out, mouse enter,
 * or mouse exit to the clients which have selected for it.  These events
 * or mouse exit to the clients which have selected for it.  These events
 * only have the window id as data, and do not propagate upwards.
 * only have the window id as data, and do not propagate upwards.
 */
 */
void GsDeliverGeneralEvent(GR_WINDOW *wp, GR_EVENT_TYPE type, GR_WINDOW *other)
void GsDeliverGeneralEvent(GR_WINDOW *wp, GR_EVENT_TYPE type, GR_WINDOW *other)
{
{
        GR_EVENT_GENERAL        *gp;            /* general event */
        GR_EVENT_GENERAL        *gp;            /* general event */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_MASK           eventmask;      /* event mask */
        GR_EVENT_MASK           eventmask;      /* event mask */
 
 
        eventmask = GR_EVENTMASK(type);
        eventmask = GR_EVENTMASK(type);
        if (eventmask == 0)
        if (eventmask == 0)
                return;
                return;
 
 
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                if ((ecp->eventmask & eventmask) == 0)
                if ((ecp->eventmask & eventmask) == 0)
                        continue;
                        continue;
 
 
                gp = (GR_EVENT_GENERAL *) GsAllocEvent(ecp->client);
                gp = (GR_EVENT_GENERAL *) GsAllocEvent(ecp->client);
                if (gp == NULL)
                if (gp == NULL)
                        continue;
                        continue;
 
 
                gp->type = type;
                gp->type = type;
                gp->wid = wp->id;
                gp->wid = wp->id;
                if (other)
                if (other)
                        gp->otherid = other->id;
                        gp->otherid = other->id;
                else gp->otherid = 0;
                else gp->otherid = 0;
        }
        }
}
}
 
 
/*
/*
 * Deliver a portrait mode changed event to all windows which
 * Deliver a portrait mode changed event to all windows which
 * have selected for it.
 * have selected for it.
 */
 */
void GsDeliverPortraitChangedEvent(void)
void GsDeliverPortraitChangedEvent(void)
{
{
        GR_WINDOW               *wp;
        GR_WINDOW               *wp;
        GR_EVENT_GENERAL        *gp;
        GR_EVENT_GENERAL        *gp;
        GR_EVENT_CLIENT         *ecp;
        GR_EVENT_CLIENT         *ecp;
 
 
        for (wp=listwp; wp; wp=wp->next) {
        for (wp=listwp; wp; wp=wp->next) {
                for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                        if ((ecp->eventmask & GR_EVENT_MASK_PORTRAIT_CHANGED) == 0)
                        if ((ecp->eventmask & GR_EVENT_MASK_PORTRAIT_CHANGED) == 0)
                                continue;
                                continue;
 
 
                        gp = (GR_EVENT_GENERAL *) GsAllocEvent(ecp->client);
                        gp = (GR_EVENT_GENERAL *) GsAllocEvent(ecp->client);
                        if (gp == NULL)
                        if (gp == NULL)
                                continue;
                                continue;
 
 
                        gp->type = GR_EVENT_TYPE_PORTRAIT_CHANGED;
                        gp->type = GR_EVENT_TYPE_PORTRAIT_CHANGED;
                        gp->wid = wp->id;
                        gp->wid = wp->id;
                        gp->otherid = 0;
                        gp->otherid = 0;
                }
                }
        }
        }
}
}
 
 
/*
/*
 * Deliver a Screen Saver event. There is only one parameter- activate the
 * Deliver a Screen Saver event. There is only one parameter- activate the
 * screen saver or deactivate it. We only deliver it to the root window,
 * screen saver or deactivate it. We only deliver it to the root window,
 * but we do send it to every client which has selected for it (because the
 * but we do send it to every client which has selected for it (because the
 * program which starts the screen saver on an activate event might not also
 * program which starts the screen saver on an activate event might not also
 * be the screen saver program which wants to catch the deactivate event).
 * be the screen saver program which wants to catch the deactivate event).
 */
 */
void GsDeliverScreenSaverEvent(GR_BOOL activate)
void GsDeliverScreenSaverEvent(GR_BOOL activate)
{
{
        GR_EVENT_SCREENSAVER    *gp;            /* screensaver event */
        GR_EVENT_SCREENSAVER    *gp;            /* screensaver event */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
 
 
        for (ecp = rootwp->eventclients; ecp; ecp = ecp->next) {
        for (ecp = rootwp->eventclients; ecp; ecp = ecp->next) {
                if ((ecp->eventmask & GR_EVENT_MASK_SCREENSAVER) == 0)
                if ((ecp->eventmask & GR_EVENT_MASK_SCREENSAVER) == 0)
                        continue;
                        continue;
 
 
                gp = (GR_EVENT_SCREENSAVER *) GsAllocEvent(ecp->client);
                gp = (GR_EVENT_SCREENSAVER *) GsAllocEvent(ecp->client);
                if (gp == NULL)
                if (gp == NULL)
                        continue;
                        continue;
 
 
                gp->type = GR_EVENT_TYPE_SCREENSAVER;
                gp->type = GR_EVENT_TYPE_SCREENSAVER;
                gp->activate = activate;
                gp->activate = activate;
        }
        }
}
}
 
 
/*
/*
 * Deliver a client data request event. Delivered to the clients who have
 * Deliver a client data request event. Delivered to the clients who have
 * selected for this event on the specified window only.
 * selected for this event on the specified window only.
 */
 */
void
void
GsDeliverClientDataReqEvent(GR_WINDOW_ID wid, GR_WINDOW_ID rid,
GsDeliverClientDataReqEvent(GR_WINDOW_ID wid, GR_WINDOW_ID rid,
                        GR_SERIALNO serial, GR_MIMETYPE mimetype)
                        GR_SERIALNO serial, GR_MIMETYPE mimetype)
{
{
        GR_EVENT_CLIENT_DATA_REQ *gp;           /* client data request event */
        GR_EVENT_CLIENT_DATA_REQ *gp;           /* client data request event */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_WINDOW *wp;
        GR_WINDOW *wp;
 
 
        if(!(wp = GsFindWindow(wid))) return;
        if(!(wp = GsFindWindow(wid))) return;
 
 
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                if ((ecp->eventmask & GR_EVENT_MASK_CLIENT_DATA_REQ) == 0)
                if ((ecp->eventmask & GR_EVENT_MASK_CLIENT_DATA_REQ) == 0)
                        continue;
                        continue;
 
 
                gp = (GR_EVENT_CLIENT_DATA_REQ *) GsAllocEvent(ecp->client);
                gp = (GR_EVENT_CLIENT_DATA_REQ *) GsAllocEvent(ecp->client);
                if (gp == NULL)
                if (gp == NULL)
                        continue;
                        continue;
 
 
                gp->type = GR_EVENT_TYPE_CLIENT_DATA_REQ;
                gp->type = GR_EVENT_TYPE_CLIENT_DATA_REQ;
                gp->wid = wid;
                gp->wid = wid;
                gp->rid = rid;
                gp->rid = rid;
                gp->serial = serial;
                gp->serial = serial;
                gp->mimetype = mimetype;
                gp->mimetype = mimetype;
                continue;
                continue;
        }
        }
}
}
 
 
/*
/*
 * Deliver a client data event. Delivered to the clients who have selected for
 * Deliver a client data event. Delivered to the clients who have selected for
 * this event on the specified window only.
 * this event on the specified window only.
 */
 */
void
void
GsDeliverClientDataEvent(GR_WINDOW_ID wid, GR_WINDOW_ID rid,
GsDeliverClientDataEvent(GR_WINDOW_ID wid, GR_WINDOW_ID rid,
        GR_SERIALNO serial, GR_LENGTH len, GR_LENGTH thislen, void *data)
        GR_SERIALNO serial, GR_LENGTH len, GR_LENGTH thislen, void *data)
{
{
        GR_EVENT_CLIENT_DATA *gp;               /* client data request event */
        GR_EVENT_CLIENT_DATA *gp;               /* client data request event */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_WINDOW *wp;
        GR_WINDOW *wp;
 
 
        if(!(wp = GsFindWindow(wid))) return;
        if(!(wp = GsFindWindow(wid))) return;
 
 
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                if ((ecp->eventmask & GR_EVENT_MASK_CLIENT_DATA) == 0)
                if ((ecp->eventmask & GR_EVENT_MASK_CLIENT_DATA) == 0)
                        continue;
                        continue;
 
 
                gp = (GR_EVENT_CLIENT_DATA *) GsAllocEvent(ecp->client);
                gp = (GR_EVENT_CLIENT_DATA *) GsAllocEvent(ecp->client);
                if (gp == NULL)
                if (gp == NULL)
                        continue;
                        continue;
 
 
                gp->type = GR_EVENT_TYPE_CLIENT_DATA;
                gp->type = GR_EVENT_TYPE_CLIENT_DATA;
                gp->wid = wid;
                gp->wid = wid;
                gp->rid = rid;
                gp->rid = rid;
                gp->serial = serial;
                gp->serial = serial;
                gp->len = len;
                gp->len = len;
                gp->datalen = thislen;
                gp->datalen = thislen;
                if(!(gp->data = malloc(thislen))) {
                if(!(gp->data = malloc(thislen))) {
                        GsError(GR_ERROR_MALLOC_FAILED, wid);
                        GsError(GR_ERROR_MALLOC_FAILED, wid);
                        return;
                        return;
                }
                }
                memcpy(gp->data, data, thislen);
                memcpy(gp->data, data, thislen);
                continue;
                continue;
        }
        }
}
}
 
 
/*
/*
 * Search for a matching mouse position event in the specified client's
 * Search for a matching mouse position event in the specified client's
 * event queue, and remove it.  This is used to prevent multiple position
 * event queue, and remove it.  This is used to prevent multiple position
 * events from being delivered, thus providing a more efficient rubber-
 * events from being delivered, thus providing a more efficient rubber-
 * banding effect than if the mouse motion events were all sent.
 * banding effect than if the mouse motion events were all sent.
 */
 */
void
void
GsFreePositionEvent(GR_CLIENT *client, GR_WINDOW_ID wid, GR_WINDOW_ID subwid)
GsFreePositionEvent(GR_CLIENT *client, GR_WINDOW_ID wid, GR_WINDOW_ID subwid)
{
{
        GR_EVENT_LIST   *elp;           /* current element list */
        GR_EVENT_LIST   *elp;           /* current element list */
        GR_EVENT_LIST   *prevelp;       /* previous element list */
        GR_EVENT_LIST   *prevelp;       /* previous element list */
 
 
        prevelp = NULL;
        prevelp = NULL;
        for (elp = client->eventhead; elp; prevelp = elp, elp = elp->next) {
        for (elp = client->eventhead; elp; prevelp = elp, elp = elp->next) {
                if (elp->event.type != GR_EVENT_TYPE_MOUSE_POSITION)
                if (elp->event.type != GR_EVENT_TYPE_MOUSE_POSITION)
                        continue;
                        continue;
                if (elp->event.mouse.wid != wid)
                if (elp->event.mouse.wid != wid)
                        continue;
                        continue;
                if (elp->event.mouse.subwid != subwid)
                if (elp->event.mouse.subwid != subwid)
                        continue;
                        continue;
 
 
                /*
                /*
                 * Found one, remove it and put it back on the free list.
                 * Found one, remove it and put it back on the free list.
                 */
                 */
                if (prevelp)
                if (prevelp)
                        prevelp->next = elp->next;
                        prevelp->next = elp->next;
                else
                else
                        client->eventhead = elp->next;
                        client->eventhead = elp->next;
                if (client->eventtail == elp)
                if (client->eventtail == elp)
                        client->eventtail = prevelp;
                        client->eventtail = prevelp;
 
 
                elp->next = eventfree;
                elp->next = eventfree;
                eventfree = elp;
                eventfree = elp;
                return;
                return;
        }
        }
}
}
 
 
/*
/*
 * Deliver a "selection owner changed" event to all windows which have
 * Deliver a "selection owner changed" event to all windows which have
 * selected for it. We deliver this event to all clients which have selected
 * selected for it. We deliver this event to all clients which have selected
 * to receive GR_EVENT_TYPE_SELECTION_CHANGED events for the window of the
 * to receive GR_EVENT_TYPE_SELECTION_CHANGED events for the window of the
 * _previous_ selection owner.
 * _previous_ selection owner.
 */
 */
void GsDeliverSelectionChangedEvent(GR_WINDOW_ID old_owner,
void GsDeliverSelectionChangedEvent(GR_WINDOW_ID old_owner,
                                        GR_WINDOW_ID new_owner)
                                        GR_WINDOW_ID new_owner)
{
{
        GR_EVENT_SELECTION_CHANGED *gp;         /* selection changed event */
        GR_EVENT_SELECTION_CHANGED *gp;         /* selection changed event */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_EVENT_CLIENT         *ecp;           /* current event client */
        GR_WINDOW *wp;
        GR_WINDOW *wp;
 
 
        if(!(wp = GsFindWindow(old_owner))) return;
        if(!(wp = GsFindWindow(old_owner))) return;
 
 
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
        for (ecp = wp->eventclients; ecp; ecp = ecp->next) {
                if ((ecp->eventmask & GR_EVENT_MASK_SELECTION_CHANGED) == 0)
                if ((ecp->eventmask & GR_EVENT_MASK_SELECTION_CHANGED) == 0)
                        continue;
                        continue;
 
 
                fprintf(stderr, "Delivering a selection changed event\n");
                fprintf(stderr, "Delivering a selection changed event\n");
                gp = (GR_EVENT_SELECTION_CHANGED *) GsAllocEvent(ecp->client);
                gp = (GR_EVENT_SELECTION_CHANGED *) GsAllocEvent(ecp->client);
                if (gp == NULL)
                if (gp == NULL)
                        continue;
                        continue;
 
 
                gp->type = GR_EVENT_TYPE_SELECTION_CHANGED;
                gp->type = GR_EVENT_TYPE_SELECTION_CHANGED;
                gp->new_owner = new_owner;
                gp->new_owner = new_owner;
        }
        }
}
}
 
 
void GsDeliverTimerEvent (GR_CLIENT *client, GR_WINDOW_ID wid, GR_TIMER_ID tid)
void GsDeliverTimerEvent (GR_CLIENT *client, GR_WINDOW_ID wid, GR_TIMER_ID tid)
{
{
    GR_EVENT_TIMER    *event;           /* general event */
    GR_EVENT_TIMER    *event;           /* general event */
    GR_EVENT_CLIENT   *ecp;             /* current event client */
    GR_EVENT_CLIENT   *ecp;             /* current event client */
    GR_WINDOW         *wp;              /* current window */
    GR_WINDOW         *wp;              /* current window */
 
 
    if ((wp = GsFindWindow (wid)) == NULL)
    if ((wp = GsFindWindow (wid)) == NULL)
    {
    {
        return;
        return;
    }
    }
 
 
    for (ecp = wp->eventclients; ecp != NULL; ecp = ecp->next)
    for (ecp = wp->eventclients; ecp != NULL; ecp = ecp->next)
    {
    {
        if ((ecp->client == client) && ((ecp->eventmask & GR_EVENT_MASK_TIMER) != 0))
        if ((ecp->client == client) && ((ecp->eventmask & GR_EVENT_MASK_TIMER) != 0))
        {
        {
            event = (GR_EVENT_TIMER*) GsAllocEvent (client);
            event = (GR_EVENT_TIMER*) GsAllocEvent (client);
            if (event == NULL)
            if (event == NULL)
            {
            {
                break;
                break;
            }
            }
 
 
            event->type = GR_EVENT_TYPE_TIMER;
            event->type = GR_EVENT_TYPE_TIMER;
            event->wid  = wid;
            event->wid  = wid;
            event->tid  = tid;
            event->tid  = tid;
        }
        }
    }
    }
}
}
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.