boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean 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 != true) { 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_ClientMessage(xfInfo* xfi, XEvent* event, BOOL app) { if ((event->xclient.message_type == xfi->WM_PROTOCOLS) && ((Atom) event->xclient.data.l[0] == xfi->WM_DELETE_WINDOW)) { if (app) { DEBUG_X11("RAIL window closed"); rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; window = window_list_get_by_extra_id(rail->list, (void*) event->xclient.window); if (window != NULL) { xf_rail_send_client_system_command(xfi, window->windowId, SC_CLOSE); } return TRUE; } else { DEBUG_X11("Main window closed"); return FALSE; } } return TRUE; }
static BOOL xf_event_FocusIn(xfInfo* xfi, XEvent* event, BOOL app) { if (event->xfocus.mode == NotifyGrab) return TRUE; xfi->focused = TRUE; if (xfi->mouse_active && (!app)) XGrabKeyboard(xfi->display, xfi->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime); if (app) { xf_rail_send_activate(xfi, event->xany.window, TRUE); rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); /* Update the server with any window changes that occured while the window was not focused. */ if (window != NULL) xf_rail_adjust_position(xfi, window); } xf_kbd_focus_in(xfi); if (!app) xf_cliprdr_check_owner(xfi); return TRUE; }
static BOOL xf_event_UnmapNotify(xfInfo* xfi, XEvent* event, BOOL app) { rdpWindow* window; rdpUpdate* update = xfi->instance->update; rdpRail* rail = ((rdpContext*) xfi->context)->rail; xf_kbd_release_all_keypress(xfi); if (!app) { update->SuppressOutput((rdpContext*) xfi->context, 0, NULL); } else { window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); if (window != NULL) { xfWindow* xfw = (xfWindow*) window->extra; xfw->is_mapped = FALSE; } } return TRUE; }
static BOOL xf_event_EnterNotify(xfInfo* xfi, XEvent* event, BOOL app) { if (!app) { xfi->mouse_active = TRUE; if (xfi->fullscreen) XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); if (xfi->focused) XGrabKeyboard(xfi->display, xfi->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime); } else { /* keep track of which window has focus so that we can apply pointer updates */ 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; xfi->window = xfw; } } return TRUE; }
boolean xf_event_ClientMessage(xfInfo* xfi, XEvent* event, boolean app) { if ((event->xclient.message_type == xfi->WM_PROTOCOLS) && ((Atom) event->xclient.data.l[0] == xfi->WM_DELETE_WINDOW)) { if (app) { rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; window = window_list_get_by_extra_id(rail->list, (void*) event->xclient.window); if (window != NULL) { xf_rail_send_client_system_command(xfi, window->windowId, SC_CLOSE); } return true; } else { return false; } } return true; }
boolean xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, boolean app) { uint16 x, y; uint16 flags; rdpInput* input; input = xfi->instance->input; x = 0; y = 0; flags = 0; switch (event->xbutton.button) { case 1: x = event->xmotion.x; y = event->xmotion.y; flags = PTR_FLAGS_BUTTON1; break; case 2: x = event->xmotion.x; y = event->xmotion.y; flags = PTR_FLAGS_BUTTON3; break; case 3: x = event->xmotion.x; y = event->xmotion.y; flags = PTR_FLAGS_BUTTON2; break; default: flags = 0; break; } if (flags != 0) { if (app) { xfWindow* xfw; rdpWindow* window; window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xany.window); if (window != NULL) { xfw = (xfWindow*) window->extra; x += xfw->left; y += xfw->top; } } input->MouseEvent(input, flags, x, y); } return True; }
boolean xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, boolean app) { uint16 x, y; uint16 flags; rdpInput* input; input = xfi->instance->input; x = 0; y = 0; flags = 0; switch (event->xbutton.button) { case 1: x = event->xbutton.x; y = event->xbutton.y; flags = PTR_FLAGS_BUTTON1; break; case 2: x = event->xbutton.x; y = event->xbutton.y; flags = PTR_FLAGS_BUTTON3; break; case 3: x = event->xbutton.x; y = event->xbutton.y; flags = PTR_FLAGS_BUTTON2; break; default: flags = 0; break; } if (flags != 0) { if (app) { rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; window = window_list_get_by_extra_id(rail->list, (void*) event->xbutton.window); if (window != NULL) { x += window->windowOffsetX; y += window->windowOffsetY; } } input->MouseEvent(input, flags, x, y); } return true; }
boolean xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, boolean app) { rdpWindow* window; window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xconfigure.window); if (window != NULL) { xfWindow* xfw; xfw = (xfWindow*) window->extra; DEBUG_X11_LMS("ConfigureNotify: send_event=%d eventWindow=0x%X window=0x%X above=0x%X rc={l=%d t=%d r=%d b=%d} " "w=%d h=%d override_redirect=%d", event->xconfigure.send_event, (uint32)event->xconfigure.event, (uint32)event->xconfigure.window, (uint32)event->xconfigure.above, event->xconfigure.x, event->xconfigure.y, event->xconfigure.x + event->xconfigure.width - 1, event->xconfigure.y + event->xconfigure.height - 1, event->xconfigure.width, event->xconfigure.height, event->xconfigure.override_redirect); if (xfw->isLocalMoveSizeModeEnabled && event->xconfigure.above != 0) { uint32 left = event->xconfigure.x; uint32 top = event->xconfigure.y; uint32 right = event->xconfigure.x + event->xconfigure.width; uint32 bottom = event->xconfigure.y + event->xconfigure.height; DEBUG_X11_LMS("MoveSendToServer: windowId=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d \n", (uint32)xfw->handle, left, top, right, bottom, event->xconfigure.width, event->xconfigure.height); xf_rail_send_windowmove(xfi, window->windowId, left, top, right, bottom); } XPutImage(xfi->display, xfi->primary, xfw->gc, xfi->image, xfw->left, xfw->top, xfw->left, xfw->top, xfw->width, xfw->height); XCopyArea(xfi->display, xfi->primary, xfw->handle, xfw->gc, xfw->left, xfw->top, xfw->width, xfw->height, 0, 0); XFlush(xfi->display); } return True; }
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled) { rdpChanMan* chanman; rdpWindow* rail_window; RAIL_ACTIVATE_ORDER activate; chanman = GET_CHANMAN(xfi->instance); rail_window = window_list_get_by_extra_id(xfi->rail->list, (void*)xwindow); if (rail_window == NULL) return; activate.windowId = rail_window->windowId; activate.enabled = enabled; xf_send_rail_client_event(chanman, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, &activate); }
void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled) { rdpRail* rail; rdpChannels* channels; rdpWindow* rail_window; RAIL_ACTIVATE_ORDER activate; rail = ((rdpContext*) xfc)->rail; channels = ((rdpContext*) xfc)->channels; rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow); if (rail_window == NULL) return; activate.windowId = rail_window->windowId; activate.enabled = enabled; xf_send_rail_client_event(channels, RailChannel_ClientActivate, &activate); }
boolean xf_event_MapNotify(xfInfo* xfi, XEvent* event, boolean app) { rdpWindow* window; if (app != True) return True; window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xany.window); if (window != NULL) { /* local restore event */ xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE); } return True; }
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; }
boolean xf_event_UnmapNotify(xfInfo* xfi, XEvent* event, boolean app) { rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; if (app != true) return true; window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); if (window != NULL) { xfWindow *xfw = (xfWindow*) window->extra; xfw->is_mapped = false; } return true; }
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, tbool enabled) { rdpRail* rail; rdpChannels* channels; rdpWindow* rail_window; RAIL_ACTIVATE_ORDER activate; rail = xfi->_context->rail; channels = xfi->_context->channels; rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow); if (rail_window == NULL) return; activate.windowId = rail_window->windowId; activate.enabled = enabled; xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, &activate); }
boolean xf_event_MapNotify(xfInfo* xfi, XEvent* event, boolean app) { rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; if (app != true) return true; window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); if (window != NULL) { /* local restore event */ xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE); xfWindow *xfw = (xfWindow*) window->extra; xfw->is_mapped = true; } return true; }
boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean app) { int x, y; int cx, cy; if (app != True) { x = event->xexpose.x; y = event->xexpose.y; cx = event->xexpose.width; cy = event->xexpose.height; XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, cx, cy, x, y); } else { #if 0 xfWindow* xfw; rdpWindow* window; window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xany.window); if (window != NULL) { xfw = (xfWindow*) window->extra; XPutImage(xfi->display, xfi->primary, xfw->gc, xfi->image, xfw->left, xfw->top, xfw->left, xfw->top, xfw->width, xfw->height); XCopyArea(xfi->display, xfi->primary, xfw->handle, xfw->gc, xfw->left, xfw->top, xfw->width, xfw->height, 0, 0); XFlush(xfi->display); xfw = (xfWindow*) window->extra; } #endif } return True; }
boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event, boolean app) { rdpInput* input; input = xfi->instance->input; if (app != True) { if (xfi->mouse_motion != True) { if ((event->xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) == 0) return True; } input->MouseEvent(input, PTR_FLAGS_MOVE, event->xmotion.x, event->xmotion.y); if (xfi->fullscreen) XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); } else if (xfi->mouse_motion == True) { xfWindow* xfw; rdpWindow* window; int x = event->xmotion.x; int y = event->xmotion.y; window = window_list_get_by_extra_id(xfi->rail->list, (void*)event->xmotion.window); if (window != NULL) { xfw = (xfWindow*) window->extra; x += xfw->left; y += xfw->top; if (!xfw->isLocalMoveSizeModeEnabled) input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); } } 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; }
boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event, boolean app) { rdpInput* input; input = xfi->instance->input; if (app != true) { if (xfi->mouse_motion != true) { if ((event->xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) == 0) return true; } input->MouseEvent(input, PTR_FLAGS_MOVE, event->xmotion.x, event->xmotion.y); if (xfi->fullscreen) XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); } else if (xfi->mouse_motion == true) { rdpWindow* window; int x = event->xmotion.x; int y = event->xmotion.y; rdpRail* rail = ((rdpContext*) xfi->context)->rail; window = window_list_get_by_extra_id(rail->list, (void*) event->xmotion.window); if (window != NULL) { x += window->windowOffsetX; y += window->windowOffsetY; input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); } } return true; }
static BOOL xf_event_MapNotify(xfInfo* xfi, XEvent* event, BOOL app) { RECTANGLE_16 rect; rdpWindow* window; rdpUpdate* update = xfi->instance->update; rdpRail* rail = ((rdpContext*) xfi->context)->rail; if (!app) { rect.left = 0; rect.top = 0; rect.right = xfi->width; rect.bottom = xfi->height; update->SuppressOutput((rdpContext*) xfi->context, 1, &rect); } else { window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); if (window != NULL) { /* local restore event */ /* This is now handled as part of the PropertyNotify * Doing this here would inhibit the ability to restore a maximized window * that is minimized back to the maximized state */ //xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE); xfWindow* xfw = (xfWindow*) window->extra; xfw->is_mapped = TRUE; } } return TRUE; }
boolean xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, boolean app) { rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; 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); if (app && ! event->xconfigure.send_event) xf_rail_adjust_position(xfi, window); } return True; }
BOOL xf_event_process(freerdp* instance, XEvent* event) { BOOL status = TRUE; xfInfo* xfi = ((xfContext*) instance->context)->xfi; rdpRail* rail = ((rdpContext*) xfi->context)->rail; rdpWindow* window; if (xfi->remote_app) { window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window); if (window) { /* Update "current" window for cursor change orders */ xfi->window = (xfWindow*) window->extra; if (xf_event_suppress_events(xfi, window, event)) return TRUE; } } if (event->type != MotionNotify) DEBUG_X11("%s Event(%d): wnd=0x%04X", X11_EVENT_STRINGS[event->type], event->type, (UINT32) event->xany.window); switch (event->type) { case Expose: status = xf_event_Expose(xfi, event, xfi->remote_app); break; case VisibilityNotify: status = xf_event_VisibilityNotify(xfi, event, xfi->remote_app); break; case MotionNotify: status = xf_event_MotionNotify(xfi, event, xfi->remote_app); break; case ButtonPress: status = xf_event_ButtonPress(xfi, event, xfi->remote_app); break; case ButtonRelease: status = xf_event_ButtonRelease(xfi, event, xfi->remote_app); break; case KeyPress: status = xf_event_KeyPress(xfi, event, xfi->remote_app); break; case KeyRelease: status = xf_event_KeyRelease(xfi, event, xfi->remote_app); break; case FocusIn: status = xf_event_FocusIn(xfi, event, xfi->remote_app); break; case FocusOut: status = xf_event_FocusOut(xfi, event, xfi->remote_app); break; case EnterNotify: status = xf_event_EnterNotify(xfi, event, xfi->remote_app); break; case LeaveNotify: status = xf_event_LeaveNotify(xfi, event, xfi->remote_app); break; case NoExpose: break; case GraphicsExpose: break; case ConfigureNotify: status = xf_event_ConfigureNotify(xfi, event, xfi->remote_app); break; case MapNotify: status = xf_event_MapNotify(xfi, event, xfi->remote_app); break; case UnmapNotify: status = xf_event_UnmapNotify(xfi, event, xfi->remote_app); break; case ReparentNotify: break; case MappingNotify: status = xf_event_MappingNotify(xfi, event, xfi->remote_app); break; case ClientMessage: status = xf_event_ClientMessage(xfi, event, xfi->remote_app); break; case SelectionNotify: status = xf_event_SelectionNotify(xfi, event, xfi->remote_app); break; case SelectionRequest: status = xf_event_SelectionRequest(xfi, event, xfi->remote_app); break; case SelectionClear: status = xf_event_SelectionClear(xfi, event, xfi->remote_app); break; case PropertyNotify: status = xf_event_PropertyNotify(xfi, event, xfi->remote_app); break; } xf_input_handle_event(xfi, event); XSync(xfi->display, FALSE); return status; }
boolean xf_event_ButtonPress(xfInfo* xfi, XEvent* event, boolean app) { uint16 x, y; uint16 flags; boolean wheel; rdpInput* input; input = xfi->instance->input; x = 0; y = 0; flags = 0; wheel = False; switch (event->xbutton.button) { case 1: x = event->xmotion.x; y = event->xmotion.y; flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1; break; case 2: x = event->xmotion.x; y = event->xmotion.y; flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3; break; case 3: x = event->xmotion.x; y = event->xmotion.y; flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2; break; case 4: wheel = True; flags = PTR_FLAGS_WHEEL | 0x0078; break; case 5: wheel = True; flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; break; default: x = 0; y = 0; flags = 0; break; } if (flags != 0) { if (wheel) { input->MouseEvent(input, flags, 0, 0); } else { if (app) { xfWindow* xfw; rdpWindow* window; window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xbutton.window); if (window != NULL) { xfw = (xfWindow*) window->extra; x += xfw->left; y += xfw->top; } } input->MouseEvent(input, flags, x, y); } } 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; }
boolean xf_event_ButtonPress(xfInfo* xfi, XEvent* event, boolean app) { uint16 x, y; uint16 flags; boolean wheel; rdpInput* input; input = xfi->instance->input; x = 0; y = 0; flags = 0; wheel = false; switch (event->xbutton.button) { case 1: x = event->xbutton.x; y = event->xbutton.y; flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1; break; case 2: x = event->xbutton.x; y = event->xbutton.y; flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3; break; case 3: x = event->xbutton.x; y = event->xbutton.y; flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2; break; case 4: wheel = true; flags = PTR_FLAGS_WHEEL | 0x0078; break; case 5: wheel = true; flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; break; default: x = 0; y = 0; flags = 0; break; } if (flags != 0) { if (wheel) { input->MouseEvent(input, flags, 0, 0); } else { if (app) { rdpWindow* window; rdpRail* rail = ((rdpContext*) xfi->context)->rail; window = window_list_get_by_extra_id(rail->list, (void*) event->xbutton.window); if (window != NULL) { x += window->windowOffsetX; y += window->windowOffsetY; } } input->MouseEvent(input, flags, x, y); } } return true; }