372 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			372 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
| /************************************************************
 | |
| 
 | |
| Copyright 2003 Sun Microsystems, Inc.
 | |
| 
 | |
| All rights reserved.
 | |
| 
 | |
| Permission is hereby granted, free of charge, to any person obtaining a
 | |
| copy of this software and associated documentation files (the
 | |
| "Software"), to deal in the Software without restriction, including
 | |
| without limitation the rights to use, copy, modify, merge, publish,
 | |
| distribute, and/or sell copies of the Software, and to permit persons
 | |
| to whom the Software is furnished to do so, provided that the above
 | |
| copyright notice(s) and this permission notice appear in all copies of
 | |
| the Software and that both the above copyright notice(s) and this
 | |
| permission notice appear in supporting documentation.
 | |
| 
 | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | |
| OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 | |
| OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 | |
| HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
 | |
| INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
 | |
| FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 | |
| NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 | |
| WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | |
| 
 | |
| Except as contained in this notice, the name of a copyright holder
 | |
| shall not be used in advertising or otherwise to promote the sale, use
 | |
| or other dealings in this Software without prior written authorization
 | |
| of the copyright holder.
 | |
| 
 | |
| ************************************************************/
 | |
| 
 | |
| #define NEED_REPLIES
 | |
| #define NEED_EVENTS
 | |
| #include <X11/X.h>
 | |
| #include <X11/Xproto.h>
 | |
| #include "misc.h"
 | |
| #include "dixstruct.h"
 | |
| #include "extnsionst.h"
 | |
| #include "colormapst.h"
 | |
| #include "scrnintstr.h"
 | |
| #include "servermd.h"
 | |
| #define  _XEVIE_SERVER_
 | |
| #include <X11/extensions/Xeviestr.h>
 | |
| #include <X11/Xfuncproto.h>
 | |
| #include "input.h"
 | |
| 
 | |
| #include "../os/osdep.h"
 | |
| 
 | |
| #define NoSuchEvent 0x80000000
 | |
| 
 | |
| extern Bool noXkbExtension;
 | |
| extern int    xeviegrabState;
 | |
| 
 | |
| static int		ProcDispatch (), SProcDispatch ();
 | |
| static void		ResetProc ();
 | |
| 
 | |
| static unsigned char	ReqCode = 0;
 | |
| static int		ErrorBase;
 | |
| 
 | |
| int			xevieFlag = 0;
 | |
| int	 		xevieClientIndex = 0;
 | |
| DeviceIntPtr		xeviekb = NULL;
 | |
| DeviceIntPtr		xeviemouse = NULL;
 | |
| Mask			xevieMask = 0;
 | |
| int       		xevieEventSent = 0;
 | |
| int			xevieKBEventSent = 0;
 | |
| Mask xevieFilters[128] = 
 | |
| {
 | |
|         NoSuchEvent,                   /* 0 */
 | |
|         NoSuchEvent,                   /* 1 */
 | |
|         KeyPressMask,                  /* KeyPress */
 | |
|         KeyReleaseMask,                /* KeyRelease */
 | |
|         ButtonPressMask,               /* ButtonPress */
 | |
|         ButtonReleaseMask,             /* ButtonRelease */
 | |
|         PointerMotionMask              /* MotionNotify (initial state) */
 | |
| };
 | |
| 
 | |
| static void XevieEnd(int clientIndex);
 | |
| static void XevieClientStateCallback(CallbackListPtr *pcbl, pointer nulldata,
 | |
|                                    pointer calldata);
 | |
| static void XevieServerGrabStateCallback(CallbackListPtr *pcbl,
 | |
|                                    pointer nulldata,
 | |
|                                    pointer calldata);
 | |
| 
 | |
| void
 | |
| XevieExtensionInit ()
 | |
| {
 | |
|     ExtensionEntry* extEntry;
 | |
| 
 | |
|     if (!AddCallback(&ServerGrabCallback,XevieServerGrabStateCallback,NULL))
 | |
|        return;
 | |
| 
 | |
|     if (extEntry = AddExtension (XEVIENAME,
 | |
| 				0,
 | |
| 				XevieNumberErrors,
 | |
| 				ProcDispatch,
 | |
| 				SProcDispatch,
 | |
| 				ResetProc,
 | |
| 				StandardMinorOpcode)) {
 | |
| 	ReqCode = (unsigned char)extEntry->base;
 | |
| 	ErrorBase = extEntry->errorBase;
 | |
|     }
 | |
| 
 | |
|     /* PC servers initialize the desktop colors (citems) here! */
 | |
| }
 | |
| 
 | |
| /*ARGSUSED*/
 | |
| static 
 | |
| void ResetProc (extEntry)
 | |
|     ExtensionEntry* extEntry;
 | |
| {
 | |
| }
 | |
| 
 | |
| static 
 | |
| int ProcQueryVersion (client)
 | |
|     register ClientPtr client;
 | |
| {
 | |
|     REQUEST (xXevieQueryVersionReq);
 | |
|     xXevieQueryVersionReply rep;
 | |
|     register int n;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH (xXevieQueryVersionReq);
 | |
|     rep.type = X_Reply;
 | |
|     rep.length = 0;
 | |
|     rep.sequence_number = client->sequence;
 | |
|     rep.server_major_version = XEVIE_MAJOR_VERSION;
 | |
|     rep.server_minor_version = XEVIE_MINOR_VERSION;
 | |
|     WriteToClient (client, sizeof (xXevieQueryVersionReply), (char *)&rep);
 | |
|     return client->noClientException;
 | |
| }
 | |
| 
 | |
| static
 | |
| int ProcStart (client)
 | |
|     register ClientPtr client;
 | |
| {
 | |
|     REQUEST (xXevieStartReq);
 | |
|     xXevieStartReply rep;
 | |
|     register int n;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH (xXevieStartReq);
 | |
|     rep.pad1 = 0;
 | |
| 
 | |
|     if(!xevieFlag){
 | |
|         if (AddCallback(&ClientStateCallback,XevieClientStateCallback,NULL)) {
 | |
|            xevieFlag = 1;
 | |
|            rep.pad1 = 1;
 | |
|            xevieClientIndex = client->index;
 | |
|         } else
 | |
|            return BadAlloc;
 | |
|     } else
 | |
|         return BadAccess;
 | |
| 
 | |
|     rep.type = X_Reply;
 | |
|     rep.sequence_number = client->sequence;
 | |
|     WriteToClient (client, sizeof (xXevieStartReply), (char *)&rep);
 | |
|     return client->noClientException;
 | |
| }
 | |
| 
 | |
| static
 | |
| int ProcEnd (client)
 | |
|     register ClientPtr client;
 | |
| {
 | |
|     xXevieEndReply rep;
 | |
| 
 | |
|     XevieEnd(xevieClientIndex);
 | |
| 
 | |
|     rep.type = X_Reply;
 | |
|     rep.sequence_number = client->sequence;
 | |
|     WriteToClient (client, sizeof (xXevieEndReply), (char *)&rep);
 | |
|     return client->noClientException;
 | |
| }
 | |
| 
 | |
| static
 | |
| int ProcSend (client)
 | |
|     register ClientPtr client;
 | |
| {
 | |
|     REQUEST (xXevieSendReq);
 | |
|     xXevieSendReply rep;
 | |
|     xEvent *xE;
 | |
|     OsCommPtr oc;
 | |
|     static unsigned char lastDetail = 0, lastType = 0;
 | |
| 
 | |
|     xE = (xEvent *)&stuff->event;
 | |
|     rep.type = X_Reply;
 | |
|     rep.sequence_number = client->sequence;
 | |
|     WriteToClient (client, sizeof (xXevieSendReply), (char *)&rep);
 | |
| 
 | |
|     switch(xE->u.u.type) {
 | |
| 	case KeyPress:
 | |
|         case KeyRelease:
 | |
| 	  xevieKBEventSent = 1;
 | |
| #ifdef XKB
 | |
|           if(noXkbExtension)
 | |
| #endif
 | |
|             CoreProcessKeyboardEvent (xE, xeviekb, 1);
 | |
| 	  break;
 | |
| 	case ButtonPress:
 | |
| 	case ButtonRelease:
 | |
| 	case MotionNotify:
 | |
| 	  xevieEventSent = 1;
 | |
| 	  CoreProcessPointerEvent(xE, xeviemouse, 1); 
 | |
| 	  break; 
 | |
| 	default:
 | |
| 	  break;
 | |
|     }
 | |
|     lastType = xE->u.u.type;
 | |
|     lastDetail = xE->u.u.detail;
 | |
|     return client->noClientException;
 | |
| }
 | |
| 
 | |
| static
 | |
| int ProcSelectInput (client)
 | |
|     register ClientPtr client;
 | |
| {
 | |
|     REQUEST (xXevieSelectInputReq);
 | |
|     xXevieSelectInputReply rep;
 | |
| 
 | |
|     xevieMask = (long)stuff->event_mask;
 | |
|     rep.type = X_Reply;
 | |
|     rep.sequence_number = client->sequence;
 | |
|     WriteToClient (client, sizeof (xXevieSelectInputReply), (char *)&rep);
 | |
|     return client->noClientException;
 | |
| }
 | |
| 
 | |
| static 
 | |
| int ProcDispatch (client)
 | |
|     register ClientPtr	client;
 | |
| {
 | |
|     REQUEST (xReq);
 | |
|     switch (stuff->data)
 | |
|     {
 | |
|     case X_XevieQueryVersion:
 | |
| 	return ProcQueryVersion (client);
 | |
|     case X_XevieStart:
 | |
| 	return ProcStart (client);
 | |
|     case X_XevieEnd:
 | |
| 	return ProcEnd (client);
 | |
|     case X_XevieSend:
 | |
| 	return ProcSend (client);
 | |
|     case X_XevieSelectInput:
 | |
| 	return ProcSelectInput(client);
 | |
|     default:
 | |
| 	return BadRequest;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static 
 | |
| int SProcQueryVersion (client)
 | |
|     register ClientPtr	client;
 | |
| {
 | |
|     register int n;
 | |
| 
 | |
|     REQUEST(xXevieQueryVersionReq);
 | |
|     swaps(&stuff->length, n);
 | |
|     return ProcQueryVersion(client);
 | |
| }
 | |
| 
 | |
| static 
 | |
| int SProcStart (client)
 | |
|     ClientPtr client;
 | |
| {
 | |
|     register int n;
 | |
| 
 | |
|     REQUEST (xXevieStartReq);
 | |
|     swaps (&stuff->length, n);
 | |
|     swapl (&stuff->screen, n);
 | |
|     REQUEST_AT_LEAST_SIZE (xXevieStartReq);
 | |
|     return ProcStart (client);
 | |
| }
 | |
| 
 | |
| static 
 | |
| int SProcEnd (client)
 | |
|     ClientPtr client;
 | |
| {
 | |
|     register int n;
 | |
|     int count;
 | |
|     xColorItem* pItem;
 | |
| 
 | |
|     REQUEST (xXevieEndReq);
 | |
|     swaps (&stuff->length, n);
 | |
|     REQUEST_AT_LEAST_SIZE (xXevieEndReq);
 | |
|     swapl(&stuff->cmap, n);
 | |
|     return ProcEnd (client);
 | |
| }
 | |
| 
 | |
| static
 | |
| int SProcSend (client)
 | |
|     ClientPtr client;
 | |
| {
 | |
|     register int n;
 | |
|     int count;
 | |
| 
 | |
|     REQUEST (xXevieSendReq);
 | |
|     swaps (&stuff->length, n);
 | |
|     REQUEST_AT_LEAST_SIZE (xXevieSendReq);
 | |
|     swapl(&stuff->event, n);
 | |
|     return ProcSend (client);
 | |
| }
 | |
| 
 | |
| static
 | |
| int SProcSelectInput (client)
 | |
|     ClientPtr client;
 | |
| {
 | |
|     register int n;
 | |
|     int count;
 | |
| 
 | |
|     REQUEST (xXevieSelectInputReq);
 | |
|     swaps (&stuff->length, n);
 | |
|     REQUEST_AT_LEAST_SIZE (xXevieSendReq);
 | |
|     swapl(&stuff->event_mask, n);
 | |
|     return ProcSelectInput (client);
 | |
| }
 | |
| 
 | |
| 
 | |
| static 
 | |
| int SProcDispatch (client)
 | |
|     register ClientPtr	client;
 | |
| {
 | |
|     REQUEST(xReq);
 | |
|     switch (stuff->data)
 | |
|     {
 | |
|     case X_XevieQueryVersion:
 | |
| 	return SProcQueryVersion (client);
 | |
|     case X_XevieStart:
 | |
| 	return SProcStart (client);
 | |
|     case X_XevieEnd:
 | |
| 	return SProcEnd (client);
 | |
|     case X_XevieSend:
 | |
| 	return SProcSend (client);
 | |
|     case X_XevieSelectInput:
 | |
| 	return SProcSelectInput(client);
 | |
|     default:
 | |
| 	return BadRequest;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| XevieEnd(int clientIndex)
 | |
| {
 | |
|     if (!clientIndex || clientIndex == xevieClientIndex) {
 | |
|        xevieFlag = 0;
 | |
|        xevieClientIndex = 0;
 | |
|        DeleteCallback (&ClientStateCallback, XevieClientStateCallback, NULL);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| XevieClientStateCallback(CallbackListPtr *pcbl, pointer nulldata,
 | |
|                         pointer calldata)
 | |
| {
 | |
|     NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
 | |
|     ClientPtr client = pci->client;
 | |
|     if (client->clientState == ClientStateGone
 | |
|        || client->clientState == ClientStateRetained)
 | |
|        XevieEnd(client->index);
 | |
| }
 | |
| 
 | |
| static void
 | |
| XevieServerGrabStateCallback(CallbackListPtr *pcbl, pointer nulldata,
 | |
|                             pointer calldata)
 | |
| {
 | |
|     ServerGrabInfoRec *grbinfo = (ServerGrabInfoRec *)calldata;
 | |
|     if (grbinfo->grabstate == SERVER_GRABBED)
 | |
|        xeviegrabState = TRUE;
 | |
|     else
 | |
|        xeviegrabState = FALSE;
 | |
| }
 | |
| 
 | |
| 
 |