pointer.c (4043B)
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 "color.h" 21#include "common/cursor.h" 22#include "common/display.h" 23#include "common/surface.h" 24#include "pointer.h" 25#include "rdp.h" 26 27#include <cairo/cairo.h> 28#include <freerdp/codec/color.h> 29#include <freerdp/freerdp.h> 30#include <freerdp/gdi/gdi.h> 31#include <guacamole/client.h> 32#include <winpr/crt.h> 33 34BOOL guac_rdp_pointer_new(rdpContext* context, rdpPointer* pointer) { 35 36 guac_client* client = ((rdp_freerdp_context*) context)->client; 37 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 38 39 /* Allocate buffer */ 40 guac_common_display_layer* buffer = guac_common_display_alloc_buffer( 41 rdp_client->display, pointer->width, pointer->height); 42 43 /* Allocate data for image */ 44 unsigned char* data = _aligned_malloc(pointer->width * pointer->height * 4, 16); 45 46 cairo_surface_t* surface; 47 48 /* Convert to alpha cursor using mask data */ 49 freerdp_image_copy_from_pointer_data(data, 50 guac_rdp_get_native_pixel_format(TRUE), 0, 0, 0, 51 pointer->width, pointer->height, pointer->xorMaskData, 52 pointer->lengthXorMask, pointer->andMaskData, 53 pointer->lengthAndMask, pointer->xorBpp, 54 &context->gdi->palette); 55 56 /* Create surface from image data */ 57 surface = cairo_image_surface_create_for_data( 58 data, CAIRO_FORMAT_ARGB32, 59 pointer->width, pointer->height, 4*pointer->width); 60 61 /* Send surface to buffer */ 62 guac_common_surface_draw(buffer->surface, 0, 0, surface); 63 64 /* Free surface */ 65 cairo_surface_destroy(surface); 66 _aligned_free(data); 67 68 /* Remember buffer */ 69 ((guac_rdp_pointer*) pointer)->layer = buffer; 70 71 return TRUE; 72 73} 74 75BOOL guac_rdp_pointer_set(rdpContext* context, const rdpPointer* pointer) { 76 77 guac_client* client = ((rdp_freerdp_context*) context)->client; 78 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 79 80 /* Set cursor */ 81 guac_common_cursor_set_surface(rdp_client->display->cursor, 82 pointer->xPos, pointer->yPos, 83 ((guac_rdp_pointer*) pointer)->layer->surface); 84 85 return TRUE; 86 87} 88 89void guac_rdp_pointer_free(rdpContext* context, rdpPointer* pointer) { 90 91 guac_client* client = ((rdp_freerdp_context*) context)->client; 92 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 93 guac_common_display_layer* buffer = ((guac_rdp_pointer*) pointer)->layer; 94 95 /* Free buffer */ 96 guac_common_display_free_buffer(rdp_client->display, buffer); 97 98 /* NOTE: FreeRDP-allocated memory for the rdpPointer will be automatically 99 * released after this free handler is invoked */ 100 101} 102 103BOOL guac_rdp_pointer_set_null(rdpContext* context) { 104 105 guac_client* client = ((rdp_freerdp_context*) context)->client; 106 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 107 108 /* Set cursor to empty/blank graphic */ 109 guac_common_cursor_set_blank(rdp_client->display->cursor); 110 111 return TRUE; 112 113} 114 115BOOL guac_rdp_pointer_set_default(rdpContext* context) { 116 117 guac_client* client = ((rdp_freerdp_context*) context)->client; 118 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 119 120 /* Set cursor to embedded pointer */ 121 guac_common_cursor_set_pointer(rdp_client->display->cursor); 122 123 return TRUE; 124} 125