mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-05 01:48:02 +02:00
Add more files to branch.
This commit is contained in:
parent
9789f35cc5
commit
fe201a8f9a
8 changed files with 2954 additions and 0 deletions
615
hw/vfb/protocol.h
Normal file
615
hw/vfb/protocol.h
Normal 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
190
hw/vfb/remwin.h
Normal 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
235
hw/vfb/rle.c
Normal 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
98
hw/vfb/rwcomm.h
Normal 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
457
hw/vfb/rwcommsock.c
Normal 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
55
hw/vfb/rwcommsock.h
Normal 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
1029
hw/vfb/rwin.c
Normal file
File diff suppressed because it is too large
Load diff
275
hw/vfb/takecontrol.c
Normal file
275
hw/vfb/takecontrol.c
Normal 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;
|
||||
}
|
||||
|
||||
Loading…
Add table
Reference in a new issue