mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Refactored xfContext.
This commit is contained in:
@@ -230,7 +230,7 @@ static BOOL xf_desktop_resize(rdpContext* context)
|
||||
{
|
||||
rdpSettings* settings;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
settings = xfc->settings;
|
||||
settings = context->settings;
|
||||
|
||||
if (xfc->primary)
|
||||
{
|
||||
@@ -249,7 +249,7 @@ static BOOL xf_desktop_resize(rdpContext* context)
|
||||
|
||||
#ifdef WITH_XRENDER
|
||||
|
||||
if (!xfc->settings->SmartSizing)
|
||||
if (!xfc->context.settings->SmartSizing)
|
||||
{
|
||||
xfc->scaledWidth = settings->DesktopWidth;
|
||||
xfc->scaledHeight = settings->DesktopHeight;
|
||||
@@ -266,7 +266,7 @@ static BOOL xf_desktop_resize(rdpContext* context)
|
||||
{
|
||||
#ifdef WITH_XRENDER
|
||||
|
||||
if (!xfc->settings->SmartSizing)
|
||||
if (!xfc->context.settings->SmartSizing)
|
||||
#endif
|
||||
{
|
||||
/* Update the saved width and height values the window will be
|
||||
@@ -504,13 +504,16 @@ BOOL xf_create_window(xfContext* xfc)
|
||||
XEvent xevent;
|
||||
int width, height;
|
||||
char* windowTitle;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
rdpGdi* gdi;
|
||||
rdpSettings* settings;
|
||||
settings = xfc->context.settings;
|
||||
gdi = xfc->context.gdi;
|
||||
ZeroMemory(&xevent, sizeof(xevent));
|
||||
width = settings->DesktopWidth;
|
||||
height = settings->DesktopHeight;
|
||||
|
||||
if (!xfc->hdc)
|
||||
if (!(xfc->hdc = gdi_CreateDC(xfc->format)))
|
||||
if (!(xfc->hdc = gdi_CreateDC(gdi->dstFormat)))
|
||||
return FALSE;
|
||||
|
||||
if (!xfc->remote_app)
|
||||
@@ -1042,7 +1045,7 @@ static void xf_button_map_init(xfContext* xfc)
|
||||
};
|
||||
|
||||
/* query system for actual remapping */
|
||||
if (!xfc->settings->UnmapButtons)
|
||||
if (!xfc->context.settings->UnmapButtons)
|
||||
{
|
||||
xf_get_x11_button_map(xfc, x11_map);
|
||||
}
|
||||
@@ -1084,8 +1087,6 @@ static BOOL xf_pre_connect(freerdp* instance)
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
UINT32 maxWidth = 0;
|
||||
UINT32 maxHeight = 0;
|
||||
xfc->settings = instance->settings;
|
||||
xfc->instance = instance;
|
||||
settings = instance->settings;
|
||||
channels = context->channels;
|
||||
settings->OsMajorType = OSMAJORTYPE_UNIX;
|
||||
@@ -1204,7 +1205,7 @@ static BOOL xf_post_connect(freerdp* instance)
|
||||
settings = instance->settings;
|
||||
update = context->update;
|
||||
|
||||
if (!gdi_init(instance, xfc->format))
|
||||
if (!gdi_init(instance, xf_get_local_color_format(xfc, TRUE)))
|
||||
return FALSE;
|
||||
|
||||
if (!xf_register_pointer(context->graphics))
|
||||
@@ -1384,7 +1385,7 @@ static BOOL xf_auto_reconnect(freerdp* instance)
|
||||
UINT32 maxRetries;
|
||||
UINT32 numRetries = 0;
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
rdpSettings* settings = instance->settings;
|
||||
maxRetries = settings->AutoReconnectMaxRetries;
|
||||
|
||||
/* Only auto reconnect on network disconnects. */
|
||||
@@ -1769,7 +1770,6 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
instance->VerifyChangedCertificate = client_cli_verify_changed_certificate;
|
||||
instance->LogonErrorInfo = xf_logon_error_info;
|
||||
settings = instance->settings;
|
||||
xfc->settings = instance->context->settings;
|
||||
PubSub_SubscribeTerminate(context->pubSub,
|
||||
(pTerminateEventHandler) xf_TerminateEventHandler);
|
||||
#ifdef WITH_XRENDER
|
||||
@@ -1853,7 +1853,7 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
xfc->screen = ScreenOfDisplay(xfc->display, xfc->screen_number);
|
||||
xfc->depth = DefaultDepthOfScreen(xfc->screen);
|
||||
xfc->big_endian = (ImageByteOrder(xfc->display) == MSBFirst);
|
||||
xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? TRUE : FALSE;
|
||||
xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? FALSE : TRUE;
|
||||
xfc->complex_regions = TRUE;
|
||||
xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds,
|
||||
WINPR_FD_READ);
|
||||
@@ -1865,18 +1865,6 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
}
|
||||
|
||||
xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number);
|
||||
xfc->format = PIXEL_FORMAT_RGBX32;
|
||||
|
||||
if (xfc->depth == 32)
|
||||
xfc->format = (xfc->invert) ? PIXEL_FORMAT_RGBA32 : PIXEL_FORMAT_BGRA32;
|
||||
else if (xfc->depth == 24)
|
||||
xfc->format = (xfc->invert) ? PIXEL_FORMAT_RGBX32 : PIXEL_FORMAT_BGRX32;
|
||||
else if (xfc->depth == 16)
|
||||
xfc->format = (xfc->invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16;
|
||||
else if (xfc->depth == 15)
|
||||
xfc->format = (xfc->invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16;
|
||||
else
|
||||
xfc->format = PIXEL_FORMAT_RGBX32;
|
||||
|
||||
if (xfc->debug)
|
||||
{
|
||||
|
||||
@@ -262,9 +262,9 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state,
|
||||
{
|
||||
rdpInput* input;
|
||||
Window childWindow;
|
||||
input = xfc->instance->input;
|
||||
input = xfc->context.input;
|
||||
|
||||
if (!xfc->settings->MouseMotion)
|
||||
if (!xfc->context.settings->MouseMotion)
|
||||
{
|
||||
if ((state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
|
||||
return TRUE;
|
||||
@@ -314,7 +314,7 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button,
|
||||
flags = 0;
|
||||
wheel = FALSE;
|
||||
extended = FALSE;
|
||||
input = xfc->instance->input;
|
||||
input = xfc->context.input;
|
||||
|
||||
switch (button)
|
||||
{
|
||||
@@ -349,7 +349,7 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button,
|
||||
case 6: /* wheel left */
|
||||
wheel = TRUE;
|
||||
|
||||
if (xfc->settings->HasHorizontalWheel)
|
||||
if (xfc->context.settings->HasHorizontalWheel)
|
||||
flags = PTR_FLAGS_HWHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0078;
|
||||
|
||||
break;
|
||||
@@ -357,7 +357,7 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button,
|
||||
case 7: /* wheel right */
|
||||
wheel = TRUE;
|
||||
|
||||
if (xfc->settings->HasHorizontalWheel)
|
||||
if (xfc->context.settings->HasHorizontalWheel)
|
||||
flags = PTR_FLAGS_HWHEEL | 0x0078;
|
||||
|
||||
break;
|
||||
@@ -421,7 +421,7 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button,
|
||||
flags = 0;
|
||||
wheel = FALSE;
|
||||
extended = FALSE;
|
||||
input = xfc->instance->input;
|
||||
input = xfc->context.input;
|
||||
|
||||
switch (button)
|
||||
{
|
||||
@@ -664,7 +664,8 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
xfc->offset_x = 0;
|
||||
xfc->offset_y = 0;
|
||||
|
||||
if (xfc->settings->SmartSizing || xfc->settings->MultiTouchGestures)
|
||||
if (xfc->context.settings->SmartSizing
|
||||
|| xfc->context.settings->MultiTouchGestures)
|
||||
{
|
||||
xfc->scaledWidth = xfc->window->width;
|
||||
xfc->scaledHeight = xfc->window->height;
|
||||
@@ -723,7 +724,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
RECTANGLE_16 rect;
|
||||
xfAppWindow* appWindow;
|
||||
rdpUpdate* update = xfc->instance->update;
|
||||
rdpUpdate* update = xfc->context.update;
|
||||
rdpSettings* settings = xfc->context.settings;
|
||||
|
||||
if (!app)
|
||||
@@ -756,7 +757,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
{
|
||||
xfAppWindow* appWindow;
|
||||
rdpUpdate* update = xfc->instance->update;
|
||||
rdpUpdate* update = xfc->context.update;
|
||||
xf_keyboard_release_all_keypress(xfc);
|
||||
|
||||
if (!app)
|
||||
|
||||
@@ -219,21 +219,24 @@ static BOOL xf_set_rop3(xfContext* xfc, UINT32 rop3)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Pixmap xf_brush_new(xfContext* xfc, int width, int height, int bpp,
|
||||
static Pixmap xf_brush_new(xfContext* xfc, UINT32 width, UINT32 height,
|
||||
UINT32 bpp,
|
||||
BYTE* data)
|
||||
{
|
||||
GC gc;
|
||||
Pixmap bitmap;
|
||||
BYTE* cdata;
|
||||
XImage* image;
|
||||
rdpGdi* gdi;
|
||||
UINT32 brushFormat;
|
||||
gdi = xfc->context.gdi;
|
||||
bitmap = XCreatePixmap(xfc->display, xfc->drawable, width, height, xfc->depth);
|
||||
|
||||
if (data)
|
||||
{
|
||||
brushFormat = gdi_get_pixel_format(bpp, FALSE);
|
||||
cdata = (BYTE*) _aligned_malloc(width * height * 4, 16);
|
||||
freerdp_image_copy(cdata, xfc->format, 0, 0, 0,
|
||||
freerdp_image_copy(cdata, gdi->dstFormat, 0, 0, 0,
|
||||
width, height, data, brushFormat, 0, 0, 0,
|
||||
&xfc->context.gdi->palette);
|
||||
image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
|
||||
@@ -903,7 +906,7 @@ static BOOL xf_gdi_surface_frame_marker(rdpContext* context,
|
||||
rdpSettings* settings;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
BOOL ret = TRUE;
|
||||
settings = xfc->instance->settings;
|
||||
settings = xfc->context.settings;
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
switch (surface_frame_marker->frameAction)
|
||||
@@ -925,7 +928,7 @@ static BOOL xf_gdi_surface_frame_marker(rdpContext* context,
|
||||
|
||||
if (settings->FrameAcknowledge > 0)
|
||||
{
|
||||
IFCALL(xfc->instance->update->SurfaceFrameAcknowledge, context,
|
||||
IFCALL(xfc->context.update->SurfaceFrameAcknowledge, context,
|
||||
surface_frame_marker->frameId);
|
||||
}
|
||||
|
||||
@@ -1021,7 +1024,7 @@ static BOOL xf_gdi_surface_bits(rdpContext* context,
|
||||
if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width,
|
||||
cmd->height,
|
||||
cmd->bitmapData, cmd->bitmapDataLength,
|
||||
xfc->bitmap_buffer, xfc->format, 0, 0, 0, cmd->width, cmd->height))
|
||||
xfc->bitmap_buffer, gdi->dstFormat, 0, 0, 0, cmd->width, cmd->height))
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
@@ -1046,7 +1049,7 @@ static BOOL xf_gdi_surface_bits(rdpContext* context,
|
||||
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
|
||||
pSrcData = cmd->bitmapData;
|
||||
pDstData = xfc->bitmap_buffer;
|
||||
freerdp_image_copy(pDstData, xfc->format, 0, 0, 0,
|
||||
freerdp_image_copy(pDstData, gdi->dstFormat, 0, 0, 0,
|
||||
cmd->width, cmd->height, pSrcData,
|
||||
PIXEL_FORMAT_BGRX32_VF, 0, 0, 0, &xfc->context.gdi->palette);
|
||||
image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
|
||||
|
||||
@@ -34,6 +34,8 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
|
||||
UINT32 surfaceX, surfaceY;
|
||||
RECTANGLE_16 surfaceRect;
|
||||
const RECTANGLE_16* extents;
|
||||
rdpGdi* gdi;
|
||||
gdi = xfc->context.gdi;
|
||||
surfaceX = surface->gdi.outputOriginX;
|
||||
surfaceY = surface->gdi.outputOriginY;
|
||||
surfaceRect.left = surfaceX;
|
||||
@@ -58,7 +60,7 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
|
||||
|
||||
if (surface->stage)
|
||||
{
|
||||
freerdp_image_copy(surface->stage, xfc->format,
|
||||
freerdp_image_copy(surface->stage, gdi->dstFormat,
|
||||
surface->stageScanline, 0, 0,
|
||||
surface->gdi.width, surface->gdi.height,
|
||||
surface->gdi.data, surface->gdi.format,
|
||||
@@ -67,7 +69,8 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
|
||||
|
||||
#ifdef WITH_XRENDER
|
||||
|
||||
if (xfc->settings->SmartSizing || xfc->settings->MultiTouchGestures)
|
||||
if (xfc->context.settings->SmartSizing
|
||||
|| xfc->context.settings->MultiTouchGestures)
|
||||
{
|
||||
XPutImage(xfc->display, xfc->primary, xfc->gc, surface->image,
|
||||
extents->left, extents->top, extents->left + surfaceX, extents->top + surfaceY,
|
||||
@@ -248,7 +251,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
|
||||
|
||||
ZeroMemory(surface->gdi.data, size);
|
||||
|
||||
if (xfc->format == surface->gdi.format)
|
||||
if (gdi->dstFormat == surface->gdi.format)
|
||||
{
|
||||
surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
|
||||
(char*) surface->gdi.data, surface->gdi.width, surface->gdi.height,
|
||||
@@ -257,7 +260,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
|
||||
else
|
||||
{
|
||||
UINT32 width = surface->gdi.width;
|
||||
UINT32 bytes = GetBytesPerPixel(xfc->format);
|
||||
UINT32 bytes = GetBytesPerPixel(gdi->dstFormat);
|
||||
surface->stageScanline = width * bytes;
|
||||
|
||||
if (xfc->scanline_pad > 0)
|
||||
|
||||
@@ -59,17 +59,7 @@ BOOL xf_decode_color(rdpGdi* gdi, const UINT32 srcColor,
|
||||
if (format)
|
||||
*format = SrcFormat;
|
||||
|
||||
if (xfc->depth == 32)
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGBA32 : PIXEL_FORMAT_BGRA32;
|
||||
else if (xfc->depth == 24)
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGB24 : PIXEL_FORMAT_BGR24;
|
||||
else if (xfc->depth == 16)
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16;
|
||||
else if (xfc->depth == 15)
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16;
|
||||
else
|
||||
DstFormat = PIXEL_FORMAT_RGBX32;
|
||||
|
||||
DstFormat = xf_get_local_color_format(xfc, FALSE);
|
||||
*color = ConvertColor(srcColor, SrcFormat,
|
||||
DstFormat, &gdi->palette);
|
||||
return TRUE;
|
||||
@@ -83,7 +73,9 @@ static BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
||||
Pixmap pixmap;
|
||||
XImage* image;
|
||||
UINT32 SrcFormat;
|
||||
rdpGdi* gdi;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
gdi = context->gdi;
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
data = bitmap->data;
|
||||
depth = GetBitsPerPixel(bitmap->format);
|
||||
@@ -103,13 +95,13 @@ static BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
|
||||
}
|
||||
|
||||
SrcFormat = bitmap->format;
|
||||
freerdp_image_copy(data, xfc->format, 0, 0, 0,
|
||||
freerdp_image_copy(data, gdi->dstFormat, 0, 0, 0,
|
||||
bitmap->width, bitmap->height,
|
||||
bitmap->data, SrcFormat,
|
||||
0, 0, 0, &context->gdi->palette);
|
||||
_aligned_free(bitmap->data);
|
||||
bitmap->data = data;
|
||||
bitmap->format = xfc->format;
|
||||
bitmap->format = gdi->dstFormat;
|
||||
}
|
||||
|
||||
image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
|
||||
@@ -175,6 +167,12 @@ static BOOL xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap,
|
||||
/* Pointer Class */
|
||||
static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
{
|
||||
rdpGdi* gdi;
|
||||
|
||||
if (!context || !pointer || !context->gdi)
|
||||
return FALSE;
|
||||
|
||||
gdi = context->gdi;
|
||||
#ifdef WITH_XCURSOR
|
||||
XcursorImage ci;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
@@ -188,14 +186,14 @@ static BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer)
|
||||
ci.yhot = pointer->yPos;
|
||||
|
||||
if (!(ci.pixels = (XcursorPixel*) calloc(ci.height,
|
||||
ci.width * GetBytesPerPixel(xfc->format))))
|
||||
ci.width * GetBytesPerPixel(gdi->dstFormat))))
|
||||
{
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (freerdp_image_copy_from_pointer_data(
|
||||
(BYTE*) ci.pixels, xfc->format,
|
||||
(BYTE*) ci.pixels, gdi->dstFormat,
|
||||
0, 0, 0, pointer->width, pointer->height,
|
||||
pointer->xorMaskData, pointer->lengthXorMask,
|
||||
pointer->andMaskData, pointer->lengthAndMask,
|
||||
@@ -461,3 +459,29 @@ BOOL xf_register_graphics(rdpGraphics* graphics)
|
||||
graphics_register_glyph(graphics, &glyph);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT32 xf_get_local_color_format(xfContext* xfc, BOOL aligned)
|
||||
{
|
||||
UINT32 DstFormat;
|
||||
|
||||
if (!xfc)
|
||||
return 0;
|
||||
|
||||
if (xfc->depth == 32)
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGBA32 : PIXEL_FORMAT_BGRA32;
|
||||
else if (xfc->depth == 24)
|
||||
{
|
||||
if (aligned)
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGBX32 : PIXEL_FORMAT_BGRX32;
|
||||
else
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGB24 : PIXEL_FORMAT_BGR24;
|
||||
}
|
||||
else if (xfc->depth == 16)
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16;
|
||||
else if (xfc->depth == 15)
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGB16 : PIXEL_FORMAT_BGR16;
|
||||
else
|
||||
DstFormat = (!xfc->invert) ? PIXEL_FORMAT_RGBX32 : PIXEL_FORMAT_BGRX32;
|
||||
|
||||
return DstFormat;
|
||||
}
|
||||
|
||||
@@ -28,5 +28,6 @@ BOOL xf_register_graphics(rdpGraphics* graphics);
|
||||
|
||||
BOOL xf_decode_color(rdpGdi* gdi, const UINT32 srcColor,
|
||||
UINT32* color, UINT32* format);
|
||||
UINT32 xf_get_local_color_format(xfContext* xfc, BOOL aligned);
|
||||
|
||||
#endif /* __XF_GRAPHICS_H */
|
||||
|
||||
@@ -104,11 +104,9 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
XIEventMask evmasks[64];
|
||||
int opcode, event, error;
|
||||
BYTE masks[8][XIMaskLen(XI_LASTEVENT)];
|
||||
|
||||
z_vector = 0;
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
|
||||
nmasks = 0;
|
||||
ndevices = 0;
|
||||
active_contacts = 0;
|
||||
@@ -121,7 +119,6 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
}
|
||||
|
||||
xfc->XInputOpcode = opcode;
|
||||
|
||||
XIQueryVersion(xfc->display, &major, &minor);
|
||||
|
||||
if (major * 1000 + minor < 2002)
|
||||
@@ -130,7 +127,7 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
if (xfc->context.settings->MultiTouchInput)
|
||||
xfc->use_xinput = TRUE;
|
||||
|
||||
info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices);
|
||||
@@ -157,11 +154,11 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
XIAnyClassInfo* class = dev->classes[j];
|
||||
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
if (xfc->context.settings->MultiTouchInput)
|
||||
{
|
||||
WLog_INFO(TAG, "%s (%d) \"%s\" id: %d",
|
||||
xf_input_get_class_string(class->type),
|
||||
class->type, dev->name, dev->deviceid);
|
||||
xf_input_get_class_string(class->type),
|
||||
class->type, dev->name, dev->deviceid);
|
||||
}
|
||||
|
||||
evmasks[nmasks].mask = masks[nmasks];
|
||||
@@ -172,11 +169,11 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
|
||||
(strcmp(dev->name, "Virtual core pointer") != 0))
|
||||
{
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
if (xfc->context.settings->MultiTouchInput)
|
||||
{
|
||||
WLog_INFO(TAG, "%s %s touch device (id: %d, mode: %d), supporting %d touches.",
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
|
||||
dev->deviceid, t->mode, t->num_touches);
|
||||
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
|
||||
dev->deviceid, t->mode, t->num_touches);
|
||||
}
|
||||
|
||||
XISetMask(masks[nmasks], XI_TouchBegin);
|
||||
@@ -187,11 +184,12 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
|
||||
if (xfc->use_xinput)
|
||||
{
|
||||
if (!touch && (class->type == XIButtonClass) && strcmp(dev->name, "Virtual core pointer"))
|
||||
if (!touch && (class->type == XIButtonClass)
|
||||
&& strcmp(dev->name, "Virtual core pointer"))
|
||||
{
|
||||
WLog_INFO(TAG, "%s button device (id: %d, mode: %d)",
|
||||
dev->name,
|
||||
dev->deviceid, t->mode);
|
||||
dev->name,
|
||||
dev->deviceid, t->mode);
|
||||
XISetMask(masks[nmasks], XI_ButtonPress);
|
||||
XISetMask(masks[nmasks], XI_ButtonRelease);
|
||||
XISetMask(masks[nmasks], XI_Motion);
|
||||
@@ -200,6 +198,7 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XIFreeDeviceInfo(info);
|
||||
|
||||
if (nmasks > 0)
|
||||
@@ -211,15 +210,13 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
BOOL xf_input_is_duplicate(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
|
||||
event = cookie->data;
|
||||
|
||||
|
||||
if ( (lastEvent.time == event->time) &&
|
||||
if ((lastEvent.time == event->time) &&
|
||||
(lastEvType == cookie->evtype) &&
|
||||
(lastEvent.detail == event->detail) &&
|
||||
(lastEvent.event_x == event->event_x) &&
|
||||
(lastEvent.event_y == event->event_y) )
|
||||
(lastEvent.event_y == event->event_y))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -230,11 +227,8 @@ BOOL xf_input_is_duplicate(XGenericEventCookie* cookie)
|
||||
void xf_input_save_last_event(XGenericEventCookie* cookie)
|
||||
{
|
||||
XIDeviceEvent* event;
|
||||
|
||||
event = cookie->data;
|
||||
|
||||
lastEvType = cookie->evtype;
|
||||
|
||||
lastEvent.time = event->time;
|
||||
lastEvent.detail = event->detail;
|
||||
lastEvent.event_x = event->event_x;
|
||||
@@ -245,10 +239,8 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
{
|
||||
double dx[2];
|
||||
double dy[2];
|
||||
|
||||
double px;
|
||||
double py;
|
||||
|
||||
double dist_x;
|
||||
double dist_y;
|
||||
|
||||
@@ -259,16 +251,12 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
|
||||
dx[0] = contacts[0].pos_x - contacts[0].last_x;
|
||||
dx[1] = contacts[1].pos_x - contacts[1].last_x;
|
||||
|
||||
dy[0] = contacts[0].pos_y - contacts[0].last_y;
|
||||
dy[1] = contacts[1].pos_y - contacts[1].last_y;
|
||||
|
||||
px = fabs(dx[0]) < fabs(dx[1]) ? dx[0] : dx[1];
|
||||
py = fabs(dy[0]) < fabs(dy[1]) ? dy[0] : dy[1];
|
||||
|
||||
px_vector += px;
|
||||
py_vector += py;
|
||||
|
||||
dist_x = fabs(contacts[0].pos_x - contacts[1].pos_x);
|
||||
dist_y = fabs(contacts[0].pos_y - contacts[1].pos_y);
|
||||
|
||||
@@ -278,15 +266,12 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.dx = 5;
|
||||
e.dy = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
px_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
@@ -295,38 +280,30 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.dx = -5;
|
||||
e.dy = 0;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
px_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (dist_x > MIN_FINGER_DIST)
|
||||
{
|
||||
|
||||
if (py_vector > PAN_THRESHOLD)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.dx = 0;
|
||||
e.dy = 5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
py_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
@@ -335,15 +312,12 @@ void xf_input_detect_pan(xfContext* xfc)
|
||||
{
|
||||
{
|
||||
PanningChangeEventArgs e;
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.dx = 0;
|
||||
e.dy = -5;
|
||||
PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
}
|
||||
|
||||
py_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
@@ -355,7 +329,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
{
|
||||
double dist;
|
||||
double zoom;
|
||||
|
||||
double delta;
|
||||
ZoomingChangeEventArgs e;
|
||||
|
||||
@@ -367,7 +340,7 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
|
||||
/* first calculate the distance */
|
||||
dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) +
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||
|
||||
/* if this is the first 2pt touch */
|
||||
if (firstDist <= 0)
|
||||
@@ -376,7 +349,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
lastDist = firstDist;
|
||||
scale_cnt = 0;
|
||||
z_vector = 0;
|
||||
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
z_vector = 0;
|
||||
@@ -385,16 +357,15 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
{
|
||||
delta = lastDist - dist;
|
||||
|
||||
if(delta > 1.0)
|
||||
if (delta > 1.0)
|
||||
delta = 1.0;
|
||||
if(delta < -1.0)
|
||||
|
||||
if (delta < -1.0)
|
||||
delta = -1.0;
|
||||
|
||||
/* compare the current distance to the first one */
|
||||
zoom = (dist / firstDist);
|
||||
|
||||
z_vector += delta;
|
||||
|
||||
lastDist = dist;
|
||||
|
||||
if (z_vector > ZOOM_THRESHOLD)
|
||||
@@ -402,7 +373,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.dx = e.dy = -10;
|
||||
PubSub_OnZoomingChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
z_vector = 0;
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
@@ -414,7 +384,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
e.dx = e.dy = 10;
|
||||
PubSub_OnZoomingChange(((rdpContext*) xfc)->pubSub, xfc, &e);
|
||||
|
||||
z_vector = 0;
|
||||
px_vector = 0;
|
||||
py_vector = 0;
|
||||
@@ -435,7 +404,6 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].count = 1;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
active_contacts++;
|
||||
break;
|
||||
}
|
||||
@@ -455,10 +423,8 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||
contacts[i].last_y = contacts[i].pos_y;
|
||||
contacts[i].pos_x = event->event_x;
|
||||
contacts[i].pos_y = event->event_y;
|
||||
|
||||
xf_input_detect_pinch(xfc);
|
||||
xf_input_detect_pan(xfc);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -474,7 +440,6 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
{
|
||||
contacts[i].id = 0;
|
||||
contacts[i].count = 0;
|
||||
|
||||
active_contacts--;
|
||||
break;
|
||||
}
|
||||
@@ -484,7 +449,6 @@ void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||
int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
|
||||
@@ -494,18 +458,21 @@ int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
||||
case XI_TouchBegin:
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_begin(xfc, cookie->data);
|
||||
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
case XI_TouchUpdate:
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_update(xfc, cookie->data);
|
||||
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
case XI_TouchEnd:
|
||||
if (xf_input_is_duplicate(cookie) == FALSE)
|
||||
xf_input_touch_end(xfc, cookie->data);
|
||||
|
||||
xf_input_save_last_event(cookie);
|
||||
break;
|
||||
|
||||
@@ -515,8 +482,7 @@ int xf_input_handle_event_local(xfContext* xfc, XEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
XFreeEventData(xfc->display,cookie);
|
||||
|
||||
XFreeEventData(xfc->display, cookie);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -535,14 +501,13 @@ char* xf_input_touch_state_string(DWORD flags)
|
||||
void xf_input_hide_cursor(xfContext* xfc)
|
||||
{
|
||||
#ifdef WITH_XCURSOR
|
||||
|
||||
if (!xfc->cursorHidden)
|
||||
{
|
||||
XcursorImage ci;
|
||||
XcursorPixel xp = 0;
|
||||
static Cursor nullcursor = None;
|
||||
|
||||
xf_lock_x11(xfc, FALSE);
|
||||
|
||||
ZeroMemory(&ci, sizeof(ci));
|
||||
ci.version = XCURSOR_IMAGE_VERSION;
|
||||
ci.size = sizeof(ci);
|
||||
@@ -555,9 +520,9 @@ void xf_input_hide_cursor(xfContext* xfc)
|
||||
XDefineCursor(xfc->display, xfc->window->handle, nullcursor);
|
||||
|
||||
xfc->cursorHidden = TRUE;
|
||||
|
||||
xf_unlock_x11(xfc, FALSE);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -594,11 +559,9 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
return 0;
|
||||
|
||||
xf_input_hide_cursor(xfc);
|
||||
|
||||
touchId = event->detail;
|
||||
x = (int) event->event_x;
|
||||
y = (int) event->event_y;
|
||||
|
||||
xf_event_adjust_coordinates(xfc, &x, &y);
|
||||
|
||||
if (evtype == XI_TouchBegin)
|
||||
@@ -627,21 +590,18 @@ int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
switch (evtype)
|
||||
{
|
||||
case XI_ButtonPress:
|
||||
|
||||
xf_generic_ButtonPress(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
case XI_ButtonRelease:
|
||||
|
||||
xf_generic_ButtonRelease(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
case XI_Motion:
|
||||
|
||||
xf_generic_MotionNotify(xfc, (int) event->event_x, (int) event->event_y,
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
event->detail, event->event, xfc->remote_app);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -651,7 +611,6 @@ int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
||||
int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
XGenericEventCookie* cookie = &event->xcookie;
|
||||
|
||||
XGetEventData(xfc->display, cookie);
|
||||
|
||||
if ((cookie->type == GenericEvent) && (cookie->extension == xfc->XInputOpcode))
|
||||
@@ -676,8 +635,7 @@ int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
XFreeEventData(xfc->display,cookie);
|
||||
|
||||
XFreeEventData(xfc->display, cookie);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -693,16 +651,17 @@ int xf_input_init(xfContext* xfc, Window window)
|
||||
int xf_input_handle_event(xfContext* xfc, XEvent* event)
|
||||
{
|
||||
#ifdef WITH_XI
|
||||
if (xfc->settings->MultiTouchInput)
|
||||
|
||||
if (xfc->context.settings->MultiTouchInput)
|
||||
{
|
||||
return xf_input_handle_event_remote(xfc, event);
|
||||
}
|
||||
|
||||
if (xfc->settings->MultiTouchGestures)
|
||||
if (xfc->context.settings->MultiTouchGestures)
|
||||
{
|
||||
return xf_input_handle_event_local(xfc, event);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -63,13 +63,12 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc)
|
||||
return FALSE;
|
||||
|
||||
xfc->keyCombinations = ArrayList_New(TRUE);
|
||||
|
||||
if (!xfc->keyCombinations)
|
||||
return FALSE;
|
||||
|
||||
ArrayList_Object(xfc->keyCombinations)->fnObjectFree = free;
|
||||
|
||||
sprintf_s(command, sizeof(command), "%s key", xfc->actionScript);
|
||||
|
||||
keyScript = popen(command, "r");
|
||||
|
||||
if (!keyScript)
|
||||
@@ -83,6 +82,7 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc)
|
||||
{
|
||||
strtok(buffer, "\n");
|
||||
keyCombination = _strdup(buffer);
|
||||
|
||||
if (!keyCombination || ArrayList_Add(xfc->keyCombinations, keyCombination) < 0)
|
||||
{
|
||||
ArrayList_Free(xfc->keyCombinations);
|
||||
@@ -95,7 +95,6 @@ BOOL xf_keyboard_action_script_init(xfContext* xfc)
|
||||
|
||||
pclose(keyScript);
|
||||
return xf_event_action_script_init(xfc);
|
||||
|
||||
}
|
||||
|
||||
void xf_keyboard_action_script_free(xfContext* xfc)
|
||||
@@ -118,10 +117,9 @@ void xf_keyboard_action_script_free(xfContext* xfc)
|
||||
BOOL xf_keyboard_init(xfContext* xfc)
|
||||
{
|
||||
xf_keyboard_clear(xfc);
|
||||
|
||||
xfc->KeyboardLayout = xfc->instance->settings->KeyboardLayout;
|
||||
xfc->KeyboardLayout = xfc->context.settings->KeyboardLayout;
|
||||
xfc->KeyboardLayout = freerdp_keyboard_init(xfc->KeyboardLayout);
|
||||
xfc->instance->settings->KeyboardLayout = xfc->KeyboardLayout;
|
||||
xfc->context.settings->KeyboardLayout = xfc->KeyboardLayout;
|
||||
|
||||
if (xfc->modifierMap)
|
||||
XFreeModifiermap(xfc->modifierMap);
|
||||
@@ -168,7 +166,6 @@ void xf_keyboard_key_release(xfContext* xfc, BYTE keycode)
|
||||
return;
|
||||
|
||||
xfc->KeyboardState[keycode] = FALSE;
|
||||
|
||||
xf_keyboard_send_key(xfc, FALSE, keycode);
|
||||
}
|
||||
|
||||
@@ -186,9 +183,10 @@ void xf_keyboard_release_all_keypress(xfContext* xfc)
|
||||
// release tab before releasing the windows key.
|
||||
// this stops the start menu from opening on unfocus event.
|
||||
if (rdp_scancode == RDP_SCANCODE_LWIN)
|
||||
freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, RDP_SCANCODE_TAB);
|
||||
freerdp_input_send_keyboard_event_ex(xfc->context.input, FALSE,
|
||||
RDP_SCANCODE_TAB);
|
||||
|
||||
freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, rdp_scancode);
|
||||
freerdp_input_send_keyboard_event_ex(xfc->context.input, FALSE, rdp_scancode);
|
||||
xfc->KeyboardState[keycode] = FALSE;
|
||||
}
|
||||
}
|
||||
@@ -204,8 +202,7 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
||||
{
|
||||
DWORD rdp_scancode;
|
||||
rdpInput* input;
|
||||
|
||||
input = xfc->instance->input;
|
||||
input = xfc->context.input;
|
||||
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
|
||||
|
||||
if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
|
||||
@@ -213,7 +210,8 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
||||
WLog_ERR(TAG, "Unknown key with X keycode 0x%02x", keycode);
|
||||
}
|
||||
else if (rdp_scancode == RDP_SCANCODE_PAUSE &&
|
||||
!xf_keyboard_key_pressed(xfc, XK_Control_L) && !xf_keyboard_key_pressed(xfc, XK_Control_R))
|
||||
!xf_keyboard_key_pressed(xfc, XK_Control_L)
|
||||
&& !xf_keyboard_key_pressed(xfc, XK_Control_R))
|
||||
{
|
||||
/* Pause without Ctrl has to be sent as a series of keycodes
|
||||
* in a single input PDU. Pause only happens on "press";
|
||||
@@ -246,13 +244,13 @@ int xf_keyboard_read_keyboard_state(xfContext* xfc)
|
||||
if (!xfc->remote_app)
|
||||
{
|
||||
XQueryPointer(xfc->display, xfc->window->handle,
|
||||
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
|
||||
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
|
||||
}
|
||||
else
|
||||
{
|
||||
XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
|
||||
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
|
||||
}
|
||||
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -277,6 +275,7 @@ static int xf_keyboard_get_keymask(xfContext* xfc, int keysym)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return keysymMask;
|
||||
}
|
||||
|
||||
@@ -304,22 +303,25 @@ static BOOL xf_keyboard_set_key_state(xfContext* xfc, BOOL on, int keysym)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return XkbLockModifiers(xfc->display, XkbUseCoreKbd, keysymMask, on ? keysymMask : 0);
|
||||
return XkbLockModifiers(xfc->display, XkbUseCoreKbd, keysymMask,
|
||||
on ? keysymMask : 0);
|
||||
}
|
||||
|
||||
UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc)
|
||||
{
|
||||
int state;
|
||||
UINT32 toggleKeysState = 0;
|
||||
|
||||
state = xf_keyboard_read_keyboard_state(xfc);
|
||||
|
||||
if (xf_keyboard_get_key_state(xfc, state, XK_Scroll_Lock))
|
||||
toggleKeysState |= KBD_SYNC_SCROLL_LOCK;
|
||||
|
||||
if (xf_keyboard_get_key_state(xfc, state, XK_Num_Lock))
|
||||
toggleKeysState |= KBD_SYNC_NUM_LOCK;
|
||||
|
||||
if (xf_keyboard_get_key_state(xfc, state, XK_Caps_Lock))
|
||||
toggleKeysState |= KBD_SYNC_CAPS_LOCK;
|
||||
|
||||
if (xf_keyboard_get_key_state(xfc, state, XK_Kana_Lock))
|
||||
toggleKeysState |= KBD_SYNC_KANA_LOCK;
|
||||
|
||||
@@ -336,9 +338,8 @@ void xf_keyboard_focus_in(xfContext* xfc)
|
||||
if (!xfc->display || !xfc->window)
|
||||
return;
|
||||
|
||||
input = xfc->instance->input;
|
||||
input = xfc->context.input;
|
||||
syncFlags = xf_keyboard_get_toggle_keys_state(xfc);
|
||||
|
||||
input->FocusInEvent(input, syncFlags);
|
||||
|
||||
/* finish with a mouse pointer position like mstsc.exe if required */
|
||||
@@ -346,7 +347,8 @@ void xf_keyboard_focus_in(xfContext* xfc)
|
||||
if (xfc->remote_app)
|
||||
return;
|
||||
|
||||
if (XQueryPointer(xfc->display, xfc->window->handle, &w, &w, &d, &d, &x, &y, &state))
|
||||
if (XQueryPointer(xfc->display, xfc->window->handle, &w, &w, &d, &d, &x, &y,
|
||||
&state))
|
||||
{
|
||||
if (x >= 0 && x < xfc->window->width && y >= 0 && y < xfc->window->height)
|
||||
{
|
||||
@@ -356,7 +358,9 @@ void xf_keyboard_focus_in(xfContext* xfc)
|
||||
}
|
||||
}
|
||||
|
||||
int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, KeySym keysym)
|
||||
static int xf_keyboard_execute_action_script(xfContext* xfc,
|
||||
XF_MODIFIER_KEYS* mod,
|
||||
KeySym keysym)
|
||||
{
|
||||
int index;
|
||||
int count;
|
||||
@@ -374,13 +378,14 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key
|
||||
return 1;
|
||||
|
||||
if ((keysym == XK_Shift_L) || (keysym == XK_Shift_R) ||
|
||||
(keysym == XK_Alt_L) || (keysym == XK_Alt_R) ||
|
||||
(keysym == XK_Control_L) || (keysym == XK_Control_R))
|
||||
(keysym == XK_Alt_L) || (keysym == XK_Alt_R) ||
|
||||
(keysym == XK_Control_L) || (keysym == XK_Control_R))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
keyStr = XKeysymToString(keysym);
|
||||
|
||||
if (keyStr == 0)
|
||||
{
|
||||
return 1;
|
||||
@@ -396,7 +401,6 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key
|
||||
strcat(combination, "Alt+");
|
||||
|
||||
strcat(combination, keyStr);
|
||||
|
||||
count = ArrayList_Count(xfc->keyCombinations);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
@@ -414,8 +418,7 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key
|
||||
return 1;
|
||||
|
||||
sprintf_s(command, sizeof(command), "%s key %s",
|
||||
xfc->actionScript, combination);
|
||||
|
||||
xfc->actionScript, combination);
|
||||
keyScript = popen(command, "r");
|
||||
|
||||
if (!keyScript)
|
||||
@@ -430,7 +433,6 @@ int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, Key
|
||||
}
|
||||
|
||||
exitCode = pclose(keyScript);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -439,26 +441,21 @@ int xk_keyboard_get_modifier_keys(xfContext* xfc, XF_MODIFIER_KEYS* mod)
|
||||
mod->LeftShift = xf_keyboard_key_pressed(xfc, XK_Shift_L);
|
||||
mod->RightShift = xf_keyboard_key_pressed(xfc, XK_Shift_R);
|
||||
mod->Shift = mod->LeftShift || mod->RightShift;
|
||||
|
||||
mod->LeftAlt = xf_keyboard_key_pressed(xfc, XK_Alt_L);
|
||||
mod->RightAlt = xf_keyboard_key_pressed(xfc, XK_Alt_R);
|
||||
mod->Alt = mod->LeftAlt || mod->RightAlt;
|
||||
|
||||
mod->LeftCtrl = xf_keyboard_key_pressed(xfc, XK_Control_L);
|
||||
mod->RightCtrl = xf_keyboard_key_pressed(xfc, XK_Control_R);
|
||||
mod->Ctrl = mod->LeftCtrl || mod->RightCtrl;
|
||||
|
||||
mod->LeftSuper = xf_keyboard_key_pressed(xfc, XK_Super_L);
|
||||
mod->RightSuper = xf_keyboard_key_pressed(xfc, XK_Super_R);
|
||||
mod->Super = mod->LeftSuper || mod->RightSuper;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
{
|
||||
XF_MODIFIER_KEYS mod = { 0 };
|
||||
|
||||
xk_keyboard_get_modifier_keys(xfc, &mod);
|
||||
|
||||
if (!xf_keyboard_execute_action_script(xfc, &mod, keysym))
|
||||
@@ -466,7 +463,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(!xfc->remote_app && xfc->fullscreen_toggle)
|
||||
if (!xfc->remote_app && xfc->fullscreen_toggle)
|
||||
{
|
||||
if (keysym == XK_Return)
|
||||
{
|
||||
@@ -491,6 +488,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
|
||||
#if 0 /* set to 1 to enable multi touch gesture simulation via keyboard */
|
||||
#ifdef WITH_XRENDER
|
||||
|
||||
if (!xfc->remote_app && xfc->settings->MultiTouchGestures)
|
||||
{
|
||||
if (mod.Ctrl && mod.Alt)
|
||||
@@ -500,18 +498,20 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
int zdx = 0;
|
||||
int zdy = 0;
|
||||
|
||||
switch(keysym)
|
||||
switch (keysym)
|
||||
{
|
||||
case XK_0: /* Ctrl-Alt-0: Reset scaling and panning */
|
||||
xfc->scaledWidth = xfc->sessionWidth;
|
||||
xfc->scaledHeight = xfc->sessionHeight;
|
||||
xfc->offset_x = 0;
|
||||
xfc->offset_y = 0;
|
||||
|
||||
if (!xfc->fullscreen && (xfc->sessionWidth != xfc->window->width ||
|
||||
xfc->sessionHeight != xfc->window->height))
|
||||
xfc->sessionHeight != xfc->window->height))
|
||||
{
|
||||
xf_ResizeDesktopWindow(xfc, xfc->window, xfc->sessionWidth, xfc->sessionHeight);
|
||||
}
|
||||
|
||||
xf_draw_screen(xfc, 0, 0, xfc->sessionWidth, xfc->sessionHeight);
|
||||
return TRUE;
|
||||
|
||||
@@ -561,6 +561,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WITH_XRENDER defined */
|
||||
#endif /* pinch/zoom/pan simulation */
|
||||
return FALSE;
|
||||
@@ -569,8 +570,8 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||
BOOL xf_keyboard_set_indicators(rdpContext* context, UINT16 led_flags)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_SCROLL_LOCK, XK_Scroll_Lock);
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_SCROLL_LOCK,
|
||||
XK_Scroll_Lock);
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_NUM_LOCK, XK_Num_Lock);
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_CAPS_LOCK, XK_Caps_Lock);
|
||||
xf_keyboard_set_key_state(xfc, led_flags & KBD_SYNC_KANA_LOCK, XK_Kana_Lock);
|
||||
|
||||
@@ -48,7 +48,6 @@ int xf_list_monitors(xfContext* xfc)
|
||||
int major, minor;
|
||||
int i, nmonitors = 0;
|
||||
XineramaScreenInfo* screen = NULL;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
|
||||
if (!display)
|
||||
@@ -66,9 +65,9 @@ int xf_list_monitors(xfContext* xfc)
|
||||
for (i = 0; i < nmonitors; i++)
|
||||
{
|
||||
printf(" %s [%d] %dx%d\t+%d+%d\n",
|
||||
(i == 0) ? "*" : " ", i,
|
||||
screen[i].width, screen[i].height,
|
||||
screen[i].x_org, screen[i].y_org);
|
||||
(i == 0) ? "*" : " ", i,
|
||||
screen[i].width, screen[i].height,
|
||||
screen[i].x_org, screen[i].y_org);
|
||||
}
|
||||
|
||||
XFree(screen);
|
||||
@@ -79,7 +78,6 @@ int xf_list_monitors(xfContext* xfc)
|
||||
#else
|
||||
Screen* screen;
|
||||
Display* display;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
|
||||
if (!display)
|
||||
@@ -89,19 +87,17 @@ int xf_list_monitors(xfContext* xfc)
|
||||
}
|
||||
|
||||
screen = ScreenOfDisplay(display, DefaultScreen(display));
|
||||
|
||||
printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen), HeightOfScreen(screen), 0, 0);
|
||||
|
||||
printf(" * [0] %dx%d\t+%d+%d\n", WidthOfScreen(screen),
|
||||
HeightOfScreen(screen), 0, 0);
|
||||
XCloseDisplay(display);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL xf_is_monitor_id_active(xfContext* xfc, UINT32 id)
|
||||
{
|
||||
int index;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
rdpSettings* settings = xfc->context.settings;
|
||||
|
||||
if (!settings->NumMonitorIds)
|
||||
return TRUE;
|
||||
@@ -121,28 +117,26 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
int nmonitors = 0;
|
||||
int primaryMonitorFound = FALSE;
|
||||
VIRTUAL_SCREEN* vscreen;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
|
||||
rdpSettings* settings = xfc->context.settings;
|
||||
int mouse_x, mouse_y, _dummy_i;
|
||||
Window _dummy_w;
|
||||
int current_monitor = 0;
|
||||
|
||||
#ifdef WITH_XINERAMA
|
||||
int major, minor;
|
||||
XineramaScreenInfo* screenInfo = NULL;
|
||||
#endif
|
||||
|
||||
vscreen = &xfc->vscreen;
|
||||
*pMaxWidth = settings->DesktopWidth;
|
||||
*pMaxHeight = settings->DesktopHeight;
|
||||
|
||||
/* get mouse location */
|
||||
if (!XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
|
||||
&_dummy_w, &_dummy_w, &mouse_x, &mouse_y,
|
||||
&_dummy_i, &_dummy_i, (void *) &_dummy_i))
|
||||
&_dummy_w, &_dummy_w, &mouse_x, &mouse_y,
|
||||
&_dummy_i, &_dummy_i, (void*) &_dummy_i))
|
||||
mouse_x = mouse_y = 0;
|
||||
|
||||
#ifdef WITH_XINERAMA
|
||||
|
||||
if (XineramaQueryExtension(xfc->display, &major, &minor))
|
||||
{
|
||||
if (XineramaIsActive(xfc->display))
|
||||
@@ -159,10 +153,11 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
vscreen->monitors[i].area.left = screenInfo[i].x_org;
|
||||
vscreen->monitors[i].area.top = screenInfo[i].y_org;
|
||||
vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1;
|
||||
vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - 1;
|
||||
vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height -
|
||||
1;
|
||||
|
||||
/* Determine which monitor that the mouse cursor is on */
|
||||
if ((mouse_x >= vscreen->monitors[i].area.left) &&
|
||||
if ((mouse_x >= vscreen->monitors[i].area.left) &&
|
||||
(mouse_x <= vscreen->monitors[i].area.right) &&
|
||||
(mouse_y >= vscreen->monitors[i].area.top) &&
|
||||
(mouse_y <= vscreen->monitors[i].area.bottom))
|
||||
@@ -173,15 +168,15 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
XFree(screenInfo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0;
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0;
|
||||
|
||||
/* WORKAROUND: With Remote Application Mode - using NET_WM_WORKAREA
|
||||
* causes issues with the ability to fully size the window vertically
|
||||
* (the bottom of the window area is never updated). So, we just set
|
||||
* the workArea to match the full Screen width/height.
|
||||
* causes issues with the ability to fully size the window vertically
|
||||
* (the bottom of the window area is never updated). So, we just set
|
||||
* the workArea to match the full Screen width/height.
|
||||
*/
|
||||
if (settings->RemoteApplicationMode || !xf_GetWorkArea(xfc))
|
||||
{
|
||||
@@ -211,8 +206,12 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
*/
|
||||
if (vscreen->nmonitors > 0)
|
||||
{
|
||||
*pMaxWidth = ((vscreen->monitors[current_monitor].area.right - vscreen->monitors[current_monitor].area.left + 1) * settings->PercentScreen) / 100;
|
||||
*pMaxHeight = ((vscreen->monitors[current_monitor].area.bottom - vscreen->monitors[current_monitor].area.top + 1) * settings->PercentScreen) / 100;
|
||||
*pMaxWidth = ((vscreen->monitors[current_monitor].area.right -
|
||||
vscreen->monitors[current_monitor].area.left + 1) * settings->PercentScreen) /
|
||||
100;
|
||||
*pMaxHeight = ((vscreen->monitors[current_monitor].area.bottom -
|
||||
vscreen->monitors[current_monitor].area.top + 1) * settings->PercentScreen) /
|
||||
100;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,8 +219,9 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
return TRUE;
|
||||
|
||||
/* If single monitor fullscreen OR workarea without remote app */
|
||||
if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors) ||
|
||||
(settings->Workarea && !settings->RemoteApplicationMode))
|
||||
if ((settings->Fullscreen && !settings->UseMultimon && !settings->SpanMonitors)
|
||||
||
|
||||
(settings->Workarea && !settings->RemoteApplicationMode))
|
||||
{
|
||||
/* If no monitors were specified on the command-line then set the current monitor as active */
|
||||
if (!settings->NumMonitorIds)
|
||||
@@ -244,10 +244,12 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
|
||||
settings->MonitorDefArray[nmonitors].x = vscreen->monitors[i].area.left;
|
||||
settings->MonitorDefArray[nmonitors].y = vscreen->monitors[i].area.top;
|
||||
settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1, *pMaxWidth);
|
||||
settings->MonitorDefArray[nmonitors].height = MIN(vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1, *pMaxHeight);
|
||||
settings->MonitorDefArray[nmonitors].width = MIN(vscreen->monitors[i].area.right
|
||||
- vscreen->monitors[i].area.left + 1, *pMaxWidth);
|
||||
settings->MonitorDefArray[nmonitors].height = MIN(
|
||||
vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1,
|
||||
*pMaxHeight);
|
||||
settings->MonitorDefArray[nmonitors].orig_screen = i;
|
||||
|
||||
nmonitors++;
|
||||
}
|
||||
|
||||
@@ -256,10 +258,13 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
{
|
||||
settings->MonitorDefArray[0].x = vscreen->monitors[current_monitor].area.left;
|
||||
settings->MonitorDefArray[0].y = vscreen->monitors[current_monitor].area.top;
|
||||
settings->MonitorDefArray[0].width = MIN(vscreen->monitors[current_monitor].area.right - vscreen->monitors[current_monitor].area.left + 1, *pMaxWidth);
|
||||
settings->MonitorDefArray[0].height = MIN(vscreen->monitors[current_monitor].area.bottom - vscreen->monitors[current_monitor].area.top + 1, *pMaxHeight);
|
||||
settings->MonitorDefArray[0].width = MIN(
|
||||
vscreen->monitors[current_monitor].area.right -
|
||||
vscreen->monitors[current_monitor].area.left + 1, *pMaxWidth);
|
||||
settings->MonitorDefArray[0].height = MIN(
|
||||
vscreen->monitors[current_monitor].area.bottom -
|
||||
vscreen->monitors[current_monitor].area.top + 1, *pMaxHeight);
|
||||
settings->MonitorDefArray[0].orig_screen = current_monitor;
|
||||
|
||||
nmonitors = 1;
|
||||
}
|
||||
|
||||
@@ -274,7 +279,8 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
int vR = vX + settings->MonitorDefArray[0].width;
|
||||
int vB = vY + settings->MonitorDefArray[0].height;
|
||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = settings->MonitorDefArray[0].orig_screen;
|
||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right =
|
||||
settings->MonitorDefArray[0].orig_screen;
|
||||
|
||||
/* Calculate bounding rectangle around all monitors to be used AND
|
||||
* also set the Xinerama indices which define left/top/right/bottom monitors.
|
||||
@@ -284,15 +290,20 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
/* does the same as gdk_rectangle_union */
|
||||
int destX = MIN(vX, settings->MonitorDefArray[i].x);
|
||||
int destY = MIN(vY, settings->MonitorDefArray[i].y);
|
||||
int destR = MAX(vR, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width);
|
||||
int destB = MAX(vB, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height);
|
||||
int destR = MAX(vR, settings->MonitorDefArray[i].x +
|
||||
settings->MonitorDefArray[i].width);
|
||||
int destB = MAX(vB, settings->MonitorDefArray[i].y +
|
||||
settings->MonitorDefArray[i].height);
|
||||
|
||||
if (vX != destX)
|
||||
xfc->fullscreenMonitors.left = settings->MonitorDefArray[i].orig_screen;
|
||||
|
||||
if (vY != destY)
|
||||
xfc->fullscreenMonitors.top = settings->MonitorDefArray[i].orig_screen;
|
||||
|
||||
if (vR != destR)
|
||||
xfc->fullscreenMonitors.right = settings->MonitorDefArray[i].orig_screen;
|
||||
|
||||
if (vB != destB)
|
||||
xfc->fullscreenMonitors.bottom = settings->MonitorDefArray[i].orig_screen;
|
||||
|
||||
@@ -304,7 +315,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
|
||||
settings->DesktopPosX = vX;
|
||||
settings->DesktopPosY = vY;
|
||||
|
||||
vscreen->area.left = 0;
|
||||
vscreen->area.right = vR - vX - 1;
|
||||
vscreen->area.top = 0;
|
||||
@@ -318,11 +328,12 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
|
||||
/* If there are multiple monitors and we have not selected a primary */
|
||||
if (!primaryMonitorFound)
|
||||
{
|
||||
{
|
||||
/* First lets try to see if there is a monitor with a 0,0 coordinate */
|
||||
for (i=0; i<settings->MonitorCount; i++)
|
||||
for (i = 0; i < settings->MonitorCount; i++)
|
||||
{
|
||||
if (!primaryMonitorFound && settings->MonitorDefArray[i].x == 0 && settings->MonitorDefArray[i].y == 0)
|
||||
if (!primaryMonitorFound && settings->MonitorDefArray[i].x == 0
|
||||
&& settings->MonitorDefArray[i].y == 0)
|
||||
{
|
||||
settings->MonitorDefArray[i].is_primary = TRUE;
|
||||
settings->MonitorLocalShiftX = settings->MonitorDefArray[i].x;
|
||||
@@ -341,16 +352,18 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
}
|
||||
}
|
||||
|
||||
/* Subtract monitor shift from monitor variables for server-side use.
|
||||
/* Subtract monitor shift from monitor variables for server-side use.
|
||||
* We maintain monitor shift value as Window requires the primary monitor to have a coordinate of 0,0
|
||||
* In some X configurations, no monitor may have a coordinate of 0,0. This can also be happen if the user
|
||||
* requests specific monitors from the command-line as well. So, we make sure to translate our primary monitor's
|
||||
* upper-left corner to 0,0 on the server.
|
||||
*/
|
||||
for (i=0; i < settings->MonitorCount; i++)
|
||||
for (i = 0; i < settings->MonitorCount; i++)
|
||||
{
|
||||
settings->MonitorDefArray[i].x = settings->MonitorDefArray[i].x - settings->MonitorLocalShiftX;
|
||||
settings->MonitorDefArray[i].y = settings->MonitorDefArray[i].y - settings->MonitorLocalShiftY;
|
||||
settings->MonitorDefArray[i].x = settings->MonitorDefArray[i].x -
|
||||
settings->MonitorLocalShiftX;
|
||||
settings->MonitorDefArray[i].y = settings->MonitorDefArray[i].y -
|
||||
settings->MonitorLocalShiftY;
|
||||
}
|
||||
|
||||
/* Set the desktop width and height according to the bounding rectangle around the active monitors */
|
||||
|
||||
@@ -83,7 +83,6 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
|
||||
{
|
||||
xfAppWindow* appWindow;
|
||||
RAIL_ACTIVATE_ORDER activate;
|
||||
|
||||
appWindow = xf_AppWindowFromX11Window(xfc, xwindow);
|
||||
|
||||
if (!appWindow)
|
||||
@@ -91,17 +90,15 @@ void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
|
||||
|
||||
activate.windowId = appWindow->windowId;
|
||||
activate.enabled = enabled;
|
||||
|
||||
xfc->rail->ClientActivate(xfc->rail, &activate);
|
||||
}
|
||||
|
||||
void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command)
|
||||
void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId,
|
||||
UINT16 command)
|
||||
{
|
||||
RAIL_SYSCOMMAND_ORDER syscommand;
|
||||
|
||||
syscommand.windowId = windowId;
|
||||
syscommand.command = command;
|
||||
|
||||
xfc->rail->ClientSystemCommand(xfc->rail, &syscommand);
|
||||
}
|
||||
|
||||
@@ -120,9 +117,9 @@ void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow)
|
||||
|
||||
/* If current window position disagrees with RDP window position, send update to RDP server */
|
||||
if (appWindow->x != appWindow->windowOffsetX ||
|
||||
appWindow->y != appWindow->windowOffsetY ||
|
||||
appWindow->width != appWindow->windowWidth ||
|
||||
appWindow->height != appWindow->windowHeight)
|
||||
appWindow->y != appWindow->windowOffsetY ||
|
||||
appWindow->width != appWindow->windowWidth ||
|
||||
appWindow->height != appWindow->windowHeight)
|
||||
{
|
||||
windowMove.windowId = appWindow->windowId;
|
||||
/*
|
||||
@@ -132,7 +129,6 @@ void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow)
|
||||
windowMove.top = appWindow->y;
|
||||
windowMove.right = windowMove.left + appWindow->width;
|
||||
windowMove.bottom = windowMove.top + appWindow->height;
|
||||
|
||||
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
|
||||
}
|
||||
}
|
||||
@@ -146,33 +142,30 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
|
||||
Window root_window;
|
||||
Window child_window;
|
||||
RAIL_WINDOW_MOVE_ORDER windowMove;
|
||||
rdpInput* input = xfc->instance->input;
|
||||
|
||||
rdpInput* input = xfc->context.input;
|
||||
/*
|
||||
* For keyboard moves send and explicit update to RDP server
|
||||
*/
|
||||
windowMove.windowId = appWindow->windowId;
|
||||
|
||||
/*
|
||||
* Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server
|
||||
*
|
||||
*/
|
||||
windowMove.left = appWindow->x;
|
||||
windowMove.top = appWindow->y;
|
||||
windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */
|
||||
windowMove.right = windowMove.left +
|
||||
appWindow->width; /* In the update to RDP the position is one past the window */
|
||||
windowMove.bottom = windowMove.top + appWindow->height;
|
||||
|
||||
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
|
||||
|
||||
/*
|
||||
* Simulate button up at new position to end the local move (per RDP spec)
|
||||
*/
|
||||
XQueryPointer(xfc->display, appWindow->handle,
|
||||
&root_window, &child_window, &x, &y, &child_x, &child_y, &mask);
|
||||
&root_window, &child_window, &x, &y, &child_x, &child_y, &mask);
|
||||
|
||||
/* only send the mouse coordinates if not a keyboard move or size */
|
||||
if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) &&
|
||||
(appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
|
||||
(appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
|
||||
{
|
||||
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
|
||||
}
|
||||
@@ -199,14 +192,13 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
|
||||
xfAppWindow* appWindow;
|
||||
const RECTANGLE_16* extents;
|
||||
REGION16 windowInvalidRegion;
|
||||
|
||||
region16_init(&windowInvalidRegion);
|
||||
|
||||
count = HashTable_GetKeys(xfc->railWindows, &pKeys);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]);
|
||||
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
|
||||
(void*) pKeys[index]);
|
||||
|
||||
if (appWindow)
|
||||
{
|
||||
@@ -214,14 +206,12 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
|
||||
windowRect.top = MAX(appWindow->y, 0);
|
||||
windowRect.right = MAX(appWindow->x + appWindow->width, 0);
|
||||
windowRect.bottom = MAX(appWindow->y + appWindow->height, 0);
|
||||
|
||||
region16_clear(&windowInvalidRegion);
|
||||
region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect);
|
||||
|
||||
if (!region16_is_empty(&windowInvalidRegion))
|
||||
{
|
||||
extents = region16_extents(&windowInvalidRegion);
|
||||
|
||||
updateRect.left = extents->left - appWindow->x;
|
||||
updateRect.top = extents->top - appWindow->y;
|
||||
updateRect.right = extents->right - appWindow->x;
|
||||
@@ -230,8 +220,8 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
|
||||
if (appWindow)
|
||||
{
|
||||
xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top,
|
||||
updateRect.right - updateRect.left,
|
||||
updateRect.bottom - updateRect.top);
|
||||
updateRect.right - updateRect.left,
|
||||
updateRect.bottom - updateRect.top);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,27 +230,25 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
|
||||
region16_uninit(&windowInvalidRegion);
|
||||
}
|
||||
|
||||
void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
|
||||
void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright,
|
||||
UINT32 ubottom)
|
||||
{
|
||||
REGION16 invalidRegion;
|
||||
RECTANGLE_16 invalidRect;
|
||||
|
||||
invalidRect.left = uleft;
|
||||
invalidRect.top = utop;
|
||||
invalidRect.right = uright;
|
||||
invalidRect.bottom = ubottom;
|
||||
|
||||
region16_init(&invalidRegion);
|
||||
region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect);
|
||||
|
||||
xf_rail_invalidate_region(xfc, &invalidRegion);
|
||||
|
||||
region16_uninit(&invalidRegion);
|
||||
}
|
||||
|
||||
/* RemoteApp Core Protocol Extension */
|
||||
|
||||
static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
|
||||
static BOOL xf_rail_window_common(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
|
||||
{
|
||||
xfAppWindow* appWindow = NULL;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
@@ -275,11 +263,9 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
return FALSE;
|
||||
|
||||
appWindow->xfc = xfc;
|
||||
|
||||
appWindow->windowId = orderInfo->windowId;
|
||||
appWindow->dwStyle = windowState->style;
|
||||
appWindow->dwExStyle = windowState->extendedStyle;
|
||||
|
||||
appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX;
|
||||
appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY;
|
||||
appWindow->width = appWindow->windowWidth = windowState->windowWidth;
|
||||
@@ -299,7 +285,7 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
}
|
||||
}
|
||||
else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
|
||||
windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
|
||||
windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
|
||||
{
|
||||
WLog_ERR(TAG, "failed to convert window title");
|
||||
/* error handled below */
|
||||
@@ -319,14 +305,14 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow);
|
||||
|
||||
HashTable_Add(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId,
|
||||
(void*) appWindow);
|
||||
xf_AppWindowInit(xfc, appWindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
|
||||
(void*) (UINT_PTR) orderInfo->windowId);
|
||||
(void*)(UINT_PTR) orderInfo->windowId);
|
||||
}
|
||||
|
||||
if (!appWindow)
|
||||
@@ -334,16 +320,15 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
|
||||
/* Keep track of any position/size update so that we can force a refresh of the window */
|
||||
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY))
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY))
|
||||
{
|
||||
position_or_size_updated = TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Update Parameters */
|
||||
|
||||
@@ -388,11 +373,12 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
}
|
||||
}
|
||||
else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
|
||||
windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
|
||||
windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
|
||||
{
|
||||
WLog_ERR(TAG, "failed to convert window title");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
free(appWindow->title);
|
||||
appWindow->title = title;
|
||||
}
|
||||
@@ -427,13 +413,14 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
|
||||
if (appWindow->numWindowRects)
|
||||
{
|
||||
appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16));
|
||||
appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects,
|
||||
sizeof(RECTANGLE_16));
|
||||
|
||||
if (!appWindow->windowRects)
|
||||
return FALSE;
|
||||
|
||||
CopyMemory(appWindow->windowRects, windowState->windowRects,
|
||||
appWindow->numWindowRects * sizeof(RECTANGLE_16));
|
||||
appWindow->numWindowRects * sizeof(RECTANGLE_16));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,13 +442,14 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
|
||||
if (appWindow->numVisibilityRects)
|
||||
{
|
||||
appWindow->visibilityRects = (RECTANGLE_16*) calloc(appWindow->numVisibilityRects, sizeof(RECTANGLE_16));
|
||||
appWindow->visibilityRects = (RECTANGLE_16*) calloc(
|
||||
appWindow->numVisibilityRects, sizeof(RECTANGLE_16));
|
||||
|
||||
if (!appWindow->visibilityRects)
|
||||
return FALSE;
|
||||
|
||||
CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
|
||||
appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
|
||||
appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,7 +457,6 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
|
||||
@@ -485,8 +472,10 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
|
||||
if (position_or_size_updated)
|
||||
{
|
||||
UINT32 visibilityRectsOffsetX = (appWindow->visibleOffsetX - (appWindow->clientOffsetX - appWindow->windowClientDeltaX));
|
||||
UINT32 visibilityRectsOffsetY = (appWindow->visibleOffsetY - (appWindow->clientOffsetY - appWindow->windowClientDeltaY));
|
||||
UINT32 visibilityRectsOffsetX = (appWindow->visibleOffsetX -
|
||||
(appWindow->clientOffsetX - appWindow->windowClientDeltaX));
|
||||
UINT32 visibilityRectsOffsetY = (appWindow->visibleOffsetY -
|
||||
(appWindow->clientOffsetY - appWindow->windowClientDeltaY));
|
||||
|
||||
/*
|
||||
* The rail server like to set the window to a small size when it is minimized even though it is hidden
|
||||
@@ -495,22 +484,25 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
*/
|
||||
if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
|
||||
{
|
||||
|
||||
/* Redraw window area if already in the correct position */
|
||||
if (appWindow->x == appWindow->windowOffsetX &&
|
||||
appWindow->y == appWindow->windowOffsetY &&
|
||||
appWindow->width == appWindow->windowWidth &&
|
||||
appWindow->height == appWindow->windowHeight)
|
||||
appWindow->y == appWindow->windowOffsetY &&
|
||||
appWindow->width == appWindow->windowWidth &&
|
||||
appWindow->height == appWindow->windowHeight)
|
||||
{
|
||||
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
|
||||
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth,
|
||||
appWindow->windowHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX, appWindow->windowOffsetY,
|
||||
appWindow->windowWidth, appWindow->windowHeight);
|
||||
xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX,
|
||||
appWindow->windowOffsetY,
|
||||
appWindow->windowWidth, appWindow->windowHeight);
|
||||
}
|
||||
|
||||
xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX, visibilityRectsOffsetY, appWindow->visibilityRects, appWindow->numVisibilityRects);
|
||||
xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX,
|
||||
visibilityRectsOffsetY, appWindow->visibilityRects,
|
||||
appWindow->numVisibilityRects);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,104 +511,103 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
{
|
||||
xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
|
||||
}*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_window_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
|
||||
static BOOL xf_rail_window_delete(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo)
|
||||
{
|
||||
xfAppWindow* appWindow = NULL;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
|
||||
(void*) (UINT_PTR) orderInfo->windowId);
|
||||
(void*)(UINT_PTR) orderInfo->windowId);
|
||||
|
||||
if (!appWindow)
|
||||
return TRUE;
|
||||
|
||||
HashTable_Remove(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId);
|
||||
|
||||
HashTable_Remove(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId);
|
||||
xf_DestroyWindow(xfc, appWindow);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_window_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
|
||||
static BOOL xf_rail_window_icon(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
|
||||
{
|
||||
BOOL bigIcon;
|
||||
xfAppWindow* railWindow;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
|
||||
railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
|
||||
(void*) (UINT_PTR) orderInfo->windowId);
|
||||
(void*)(UINT_PTR) orderInfo->windowId);
|
||||
|
||||
if (!railWindow)
|
||||
return FALSE;
|
||||
|
||||
bigIcon = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? TRUE : FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_window_cached_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* windowCachedIcon)
|
||||
static BOOL xf_rail_window_cached_icon(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* windowCachedIcon)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_notify_icon_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
|
||||
static BOOL xf_rail_notify_icon_common(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
|
||||
{
|
||||
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_notify_icon_create(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
|
||||
static BOOL xf_rail_notify_icon_create(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
|
||||
{
|
||||
return xf_rail_notify_icon_common(context, orderInfo, notifyIconState);
|
||||
}
|
||||
|
||||
static BOOL xf_rail_notify_icon_update(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
|
||||
static BOOL xf_rail_notify_icon_update(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
|
||||
{
|
||||
return xf_rail_notify_icon_common(context, orderInfo, notifyIconState);
|
||||
}
|
||||
|
||||
static BOOL xf_rail_notify_icon_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
|
||||
static BOOL xf_rail_notify_icon_delete(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_monitored_desktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop)
|
||||
static BOOL xf_rail_monitored_desktop(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_rail_non_monitored_desktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
|
||||
static BOOL xf_rail_non_monitored_desktop(rdpContext* context,
|
||||
WINDOW_ORDER_INFO* orderInfo)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
xf_rail_disable_remoteapp_mode(xfc);
|
||||
@@ -626,7 +617,6 @@ static BOOL xf_rail_non_monitored_desktop(rdpContext* context, WINDOW_ORDER_INFO
|
||||
void xf_rail_register_update_callbacks(rdpUpdate* update)
|
||||
{
|
||||
rdpWindowUpdate* window = update->window;
|
||||
|
||||
window->WindowCreate = xf_rail_window_common;
|
||||
window->WindowUpdate = xf_rail_window_common;
|
||||
window->WindowDelete = xf_rail_window_delete;
|
||||
@@ -646,14 +636,15 @@ void xf_rail_register_update_callbacks(rdpUpdate* update)
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT xf_rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult)
|
||||
static UINT xf_rail_server_execute_result(RailClientContext* context,
|
||||
RAIL_EXEC_RESULT_ORDER* execResult)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) context->custom;
|
||||
|
||||
if (execResult->execResult != RAIL_EXEC_S_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "RAIL exec error: execResult=%s NtError=0x%X\n",
|
||||
error_code_names[execResult->execResult], execResult->rawResult);
|
||||
error_code_names[execResult->execResult], execResult->rawResult);
|
||||
xfc->disconnect = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -669,7 +660,8 @@ static UINT xf_rail_server_execute_result(RailClientContext* context, RAIL_EXEC_
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT xf_rail_server_system_param(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
static UINT xf_rail_server_system_param(RailClientContext* context,
|
||||
RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
@@ -679,18 +671,17 @@ static UINT xf_rail_server_system_param(RailClientContext* context, RAIL_SYSPARA
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT xf_rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake)
|
||||
static UINT xf_rail_server_handshake(RailClientContext* context,
|
||||
RAIL_HANDSHAKE_ORDER* handshake)
|
||||
{
|
||||
RAIL_EXEC_ORDER exec;
|
||||
RAIL_SYSPARAM_ORDER sysparam;
|
||||
RAIL_HANDSHAKE_ORDER clientHandshake;
|
||||
RAIL_CLIENT_STATUS_ORDER clientStatus;
|
||||
xfContext* xfc = (xfContext*) context->custom;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
|
||||
rdpSettings* settings = xfc->context.settings;
|
||||
clientHandshake.buildNumber = 0x00001DB0;
|
||||
context->ClientHandshake(context, &clientHandshake);
|
||||
|
||||
ZeroMemory(&clientStatus, sizeof(RAIL_CLIENT_STATUS_ORDER));
|
||||
clientStatus.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
|
||||
context->ClientInformation(context, &clientStatus);
|
||||
@@ -703,44 +694,31 @@ static UINT xf_rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_
|
||||
}
|
||||
|
||||
ZeroMemory(&sysparam, sizeof(RAIL_SYSPARAM_ORDER));
|
||||
|
||||
sysparam.params = 0;
|
||||
|
||||
sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST;
|
||||
sysparam.highContrast.colorScheme.string = NULL;
|
||||
sysparam.highContrast.colorScheme.length = 0;
|
||||
sysparam.highContrast.flags = 0x7E;
|
||||
|
||||
sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP;
|
||||
sysparam.mouseButtonSwap = FALSE;
|
||||
|
||||
sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF;
|
||||
sysparam.keyboardPref = FALSE;
|
||||
|
||||
sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS;
|
||||
sysparam.dragFullWindows = FALSE;
|
||||
|
||||
sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES;
|
||||
sysparam.keyboardCues = FALSE;
|
||||
|
||||
sysparam.params |= SPI_MASK_SET_WORK_AREA;
|
||||
sysparam.workArea.left = 0;
|
||||
sysparam.workArea.top = 0;
|
||||
sysparam.workArea.right = settings->DesktopWidth;
|
||||
sysparam.workArea.bottom = settings->DesktopHeight;
|
||||
|
||||
sysparam.dragFullWindows = FALSE;
|
||||
|
||||
context->ClientSystemParam(context, &sysparam);
|
||||
|
||||
ZeroMemory(&exec, sizeof(RAIL_EXEC_ORDER));
|
||||
|
||||
exec.RemoteApplicationProgram = settings->RemoteApplicationProgram;
|
||||
exec.RemoteApplicationWorkingDir = settings->ShellWorkingDirectory;
|
||||
exec.RemoteApplicationArguments = settings->RemoteApplicationCmdLine;
|
||||
|
||||
context->ClientExecute(context, &exec);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
@@ -749,7 +727,8 @@ static UINT xf_rail_server_handshake(RailClientContext* context, RAIL_HANDSHAKE_
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT xf_rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||
static UINT xf_rail_server_handshake_ex(RailClientContext* context,
|
||||
RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||
{
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
@@ -759,16 +738,16 @@ static UINT xf_rail_server_handshake_ex(RailClientContext* context, RAIL_HANDSHA
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT xf_rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
|
||||
static UINT xf_rail_server_local_move_size(RailClientContext* context,
|
||||
RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
int direction = 0;
|
||||
Window child_window;
|
||||
xfAppWindow* appWindow = NULL;
|
||||
xfContext* xfc = (xfContext*) context->custom;
|
||||
|
||||
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
|
||||
(void*) (UINT_PTR) localMoveSize->windowId);
|
||||
(void*)(UINT_PTR) localMoveSize->windowId);
|
||||
|
||||
if (!appWindow)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
@@ -826,8 +805,8 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context, RAIL_LOCA
|
||||
case RAIL_WMSZ_MOVE:
|
||||
direction = _NET_WM_MOVERESIZE_MOVE;
|
||||
XTranslateCoordinates(xfc->display, appWindow->handle,
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
localMoveSize->posX, localMoveSize->posY, &x, &y, &child_window);
|
||||
RootWindowOfScreen(xfc->screen),
|
||||
localMoveSize->posX, localMoveSize->posY, &x, &y, &child_window);
|
||||
break;
|
||||
|
||||
case RAIL_WMSZ_KEYMOVE:
|
||||
@@ -864,23 +843,22 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context, RAIL_LOCA
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT xf_rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo)
|
||||
static UINT xf_rail_server_min_max_info(RailClientContext* context,
|
||||
RAIL_MINMAXINFO_ORDER* minMaxInfo)
|
||||
{
|
||||
xfAppWindow* appWindow = NULL;
|
||||
xfContext* xfc = (xfContext*) context->custom;
|
||||
|
||||
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
|
||||
(void*) (UINT_PTR) minMaxInfo->windowId);
|
||||
(void*)(UINT_PTR) minMaxInfo->windowId);
|
||||
|
||||
if (!appWindow)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
xf_SetWindowMinMaxInfo(xfc, appWindow,
|
||||
minMaxInfo->maxWidth, minMaxInfo->maxHeight,
|
||||
minMaxInfo->maxPosX, minMaxInfo->maxPosY,
|
||||
minMaxInfo->minTrackWidth, minMaxInfo->minTrackHeight,
|
||||
minMaxInfo->maxTrackWidth, minMaxInfo->maxTrackHeight);
|
||||
|
||||
minMaxInfo->maxWidth, minMaxInfo->maxHeight,
|
||||
minMaxInfo->maxPosX, minMaxInfo->maxPosY,
|
||||
minMaxInfo->minTrackWidth, minMaxInfo->minTrackHeight,
|
||||
minMaxInfo->maxTrackWidth, minMaxInfo->maxTrackHeight);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
@@ -889,7 +867,8 @@ static UINT xf_rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXI
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT xf_rail_server_language_bar_info(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
||||
static UINT xf_rail_server_language_bar_info(RailClientContext* context,
|
||||
RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
||||
{
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
@@ -899,7 +878,8 @@ static UINT xf_rail_server_language_bar_info(RailClientContext* context, RAIL_LA
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT xf_rail_server_get_appid_response(RailClientContext* context, RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
|
||||
static UINT xf_rail_server_get_appid_response(RailClientContext* context,
|
||||
RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
|
||||
{
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
@@ -907,13 +887,9 @@ static UINT xf_rail_server_get_appid_response(RailClientContext* context, RAIL_G
|
||||
int xf_rail_init(xfContext* xfc, RailClientContext* rail)
|
||||
{
|
||||
rdpContext* context = (rdpContext*) xfc;
|
||||
|
||||
xfc->rail = rail;
|
||||
|
||||
xf_rail_register_update_callbacks(context->update);
|
||||
|
||||
rail->custom = (void*) xfc;
|
||||
|
||||
rail->ServerExecuteResult = xf_rail_server_execute_result;
|
||||
rail->ServerSystemParam = xf_rail_server_system_param;
|
||||
rail->ServerHandshake = xf_rail_server_handshake;
|
||||
@@ -922,8 +898,8 @@ int xf_rail_init(xfContext* xfc, RailClientContext* rail)
|
||||
rail->ServerMinMaxInfo = xf_rail_server_min_max_info;
|
||||
rail->ServerLanguageBarInfo = xf_rail_server_language_bar_info;
|
||||
rail->ServerGetAppIdResponse = xf_rail_server_get_appid_response;
|
||||
|
||||
xfc->railWindows = HashTable_New(TRUE);
|
||||
|
||||
if (!xfc->railWindows)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -108,15 +108,14 @@ typedef struct _PropMotifWmHints PropMotifWmHints;
|
||||
/**
|
||||
* Post an event from the client to the X server
|
||||
*/
|
||||
void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int numArgs, ...)
|
||||
void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom,
|
||||
unsigned int numArgs, ...)
|
||||
{
|
||||
XEvent xevent;
|
||||
unsigned int i;
|
||||
va_list argp;
|
||||
va_start(argp, numArgs);
|
||||
|
||||
ZeroMemory(&xevent, sizeof(XEvent));
|
||||
|
||||
xevent.xclient.type = ClientMessage;
|
||||
xevent.xclient.serial = 0;
|
||||
xevent.xclient.send_event = False;
|
||||
@@ -125,29 +124,26 @@ void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int n
|
||||
xevent.xclient.message_type = atom;
|
||||
xevent.xclient.format = 32;
|
||||
|
||||
for (i=0; i<numArgs; i++)
|
||||
for (i = 0; i < numArgs; i++)
|
||||
{
|
||||
xevent.xclient.data.l[i] = va_arg(argp, int);
|
||||
}
|
||||
|
||||
DEBUG_X11("Send ClientMessage Event: wnd=0x%04X", (unsigned int) xevent.xclient.window);
|
||||
|
||||
DEBUG_X11("Send ClientMessage Event: wnd=0x%04X",
|
||||
(unsigned int) xevent.xclient.window);
|
||||
XSendEvent(xfc->display, RootWindowOfScreen(xfc->screen), False,
|
||||
SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
|
||||
|
||||
SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
|
||||
XSync(xfc->display, False);
|
||||
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
{
|
||||
int i;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
rdpSettings* settings = xfc->context.settings;
|
||||
int startX, startY;
|
||||
UINT32 width = window->width;
|
||||
UINT32 height = window->height;
|
||||
|
||||
window->decorations = xfc->decorations;
|
||||
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
|
||||
|
||||
@@ -169,34 +165,34 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
}
|
||||
|
||||
/* Determine the x,y starting location for the fullscreen window */
|
||||
if (fullscreen && xfc->instance->settings->MonitorCount)
|
||||
if (fullscreen && xfc->context.settings->MonitorCount)
|
||||
{
|
||||
/* Initialize startX and startY with reasonable values */
|
||||
startX = xfc->instance->settings->MonitorDefArray[0].x;
|
||||
startY = xfc->instance->settings->MonitorDefArray[0].y;
|
||||
startX = xfc->context.settings->MonitorDefArray[0].x;
|
||||
startY = xfc->context.settings->MonitorDefArray[0].y;
|
||||
|
||||
/* Search all monitors to find the lowest startX and startY values */
|
||||
for (i=0; i < xfc->instance->settings->MonitorCount; i++)
|
||||
for (i = 0; i < xfc->context.settings->MonitorCount; i++)
|
||||
{
|
||||
startX = MIN(startX, xfc->instance->settings->MonitorDefArray[i].x);
|
||||
startY = MIN(startY, xfc->instance->settings->MonitorDefArray[i].y);
|
||||
startX = MIN(startX, xfc->context.settings->MonitorDefArray[i].x);
|
||||
startY = MIN(startY, xfc->context.settings->MonitorDefArray[i].y);
|
||||
}
|
||||
|
||||
/* Lastly apply any monitor shift(translation from remote to local coordinate system)
|
||||
* to startX and startY values
|
||||
*/
|
||||
startX = startX + xfc->instance->settings->MonitorLocalShiftX;
|
||||
startY = startY + xfc->instance->settings->MonitorLocalShiftY;
|
||||
startX = startX + xfc->context.settings->MonitorLocalShiftX;
|
||||
startY = startY + xfc->context.settings->MonitorLocalShiftY;
|
||||
|
||||
/* Set monitor bounds */
|
||||
if (settings->MonitorCount > 1)
|
||||
{
|
||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
|
||||
xfc->fullscreenMonitors.top,
|
||||
xfc->fullscreenMonitors.bottom,
|
||||
xfc->fullscreenMonitors.left,
|
||||
xfc->fullscreenMonitors.right,
|
||||
1);
|
||||
xfc->fullscreenMonitors.top,
|
||||
xfc->fullscreenMonitors.bottom,
|
||||
xfc->fullscreenMonitors.left,
|
||||
xfc->fullscreenMonitors.right,
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,8 +206,8 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
|
||||
/* Set the fullscreen state */
|
||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
|
||||
fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
|
||||
xfc->_NET_WM_STATE_FULLSCREEN, 0, 0);
|
||||
fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
|
||||
xfc->_NET_WM_STATE_FULLSCREEN, 0, 0);
|
||||
|
||||
if (!fullscreen)
|
||||
{
|
||||
@@ -222,8 +218,9 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
|
||||
/* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */
|
||||
|
||||
BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length,
|
||||
unsigned long* nitems, unsigned long* bytes, BYTE** prop)
|
||||
BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property,
|
||||
int length,
|
||||
unsigned long* nitems, unsigned long* bytes, BYTE** prop)
|
||||
{
|
||||
int status;
|
||||
Atom actual_type;
|
||||
@@ -233,8 +230,8 @@ BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int leng
|
||||
return FALSE;
|
||||
|
||||
status = XGetWindowProperty(xfc->display, window,
|
||||
property, 0, length, FALSE, AnyPropertyType,
|
||||
&actual_type, &actual_format, nitems, bytes, prop);
|
||||
property, 0, length, FALSE, AnyPropertyType,
|
||||
&actual_type, &actual_format, nitems, bytes, prop);
|
||||
|
||||
if (status != Success)
|
||||
return FALSE;
|
||||
@@ -253,36 +250,32 @@ BOOL xf_GetCurrentDesktop(xfContext* xfc)
|
||||
BOOL status;
|
||||
unsigned long nitems;
|
||||
unsigned long bytes;
|
||||
unsigned char *prop;
|
||||
|
||||
unsigned char* prop;
|
||||
status = xf_GetWindowProperty(xfc, DefaultRootWindow(xfc->display),
|
||||
xfc->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop);
|
||||
xfc->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop);
|
||||
|
||||
if (!status)
|
||||
return FALSE;
|
||||
|
||||
xfc->current_desktop = (int) *prop;
|
||||
|
||||
xfc->current_desktop = (int) * prop;
|
||||
free(prop);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL xf_GetWorkArea(xfContext* xfc)
|
||||
{
|
||||
long *plong;
|
||||
long* plong;
|
||||
BOOL status;
|
||||
unsigned long nitems;
|
||||
unsigned long bytes;
|
||||
unsigned char *prop;
|
||||
|
||||
unsigned char* prop;
|
||||
status = xf_GetCurrentDesktop(xfc);
|
||||
|
||||
if (!status)
|
||||
return FALSE;
|
||||
|
||||
status = xf_GetWindowProperty(xfc, DefaultRootWindow(xfc->display),
|
||||
xfc->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop);
|
||||
xfc->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop);
|
||||
|
||||
if (!status)
|
||||
return FALSE;
|
||||
@@ -298,35 +291,30 @@ BOOL xf_GetWorkArea(xfContext* xfc)
|
||||
xfc->workArea.y = plong[xfc->current_desktop * 4 + 1];
|
||||
xfc->workArea.width = plong[xfc->current_desktop * 4 + 2];
|
||||
xfc->workArea.height = plong[xfc->current_desktop * 4 + 3];
|
||||
|
||||
free(prop);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void xf_SetWindowDecorations(xfContext* xfc, Window window, BOOL show)
|
||||
{
|
||||
PropMotifWmHints hints;
|
||||
|
||||
hints.decorations = (show) ? MWM_DECOR_ALL : 0;
|
||||
hints.functions = MWM_FUNC_ALL ;
|
||||
hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
|
||||
hints.inputMode = 0;
|
||||
hints.status = 0;
|
||||
|
||||
XChangeProperty(xfc->display, window, xfc->_MOTIF_WM_HINTS, xfc->_MOTIF_WM_HINTS, 32,
|
||||
PropModeReplace, (BYTE*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
|
||||
XChangeProperty(xfc->display, window, xfc->_MOTIF_WM_HINTS,
|
||||
xfc->_MOTIF_WM_HINTS, 32,
|
||||
PropModeReplace, (BYTE*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
|
||||
}
|
||||
|
||||
void xf_SetWindowUnlisted(xfContext* xfc, Window window)
|
||||
{
|
||||
Atom window_state[2];
|
||||
|
||||
window_state[0] = xfc->_NET_WM_STATE_SKIP_PAGER;
|
||||
window_state[1] = xfc->_NET_WM_STATE_SKIP_TASKBAR;
|
||||
|
||||
XChangeProperty(xfc->display, window, xfc->_NET_WM_STATE,
|
||||
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_state, 2);
|
||||
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_state, 2);
|
||||
}
|
||||
|
||||
static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid)
|
||||
@@ -337,19 +325,20 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid)
|
||||
pid = getpid();
|
||||
|
||||
am_wm_pid = xfc->_NET_WM_PID;
|
||||
|
||||
XChangeProperty(xfc->display, window, am_wm_pid, XA_CARDINAL,
|
||||
32, PropModeReplace, (BYTE*) &pid, 1);
|
||||
32, PropModeReplace, (BYTE*) &pid, 1);
|
||||
}
|
||||
|
||||
static const char* get_shm_id()
|
||||
{
|
||||
static char shm_id[64];
|
||||
sprintf_s(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
|
||||
sprintf_s(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X",
|
||||
GetCurrentProcessId());
|
||||
return shm_id;
|
||||
}
|
||||
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height)
|
||||
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width,
|
||||
int height)
|
||||
{
|
||||
XEvent xevent;
|
||||
int input_mask;
|
||||
@@ -357,28 +346,25 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
Window parentWindow;
|
||||
XClassHint* classHints;
|
||||
rdpSettings* settings;
|
||||
|
||||
window = (xfWindow*) calloc(1, sizeof(xfWindow));
|
||||
|
||||
if (!window)
|
||||
return NULL;
|
||||
|
||||
settings = xfc->instance->settings;
|
||||
parentWindow = (Window) xfc->settings->ParentWindowId;
|
||||
|
||||
settings = xfc->context.settings;
|
||||
parentWindow = (Window) xfc->context.settings->ParentWindowId;
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
window->decorations = xfc->decorations;
|
||||
window->is_mapped = FALSE;
|
||||
window->is_transient = FALSE;
|
||||
|
||||
window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
|
||||
xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height,
|
||||
0, xfc->depth, InputOutput, xfc->visual,
|
||||
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
||||
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
|
||||
|
||||
window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE));
|
||||
xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height,
|
||||
0, xfc->depth, InputOutput, xfc->visual,
|
||||
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
|
||||
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
|
||||
window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR),
|
||||
(S_IREAD | S_IWRITE));
|
||||
|
||||
if (window->shmid < 0)
|
||||
{
|
||||
@@ -387,10 +373,9 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
else
|
||||
{
|
||||
void* mem;
|
||||
|
||||
ftruncate(window->shmid, sizeof(window->handle));
|
||||
|
||||
mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, window->shmid, 0);
|
||||
mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
window->shmid, 0);
|
||||
|
||||
if (mem == MAP_FAILED)
|
||||
{
|
||||
@@ -409,8 +394,8 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
{
|
||||
classHints->res_name = "xfreerdp";
|
||||
|
||||
if (xfc->settings->WmClass)
|
||||
classHints->res_class = xfc->settings->WmClass;
|
||||
if (xfc->context.settings->WmClass)
|
||||
classHints->res_class = xfc->context.settings->WmClass;
|
||||
else
|
||||
classHints->res_class = "xfreerdp";
|
||||
|
||||
@@ -421,17 +406,17 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
xf_ResizeDesktopWindow(xfc, window, width, height);
|
||||
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
|
||||
xf_SetWindowPID(xfc, window->handle, 0);
|
||||
|
||||
input_mask =
|
||||
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
|
||||
VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
|
||||
PointerMotionMask | ExposureMask | PropertyChangeMask;
|
||||
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
|
||||
VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
|
||||
PointerMotionMask | ExposureMask | PropertyChangeMask;
|
||||
|
||||
if (xfc->grab_keyboard)
|
||||
input_mask |= EnterWindowMask | LeaveWindowMask;
|
||||
|
||||
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
|
||||
PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop));
|
||||
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL,
|
||||
32,
|
||||
PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop));
|
||||
|
||||
if (parentWindow)
|
||||
XReparentWindow(xfc->display, window->handle, parentWindow, 0, 0);
|
||||
@@ -439,7 +424,6 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
XSelectInput(xfc->display, window->handle, input_mask);
|
||||
XClearWindow(xfc->display, window->handle);
|
||||
XMapWindow(xfc->display, window->handle);
|
||||
|
||||
xf_input_init(xfc, window->handle);
|
||||
|
||||
/*
|
||||
@@ -451,47 +435,46 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
|
||||
XMaskEvent(xfc->display, VisibilityChangeMask, &xevent);
|
||||
}
|
||||
while (xevent.type != VisibilityNotify);
|
||||
|
||||
/*
|
||||
* The XCreateWindow call will start the window in the upper-left corner of our current
|
||||
* monitor instead of the upper-left monitor for remote app mode (which uses all monitors).
|
||||
* This extra call after the window is mapped will position the login window correctly
|
||||
*/
|
||||
if (xfc->settings->RemoteApplicationMode)
|
||||
if (xfc->context.settings->RemoteApplicationMode)
|
||||
{
|
||||
XMoveWindow(xfc->display, window->handle, 0, 0);
|
||||
}
|
||||
else if (settings->DesktopPosX || settings->DesktopPosY)
|
||||
{
|
||||
XMoveWindow(xfc->display, window->handle, settings->DesktopPosX, settings->DesktopPosY);
|
||||
XMoveWindow(xfc->display, window->handle, settings->DesktopPosX,
|
||||
settings->DesktopPosY);
|
||||
}
|
||||
|
||||
XStoreName(xfc->display, window->handle, name);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height)
|
||||
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width,
|
||||
int height)
|
||||
{
|
||||
XSizeHints* size_hints;
|
||||
|
||||
if (!xfc || !window)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (!(size_hints = XAllocSizeHints()))
|
||||
return;
|
||||
return;
|
||||
|
||||
size_hints->flags = PMinSize | PMaxSize | PWinGravity;
|
||||
|
||||
size_hints->win_gravity = NorthWestGravity;
|
||||
size_hints->min_width = size_hints->min_height = 1;
|
||||
size_hints->max_width = size_hints->max_height = 16384;
|
||||
|
||||
XSetWMNormalHints(xfc->display, window->handle, size_hints);
|
||||
|
||||
XResizeWindow(xfc->display, window->handle, width, height);
|
||||
|
||||
#ifdef WITH_XRENDER
|
||||
if (!xfc->settings->SmartSizing)
|
||||
|
||||
if (!xfc->context.settings->SmartSizing)
|
||||
#endif
|
||||
{
|
||||
if (!xfc->fullscreen)
|
||||
@@ -529,14 +512,13 @@ void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window)
|
||||
close(window->shmid);
|
||||
|
||||
shm_unlink(get_shm_id());
|
||||
|
||||
window->xfwin = (Window*) -1;
|
||||
window->xfwin = (Window*) - 1;
|
||||
window->shmid = -1;
|
||||
|
||||
free(window);
|
||||
}
|
||||
|
||||
void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style)
|
||||
void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style,
|
||||
UINT32 ex_style)
|
||||
{
|
||||
Atom window_type;
|
||||
|
||||
@@ -553,7 +535,8 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
|
||||
*/
|
||||
XSetWindowAttributes attrs;
|
||||
attrs.override_redirect = True;
|
||||
XChangeWindowAttributes(xfc->display, appWindow->handle, CWOverrideRedirect, &attrs);
|
||||
XChangeWindowAttributes(xfc->display, appWindow->handle, CWOverrideRedirect,
|
||||
&attrs);
|
||||
appWindow->is_transient = TRUE;
|
||||
xf_SetWindowUnlisted(xfc, appWindow->handle);
|
||||
window_type = xfc->_NET_WM_WINDOW_TYPE_POPUP;
|
||||
@@ -571,7 +554,6 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
|
||||
/* this includes dialogs, popups, etc, that need to be full-fledged windows */
|
||||
appWindow->is_transient = TRUE;
|
||||
window_type = xfc->_NET_WM_WINDOW_TYPE_DIALOG;
|
||||
|
||||
xf_SetWindowUnlisted(xfc, appWindow->handle);
|
||||
}
|
||||
else
|
||||
@@ -580,22 +562,21 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
|
||||
}
|
||||
|
||||
XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE,
|
||||
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
|
||||
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
|
||||
}
|
||||
|
||||
void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name)
|
||||
{
|
||||
const size_t i = strlen(name);
|
||||
XStoreName(xfc->display, appWindow->handle, name);
|
||||
|
||||
Atom wm_Name = xfc->_NET_WM_NAME;
|
||||
Atom utf8Str = xfc->UTF8_STRING;
|
||||
|
||||
XChangeProperty(xfc->display, appWindow->handle, wm_Name, utf8Str, 8,
|
||||
PropModeReplace, (unsigned char *)name, i);
|
||||
PropModeReplace, (unsigned char*)name, i);
|
||||
}
|
||||
|
||||
void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, int* height)
|
||||
void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width,
|
||||
int* height)
|
||||
{
|
||||
int vscreen_width;
|
||||
int vscreen_height;
|
||||
@@ -606,24 +587,29 @@ void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, int* he
|
||||
{
|
||||
*width = 1;
|
||||
}
|
||||
|
||||
if (*height < 1)
|
||||
{
|
||||
*height = 1;
|
||||
}
|
||||
|
||||
if (*x < xfc->vscreen.area.left)
|
||||
{
|
||||
*width += *x;
|
||||
*x = xfc->vscreen.area.left;
|
||||
}
|
||||
|
||||
if (*y < xfc->vscreen.area.top)
|
||||
{
|
||||
*height += *y;
|
||||
*y = xfc->vscreen.area.top;
|
||||
}
|
||||
|
||||
if (*width > vscreen_width)
|
||||
{
|
||||
*width = vscreen_width;
|
||||
}
|
||||
|
||||
if (*height > vscreen_height)
|
||||
{
|
||||
*height = vscreen_height;
|
||||
@@ -636,9 +622,8 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
|
||||
int input_mask;
|
||||
XWMHints* InputModeHint;
|
||||
XClassHint* class_hints;
|
||||
|
||||
xf_FixWindowCoordinates(xfc, &appWindow->x, &appWindow->y, &appWindow->width, &appWindow->height);
|
||||
|
||||
xf_FixWindowCoordinates(xfc, &appWindow->x, &appWindow->y, &appWindow->width,
|
||||
&appWindow->height);
|
||||
appWindow->decorations = FALSE;
|
||||
appWindow->fullscreen = FALSE;
|
||||
appWindow->local_move.state = LMS_NOT_ACTIVE;
|
||||
@@ -646,26 +631,25 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
|
||||
appWindow->is_transient = FALSE;
|
||||
appWindow->rail_state = 0;
|
||||
appWindow->rail_ignore_configure = FALSE;
|
||||
|
||||
appWindow->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
|
||||
appWindow->x, appWindow->y, appWindow->width, appWindow->height,
|
||||
0, xfc->depth, InputOutput, xfc->visual, 0, &xfc->attribs);
|
||||
appWindow->x, appWindow->y, appWindow->width, appWindow->height,
|
||||
0, xfc->depth, InputOutput, xfc->visual, 0, &xfc->attribs);
|
||||
|
||||
if (!appWindow->handle)
|
||||
return -1;
|
||||
|
||||
ZeroMemory(&gcv, sizeof(gcv));
|
||||
appWindow->gc = XCreateGC(xfc->display, appWindow->handle, GCGraphicsExposures, &gcv);
|
||||
|
||||
appWindow->gc = XCreateGC(xfc->display, appWindow->handle, GCGraphicsExposures,
|
||||
&gcv);
|
||||
class_hints = XAllocClassHint();
|
||||
|
||||
if (class_hints)
|
||||
{
|
||||
char* class = NULL;
|
||||
|
||||
if (xfc->settings->WmClass)
|
||||
if (xfc->context.settings->WmClass)
|
||||
{
|
||||
class_hints->res_class = xfc->settings->WmClass;
|
||||
class_hints->res_class = xfc->context.settings->WmClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -677,7 +661,6 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
|
||||
class_hints->res_name = "RAIL";
|
||||
XSetClassHint(xfc->display, appWindow->handle, class_hints);
|
||||
XFree(class_hints);
|
||||
|
||||
free(class);
|
||||
}
|
||||
|
||||
@@ -685,42 +668,34 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
|
||||
InputModeHint = XAllocWMHints();
|
||||
InputModeHint->flags = (1L << 0);
|
||||
InputModeHint->input = True;
|
||||
|
||||
XSetWMHints(xfc->display, appWindow->handle, InputModeHint);
|
||||
XFree(InputModeHint);
|
||||
|
||||
XSetWMProtocols(xfc->display, appWindow->handle, &(xfc->WM_DELETE_WINDOW), 1);
|
||||
|
||||
input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
|
||||
ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
|
||||
PointerMotionMask | Button1MotionMask | Button2MotionMask |
|
||||
Button3MotionMask | Button4MotionMask | Button5MotionMask |
|
||||
ButtonMotionMask | KeymapStateMask | ExposureMask |
|
||||
VisibilityChangeMask | StructureNotifyMask | SubstructureNotifyMask |
|
||||
SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask |
|
||||
ColormapChangeMask | OwnerGrabButtonMask;
|
||||
|
||||
ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
|
||||
PointerMotionMask | Button1MotionMask | Button2MotionMask |
|
||||
Button3MotionMask | Button4MotionMask | Button5MotionMask |
|
||||
ButtonMotionMask | KeymapStateMask | ExposureMask |
|
||||
VisibilityChangeMask | StructureNotifyMask | SubstructureNotifyMask |
|
||||
SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask |
|
||||
ColormapChangeMask | OwnerGrabButtonMask;
|
||||
XSelectInput(xfc->display, appWindow->handle, input_mask);
|
||||
|
||||
xf_SetWindowDecorations(xfc, appWindow->handle, appWindow->decorations);
|
||||
xf_SetWindowStyle(xfc, appWindow, appWindow->dwStyle, appWindow->dwExStyle);
|
||||
xf_SetWindowPID(xfc, appWindow->handle, 0);
|
||||
xf_ShowWindow(xfc, appWindow, WINDOW_SHOW);
|
||||
|
||||
XClearWindow(xfc->display, appWindow->handle);
|
||||
XMapWindow(xfc->display, appWindow->handle);
|
||||
|
||||
/* Move doesn't seem to work until window is mapped. */
|
||||
xf_MoveWindow(xfc, appWindow, appWindow->x, appWindow->y, appWindow->width, appWindow->height);
|
||||
|
||||
xf_MoveWindow(xfc, appWindow, appWindow->x, appWindow->y, appWindow->width,
|
||||
appWindow->height);
|
||||
xf_SetWindowText(xfc, appWindow, appWindow->title);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow,
|
||||
int maxWidth, int maxHeight, int maxPosX, int maxPosY,
|
||||
int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight)
|
||||
int maxWidth, int maxHeight, int maxPosX, int maxPosY,
|
||||
int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight)
|
||||
{
|
||||
XSizeHints* size_hints;
|
||||
size_hints = XAllocSizeHints();
|
||||
@@ -739,7 +714,8 @@ void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow,
|
||||
}
|
||||
}
|
||||
|
||||
void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y)
|
||||
void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow,
|
||||
int direction, int x, int y)
|
||||
{
|
||||
if (appWindow->local_move.state != LMS_NOT_ACTIVE)
|
||||
return;
|
||||
@@ -752,17 +728,15 @@ void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction
|
||||
appWindow->local_move.root_y = y;
|
||||
appWindow->local_move.state = LMS_STARTING;
|
||||
appWindow->local_move.direction = direction;
|
||||
|
||||
XUngrabPointer(xfc->display, CurrentTime);
|
||||
|
||||
xf_SendClientEvent(xfc, appWindow->handle,
|
||||
xfc->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */
|
||||
5, /* 5 arguments to follow */
|
||||
x, /* x relative to root window */
|
||||
y, /* y relative to root window */
|
||||
direction, /* extended ICCM direction flag */
|
||||
1, /* simulated mouse button 1 */
|
||||
1); /* 1 == application request per extended ICCM */
|
||||
xfc->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */
|
||||
5, /* 5 arguments to follow */
|
||||
x, /* x relative to root window */
|
||||
y, /* y relative to root window */
|
||||
direction, /* extended ICCM direction flag */
|
||||
1, /* simulated mouse button 1 */
|
||||
1); /* 1 == application request per extended ICCM */
|
||||
}
|
||||
|
||||
void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow)
|
||||
@@ -779,19 +753,20 @@ void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow)
|
||||
* Per ICCM, the X client can ask to cancel an active move.
|
||||
*/
|
||||
xf_SendClientEvent(xfc, appWindow->handle,
|
||||
xfc->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */
|
||||
5, /* 5 arguments to follow */
|
||||
appWindow->local_move.root_x, /* x relative to root window */
|
||||
appWindow->local_move.root_y, /* y relative to root window */
|
||||
_NET_WM_MOVERESIZE_CANCEL, /* extended ICCM direction flag */
|
||||
1, /* simulated mouse button 1 */
|
||||
1); /* 1 == application request per extended ICCM */
|
||||
xfc->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */
|
||||
5, /* 5 arguments to follow */
|
||||
appWindow->local_move.root_x, /* x relative to root window */
|
||||
appWindow->local_move.root_y, /* y relative to root window */
|
||||
_NET_WM_MOVERESIZE_CANCEL, /* extended ICCM direction flag */
|
||||
1, /* simulated mouse button 1 */
|
||||
1); /* 1 == application request per extended ICCM */
|
||||
}
|
||||
|
||||
appWindow->local_move.state = LMS_NOT_ACTIVE;
|
||||
}
|
||||
|
||||
void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height)
|
||||
void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
BOOL resize = FALSE;
|
||||
|
||||
@@ -802,7 +777,7 @@ void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int wid
|
||||
resize = TRUE;
|
||||
|
||||
if (appWindow->local_move.state == LMS_STARTING ||
|
||||
appWindow->local_move.state == LMS_ACTIVE)
|
||||
appWindow->local_move.state == LMS_ACTIVE)
|
||||
return;
|
||||
|
||||
appWindow->x = x;
|
||||
@@ -833,9 +808,10 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
|
||||
case WINDOW_SHOW_MAXIMIZED:
|
||||
/* Set the window as maximized */
|
||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4,
|
||||
_NET_WM_STATE_ADD,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_VERT,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||
_NET_WM_STATE_ADD,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_VERT,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||
|
||||
/*
|
||||
* This is a workaround for the case where the window is maximized locally before the rail server is told to maximize
|
||||
* the window, this appears to be a race condition where the local window with incomplete data and once the window is
|
||||
@@ -844,16 +820,19 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
|
||||
*/
|
||||
if (appWindow->rail_state == WINDOW_SHOW_MAXIMIZED)
|
||||
{
|
||||
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
|
||||
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth,
|
||||
appWindow->windowHeight);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WINDOW_SHOW:
|
||||
/* Ensure the window is not maximized */
|
||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4,
|
||||
_NET_WM_STATE_REMOVE,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_VERT,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||
_NET_WM_STATE_REMOVE,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_VERT,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||
|
||||
/*
|
||||
* Ignore configure requests until both the Maximized properties have been processed
|
||||
* to prevent condition where WM overrides size of request due to one or both of these properties
|
||||
@@ -865,6 +844,7 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
|
||||
|
||||
if (appWindow->is_transient)
|
||||
xf_SetWindowUnlisted(xfc, appWindow->handle);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -879,9 +859,9 @@ void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon)
|
||||
int x, y;
|
||||
int pixels;
|
||||
int propsize;
|
||||
long *propdata;
|
||||
long *dstp;
|
||||
UINT32 *srcp;
|
||||
long* propdata;
|
||||
long* dstp;
|
||||
UINT32* srcp;
|
||||
|
||||
if (!icon->big)
|
||||
return;
|
||||
@@ -902,16 +882,16 @@ void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon)
|
||||
}
|
||||
}
|
||||
|
||||
XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
|
||||
PropModeReplace, (BYTE *) propdata, propsize);
|
||||
|
||||
XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_ICON, XA_CARDINAL,
|
||||
32,
|
||||
PropModeReplace, (BYTE*) propdata, propsize);
|
||||
XFlush(xfc->display);
|
||||
|
||||
free(propdata);
|
||||
}
|
||||
#endif
|
||||
|
||||
void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects)
|
||||
void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow,
|
||||
RECTANGLE_16* rects, int nrects)
|
||||
{
|
||||
int i;
|
||||
XRectangle* xrects;
|
||||
@@ -930,13 +910,14 @@ void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rec
|
||||
xrects[i].height = rects[i].bottom - rects[i].top;
|
||||
}
|
||||
|
||||
XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
|
||||
XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0,
|
||||
xrects, nrects, ShapeSet, 0);
|
||||
free(xrects);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects)
|
||||
void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow,
|
||||
UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects)
|
||||
{
|
||||
int i;
|
||||
XRectangle* xrects;
|
||||
@@ -955,38 +936,36 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32
|
||||
xrects[i].height = rects[i].bottom - rects[i].top;
|
||||
}
|
||||
|
||||
XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, rectsOffsetX, rectsOffsetY, xrects, nrects, ShapeSet, 0);
|
||||
XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding,
|
||||
rectsOffsetX, rectsOffsetY, xrects, nrects, ShapeSet, 0);
|
||||
free(xrects);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y,
|
||||
int width, int height)
|
||||
int width, int height)
|
||||
{
|
||||
int ax, ay;
|
||||
|
||||
ax = x + appWindow->windowOffsetX;
|
||||
ay = y + appWindow->windowOffsetY;
|
||||
|
||||
if (ax + width > appWindow->windowOffsetX + appWindow->width)
|
||||
width = (appWindow->windowOffsetX + appWindow->width - 1) - ax;
|
||||
|
||||
if (ay + height > appWindow->windowOffsetY + appWindow->height)
|
||||
height = (appWindow->windowOffsetY + appWindow->height - 1) - ay;
|
||||
|
||||
xf_lock_x11(xfc, TRUE);
|
||||
|
||||
if (xfc->settings->SoftwareGdi)
|
||||
if (xfc->context.settings->SoftwareGdi)
|
||||
{
|
||||
XPutImage(xfc->display, xfc->primary, appWindow->gc, xfc->image,
|
||||
ax, ay, ax, ay, width, height);
|
||||
ax, ay, ax, ay, width, height);
|
||||
}
|
||||
|
||||
XCopyArea(xfc->display, xfc->primary, appWindow->handle, appWindow->gc,
|
||||
ax, ay, width, height, x, y);
|
||||
|
||||
ax, ay, width, height, x, y);
|
||||
XFlush(xfc->display);
|
||||
|
||||
xf_unlock_x11(xfc, TRUE);
|
||||
}
|
||||
|
||||
@@ -1011,14 +990,11 @@ void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow)
|
||||
close(appWindow->shmid);
|
||||
|
||||
shm_unlink(get_shm_id());
|
||||
|
||||
appWindow->xfwin = (Window*) -1;
|
||||
appWindow->xfwin = (Window*) - 1;
|
||||
appWindow->shmid = -1;
|
||||
|
||||
free(appWindow->title);
|
||||
free(appWindow->windowRects);
|
||||
free(appWindow->visibilityRects);
|
||||
|
||||
free(appWindow);
|
||||
}
|
||||
|
||||
@@ -1028,12 +1004,12 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
|
||||
int count;
|
||||
ULONG_PTR* pKeys = NULL;
|
||||
xfAppWindow* appWindow;
|
||||
|
||||
count = HashTable_GetKeys(xfc->railWindows, &pKeys);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]);
|
||||
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
|
||||
(void*) pKeys[index]);
|
||||
|
||||
if (appWindow->handle == wnd)
|
||||
{
|
||||
@@ -1043,6 +1019,5 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
|
||||
}
|
||||
|
||||
free(pKeys);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -94,16 +94,12 @@ struct xf_context
|
||||
rdpContext context;
|
||||
DEFINE_RDP_CLIENT_COMMON();
|
||||
|
||||
freerdp* instance;
|
||||
rdpSettings* settings;
|
||||
|
||||
GC gc;
|
||||
int xfds;
|
||||
int depth;
|
||||
|
||||
GC gc_mono;
|
||||
BOOL invert;
|
||||
UINT32 format;
|
||||
Screen* screen;
|
||||
XImage* image;
|
||||
Pixmap primary;
|
||||
|
||||
Reference in New Issue
Block a user