From cd6eb6a2664a1bb8800eb9953bb7bab2ac1af5e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 24 Aug 2011 02:38:39 -0400 Subject: [PATCH] libfreerdp-core: add support for pointer updates --- client/X11/CMakeLists.txt | 7 +++ cmake/FindXcursor.cmake | 49 ++++++++++++++++ include/freerdp/update.h | 115 +++++++++++++++++++++++++++++--------- libfreerdp-core/rdp.c | 1 + libfreerdp-core/update.c | 85 ++++++++++++++++++++++++++++ libfreerdp-core/update.h | 1 + 6 files changed, 233 insertions(+), 25 deletions(-) create mode 100644 cmake/FindXcursor.cmake diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index d74a03b34..4ba0a6c16 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -45,6 +45,13 @@ if(Xext_FOUND) target_link_libraries(xfreerdp ${Xext_LIBRARIES}) endif() +find_package(Xcursor) +if(Xcursor_FOUND) + add_definitions(-DWITH_XCURSOR) + include_directories(${Xcursor_INCLUDE_DIRS}) + target_link_libraries(xfreerdp ${Xext_LIBRARIES}) +endif() + target_link_libraries(xfreerdp freerdp-core) target_link_libraries(xfreerdp freerdp-gdi) target_link_libraries(xfreerdp freerdp-kbd) diff --git a/cmake/FindXcursor.cmake b/cmake/FindXcursor.cmake new file mode 100644 index 000000000..c6afd1cf9 --- /dev/null +++ b/cmake/FindXcursor.cmake @@ -0,0 +1,49 @@ +# - Find Xcursor +# Find the Xcursor libraries +# +# This module defines the following variables: +# Xcursor_FOUND - True if Xcursor_INCLUDE_DIR & Xcursor_LIBRARY are found +# Xcursor_LIBRARIES - Set when Xcursor_LIBRARY is found +# Xcursor_INCLUDE_DIRS - Set when Xcursor_INCLUDE_DIR is found +# +# Xcursor_INCLUDE_DIR - where to find Xcursor.h, etc. +# Xcursor_LIBRARY - the Xcursor library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(Xcursor_INCLUDE_DIR NAMES Xcursor.h + PATH_SUFFIXES X11/Xcursor + DOC "The Xcursor include directory" +) + +find_library(Xcursor_LIBRARY NAMES Xcursor + DOC "The Xcursor library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xcursor DEFAULT_MSG Xcursor_LIBRARY Xcursor_INCLUDE_DIR) + +if(Xcursor_FOUND) + set( Xcursor_LIBRARIES ${Xcursor_LIBRARY} ) + set( Xcursor_INCLUDE_DIRS ${Xcursor_INCLUDE_DIR} ) +endif() + +mark_as_advanced(Xcursor_INCLUDE_DIR Xcursor_LIBRARY) + diff --git a/include/freerdp/update.h b/include/freerdp/update.h index f0a400465..ed576aa59 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -80,6 +80,47 @@ struct _PALETTE_UPDATE }; typedef struct _PALETTE_UPDATE PALETTE_UPDATE; +/* Pointer Updates */ + +struct _POINTER_POSITION_UPDATE +{ + uint16 xPos; + uint16 yPos; +}; +typedef struct _POINTER_POSITION_UPDATE POINTER_POSITION_UPDATE; + +struct _POINTER_SYSTEM_UPDATE +{ + uint32 type; +}; +typedef struct _POINTER_SYSTEM_UPDATE POINTER_SYSTEM_UPDATE; + +struct _POINTER_COLOR_UPDATE +{ + uint16 cacheIndex; + uint32 hotSpot; + uint16 width; + uint16 height; + uint16 lengthAndMask; + uint16 lengthXorMask; + uint8* xorMaskData; + uint8* andMaskData; +}; +typedef struct _POINTER_COLOR_UPDATE POINTER_COLOR_UPDATE; + +struct _POINTER_NEW_UPDATE +{ + uint16 xorBpp; + POINTER_COLOR_UPDATE colorPtrAttr; +}; +typedef struct _POINTER_NEW_UPDATE POINTER_NEW_UPDATE; + +struct _POINTER_CACHED_UPDATE +{ + uint16 cacheIndex; +}; +typedef struct _POINTER_CACHED_UPDATE POINTER_CACHED_UPDATE; + /* Orders Updates */ /* Primary Drawing Orders */ @@ -795,37 +836,43 @@ typedef struct _SURFACE_BITS_COMMAND SURFACE_BITS_COMMAND; /* Constants */ -#define CACHED_BRUSH 0x80 +#define PTR_MSG_TYPE_SYSTEM 0x0001 +#define PTR_MSG_TYPE_POSITION 0x0003 +#define PTR_MSG_TYPE_COLOR 0x0006 +#define PTR_MSG_TYPE_CACHED 0x0007 +#define PTR_MSG_TYPE_POINTER 0x0008 -#define BMF_1BPP 0x1 -#define BMF_8BPP 0x3 -#define BMF_16BPP 0x4 -#define BMF_24BPP 0x5 -#define BMF_32BPP 0x6 +#define CACHED_BRUSH 0x80 + +#define BMF_1BPP 0x1 +#define BMF_8BPP 0x3 +#define BMF_16BPP 0x4 +#define BMF_24BPP 0x5 +#define BMF_32BPP 0x6 #ifndef _WIN32 -#define BS_SOLID 0x00 -#define BS_NULL 0x01 -#define BS_HATCHED 0x02 -#define BS_PATTERN 0x03 +#define BS_SOLID 0x00 +#define BS_NULL 0x01 +#define BS_HATCHED 0x02 +#define BS_PATTERN 0x03 #endif -#define HS_HORIZONTAL 0x00 -#define HS_VERTICAL 0x01 -#define HS_FDIAGONAL 0x02 -#define HS_BDIAGONAL 0x03 -#define HS_CROSS 0x04 -#define HS_DIAGCROSS 0x05 +#define HS_HORIZONTAL 0x00 +#define HS_VERTICAL 0x01 +#define HS_FDIAGONAL 0x02 +#define HS_BDIAGONAL 0x03 +#define HS_CROSS 0x04 +#define HS_DIAGCROSS 0x05 -#define DSDNG_STRETCH 0x00000001 -#define DSDNG_TILE 0x00000002 -#define DSDNG_PERPIXELALPHA 0x00000004 -#define DSDNG_TRANSPARENT 0x00000008 -#define DSDNG_MUSTFLIP 0x00000010 -#define DSDNG_TRUESIZE 0x00000020 +#define DSDNG_STRETCH 0x00000001 +#define DSDNG_TILE 0x00000002 +#define DSDNG_PERPIXELALPHA 0x00000004 +#define DSDNG_TRANSPARENT 0x00000008 +#define DSDNG_MUSTFLIP 0x00000010 +#define DSDNG_TRUESIZE 0x00000020 -#define FRAME_START 0x00000000 -#define FRAME_END 0x00000001 +#define FRAME_START 0x00000000 +#define FRAME_END 0x00000001 #define STREAM_BITMAP_END 0x01 #define STREAM_BITMAP_COMPRESSED 0x02 @@ -942,6 +989,12 @@ typedef void (*pcSynchronize)(rdpUpdate* update); typedef void (*pcBitmap)(rdpUpdate* update, BITMAP_UPDATE* bitmap); typedef void (*pcPalette)(rdpUpdate* update, PALETTE_UPDATE* palette); +typedef void (*pcPointerPosition)(rdpUpdate* update, POINTER_POSITION_UPDATE* pointer_position); +typedef void (*pcPointerSystem)(rdpUpdate* update, POINTER_SYSTEM_UPDATE* pointer_system); +typedef void (*pcPointerColor)(rdpUpdate* update, POINTER_COLOR_UPDATE* pointer_color); +typedef void (*pcPointerNew)(rdpUpdate* update, POINTER_NEW_UPDATE* pointer_new); +typedef void (*pcPointerCached)(rdpUpdate* update, POINTER_CACHED_UPDATE* pointer_cached); + typedef void (*pcDstBlt)(rdpUpdate* update, DSTBLT_ORDER* dstblt); typedef void (*pcPatBlt)(rdpUpdate* update, PATBLT_ORDER* patblt); typedef void (*pcScrBlt)(rdpUpdate* update, SCRBLT_ORDER* scrblt); @@ -1014,6 +1067,12 @@ struct rdp_update pcBitmap Bitmap; pcPalette Palette; + pcPointerPosition PointerPosition; + pcPointerSystem PointerSystem; + pcPointerColor PointerColor; + pcPointerNew PointerNew; + pcPointerCached PointerCached; + pcDstBlt DstBlt; pcPatBlt PatBlt; pcScrBlt ScrBlt; @@ -1074,8 +1133,14 @@ struct rdp_update BITMAP_UPDATE bitmap_update; PALETTE_UPDATE palette_update; - ORDER_INFO order_info; + POINTER_POSITION_UPDATE pointer_position; + POINTER_SYSTEM_UPDATE pointer_system; + POINTER_COLOR_UPDATE pointer_color; + POINTER_NEW_UPDATE pointer_new; + POINTER_CACHED_UPDATE pointer_cached; + + ORDER_INFO order_info; DSTBLT_ORDER dstblt; PATBLT_ORDER patblt; SCRBLT_ORDER scrblt; diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c index d1bd26903..c038c08c7 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp-core/rdp.c @@ -320,6 +320,7 @@ void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) break; case DATA_PDU_TYPE_POINTER: + update_recv_pointer(rdp->update, s); break; case DATA_PDU_TYPE_INPUT: diff --git a/libfreerdp-core/update.c b/libfreerdp-core/update.c index c8a9bf65c..35e529464 100644 --- a/libfreerdp-core/update.c +++ b/libfreerdp-core/update.c @@ -156,6 +156,91 @@ void update_read_synchronize(rdpUpdate* update, STREAM* s) */ } +void update_read_pointer_position(STREAM* s, POINTER_POSITION_UPDATE* pointer_position) +{ + stream_read_uint16(s, pointer_position->xPos); /* xPos (2 bytes) */ + stream_read_uint16(s, pointer_position->yPos); /* yPos (2 bytes) */ +} + +void update_read_pointer_system(STREAM* s, POINTER_SYSTEM_UPDATE* pointer_system) +{ + stream_read_uint32(s, pointer_system->type); /* systemPointerType (4 bytes) */ +} + +void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color) +{ + stream_read_uint16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */ + stream_read_uint32(s, pointer_color->hotSpot); /* hotSpot (4 bytes) */ + stream_read_uint16(s, pointer_color->width); /* width (2 bytes) */ + stream_read_uint16(s, pointer_color->height); /* height (2 bytes) */ + stream_read_uint16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */ + stream_read_uint16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */ + + if (pointer_color->lengthXorMask > 0) + { + pointer_color->xorMaskData = (uint8*) xmalloc(pointer_color->lengthXorMask); + stream_read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask); + } + + if (pointer_color->lengthAndMask > 0) + { + pointer_color->andMaskData = (uint8*) xmalloc(pointer_color->lengthAndMask); + stream_read(s, pointer_color->andMaskData, pointer_color->lengthAndMask); + } + + stream_seek_uint8(s); /* pad (1 byte) */ +} + +void update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new) +{ + stream_read_uint16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ + update_read_pointer_color(s, &pointer_new->colorPtrAttr); /* colorPtrAttr */ +} + +void update_read_pointer_cached(STREAM* s, POINTER_CACHED_UPDATE* pointer_cached) +{ + stream_read_uint16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ +} + +void update_recv_pointer(rdpUpdate* update, STREAM* s) +{ + uint16 messageType; + + stream_read_uint16(s, messageType); /* messageType (2 bytes) */ + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ + + switch (messageType) + { + case PTR_MSG_TYPE_POSITION: + update_read_pointer_position(s, &update->pointer_position); + IFCALL(update->PointerPosition, update, &update->pointer_position); + break; + + case PTR_MSG_TYPE_SYSTEM: + update_read_pointer_system(s, &update->pointer_system); + IFCALL(update->PointerSystem, update, &update->pointer_system); + break; + + case PTR_MSG_TYPE_COLOR: + update_read_pointer_color(s, &update->pointer_color); + IFCALL(update->PointerColor, update, &update->pointer_color); + break; + + case PTR_MSG_TYPE_POINTER: + update_read_pointer_new(s, &update->pointer_new); + IFCALL(update->PointerNew, update, &update->pointer_new); + break; + + case PTR_MSG_TYPE_CACHED: + update_read_pointer_cached(s, &update->pointer_cached); + IFCALL(update->PointerCached, update, &update->pointer_cached); + break; + + default: + break; + } +} + void update_recv(rdpUpdate* update, STREAM* s) { uint16 updateType; diff --git a/libfreerdp-core/update.h b/libfreerdp-core/update.h index 5ddef6ac4..eddb5d505 100644 --- a/libfreerdp-core/update.h +++ b/libfreerdp-core/update.h @@ -41,6 +41,7 @@ void update_reset_state(rdpUpdate* update); void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_update); void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update); +void update_recv_pointer(rdpUpdate* update, STREAM* s); void update_recv(rdpUpdate* update, STREAM* s); void update_register_server_callbacks(rdpUpdate* update);