Refactored xfContext.

This commit is contained in:
Armin Novak
2016-08-03 14:16:20 +02:00
parent fbdb00aa0c
commit c8a7065f93
12 changed files with 462 additions and 522 deletions

View File

@@ -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)
{

View File

@@ -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)

View File

@@ -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,

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;