void xf_draw_screen(xfContext* xfc, int x, int y, int w, int h) { if (w == 0 || h == 0) { WLog_WARN(TAG, "invalid width and/or height specified: w=%d h=%d", w, h); return; } #ifdef WITH_XRENDER if (xf_picture_transform_required(xfc)) { xf_draw_screen_scaled(xfc, x, y, w, h); return; } #endif XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y); }
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app) { int x, y; int w, h; x = event->xexpose.x; y = event->xexpose.y; w = event->xexpose.width; h = event->xexpose.height; if (xfc->gfx) { xf_OutputExpose(xfc, x, y, w, h); return TRUE; } if (!app) { if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) { xf_draw_screen_scaled(xfc, x - xfc->offset_x, y - xfc->offset_y, w, h, FALSE); } else { XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y); } } else { xfWindow* xfw; rdpWindow* window; rdpRail* rail = ((rdpContext*) xfc)->rail; window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window); if (window) { xfw = (xfWindow*) window->extra; xf_UpdateWindowArea(xfc, xfw, x, y, w, h); } } return TRUE; }
static BOOL xf_event_Expose(xfInfo* xfi, XEvent* event, BOOL app) { int x, y; int w, h; x = event->xexpose.x; y = event->xexpose.y; w = event->xexpose.width; h = event->xexpose.height; if (!app) { if (xfi->scale != 1.0) { xf_draw_screen_scaled(xfi); } else { XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); } } else { xfWindow* xfw; rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window); if (window != NULL) { xfw = (xfWindow*) window->extra; xf_UpdateWindowArea(xfi, xfw, x, y, w, h); } } return TRUE; }
static BOOL xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, BOOL app) { rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; if (xfi->width != event->xconfigure.width) { xfi->scale = (double) event->xconfigure.width / (double) xfi->originalWidth; xfi->currentWidth = event->xconfigure.width; xfi->currentHeight = event->xconfigure.width; xf_draw_screen_scaled(xfi); } window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window); if (window != NULL) { xfWindow* xfw; Window childWindow; xfw = (xfWindow*) window->extra; /* * ConfigureNotify coordinates are expressed relative to the window parent. * Translate these to root window coordinates. */ XTranslateCoordinates(xfi->display, xfw->handle, RootWindowOfScreen(xfi->screen), 0, 0, &xfw->left, &xfw->top, &childWindow); xfw->width = event->xconfigure.width; xfw->height = event->xconfigure.height; xfw->right = xfw->left + xfw->width - 1; xfw->bottom = xfw->top + xfw->height - 1; DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u send_event=%d", (UINT32) xfw->handle, xfw->left, xfw->top, xfw->right, xfw->bottom, xfw->width, xfw->height, event->xconfigure.send_event); /* * Additonal checks for not in a local move and not ignoring configure to send * position update to server, also should the window not be focused then do not * send to server yet(ie. resizing using window decoration). * The server will be updated when the window gets refocused. */ if (app && xfw->decorations) { /* moving resizing using window decoration */ xf_rail_adjust_position(xfi, window); window->windowOffsetX = xfw->left; window->visibleOffsetX = window->windowOffsetX; window->windowOffsetY = xfw->top; window->visibleOffsetY = window->windowOffsetY; window->windowWidth = xfw->width; window->windowHeight = xfw->height; } else { if (app && (!event->xconfigure.send_event || xfi->window->local_move.state == LMS_NOT_ACTIVE) && !xfw->rail_ignore_configure && xfi->focused) xf_rail_adjust_position(xfi, window); } } return True; }
void xf_hw_end_paint(rdpContext *context) { INT32 x, y; UINT32 w, h; xfContext *xfc = (xfContext *) context; if(!xfc->remote_app) { if(!xfc->complex_regions) { if(xfc->hdc->hwnd->invalid->null) return; x = xfc->hdc->hwnd->invalid->x; y = xfc->hdc->hwnd->invalid->y; w = xfc->hdc->hwnd->invalid->w; h = xfc->hdc->hwnd->invalid->h; xf_lock_x11(xfc, FALSE); if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) { xf_draw_screen_scaled(xfc, x, y, w, h, TRUE); } else { XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, x, y, w, h, x, y); } xf_unlock_x11(xfc, FALSE); } else { int i; int ninvalid; HGDI_RGN cinvalid; if(xfc->hdc->hwnd->ninvalid < 1) return; ninvalid = xfc->hdc->hwnd->ninvalid; cinvalid = xfc->hdc->hwnd->cinvalid; xf_lock_x11(xfc, FALSE); for(i = 0; i < ninvalid; i++) { x = cinvalid[i].x; y = cinvalid[i].y; w = cinvalid[i].w; h = cinvalid[i].h; if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) { xf_draw_screen_scaled(xfc, x, y, w, h, TRUE); } else { XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, x, y, w, h, x, y); } } XFlush(xfc->display); xf_unlock_x11(xfc, FALSE); } } else { if(xfc->hdc->hwnd->invalid->null) return; x = xfc->hdc->hwnd->invalid->x; y = xfc->hdc->hwnd->invalid->y; w = xfc->hdc->hwnd->invalid->w; h = xfc->hdc->hwnd->invalid->h; xf_lock_x11(xfc, FALSE); xf_rail_paint(xfc, context->rail, x, y, x + w - 1, y + h - 1); xf_unlock_x11(xfc, FALSE); } }
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)) { return TRUE; } if(xfc->fullscreen_toggle) { if (keysym == XK_Return) { if (mod.Ctrl && mod.Alt) { /* Ctrl-Alt-Enter: toggle full screen */ xf_toggle_fullscreen(xfc); return TRUE; } } } if ((keysym == XK_c) || (keysym == XK_C)) { if (mod.Ctrl && mod.Alt) { /* Ctrl-Alt-C: toggle control */ xf_toggle_control(xfc); return TRUE; } } if (keysym == XK_period) { if (mod.Ctrl && mod.Alt) { /* Zoom In (scale larger) */ double s = xfc->settings->ScalingFactor; s += 0.1; if (s > 2.0) s = 2.0; xfc->settings->ScalingFactor = s; xfc->currentWidth = xfc->originalWidth * s; xfc->currentHeight = xfc->originalHeight * s; xf_transform_window(xfc); { ResizeWindowEventArgs e; EventArgsInit(&e, "xfreerdp"); e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor; e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor; PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e); } xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE); return TRUE; } } if (keysym == XK_comma) { if (mod.Ctrl && mod.Alt) { /* Zoom Out (scale smaller) */ double s = xfc->settings->ScalingFactor; s -= 0.1; if (s < 0.5) s = 0.5; xfc->settings->ScalingFactor = s; xfc->currentWidth = xfc->originalWidth * s; xfc->currentHeight = xfc->originalHeight * s; xf_transform_window(xfc); { ResizeWindowEventArgs e; EventArgsInit(&e, "xfreerdp"); e.width = (int) xfc->originalWidth * xfc->settings->ScalingFactor; e.height = (int) xfc->originalHeight * xfc->settings->ScalingFactor; PubSub_OnResizeWindow(((rdpContext*) xfc)->pubSub, xfc, &e); } xf_draw_screen_scaled(xfc, 0, 0, 0, 0, FALSE); return TRUE; } } if (keysym == XK_KP_4) { if (mod.Ctrl && mod.Alt) { { PanningChangeEventArgs e; EventArgsInit(&e, "xfreerdp"); e.XPan = -5; e.YPan = 0; PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e); } return TRUE; } } if (keysym == XK_KP_6) { if (mod.Ctrl && mod.Alt) { { PanningChangeEventArgs e; EventArgsInit(&e, "xfreerdp"); e.XPan = 5; e.YPan = 0; PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e); } return TRUE; } } if (keysym == XK_KP_8) { if (mod.Ctrl && mod.Alt) { { PanningChangeEventArgs e; EventArgsInit(&e, "xfreerdp"); e.XPan = 0; e.YPan = -5; PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e); } return TRUE; } } if (keysym == XK_KP_2) { if (mod.Ctrl && mod.Alt) { { PanningChangeEventArgs e; EventArgsInit(&e, "xfreerdp"); e.XPan = 0; e.YPan = 5; PubSub_OnPanningChange(((rdpContext*) xfc)->pubSub, xfc, &e); } return TRUE; } } return FALSE; }
void xf_sw_end_paint(rdpContext* context) { rdpGdi* gdi; xfInfo* xfi; INT32 x, y; UINT32 w, h; xfi = ((xfContext*) context)->xfi; gdi = context->gdi; if (!xfi->remote_app) { if (!xfi->complex_regions) { if (gdi->primary->hdc->hwnd->invalid->null) return; x = gdi->primary->hdc->hwnd->invalid->x; y = gdi->primary->hdc->hwnd->invalid->y; w = gdi->primary->hdc->hwnd->invalid->w; h = gdi->primary->hdc->hwnd->invalid->h; xf_lock_x11(xfi, FALSE); XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h); if (xfi->scale != 1.0) { xf_draw_screen_scaled(xfi); } else { XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); } xf_unlock_x11(xfi, FALSE); } else { int i; int ninvalid; HGDI_RGN cinvalid; if (gdi->primary->hdc->hwnd->ninvalid < 1) return; ninvalid = gdi->primary->hdc->hwnd->ninvalid; cinvalid = gdi->primary->hdc->hwnd->cinvalid; xf_lock_x11(xfi, FALSE); for (i = 0; i < ninvalid; i++) { x = cinvalid[i].x; y = cinvalid[i].y; w = cinvalid[i].w; h = cinvalid[i].h; XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h); if (xfi->scale != 1.0) { xf_draw_screen_scaled(xfi); } else { XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); } } XFlush(xfi->display); xf_unlock_x11(xfi, FALSE); } } else { if (gdi->primary->hdc->hwnd->invalid->null) return; x = gdi->primary->hdc->hwnd->invalid->x; y = gdi->primary->hdc->hwnd->invalid->y; w = gdi->primary->hdc->hwnd->invalid->w; h = gdi->primary->hdc->hwnd->invalid->h; xf_lock_x11(xfi, FALSE); xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1); xf_unlock_x11(xfi, FALSE); } }