Add more files to branch.

This commit is contained in:
Deron 2007-06-04 20:10:38 -07:00
parent 9789f35cc5
commit fe201a8f9a
8 changed files with 2954 additions and 0 deletions

615
hw/vfb/protocol.h Normal file
View file

@ -0,0 +1,615 @@
/*****************************************************************
Copyright 2007 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.
******************************************************************/
#ifndef PROTOCOL_H
#define PROTOCOL_H
/*
** Client-to-Server Messages
*/
#define CLIENT_MESSAGE_TYPE_INVALID 0
#define CLIENT_MESSAGE_TYPE_KEY 1
#define CLIENT_MESSAGE_TYPE_POINTER 2
#define CLIENT_MESSAGE_TYPE_TAKE_CONTROL 3
#define CLIENT_MESSAGE_TYPE_SET_WINDOW_TITLES 4
#define CLIENT_MESSAGE_TYPE_MOVE_WINDOW 5
#define CLIENT_MESSAGE_TYPE_RESIZE_WINDOW 6
#define CLIENT_MESSAGE_TYPE_DESTROY_WINDOW 7
#define CLIENT_MESSAGE_TYPE_HELLO 8
typedef struct keyeventmessage_struct {
CARD8 msgType;
CARD8 isPressed;
CARD16 pad;
CARD32 keysym;
CARD32 clientId;
} KeyEventMessage;
#define KEY_EVENT_MESSAGE_SIZE sizeof(KeyEventMessage)
#define KEY_EVENT_MESSAGE_GET_ISPRESSED(pBuf) \
((KeyEventMessage*)(pBuf))->isPressed
#define KEY_EVENT_MESSAGE_GET_KEYSYM(pBuf) \
((KeyEventMessage*)(pBuf))->keysym
#define KEY_EVENT_MESSAGE_GET_CLIENTID(pBuf) \
((KeyEventMessage*)(pBuf))->clientId
typedef struct pointereventmessage_struct {
CARD8 msgType;
CARD8 mask;
CARD16 x;
CARD16 y;
CARD16 pad;
CARD32 wid;
CARD32 clientId;
} PointerEventMessage;
#define POINTER_EVENT_MESSAGE_SIZE sizeof(PointerEventMessage)
#define POINTER_EVENT_MESSAGE_GET_MASK(pBuf) \
((PointerEventMessage *)(pBuf))->mask
#define POINTER_EVENT_MESSAGE_GET_X(pBuf) \
((PointerEventMessage*)(pBuf))->x
#define POINTER_EVENT_MESSAGE_GET_Y(pBuf) \
((PointerEventMessage*)(pBuf))->y
#define POINTER_EVENT_MESSAGE_GET_WID(pBuf) \
((PointerEventMessage*)(pBuf))->wid
#define POINTER_EVENT_MESSAGE_GET_CLIENTID(pBuf) \
((PointerEventMessage*)(pBuf))->clientId
typedef struct takecontrolmessage_struct {
CARD8 msgType;
CARD8 steal;
CARD16 pad;
CARD32 clientId;
} TakeControlMessage;
#define TAKE_CONTROL_MESSAGE_SIZE sizeof(TakeControlMessage)
#define TAKE_CONTROL_MESSAGE_GET_STEAL(pBuf) \
((((TakeControlMessage*)(pBuf))->steal == 1) ? TRUE : FALSE)
#define TAKE_CONTROL_MESSAGE_GET_CLIENTID(pBuf) \
((TakeControlMessage*)(pBuf))->clientId
/* Same structure used for both server and client messages */
typedef struct setwindowtitlesmessage_struct {
CARD8 msgType;
CARD8 pad;
CARD16 strLen;
/* Followed by strLen bytes */
} SetWindowTitlesMessage;
#define SET_WINDOW_TITLES_MESSAGE_SIZE sizeof(SetWindowTitlesMessage)
#define SET_WINDOW_TITLES_MESSAGE_SET_TYPE(pBuf, mType) \
((SetWindowTitlesMessage *)(pBuf))->msgType = (mType)
#define SET_WINDOW_TITLES_MESSAGE_GET_STRLEN(pBuf) \
((((SetWindowTitlesMessage*)(pBuf))->strLen))
#define SET_WINDOW_TITLES_MESSAGE_SET_STRLEN(pBuf, len) \
((SetWindowTitlesMessage *)(pBuf))->strLen = (len)
/* Same structure used for both server and client messages */
typedef struct movewindowmessage_struct {
CARD8 msgType;
CARD8 pad;
CARD16 x;
CARD32 clientId;
CARD32 wid;
CARD16 y;
} MoveWindowMessage;
#define MOVE_WINDOW_MESSAGE_SIZE sizeof(MoveWindowMessage)
#define MOVE_WINDOW_MESSAGE_SET_TYPE(pBuf, mType) \
((MoveWindowMessage *)(pBuf))->msgType = (mType)
#define MOVE_WINDOW_MESSAGE_GET_X(pBuf) \
((((MoveWindowMessage*)(pBuf))->x))
#define MOVE_WINDOW_MESSAGE_SET_X(pBuf, xval) \
((MoveWindowMessage *)(pBuf))->x = (xval)
#define MOVE_WINDOW_MESSAGE_GET_CLIENT_ID(pBuf) \
((((MoveWindowMessage*)(pBuf))->clientId))
#define MOVE_WINDOW_MESSAGE_SET_CLIENT_ID(pBuf, cid) \
((MoveWindowMessage *)(pBuf))->clientId = (cid)
#define MOVE_WINDOW_MESSAGE_GET_WID(pBuf) \
((((MoveWindowMessage*)(pBuf))->wid))
#define MOVE_WINDOW_MESSAGE_SET_WID(pBuf, widval) \
((MoveWindowMessage *)(pBuf))->wid = (widval)
#define MOVE_WINDOW_MESSAGE_GET_Y(pBuf) \
((((MoveWindowMessage*)(pBuf))->y))
#define MOVE_WINDOW_MESSAGE_SET_Y(pBuf, yval) \
((MoveWindowMessage *)(pBuf))->y = (yval)
/* Same structure used for both server and client messages */
typedef struct resizewindowmessage_struct {
CARD8 msgType;
CARD8 pad1;
CARD16 pad2;
CARD32 clientId;
CARD32 wid;
CARD32 width;
CARD32 height;
} ResizeWindowMessage;
#define RESIZE_WINDOW_MESSAGE_SIZE sizeof(ResizeWindowMessage)
#define RESIZE_WINDOW_MESSAGE_SET_TYPE(pBuf, mType) \
((ResizeWindowMessage *)(pBuf))->msgType = (mType)
#define RESIZE_WINDOW_MESSAGE_GET_CLIENT_ID(pBuf) \
((((ResizeWindowMessage*)(pBuf))->clientId))
#define RESIZE_WINDOW_MESSAGE_SET_CLIENT_ID(pBuf, cid) \
((ResizeWindowMessage *)(pBuf))->CLIENT_ID = (cid)
#define RESIZE_WINDOW_MESSAGE_GET_WID(pBuf) \
((((ResizeWindowMessage*)(pBuf))->wid))
#define RESIZE_WINDOW_MESSAGE_SET_WID(pBuf, widval) \
((ResizeWindowMessage *)(pBuf))->wid = (widval)
#define RESIZE_WINDOW_MESSAGE_GET_WIDTH(pBuf) \
((((ResizeWindowMessage*)(pBuf))->width))
#define RESIZE_WINDOW_MESSAGE_SET_WIDTH(pBuf, w) \
((ResizeWindowMessage *)(pBuf))->width = (w)
#define RESIZE_WINDOW_MESSAGE_GET_HEIGHT(pBuf) \
((((ResizeWindowMessage*)(pBuf))->height))
#define RESIZE_WINDOW_MESSAGE_SET_HEIGHT(pBuf, h) \
((ResizeWindowMessage *)(pBuf))->height = (h)
typedef struct hellomessage_struct {
CARD8 msgType;
} HelloMessage;
#define MOVE_WINDOW_MESSAGE_SIZE sizeof(MoveWindowMessage)
/*
** Server to Client Messages
*/
#define SERVER_MESSAGE_TYPE_CREATE_WINDOW 0
#define SERVER_MESSAGE_TYPE_DESTROY_WINDOW 1
#define SERVER_MESSAGE_TYPE_SHOW_WINDOW 2
#define SERVER_MESSAGE_TYPE_CONFIGURE_WINDOW 3
#define SERVER_MESSAGE_TYPE_POSITION_WINDOW 4
#define SERVER_MESSAGE_TYPE_WINDOW_SET_DECORATED 5
#define SERVER_MESSAGE_TYPE_WINDOW_SET_BORDER_WIDTH 6
#define SERVER_MESSAGE_TYPE_BEEP 7
#define SERVER_MESSAGE_TYPE_DISPLAY_PIXELS 8
#define SERVER_MESSAGE_TYPE_COPY_AREA 9
#define SERVER_MESSAGE_TYPE_CONTROLLER_STATUS 10
#define SERVER_MESSAGE_TYPE_DISPLAY_CURSOR 11
#define SERVER_MESSAGE_TYPE_MOVE_CURSOR 12
#define SERVER_MESSAGE_TYPE_SHOW_CURSOR 13
#define SERVER_MESSAGE_TYPE_SET_WINDOW_TITLES 14
#define SERVER_MESSAGE_TYPE_WELCOME 15
#define SERVER_MESSAGE_TYPE_PING 16
typedef struct {
CARD8 msgType;
CARD8 decorated;
CARD16 borderWidth;
CARD32 wid;
CARD16 x;
CARD16 y;
CARD32 wAndBorder; /* Includes 2 * bw */
CARD32 hAndBorder; /* Includes 2 * bw */
} CreateWindowMessage;
#define CREATE_WINDOW_MESSAGE_SIZE sizeof(CreateWindowMessage)
#define CREATE_WINDOW_MESSAGE_SET_TYPE(pBuf, mType) \
((CreateWindowMessage *)(pBuf))->msgType = (mType)
#define CREATE_WINDOW_MESSAGE_SET_DECORATED(pBuf, decor) \
((CreateWindowMessage *)(pBuf))->decorated = (decor)
#define CREATE_WINDOW_MESSAGE_SET_BORDER_WIDTH(pBuf, bw) \
((CreateWindowMessage *)(pBuf))->borderWidth = (bw)
#define CREATE_WINDOW_MESSAGE_SET_WID(pBuf, windowId) \
((CreateWindowMessage *)(pBuf))->wid = (windowId)
#define CREATE_WINDOW_MESSAGE_SET_X(pBuf, xval) \
((CreateWindowMessage *)(pBuf))->x = (xval)
#define CREATE_WINDOW_MESSAGE_SET_Y(pBuf, yval) \
((CreateWindowMessage *)(pBuf))->y = (yval)
#define CREATE_WINDOW_MESSAGE_SET_WANDBORDER(pBuf, wandb) \
((CreateWindowMessage *)(pBuf))->wAndBorder = (wandb)
#define CREATE_WINDOW_MESSAGE_SET_HANDBORDER(pBuf, handb) \
((CreateWindowMessage *)(pBuf))->hAndBorder = (handb)
/* Same structure used for both server and client messages */
typedef struct {
CARD8 msgType;
CARD8 pad1;
CARD16 pad2;
CARD32 wid;
} DestroyWindowMessage;
#define DESTROY_WINDOW_MESSAGE_SIZE sizeof(DestroyWindowMessage)
#define DESTROY_WINDOW_MESSAGE_SET_TYPE(pBuf, mType) \
((DestroyWindowMessage *)(pBuf))->msgType = (mType)
#define DESTROY_WINDOW_MESSAGE_GET_WID(pBuf) \
((((DestroyWindowMessage*)(pBuf))->wid))
#define DESTROY_WINDOW_MESSAGE_SET_WID(pBuf, windowId) \
((DestroyWindowMessage *)(pBuf))->wid = (windowId)
typedef struct {
CARD8 msgType;
CARD8 show;
CARD16 pad;
CARD32 wid;
} ShowWindowMessage;
#define SHOW_WINDOW_MESSAGE_SIZE sizeof(ShowWindowMessage)
#define SHOW_WINDOW_MESSAGE_SET_TYPE(pBuf, mType) \
((ShowWindowMessage *)(pBuf))->msgType = (mType)
#define SHOW_WINDOW_MESSAGE_SET_WID(pBuf, windowId) \
((ShowWindowMessage *)(pBuf))->wid = (windowId)
#define SHOW_WINDOW_MESSAGE_SET_SHOW(pBuf, showit) \
((ShowWindowMessage *)(pBuf))->show = (showit)
typedef struct {
CARD8 msgType;
CARD8 pad1;
CARD16 pad2;
CARD32 clientId;
CARD32 wid;
CARD16 x;
CARD16 y;
CARD32 wAndBorder; /* Includes 2 * bw */
CARD32 hAndBorder; /* Includes 2 * bw */
CARD32 sibid;
} ConfigureWindowMessage;
#define CONFIGURE_WINDOW_MESSAGE_SIZE sizeof(ConfigureWindowMessage)
#define CONFIGURE_WINDOW_MESSAGE_SET_TYPE(pBuf, mType) \
((ConfigureWindowMessage *)(pBuf))->msgType = (mType)
#define CONFIGURE_WINDOW_MESSAGE_SET_CLIENT_ID(pBuf, cid) \
((ConfigureWindowMessage *)(pBuf))->clientId = (clientId)
#define CONFIGURE_WINDOW_MESSAGE_SET_WID(pBuf, windowId) \
((ConfigureWindowMessage *)(pBuf))->wid = (windowId)
#define CONFIGURE_WINDOW_MESSAGE_SET_X(pBuf, xval) \
((ConfigureWindowMessage *)(pBuf))->x = (xval)
#define CONFIGURE_WINDOW_MESSAGE_SET_Y(pBuf, yval) \
((ConfigureWindowMessage *)(pBuf))->y = (yval)
#define CONFIGURE_WINDOW_MESSAGE_SET_WANDBORDER(pBuf, wandb) \
((ConfigureWindowMessage *)(pBuf))->wAndBorder = (wandb)
#define CONFIGURE_WINDOW_MESSAGE_SET_HANDBORDER(pBuf, handb) \
((ConfigureWindowMessage *)(pBuf))->hAndBorder = (handb)
#define CONFIGURE_WINDOW_MESSAGE_SET_SIBID(pBuf, siblingId) \
((ConfigureWindowMessage *)(pBuf))->sibid = (siblingId)
typedef struct {
CARD8 msgType;
CARD8 pad1;
CARD16 pad2;
CARD32 clientId;
CARD32 wid;
CARD16 x;
CARD16 y;
} PositionWindowMessage;
#define POSITION_WINDOW_MESSAGE_SIZE sizeof(PositionWindowMessage)
#define POSITION_WINDOW_MESSAGE_SET_TYPE(pBuf, mType) \
((PositionWindowMessage *)(pBuf))->msgType = (mType)
#define POSITION_WINDOW_MESSAGE_SET_CLIENT_ID(pBuf, cid) \
((PositionWindowMessage *)(pBuf))->clientId = (clientId)
#define POSITION_WINDOW_MESSAGE_SET_WID(pBuf, windowId) \
((PositionWindowMessage *)(pBuf))->wid = (windowId)
#define POSITION_WINDOW_MESSAGE_SET_X(pBuf, xval) \
((PositionWindowMessage *)(pBuf))->x = (xval)
#define POSITION_WINDOW_MESSAGE_SET_Y(pBuf, yval) \
((PositionWindowMessage *)(pBuf))->y = (yval)
typedef struct {
CARD8 msgType;
CARD8 decorated;
CARD16 pad;
CARD32 wid;
} WindowSetDecoratedMessage;
#define WINDOW_SET_DECORATED_MESSAGE_SIZE sizeof(WindowSetDecoratedMessage)
#define WINDOW_SET_DECORATED_MESSAGE_SET_TYPE(pBuf, mType) \
((WindowSetDecoratedMessage *)(pBuf))->msgType = (mType)
#define WINDOW_SET_DECORATED_MESSAGE_SET_DECORATED(pBuf, decor) \
((WindowSetDecoratedMessage *)(pBuf))->decorated = (decor)
#define WINDOW_SET_DECORATED_MESSAGE_SET_WID(pBuf, windowId) \
((WindowSetDecoratedMessage *)(pBuf))->wid = (windowId)
typedef struct {
CARD8 msgType;
CARD8 pad;
CARD16 borderWidth;
CARD32 wid;
} WindowSetBorderWidthMessage;
#define WINDOW_SET_BORDER_WIDTH_MESSAGE_SIZE sizeof(WindowSetBorderWidthMessage)
#define WINDOW_SET_BORDER_WIDTH_MESSAGE_SET_TYPE(pBuf, mType) \
((WindowSetBorderWidthMessage *)(pBuf))->msgType = (mType)
#define WINDOW_SET_BORDER_WIDTH_MESSAGE_SET_BORDER_WIDTH(pBuf, bw) \
((WindowSetBorderWidthMessage *)(pBuf))->borderWidth = (bw)
#define WINDOW_SET_BORDER_WIDTH_MESSAGE_SET_WID(pBuf, windowId) \
((WindowSetBorderWidthMessage *)(pBuf))->wid = (windowId)
typedef struct {
CARD8 msgType;
} BeepMessage;
#define BEEP_MESSAGE_SIZE sizeof(BeepMessage)
#define BEEP_MESSAGE_SET_TYPE(pBuf, mType) \
((BeepMessage *)(pBuf))->msgType = (mType)
#define DISPLAY_PIXELS_ENCODING_UNCODED 0
#define DISPLAY_PIXELS_ENCODING_RLE24 1
/*
** Note: Don't use xRectangle because x and y are constrained
** to fit in shorts because they are clipped to the screen.
*/
typedef struct {
CARD16 x;
CARD16 y;
CARD16 width;
CARD16 height;
/* How pixels which follow are encoded */
CARD32 encodingType;
} DirtyAreaRectRec, *DirtyAreaRectPtr;
#define DIRTY_AREA_RECT_SIZE sizeof(DirtyAreaRectRec)
typedef struct {
CARD8 msgType;
CARD8 pad;
CARD16 numDirty;
CARD32 wid;
} DisplayPixelsMessage;
#define DISPLAY_PIXELS_MESSAGE_SIZE sizeof(DisplayPixelsMessage)
#define DISPLAY_PIXELS_MESSAGE_SET_TYPE(pBuf, mType) \
((DisplayPixelsMessage *)(pBuf))->msgType = (mType)
#define DISPLAY_PIXELS_MESSAGE_SET_NUM_DIRTY(pBuf, n) \
((DisplayPixelsMessage *)(pBuf))->numDirty = (n)
#define DISPLAY_PIXELS_MESSAGE_SET_WID(pBuf, windowId) \
((DisplayPixelsMessage *)(pBuf))->wid = (windowId)
typedef struct {
CARD8 msgType;
CARD8 pad1;
CARD16 pad2;
CARD32 wid;
CARD32 srcx;
CARD32 srcy;
CARD32 width;
CARD32 height;
CARD32 dstx;
CARD32 dsty;
} CopyAreaMessage;
#define COPY_AREA_MESSAGE_SIZE sizeof(CopyAreaMessage)
#define COPY_AREA_MESSAGE_SET_TYPE(pBuf, mType) \
((CopyAreaMessage *)(pBuf))->msgType = (mType)
#define COPY_AREA_MESSAGE_SET_WID(pBuf, windowId) \
((CopyAreaMessage *)(pBuf))->wid = (windowId)
#define COPY_AREA_MESSAGE_SET_SRCX(pBuf, sx) \
((CopyAreaMessage *)(pBuf))->srcx = (sx)
#define COPY_AREA_MESSAGE_SET_SRCY(pBuf, sy) \
((CopyAreaMessage *)(pBuf))->srcy = (sy)
#define COPY_AREA_MESSAGE_SET_WIDTH(pBuf, w) \
((CopyAreaMessage *)(pBuf))->width = (w)
#define COPY_AREA_MESSAGE_SET_HEIGHT(pBuf, h) \
((CopyAreaMessage *)(pBuf))->height = (h)
#define COPY_AREA_MESSAGE_SET_DSTX(pBuf, dx) \
((CopyAreaMessage *)(pBuf))->dstx = (dx)
#define COPY_AREA_MESSAGE_SET_DSTY(pBuf, dy) \
((CopyAreaMessage *)(pBuf))->dsty = (dy)
typedef struct controllerstatusmessage_struct {
CARD8 msgType;
CARD8 status;
CARD16 pad;
CARD32 clientId;
} ControllerStatusMessage;
/* The attempt of the specified client to take control has been refused */
#define CONTROLLER_STATUS_REFUSED 0
/* The specified client has lost control */
#define CONTROLLER_STATUS_LOST 1
/* The specified client has gained control */
#define CONTROLLER_STATUS_GAINED 2
#define CONTROLLER_STATUS_MESSAGE_SIZE sizeof(ControllerStatusMessage)
#define CONTROLLER_STATUS_MESSAGE_SET_TYPE(pBuf, mType) \
((ControllerStatusMessage *)(pBuf))->msgType = (mType)
#define CONTROLLER_STATUS_MESSAGE_SET_STATUS(pBuf, stat) \
((ControllerStatusMessage*)(pBuf))->status = (stat)
#define CONTROLLER_STATUS_MESSAGE_SET_CLIENTID(pBuf, cid) \
((ControllerStatusMessage*)(pBuf))->clientId = (cid)
typedef struct displaycursormessage_struct {
CARD8 msgType;
CARD8 pad1;
CARD16 pad2;
CARD16 width;
CARD16 height;
CARD16 xhot;
CARD16 yhot;
/* Followed by (width * height) 32-bit pixels */
} DisplayCursorMessage;
#define DISPLAY_CURSOR_MESSAGE_SIZE sizeof(DisplayCursorMessage)
#define DISPLAY_CURSOR_MESSAGE_SET_TYPE(pBuf, mType) \
((DisplayCursorMessage *)(pBuf))->msgType = (mType)
#define DISPLAY_CURSOR_MESSAGE_SET_WIDTH(pBuf, w) \
((DisplayCursorMessage *)(pBuf))->width = (w)
#define DISPLAY_CURSOR_MESSAGE_SET_HEIGHT(pBuf, h) \
((DisplayCursorMessage *)(pBuf))->height = (h)
#define DISPLAY_CURSOR_MESSAGE_SET_XHOT(pBuf, xh) \
((DisplayCursorMessage *)(pBuf))->xhot = (xh)
#define DISPLAY_CURSOR_MESSAGE_SET_YHOT(pBuf, yh) \
((DisplayCursorMessage *)(pBuf))->yhot = (yh)
typedef struct movecursormessage_struct {
CARD8 msgType;
CARD8 pad1;
CARD16 pad2;
CARD32 wid;
CARD32 x;
CARD32 y;
} MoveCursorMessage;
#define MOVE_CURSOR_MESSAGE_SIZE sizeof(MoveCursorMessage)
#define MOVE_CURSOR_MESSAGE_SET_TYPE(pBuf, mType) \
((MoveCursorMessage *)(pBuf))->msgType = (mType)
#define MOVE_CURSOR_MESSAGE_SET_WID(pBuf, windowId) \
((MoveCursorMessage *)(pBuf))->wid = (windowId)
#define MOVE_CURSOR_MESSAGE_SET_X(pBuf, cx) \
((MoveCursorMessage *)(pBuf))->x = (cx)
#define MOVE_CURSOR_MESSAGE_SET_Y(pBuf, cy) \
((MoveCursorMessage *)(pBuf))->y = (cy)
typedef struct showcursormessage_struct {
CARD8 msgType;
CARD8 show;
} ShowCursorMessage;
#define SHOW_CURSOR_MESSAGE_SIZE sizeof(ShowCursorMessage)
#define SHOW_CURSOR_MESSAGE_SET_TYPE(pBuf, mType) \
((ShowCursorMessage *)(pBuf))->msgType = (mType)
#define SHOW_CURSOR_MESSAGE_SET_SHOW(pBuf, showit) \
((ShowCursorMessage *)(pBuf))->show = (showit)
typedef struct welcomessage_struct {
CARD8 msgType;
CARD8 pad1;
CARD16 pad2;
CARD32 clientId;
} WelcomeMessage;
#define WELCOME_MESSAGE_SIZE sizeof(WelcomeMessage)
#define WELCOME_MESSAGE_SET_TYPE(pBuf, mType) \
((WelcomeMessage *)(pBuf))->msgType = (mType)
#define WELCOME_MESSAGE_SET_CLIENT_ID(pBuf, cid) \
((WelcomeMessage *)(pBuf))->clientId = (cid)
#endif /* PROTOCOL_H */

190
hw/vfb/remwin.h Normal file
View file

@ -0,0 +1,190 @@
/*****************************************************************
Copyright 2007 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.
******************************************************************/
#ifndef REMWIN_H
#define REMWIN_H
#include "scrnintstr.h"
#include "regionstr.h"
#include "rwcomm.h"
#include "gcstruct.h"
/* Don't send any pixel buffers larger than 16KB */
#define PIXEL_BUF_MAX_NUM_BYTES (1024*16)
#define PIXEL_BUF_MAX_NUM_PIXELS (PIXEL_BUF_MAX_NUM_BYTES/4)
/*
** The RLE algorithm used never creates more pixels than
** is in the original buffer, so the max number of pixels
** provides an upper bound on the maximum number of runs.
*/
#define RLE_BUF_MAX_NUM_BYTES PIXEL_BUF_MAX_NUM_BYTES
#define RLE_BUF_MAX_NUM_PIXELS (RLE_BUF_MAX_NUM_BYTES/4)
typedef struct remwin_scr_priv_rec {
RwcommPtr pComm;
OsTimerPtr outputTimer;
CloseScreenProcPtr CloseScreen;
ScreenWakeupHandlerProcPtr WakeupHandler;
CreateWindowProcPtr CreateWindow;
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
DestroyWindowProcPtr DestroyWindow;
PositionWindowProcPtr PositionWindow;
ResizeWindowProcPtr ResizeWindow;
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
CreateGCProcPtr CreateGC;
DisplayCursorProcPtr DisplayCursor;
SetCursorPositionProcPtr SetCursorPosition;
unsigned char *pPixelBuf;
unsigned char *pRleBuf;
/* List of managed o(top-level, drawable) windows */
WindowPtr pManagedWindows;
/*
** Which client currently has interactive control.
** -1 indicates no one has control.
*/
int controller;
/* Which pointer buttons the controller has pressed */
int controllerButtonMask;
/* The currently displayed cursor */
CursorPtr pCursor;
/*
** The managed window the cursor is in.
** NULL if cursor isn't shown
*/
WindowPtr pCursorWin;
/* The cursor position (relative to pCursorWin) */
int cursorX;
int cursorY;
/* The window manager client */
ClientPtr pWmClient;
/*
** When this is -1 window moves and resizes are programmatic.
** (i.e. invoked by the application). When this is not -1
** window moves and resizes are being made by the user.
*/
int configuringClient;
/* True when any windows may have unsent dirty pixels */
Bool windowsAreDirty;
} RemwinScreenPrivRec, *RemwinScreenPrivPtr;
#define REMWIN_GET_SCRPRIV(pScreen) \
((RemwinScreenPrivPtr)((pScreen)->devPrivates[remwinScreenIndex].ptr))
#define REMWIN_GET_WINPRIV(pWin) \
((RemwinWindowPrivPtr)(pWin)->devPrivates[remwinWinIndex].ptr);
/* DELETE: no longer used
#define REMWIN_SET_WINPRIV(pWin, pWinPriv) \
(pWin)->devPrivates[remwinWinIndex].ptr = (pointer)pWinPriv;
*/
typedef struct remwin_window_priv_rec *RemwinWindowPrivPtr;
typedef struct remwin_window_priv_rec {
/*
** The window has been dirtied. That is, there are updates to send
** to the client. (One or both of the regions has been updated).
*/
Bool dirty;
/* Whether the window has been mapped */
Bool mapped;
/* The area of the window that has been dirtied */
RegionRec dirtyReg;
/* The link to the next window (not winpriv!) */
WindowPtr pWinNext;
} RemwinWindowPrivRec;
#define REMWIN_GET_GCPRIV(pGC) \
((RemwinGCPrivPtr)(pGC)->devPrivates[remwinGCIndex].ptr);
/* DELETE: no longer used
#define REMWIN_SET_GCPRIV(pGC, pGCPriv) \
(pWin)->devPrivates[remwinGCIndex].ptr = (pointer)pGCPriv;
*/
typedef struct remwin_gc_priv_rec *RemwinGCPrivPtr;
typedef struct remwin_gc_priv_rec {
GCOps *wrapOps; /* wrapped ops */
GCFuncs *wrapFuncs; /* wrapped funcs */
} RemwinGCPrivRec;
extern RemwinScreenPrivRec remwinScreenPriv;
extern void rwoutTimerCreate (ScreenPtr pScreen);
extern void rwoutTimerDestroy (ScreenPtr pScreen);
extern void rwinHandler (ScreenPtr pScreen);
/* Maximum pixel output rate is 30 fps */
#define MAX_OUTPUT_RATE 30.0
#define TIMER_MS ((int)((1/MAX_OUTPUT_RATE) * 1000.0))
extern Bool rwoutInitScreen (ScreenPtr pScreen);
extern void rwTakeControlInit (ScreenPtr pScreen);
extern void rwTakeControl (ScreenPtr pScreen, int clientId, Bool steal);
extern int remwinScreenIndex;
extern Bool rwoutSetWindowTitlesWrite (ScreenPtr pScreen, int strLen, char *buf);
extern void rwoutBeep (int percent, DeviceIntPtr pDevice,
pointer ctrl, int unused);
extern void rwoutSyncClientOnConnect (ScreenPtr pScreen, RwcommClientPtr pCommClient);
extern Bool rlePixelsWrite (ScreenPtr pScreen, WindowPtr pWin, int x, int y, int w, int h);
extern Bool vfbRemoteWindow;
#endif /* REMWIN_H */

235
hw/vfb/rle.c Normal file
View file

@ -0,0 +1,235 @@
#undef VERBOSE
/*****************************************************************
Copyright 2007 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.
******************************************************************/
/* TODO: prune these */
#include <unistd.h>
#include "regionstr.h"
#include "damage.h"
#include "windowstr.h"
#include "remwin.h"
#include "rwcomm.h"
#include "misc.h"
#include "protocol.h"
#include "cursorstr.h"
#include "servermd.h"
#include "rwcommsock.h"
extern Bool rwRleVerifyPixels;
#define RGB_MASK 0x00ffffff
#define ROUNDUP(fval) (int)((fval)+1)
#define MIN(a, b) (((a)>(b))?(b):(a))
#define MAX_COUNT 255
#define NEXT_PIXEL(pixel) { \
if (linesLeftInChunk <= 0) { \
/* End of chunk */ \
(pixel) = -1; \
/*ErrorF("y,x,ll at end of chunk = %d, %d, %d\n", y, x, linesLeftInChunk);*/ \
} else {\
(pixel) = *(pPixel++) & RGB_MASK; \
/* Advance pointers */ \
if (++x >= xLimit) { \
y++; \
linesLeftInChunk--; \
pLine += w; \
pPixel = pLine; \
x = xStart;\
} \
} \
}
#ifdef VERBOSE
static int maxVerboseRuns = 120;
static int numRunsOutput = 0;
#define OUTPUT_PIXEL(count, pixel) { \
/* \
if (numRunsOutput++ < maxVerboseRuns) { \
ErrorF("numRuns = %d, count = %d, pixel = 0x%x\n", numRunsOutput, count, pixel); \
} \
*/ \
if (pDst >= pDstLimit) { \
FatalError("Buffer overflow, pDst = 0x%x, 0x%x\n", (int)pDst, (int)pDstLimit); \
} \
*pDst++ = ((count) << 24) | (pixel); \
bytesInChunk += 4; \
}
#else
#define OUTPUT_PIXEL(count, pixel) { \
*pDst++ = ((count) << 24) | (pixel); \
bytesInChunk += 4; \
}
#endif /* VERBOSE */
Bool
rlePixelsWrite (ScreenPtr pScreen, WindowPtr pWin, int x, int y, int w, int h)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
RwcommPtr pComm = pScrPriv->pComm;
char buf[DIRTY_AREA_RECT_SIZE];
DirtyAreaRectPtr pDirty = (DirtyAreaRectPtr) &buf[0];
int *pSrc, *pDst, *pLine, *pPixel, *pChunkHeight, *pNumOutBytes;
int linesLeft, xStart, xLimit, chunkHeight;
int numChunks, linesLeftInChunk;
int count, a, b;
int bytesInChunk;
int i, n;
/* TODO: for debug */
int *pDstLimit;
chunkHeight = RLE_BUF_MAX_NUM_PIXELS / w;
numChunks = ROUNDUP((float)h / chunkHeight);
#ifdef VERBOSE
ErrorF("chunkHeight = %d\n", chunkHeight);
ErrorF("numChunks = %d\n", numChunks);
#endif /* VERBOSE */
/* Prepare rectangle description */
pDirty->x = x;
pDirty->y = y;
pDirty->width = w;
/* TODO: HACK: notify the client of verification via negative numChunks */
if (rwRleVerifyPixels) {
pDirty->height = -numChunks;
} else {
pDirty->height = numChunks;
}
pDirty->encodingType = DISPLAY_PIXELS_ENCODING_RLE24;
#ifdef VERBOSE
ErrorF("x = %d\n", x);
ErrorF("y = %d\n", y);
ErrorF("y = %d\n", h);
ErrorF("w = %d\n", w);
#endif /* VERBOSE */
swaps(&pDirty->x, n);
swaps(&pDirty->y, n);
swaps(&pDirty->width, n);
swaps(&pDirty->height, n);
swapl(&pDirty->encodingType, a);
/* Send it off */
if (!RWCOMM_BUFFER_WRITE(pComm, buf, DIRTY_AREA_RECT_SIZE)) {
return FALSE;
}
/* Lazy allocation of pixel buffer*/
if (pScrPriv->pPixelBuf == NULL) {
pScrPriv->pPixelBuf = (unsigned char *)
xalloc(PIXEL_BUF_MAX_NUM_BYTES);
}
pSrc = (int *) pScrPriv->pPixelBuf;
/* Lazy allocation of rle output buffer*/
if (pScrPriv->pRleBuf == NULL) {
pScrPriv->pRleBuf = (unsigned char *)
xalloc(RLE_BUF_MAX_NUM_BYTES + 10);
}
linesLeft = h;
xStart = x;
xLimit = x + w;
pChunkHeight = (int *) buf;
for (i = 0; i < numChunks; i++) {
/* ErrorF("Filling chunk %d\n", i); */
/* This is a fresh chunk; start at the beginning of the buffer */
pDst = (int *) pScrPriv->pRleBuf;
pDstLimit = (int *) ((char *)pDst + RLE_BUF_MAX_NUM_BYTES + 10);
/* Clamp chunk height and send it */
chunkHeight = MIN(linesLeft, chunkHeight);
*pChunkHeight = chunkHeight;
swapl(pChunkHeight, n);
if (!RWCOMM_BUFFER_WRITE(pComm, buf, 4)) {
return FALSE;
}
/* Fetch chunk from frame buffer */
(*pScreen->GetImage)((DrawablePtr)pWin, x, y, w, chunkHeight,
ZPixmap, ~0, (char *) pSrc);
pLine = pSrc;
pPixel = pLine;
linesLeftInChunk = chunkHeight;
bytesInChunk = 0;
count = 1;
NEXT_PIXEL(a);
NEXT_PIXEL(b);
while (b >= 0) {
if (a == b) {
if (count == MAX_COUNT) {
OUTPUT_PIXEL(count, a);
count = 1;
} else {
count++;
}
} else {
OUTPUT_PIXEL(count, a);
a = b;
count = 1;
}
NEXT_PIXEL(b);
}
OUTPUT_PIXEL(count, a);
/*
** Now send the number of bytes in the chunk followed by
** the chunk data.
*/
pNumOutBytes = (int *) buf;
*pNumOutBytes = bytesInChunk;
swapl(pNumOutBytes, n);
if (!RWCOMM_BUFFER_WRITE(pComm, buf, 4)) {
return FALSE;
}
if (!RWCOMM_BUFFER_WRITE(pComm, (char *)pScrPriv->pRleBuf, bytesInChunk)) {
return FALSE;
}
linesLeft -= chunkHeight;
}
return TRUE;
}

98
hw/vfb/rwcomm.h Normal file
View file

@ -0,0 +1,98 @@
/*****************************************************************
Copyright 2007 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.
******************************************************************/
#ifndef RWCOMM_H
#define RWCOMM_H
#define RWCOMM_DESTROY(pComm) \
(pComm)->funcs.destroy(pComm)
#define RWCOMM_CONNECT(pComm) \
(pComm)->funcs.connect(pComm)
#define RWCOMM_DISCONNECT(pComm) \
(pComm)->funcs.disconnect(pComm)
#define RWCOMM_IS_CONNECTED(pComm) \
(pComm)->funcs.isConnected(pComm)
#define RWCOMM_BUFFER_WRITE(pComm, pBuf, bufLen) \
(pComm)->funcs.bufferWrite((pComm), (pBuf), (bufLen))
#define RWCOMM_BUFFER_WRITE_TO_CLIENT(pComm, clientId, pBuf, bufLen) \
(pComm)->funcs.bufferWriteToClient((pComm), (clientId), (pBuf), (bufLen))
#define RWCOMM_NEXT_MESSAGE_TYPE_READ(pComm) \
(pComm)->funcs.nextMessageTypeRead(pComm)
#define RWCOMM_NEXT_MESSAGE_BUFFER_READ(pComm, buf, readLen) \
(pComm)->funcs.nextMessageBufferRead((pComm), (buf), (readLen))
#define RWCOMM_CLIENT_MESSAGE_POLL(pComm, pReadMask) \
(pComm)->funcs.clientMessagePoll((pComm), (pReadmask))
typedef struct rwcomm_rec *RwcommPtr;
typedef void (*RwcommFuncPtrDestroy)(RwcommPtr pComm);
typedef void (*RwcommFuncPtrConnect)(RwcommPtr pComm);
typedef void (*RwcommFuncPtrDisconnect)(RwcommPtr pComm);
typedef Bool (*RwcommFuncPtrIsConnected)(RwcommPtr pComm);
typedef Bool (*RwcommFuncPtrBufferWrite)(RwcommPtr pComm,
char *buf, int bufLen);
typedef Bool (*RwcommFuncPtrBufferWriteToClient)(RwcommPtr pComm,
int clientId, char *buf, int bufLen);
typedef int (*RwcommFuncPtrNextMessageTypeRead)(RwcommPtr pComm);
typedef int (*RwcommFuncPtrNextMessageBufferRead)(RwcommPtr pComm,
char *buf, int readLen);
typedef void (*RwcommFuncPtrClientMessagePoll)(RwcommPtr pComm, fd_set *pReadMask);
typedef struct rwcomm_funcptr_rec {
RwcommFuncPtrDestroy destroy;
RwcommFuncPtrConnect connect;
RwcommFuncPtrDisconnect disconnect;
RwcommFuncPtrIsConnected isConnected;
RwcommFuncPtrBufferWrite bufferWrite;
RwcommFuncPtrBufferWriteToClient bufferWriteToClient;
RwcommFuncPtrNextMessageTypeRead nextMessageTypeRead;
RwcommFuncPtrNextMessageBufferRead nextMessageBufferRead;
RwcommFuncPtrClientMessagePoll clientMessagePoll;
} RwcommFuncPtrRec, *RwcommFuncPtrPtr;
typedef struct rwcomm_rec {
RwcommFuncPtrRec funcs;
} RwcommRec;
typedef pointer RwcommClientPtr;
#endif /* RWCOMM_H */

457
hw/vfb/rwcommsock.c Normal file
View file

@ -0,0 +1,457 @@
#undef VERBOSE
/*****************************************************************
Copyright 2007 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.
******************************************************************/
#include <unistd.h>
#include <errno.h>
#include <X11/Xproto.h>
#include "dix-config.h"
#include "remwin.h"
#include "rwcomm.h"
#include "rwcommsock.h"
#include "protocol.h"
#include "opaque.h"
#include <arpa/inet.h>
#include <fcntl.h>
static void rwcommsockDisconnect (RwcommPtr pComm);
static int WriteFully (int sock, char *pbuf, int bufLen);
static int ReadFully (int sock, char *pbuf, int bufLen);
/*
** Disconnect all activate connections and free the comm module.
*/
static void
rwcommsockDestroy (RwcommPtr pComm)
{
rwcommsockDisconnect(pComm);
xfree(pComm);
}
/* TODO: notyet
static Bool firstClient = TRUE;
*/
/*
** Called when a new client connection is received.
*/
static void
rwcommsockConnect (RwcommPtr pComm)
{
RwcommsockPtr pCommsock = (RwcommsockPtr) pComm;
ScreenPtr pScreen = pCommsock->pScreen;
pCommsock->isConnected = TRUE;
rwoutTimerCreate(pScreen);
rwTakeControlInit(pScreen);
// TODO: DS: clientptr is an opaque handle to the client's sessionid
rwoutSyncClientOnConnect(pScreen, NULL);
/* TODO: notyet
if (firstClient) {
// By this time we know that composite has been enabled and
// it is safe to discard frame buffer memory
ErrorF("Discarding fb memory");
ddxGiveUp();
firstClient = FALSE;
}
*/
}
/*
** Disconnect all connections.
*/
static void
rwcommsockDisconnect (RwcommPtr pComm)
{
RwcommsockPtr pCommsock = (RwcommsockPtr) pComm;
FD_CLR(pCommsock->socket, &pCommsock->fdSetPoll);
RemoveEnabledDevice(pCommsock->socket);
close(pCommsock->socket);
if (pCommsock->sockServer > 0) {
if (close(pCommsock->sockServer)) {
ErrorF("rwcommsockDisconnect failed\n");
return;
}
}
pCommsock->isConnected = FALSE;
rwoutTimerDestroy(pCommsock->pScreen);
ErrorF("Client disconnected\n");
}
static Bool
rwcommsockIsConnected (RwcommPtr pComm)
{
RwcommsockPtr pCommsock = (RwcommsockPtr) pComm;
return pCommsock->isConnected;
}
/*
** Broadcast buffer to all clients
*/
static Bool
rwcommsockBufferWrite (RwcommPtr pComm, char *pbuf, int bufLen)
{
RwcommsockPtr pCommsock = (RwcommsockPtr) pComm;
int ret;
ret = WriteFully(pCommsock->socket, pbuf, bufLen);
if (ret < 0) {
ErrorF("rwcommsockBufferWrite: IO error\n");
rwcommsockDestroy((RwcommPtr)pCommsock);
return FALSE;
}
#ifdef VERBOSE
{ int i;
bufLen = (bufLen > 50) ? 50 : bufLen;
ErrorF("Broadcast: ");
for (i = 0; i < bufLen; i++) {
ErrorF("0x%x ", ((int)buf[i]) & 0xff);
}
ErrorF("\n");
}
#endif /* VERBOSE */
return TRUE;
}
/*
** Unicast buffer to specified client.
*/
static Bool
rwcommsockBufferWriteToClient (RwcommPtr pComm, int clientId, char *buf, int bufLen)
{
RwcommsockPtr pCommsock = (RwcommsockPtr) pComm;
int ret;
/*
** Note: we can't do unicast in the socket implementation. We can
** only do broadcast. So clients will need to ignore this if necessary.
*/
ret = WriteFully(pCommsock->socket, buf, bufLen);
if (ret <= 0) {
ErrorF("rwcommsockBufferWriteToClient: IO error\n");
rwcommsockDestroy((RwcommPtr)pCommsock);
return FALSE;
}
#ifdef VERBOSE
{ int i;
bufLen = (bufLen > 50) ? 50 : bufLen;
ErrorF("Unicast to client %d: ", clientId);
for (i = 0; i < bufLen; i++) {
ErrorF("0x%x ", ((int)buf[i]) & 0xff);
}
ErrorF("\n");
}
#endif /* VERBOSE */
return TRUE;
}
static int
rwcommsockNextMessageTypeRead (RwcommPtr pComm)
{
RwcommsockPtr pCommsock = (RwcommsockPtr) pComm;
char msgType;
int ret;
ret = ReadFully(pCommsock->socket, &msgType, 1);
if (ret <= 0) {
if (ret != 0) {
ErrorF("rwcommsockNextMessageTypeRead: IO error\n");
}
rwcommsockDestroy((RwcommPtr)pCommsock);
return CLIENT_MESSAGE_TYPE_INVALID;
}
return (int) msgType;
}
static Bool
rwcommsockNextMessageBufferRead (RwcommPtr pComm, char *pbuf, int readLen)
{
RwcommsockPtr pCommsock = (RwcommsockPtr) pComm;
int ret;
ret = ReadFully(pCommsock->socket, pbuf, readLen);
if (ret <= 0) {
if (ret != 0) {
ErrorF("rwcommsockNextMessageBufferRead: IO error\n");
}
rwcommsockDestroy((RwcommPtr)pCommsock);
return FALSE;
}
return TRUE;
}
static void
rwcommsockClientMessagePoll (RwcommPtr pComm, fd_set *pReadMask)
{
RwcommsockPtr pCommsock = (RwcommsockPtr) pComm;
int numFdsSet;
fd_set tempFds;
struct timeval waittime;
memcpy((char *)&tempFds, (char *)&pCommsock->fdSetPoll, sizeof(fd_set));
waittime.tv_usec = 0;
waittime.tv_sec = 0;
numFdsSet = select(pCommsock->fdMax + 1, &tempFds, NULL, NULL, &waittime);
if (numFdsSet <= 0) {
if (numFdsSet == 0) return;
if (errno != EINTR) {
ErrorF("rwcommsockClientMessagePoll: select error\n");
}
return;
}
/*
** We only listen for a single connection. Only accept a new connection
** if we aren't already connected.
*/
if (!pCommsock->isConnected &&
pCommsock->sockServer != -1 &&
FD_ISSET(pCommsock->sockServer, pReadMask)) {
int newSocket;
struct sockaddr_in addrDummy;
socklen_t lenDummy = sizeof(struct sockaddr_in);
if ((newSocket = accept(pCommsock->sockServer,
(struct sockaddr *)&addrDummy, &lenDummy)) < 0) {
perror("rwcommsockClientMessagePoll: accept");
return;
}
/*
if (fcntl(newSocket, F_SETFL, O_NONBLOCK) < 0) {
perror("rwcommsockClientMessagePoll: fcntl");
close(newSocket);
return;
}
*/
pCommsock->fdMax = (newSocket > pCommsock->fdMax) ? newSocket :pCommsock->fdMax;
FD_SET(newSocket, &pCommsock->fdSetPoll);
AddEnabledDevice(newSocket);
pCommsock->socket = newSocket;
RWCOMM_CONNECT((RwcommPtr)pCommsock);
ErrorF("New client connected\n");
numFdsSet--;
if (numFdsSet == 0) {
return;
}
}
/* Call input handler when the socket has data */
if (FD_ISSET(pCommsock->socket, pReadMask) &&
FD_ISSET(pCommsock->socket, &pCommsock->fdSetPoll)) {
rwinHandler(pCommsock->pScreen);
}
}
/*
** Create the comm module and accept connections.
*/
RwcommPtr
rwcommsockCreate (ScreenPtr pScreen)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
RwcommsockPtr pCommsock;
struct sockaddr_in sockAddr;
int val = 1;
pCommsock = (RwcommsockPtr) xalloc(sizeof(RwcommsockRec));
if (pCommsock == NULL) {
return NULL;
}
pCommsock->pScreen = pScreen;
pCommsock->sockServer = -1;
pCommsock->isConnected = FALSE;
pCommsock->funcs.destroy = rwcommsockDestroy;
pCommsock->funcs.connect = rwcommsockConnect;
pCommsock->funcs.disconnect = rwcommsockDisconnect;
pCommsock->funcs.isConnected = rwcommsockIsConnected;
pCommsock->funcs.bufferWrite = rwcommsockBufferWrite;
pCommsock->funcs.bufferWriteToClient = rwcommsockBufferWriteToClient;
pCommsock->funcs.nextMessageTypeRead = rwcommsockNextMessageTypeRead;
pCommsock->funcs.nextMessageBufferRead = rwcommsockNextMessageBufferRead;
pCommsock->funcs.clientMessagePoll = rwcommsockClientMessagePoll;
pScrPriv->pComm = (RwcommPtr) pCommsock;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(RWCOMMSOCK_SERVER_PORT + atoi(display));
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
pCommsock->sockServer = socket(AF_INET, SOCK_STREAM, 0);
if (pCommsock->sockServer < 0) {
xfree(pCommsock);
return NULL;
}
if (setsockopt(pCommsock->sockServer, SOL_SOCKET, SO_REUSEADDR, (char *)&val, 4) < 0) {
close(pCommsock->sockServer);
xfree(pCommsock);
return NULL;
}
if (bind(pCommsock->sockServer,
(struct sockaddr *)&sockAddr, sizeof(struct sockaddr_in)) < 0) {
close(pCommsock->sockServer);
xfree(pCommsock);
return NULL;
}
if (listen(pCommsock->sockServer, 1) < 0) {
close(pCommsock->sockServer);
xfree(pCommsock);
return NULL;
}
FD_ZERO(&pCommsock->fdSetPoll);
FD_SET(pCommsock->sockServer, &pCommsock->fdSetPoll);
pCommsock->fdMax = pCommsock->sockServer;
AddEnabledDevice(pCommsock->sockServer);
return (RwcommPtr)pCommsock;
}
static int
ReadFully (int sock, char *pbuf, int bufLen)
{
int bytes_read;
errno = 0;
bytes_read = read(sock, pbuf, bufLen);
while (bytes_read != bufLen) {
if (bytes_read > 0) {
bufLen -= bytes_read;
pbuf += bytes_read;
} else if (bytes_read == 0) {
/* Read failed because of end of file! */
errno = EPIPE;
return -1;
} else if (errno == EWOULDBLOCK ||
errno == EAGAIN) {
int ret;
fd_set r_mask;
FD_ZERO(&r_mask);
for (;;) {
FD_SET(sock, &r_mask);
ret = select(sock + 1, &r_mask, NULL, NULL, NULL);
if (ret == -1 &&
errno != EINTR) {
return -1;
}
if (ret <= 0) {
continue;
}
if (FD_ISSET(sock, &r_mask)) {
break;
}
}
errno = 0;
} else {
if (errno != EINTR) {
return -1;
}
}
bytes_read = read(sock, pbuf, bufLen);
}
return bufLen;
}
static int
WriteFully (int sock, char *pbuf, int bufLen)
{
int todo = bufLen;
int ret;
while (bufLen != 0) {
ret = write(sock, pbuf, todo);
if (ret >= 0) {
pbuf += ret;
bufLen -= ret;
todo = bufLen;
} else if (errno == EWOULDBLOCK ||
errno == EAGAIN) {
int nfound;
fd_set w_mask;
FD_ZERO(&w_mask);
for (;;) {
FD_SET(sock, &w_mask);
do {
nfound = select(sock + 1, NULL, &w_mask, NULL, NULL);
if (nfound < 0 && errno != EINTR) {
return -1;
}
} while (nfound <= 0);
}
} else if (errno != EINTR) {
return -1;
}
}
return bufLen;
}

55
hw/vfb/rwcommsock.h Normal file
View file

@ -0,0 +1,55 @@
/*****************************************************************
Copyright 2007 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.
******************************************************************/
#ifndef RWCOMMSOCK_H
#define RWCOMMSOCK_H
/* TODO: rewrite: change this */
#define RWCOMMSOCK_SERVER_PORT 5900
typedef struct rwcommsock_rec {
RwcommFuncPtrRec funcs;
ScreenPtr pScreen;
Bool isConnected;
fd_set fdSetPoll;
int fdMax;
int sockServer;
int socket;
} RwcommsockRec, *RwcommsockPtr;
extern RwcommPtr rwcommsockCreate (ScreenPtr pScreen);
extern int ReadExact(int sock, char *buf, int len);
extern int WriteExact(int sock, char *buf, int len);
#endif /* RWCOMMSOCK_H */

1029
hw/vfb/rwin.c Normal file

File diff suppressed because it is too large Load diff

275
hw/vfb/takecontrol.c Normal file
View file

@ -0,0 +1,275 @@
/*****************************************************************
Copyright 2007 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.
Copyright 1985, 1987, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
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. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
******************************************************************/
#include "inputstr.h"
#include "remwin.h"
#include "protocol.h"
/*
** Each time we grant control to a new controller, we need
** to make sure that if control was granted while the previous
** controller had any keys or buttons down that we start out the
** keyboard state and button state with a clean state.
*/
static void
initKeyboardState (ScreenPtr pScreen)
{
DeviceIntPtr pKeyboard = inputInfo.keyboard;
unsigned long when = GetTimeInMillis();
xEvent event;
int i, k;
for (i = 0; i < DOWN_LENGTH; i++) {
if (pKeyboard->key->down[i] == 0) {
continue;
}
for (k = 0; k < 8; k++) {
int mask = 1 << k;
if (pKeyboard->key->down[i] & mask) {
event.u.u.type = KeyRelease;
event.u.u.detail = (i << 3) | k;
event.u.keyButtonPointer.time = when;
(*pKeyboard->public.processInputProc)(&event, pKeyboard, 1);
}
}
}
}
static void
initPointerState (ScreenPtr pScreen)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
DeviceIntPtr pPointer = inputInfo.pointer;
xEvent event;
int button;
for (button = 0; button < 5; button++) {
int mask = 1 << button;
if (pScrPriv->controllerButtonMask & mask) {
event.u.u.type = ButtonRelease;
event.u.u.detail = button + 1;
event.u.keyButtonPointer.time = GetTimeInMillis();
(*pPointer->public.processInputProc)(&event, pPointer, 1);
}
}
}
static void
rwGrantControl (ScreenPtr pScreen, int clientId)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
/* Are we granting to someone who already has control? */
if (pScrPriv->controller == clientId) {
return;
}
pScrPriv->controller = clientId;
initKeyboardState(pScreen);
initPointerState(pScreen);
/* TODO: what else? */
}
/*
** Notify everyone that the current controller has lost control
*/
static Bool
notifyControlLost (ScreenPtr pScreen)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
RwcommPtr pComm = pScrPriv->pComm;
char buf[CONTROLLER_STATUS_MESSAGE_SIZE];
int losingClient;
int n;
if (!RWCOMM_IS_CONNECTED(pComm)) {
ErrorF("Connection lost.\n");
return FALSE;
}
losingClient = pScrPriv->controller;
swapl(&losingClient, n);
CONTROLLER_STATUS_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_CONTROLLER_STATUS);
CONTROLLER_STATUS_MESSAGE_SET_STATUS(buf, CONTROLLER_STATUS_LOST);
CONTROLLER_STATUS_MESSAGE_SET_CLIENTID(buf, losingClient);
if (!RWCOMM_BUFFER_WRITE(pComm, buf, CONTROLLER_STATUS_MESSAGE_SIZE)) {
ErrorF("Write to connection failed.\n");
return FALSE;
}
return TRUE;
}
/*
** Notify everyone that the current controller has gained control
*/
static Bool
notifyControlGained (ScreenPtr pScreen)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
RwcommPtr pComm = pScrPriv->pComm;
char buf[CONTROLLER_STATUS_MESSAGE_SIZE];
int gainingClient;
int n;
if (!RWCOMM_IS_CONNECTED(pComm)) {
ErrorF("Connection lost.\n");
return FALSE;
}
gainingClient = pScrPriv->controller;
swapl(&gainingClient, n);
CONTROLLER_STATUS_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_CONTROLLER_STATUS);
CONTROLLER_STATUS_MESSAGE_SET_STATUS(buf, CONTROLLER_STATUS_GAINED);
CONTROLLER_STATUS_MESSAGE_SET_CLIENTID(buf, gainingClient);
if (!RWCOMM_BUFFER_WRITE(pComm, buf, CONTROLLER_STATUS_MESSAGE_SIZE)) {
ErrorF("Write to connection failed.\n");
return FALSE;
}
return TRUE;
}
/*
** Notify the given client that its request for control is refused.
*/
static Bool
notifyControlRefused (ScreenPtr pScreen, int clientId)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
RwcommPtr pComm = pScrPriv->pComm;
char buf[CONTROLLER_STATUS_MESSAGE_SIZE];
int refusedClient;
int n;
if (!RWCOMM_IS_CONNECTED(pComm)) {
ErrorF("Connection lost.\n");
return FALSE;
}
refusedClient = pScrPriv->controller;
swapl(&refusedClient, n);
CONTROLLER_STATUS_MESSAGE_SET_TYPE(buf, SERVER_MESSAGE_TYPE_CONTROLLER_STATUS);
CONTROLLER_STATUS_MESSAGE_SET_STATUS(buf, CONTROLLER_STATUS_REFUSED);
CONTROLLER_STATUS_MESSAGE_SET_CLIENTID(buf, refusedClient);
if (!RWCOMM_BUFFER_WRITE_TO_CLIENT(pComm, clientId,
buf, CONTROLLER_STATUS_MESSAGE_SIZE)) {
ErrorF("Write to connection failed.\n");
return FALSE;
}
return TRUE;
}
void
rwTakeControl (ScreenPtr pScreen, int clientId, Bool steal)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
/* If client already has control do nothing */
if (pScrPriv->controller == clientId) {
return;
}
if (pScrPriv->controller == -1 || steal) {
/* Nobody has control or client is stealing -- Grant control */
if (!notifyControlLost(pScreen)) {
ErrorF("Cannot notify clients that control is lost.\n");
return;
}
rwGrantControl(pScreen, clientId);
if (!notifyControlGained(pScreen)) {
ErrorF("Cannot notify clients that control is gained.\n");
return;
}
} else {
if (!notifyControlRefused(pScreen, clientId)) {
ErrorF("Cannot notify client %d that control is refused.\n",
clientId);
return;
}
}
}
void
rwTakeControlInit (ScreenPtr pScreen)
{
RemwinScreenPrivPtr pScrPriv = REMWIN_GET_SCRPRIV(pScreen);
pScrPriv->controller = -1;
pScrPriv->controllerButtonMask = 0;
pScrPriv->configuringClient = -1;
}