xfreerdp: initial cursor support

This commit is contained in:
Marc-André Moreau 2011-09-29 00:33:16 -04:00
parent 8f87f3e817
commit 6f3696f22b
9 changed files with 201 additions and 18 deletions

View File

@ -70,10 +70,10 @@ if(XEXT_FOUND)
endif()
find_suggested_package(Xcursor)
if(Xcursor_FOUND)
if(XCURSOR_FOUND)
add_definitions(-DWITH_XCURSOR)
include_directories(${Xcursor_INCLUDE_DIRS})
target_link_libraries(xfreerdp ${Xcursor_LIBRARIES})
include_directories(${XCURSOR_INCLUDE_DIRS})
target_link_libraries(xfreerdp ${XCURSOR_LIBRARIES})
endif()
find_suggested_package(Xv)

View File

@ -21,6 +21,7 @@
#include <freerdp/rfx/rfx.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/common/color.h>
#include "xf_gdi.h"

View File

@ -20,6 +20,10 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef WITH_XCURSOR
#include <X11/Xcursor/Xcursor.h>
#endif
#ifdef WITH_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
@ -37,9 +41,11 @@
#include <sys/select.h>
#include <freerdp/rfx/rfx.h>
#include <freerdp/constants.h>
#include <freerdp/common/color.h>
#include <freerdp/utils/args.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/semaphore.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/event.h>
#include <freerdp/utils/passphrase.h>
#include <freerdp/plugins/cliprdr.h>
@ -224,6 +230,76 @@ void xf_hw_desktop_resize(rdpUpdate* update)
}
}
void xf_pointer_position(rdpUpdate* update, POINTER_POSITION_UPDATE* pointer_position)
{
}
void xf_pointer_system(rdpUpdate* update, POINTER_SYSTEM_UPDATE* pointer_system)
{
}
void xf_pointer_color(rdpUpdate* update, POINTER_COLOR_UPDATE* pointer_color)
{
}
void xf_pointer_new(rdpUpdate* update, POINTER_NEW_UPDATE* pointer_new)
{
xfInfo* xfi;
Cursor cursor;
XcursorImage ci;
POINTER_COLOR_UPDATE* ptrAttr;
xfi = GET_XFI(update);
ptrAttr = &pointer_new->colorPtrAttr;
memset(&ci, 0, sizeof(ci));
ci.version = XCURSOR_IMAGE_VERSION;
ci.size = sizeof(ci);
ci.width = ptrAttr->width;
ci.height = ptrAttr->height;
ci.xhot = ptrAttr->xPos;
ci.yhot = ptrAttr->yPos;
ci.pixels = (XcursorPixel*) malloc(ci.width * ci.height * 4);
memset(ci.pixels, 0, ci.width * ci.height * 4);
if ((ptrAttr->andMaskData != 0) && (ptrAttr->xorMaskData != 0))
{
freerdp_alpha_cursor_convert((uint8*) (ci.pixels), ptrAttr->xorMaskData, ptrAttr->andMaskData,
ptrAttr->width, ptrAttr->height, pointer_new->xorBpp, xfi->clrconv);
}
if (pointer_new->xorBpp > 24)
{
printf("xorBpp:%d\n", pointer_new->xorBpp);
}
cursor = XcursorImageLoadCursor(xfi->display, &ci);
xfree(ci.pixels);
pointer_put(xfi->cache->pointer, ptrAttr->cacheIndex, NULL, (void*) cursor);
if (xfi->remote_app != True)
XDefineCursor(xfi->display, xfi->window->handle, cursor);
}
void xf_pointer_cached(rdpUpdate* update, POINTER_CACHED_UPDATE* pointer_cached)
{
xfInfo* xfi;
void* extra;
Cursor cursor;
xfi = GET_XFI(update);
pointer_get(xfi->cache->pointer, pointer_cached->cacheIndex, &extra);
cursor = (Cursor) extra;
if (xfi->remote_app != True)
XDefineCursor(xfi->display, xfi->window->handle, cursor);
}
boolean xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount)
{
xfInfo* xfi = GET_XFI(instance);
@ -549,6 +625,12 @@ boolean xf_post_connect(freerdp* instance)
instance->update->DesktopResize = xf_hw_desktop_resize;
}
instance->update->PointerPosition = xf_pointer_position;
instance->update->PointerSystem = xf_pointer_system;
instance->update->PointerColor = xf_pointer_color;
instance->update->PointerNew = xf_pointer_new;
instance->update->PointerCached = xf_pointer_cached;
xfi->rail = rail_new(instance->settings);
instance->update->rail = (void*) xfi->rail;
rail_register_update_callbacks(xfi->rail, instance->update);

View File

@ -2,12 +2,12 @@
# 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_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
# XCURSOR_INCLUDE_DIR - where to find Xcursor.h, etc.
# XCURSOR_LIBRARY - the Xcursor library
#
#=============================================================================
@ -28,22 +28,22 @@
# limitations under the License.
#=============================================================================
find_path(Xcursor_INCLUDE_DIR NAMES Xcursor.h
find_path(XCURSOR_INCLUDE_DIR NAMES Xcursor.h
PATH_SUFFIXES X11/Xcursor
DOC "The Xcursor include directory"
)
find_library(Xcursor_LIBRARY NAMES Xcursor
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)
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} )
if(XCURSOR_FOUND)
set( XCURSOR_LIBRARIES ${XCURSOR_LIBRARY} )
set( XCURSOR_INCLUDE_DIRS ${XCURSOR_INCLUDE_DIR} )
endif()
mark_as_advanced(Xcursor_INCLUDE_DIR Xcursor_LIBRARY)
mark_as_advanced(XCURSOR_INCLUDE_DIR XCURSOR_LIBRARY)

View File

@ -242,6 +242,7 @@ FREERDP_API uint8* freerdp_glyph_convert(int width, int height, uint8* data);
FREERDP_API uint8* freerdp_image_invert(uint8* srcData, uint8* dstData, int width, int height, int bpp);
FREERDP_API uint8* freerdp_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv);
FREERDP_API uint8* freerdp_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv);
FREERDP_API void freerdp_alpha_cursor_convert(uint8* alphaData, uint8* xorMask, uint8* andMask, int width, int height, int bpp, HCLRCONV clrconv);
#ifdef __cplusplus
}

View File

@ -104,7 +104,8 @@ typedef struct _POINTER_SYSTEM_UPDATE POINTER_SYSTEM_UPDATE;
struct _POINTER_COLOR_UPDATE
{
uint16 cacheIndex;
uint32 hotSpot;
uint16 xPos;
uint16 yPos;
uint16 width;
uint16 height;
uint16 lengthAndMask;

View File

@ -35,7 +35,7 @@ void* pointer_get(rdpPointer* pointer, uint16 index, void** extra)
entry = pointer->entries[index].entry;
if (extra != NULL)
extra = pointer->entries[index].extra;
*extra = pointer->entries[index].extra;
return entry;
}

View File

@ -23,6 +23,67 @@
#include <freerdp/freerdp.h>
#include <freerdp/common/color.h>
int freerdp_get_pixel(uint8 * data, int x, int y, int width, int height, int bpp)
{
int start;
int shift;
uint16 *src16;
uint32 *src32;
int red, green, blue;
switch (bpp)
{
case 1:
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
return (data[start] & (0x80 >> shift)) != 0;
case 8:
return data[y * width + x];
case 15:
case 16:
src16 = (uint16*) data;
return src16[y * width + x];
case 24:
data += y * width * 3;
data += x * 3;
red = data[0];
green = data[1];
blue = data[2];
return RGB24(red, green, blue);
case 32:
src32 = (uint32*) data;
return src32[y * width + x];
default:
break;
}
return 0;
}
void freerdp_set_pixel(uint8* data, int x, int y, int width, int height, int bpp, int pixel)
{
int start;
int shift;
int *dst32;
if (bpp == 1)
{
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
if (pixel)
data[start] = data[start] | (0x80 >> shift);
else
data[start] = data[start] & ~(0x80 >> shift);
}
else if (bpp == 32)
{
dst32 = (int*) data;
dst32[y * width + x] = pixel;
}
}
uint32 freerdp_color_convert_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
{
uint8 red = 0;
@ -779,3 +840,39 @@ uint8* freerdp_mono_image_convert(uint8* srcData, int width, int height, int src
return srcData;
}
void freerdp_alpha_cursor_convert(uint8* alphaData, uint8* xorMask, uint8* andMask, int width, int height, int bpp, HCLRCONV clrconv)
{
int xpixel;
int apixel;
int i, j, jj;
for (j = 0; j < height; j++)
{
jj = (bpp == 1) ? j : (height - 1) - j;
for (i = 0; i < width; i++)
{
xpixel = freerdp_get_pixel(xorMask, i, jj, width, height, bpp);
xpixel = freerdp_color_convert(xpixel, bpp, 32, clrconv);
apixel = freerdp_get_pixel(andMask, i, jj, width, height, 1);
if (apixel != 0)
{
if ((xpixel & 0xffffff) == 0xffffff)
{
/* use pattern (not solid black) for xor area */
xpixel = (i & 1) == (j & 1);
xpixel = xpixel ? 0xffffff : 0;
xpixel |= 0xff000000;
}
else if (xpixel == 0xff000000)
{
xpixel = 0;
}
}
freerdp_set_pixel(alphaData, i, j, width, height, 32, xpixel);
}
}
}

View File

@ -194,7 +194,8 @@ void update_read_pointer_system(STREAM* s, POINTER_SYSTEM_UPDATE* pointer_system
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->xPos); /* xPos (2 bytes) */
stream_read_uint16(s, pointer_color->yPos); /* yPos (2 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) */