input.c (6765B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#include "channels/disp.h" 21#include "channels/rdpei.h" 22#include "common/cursor.h" 23#include "common/display.h" 24#include "input.h" 25#include "keyboard.h" 26#include "rdp.h" 27#include "settings.h" 28 29#include <freerdp/freerdp.h> 30#include <freerdp/input.h> 31#include <guacamole/client.h> 32#include <guacamole/recording.h> 33#include <guacamole/user.h> 34 35#include <stdlib.h> 36 37int guac_rdp_user_mouse_handler(guac_user* user, int x, int y, int mask) { 38 39 guac_client* client = user->client; 40 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 41 42 pthread_rwlock_rdlock(&(rdp_client->lock)); 43 44 /* Skip if not yet connected */ 45 freerdp* rdp_inst = rdp_client->rdp_inst; 46 if (rdp_inst == NULL) 47 goto complete; 48 49 /* Store current mouse location/state */ 50 guac_common_cursor_update(rdp_client->display->cursor, user, x, y, mask); 51 52 /* Report mouse position within recording */ 53 if (rdp_client->recording != NULL) 54 guac_recording_report_mouse(rdp_client->recording, x, y, mask); 55 56 /* If button mask unchanged, just send move event */ 57 if (mask == rdp_client->mouse_button_mask) { 58 pthread_mutex_lock(&(rdp_client->message_lock)); 59 rdp_inst->input->MouseEvent(rdp_inst->input, PTR_FLAGS_MOVE, x, y); 60 pthread_mutex_unlock(&(rdp_client->message_lock)); 61 } 62 63 /* Otherwise, send events describing button change */ 64 else { 65 66 /* Mouse buttons which have JUST become released */ 67 int released_mask = rdp_client->mouse_button_mask & ~mask; 68 69 /* Mouse buttons which have JUST become pressed */ 70 int pressed_mask = ~rdp_client->mouse_button_mask & mask; 71 72 /* Release event */ 73 if (released_mask & 0x07) { 74 75 /* Calculate flags */ 76 int flags = 0; 77 if (released_mask & 0x01) flags |= PTR_FLAGS_BUTTON1; 78 if (released_mask & 0x02) flags |= PTR_FLAGS_BUTTON3; 79 if (released_mask & 0x04) flags |= PTR_FLAGS_BUTTON2; 80 81 pthread_mutex_lock(&(rdp_client->message_lock)); 82 rdp_inst->input->MouseEvent(rdp_inst->input, flags, x, y); 83 pthread_mutex_unlock(&(rdp_client->message_lock)); 84 85 } 86 87 /* Press event */ 88 if (pressed_mask & 0x07) { 89 90 /* Calculate flags */ 91 int flags = PTR_FLAGS_DOWN; 92 if (pressed_mask & 0x01) flags |= PTR_FLAGS_BUTTON1; 93 if (pressed_mask & 0x02) flags |= PTR_FLAGS_BUTTON3; 94 if (pressed_mask & 0x04) flags |= PTR_FLAGS_BUTTON2; 95 if (pressed_mask & 0x08) flags |= PTR_FLAGS_WHEEL | 0x78; 96 if (pressed_mask & 0x10) flags |= PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x88; 97 98 /* Send event */ 99 pthread_mutex_lock(&(rdp_client->message_lock)); 100 rdp_inst->input->MouseEvent(rdp_inst->input, flags, x, y); 101 pthread_mutex_unlock(&(rdp_client->message_lock)); 102 103 } 104 105 /* Scroll event */ 106 if (pressed_mask & 0x18) { 107 108 /* Down */ 109 if (pressed_mask & 0x08) { 110 pthread_mutex_lock(&(rdp_client->message_lock)); 111 rdp_inst->input->MouseEvent(rdp_inst->input, PTR_FLAGS_WHEEL | 0x78, x, y); 112 pthread_mutex_unlock(&(rdp_client->message_lock)); 113 } 114 115 /* Up */ 116 if (pressed_mask & 0x10) { 117 pthread_mutex_lock(&(rdp_client->message_lock)); 118 rdp_inst->input->MouseEvent(rdp_inst->input, PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x88, x, y); 119 pthread_mutex_unlock(&(rdp_client->message_lock)); 120 } 121 122 } 123 124 rdp_client->mouse_button_mask = mask; 125 } 126 127complete: 128 pthread_rwlock_unlock(&(rdp_client->lock)); 129 130 return 0; 131} 132 133int guac_rdp_user_touch_handler(guac_user* user, int id, int x, int y, 134 int x_radius, int y_radius, double angle, double force) { 135 136 guac_client* client = user->client; 137 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 138 139 pthread_rwlock_rdlock(&(rdp_client->lock)); 140 141 /* Skip if not yet connected */ 142 freerdp* rdp_inst = rdp_client->rdp_inst; 143 if (rdp_inst == NULL) 144 goto complete; 145 146 /* Report touch event within recording */ 147 if (rdp_client->recording != NULL) 148 guac_recording_report_touch(rdp_client->recording, id, x, y, 149 x_radius, y_radius, angle, force); 150 151 /* Forward touch event along RDPEI channel */ 152 guac_rdp_rdpei_touch_update(rdp_client->rdpei, id, x, y, force); 153 154complete: 155 pthread_rwlock_unlock(&(rdp_client->lock)); 156 157 return 0; 158} 159 160int guac_rdp_user_key_handler(guac_user* user, int keysym, int pressed) { 161 162 guac_client* client = user->client; 163 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 164 int retval = 0; 165 166 pthread_rwlock_rdlock(&(rdp_client->lock)); 167 168 /* Report key state within recording */ 169 if (rdp_client->recording != NULL) 170 guac_recording_report_key(rdp_client->recording, 171 keysym, pressed); 172 173 /* Skip if keyboard not yet ready */ 174 if (rdp_client->keyboard == NULL) 175 goto complete; 176 177 /* Update keysym state */ 178 retval = guac_rdp_keyboard_update_keysym(rdp_client->keyboard, 179 keysym, pressed, GUAC_RDP_KEY_SOURCE_CLIENT); 180 181complete: 182 pthread_rwlock_unlock(&(rdp_client->lock)); 183 184 return retval; 185 186} 187 188int guac_rdp_user_size_handler(guac_user* user, int width, int height) { 189 190 guac_client* client = user->client; 191 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 192 guac_rdp_settings* settings = rdp_client->settings; 193 freerdp* rdp_inst = rdp_client->rdp_inst; 194 195 /* Convert client pixels to remote pixels */ 196 width = width * settings->resolution / user->info.optimal_resolution; 197 height = height * settings->resolution / user->info.optimal_resolution; 198 199 /* Send display update */ 200 guac_rdp_disp_set_size(rdp_client->disp, settings, rdp_inst, width, height); 201 202 return 0; 203 204} 205