cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

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