instruction-copy.c (3270B)
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 "config.h" 21#include "display.h" 22#include "log.h" 23 24#include <guacamole/client.h> 25 26#include <stdlib.h> 27 28int guacenc_handle_copy(guacenc_display* display, int argc, char** argv) { 29 30 /* Verify argument count */ 31 if (argc < 9) { 32 guacenc_log(GUAC_LOG_WARNING, "\"copy\" instruction incomplete"); 33 return 1; 34 } 35 36 /* Parse arguments */ 37 int sindex = atoi(argv[0]); 38 int sx = atoi(argv[1]); 39 int sy = atoi(argv[2]); 40 int width = atoi(argv[3]); 41 int height = atoi(argv[4]); 42 int mask = atoi(argv[5]); 43 int dindex = atoi(argv[6]); 44 int dx = atoi(argv[7]); 45 int dy = atoi(argv[8]); 46 47 /* Pull buffer of source layer/buffer */ 48 guacenc_buffer* src = guacenc_display_get_related_buffer(display, sindex); 49 if (src == NULL) 50 return 1; 51 52 /* Pull buffer of destination layer/buffer */ 53 guacenc_buffer* dst = guacenc_display_get_related_buffer(display, dindex); 54 if (dst == NULL) 55 return 1; 56 57 /* Expand the destination buffer as necessary to fit the draw operation */ 58 if (dst->autosize) 59 guacenc_buffer_fit(dst, dx + width, dy + height); 60 61 /* Copy rectangle from source to destination */ 62 if (src->surface != NULL && dst->cairo != NULL) { 63 64 /* If surfaces are different, no need to copy */ 65 cairo_surface_t* surface; 66 if (src != dst) 67 surface = src->surface; 68 69 /* Otherwise, copy to a temporary surface */ 70 else { 71 72 /* Create new surface to hold the source rect */ 73 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 74 width, height); 75 76 /* Copy relevant rectangle from source surface */ 77 cairo_t* cairo = cairo_create(surface); 78 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); 79 cairo_set_source_surface(cairo, src->surface, -sx, -sy); 80 cairo_paint(cairo); 81 cairo_destroy(cairo); 82 83 /* Source coordinates are now (0, 0) */ 84 sx = sy = 0; 85 86 } 87 88 /* Perform copy */ 89 cairo_set_operator(dst->cairo, guacenc_display_cairo_operator(mask)); 90 cairo_set_source_surface(dst->cairo, surface, dx - sx, dy - sy); 91 cairo_rectangle(dst->cairo, dx, dy, width, height); 92 cairo_fill(dst->cairo); 93 94 /* Destroy temporary surface if it was created */ 95 if (surface != src->surface) 96 cairo_surface_destroy(surface); 97 98 } 99 100 return 0; 101 102} 103