xfreerdp: initial cursor support
This commit is contained in:
parent
8f87f3e817
commit
6f3696f22b
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) */
|
||||
|
Loading…
Reference in New Issue
Block a user