1/* 2 * Copyright © 2015 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 * 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#include <X11/Xlib.h> 30#include <X11/extensions/Xfixes.h> 31 32#include <stdint.h> 33#include <stdio.h> 34#include <stdlib.h> 35#include <png.h> 36 37int main(int argc, char **argv) 38{ 39 Display *dpy; 40 XFixesCursorImage *cur; 41 unsigned long *src; /* XXX deep sigh */ 42 unsigned x, y; 43 png_struct *png; 44 png_info *info; 45 png_byte **rows; 46 FILE *file; 47 48 dpy = XOpenDisplay(NULL); 49 if (dpy == NULL) 50 return 1; 51 52 if (!XFixesQueryExtension(dpy, (int *)&x, (int *)&y)) 53 return 1; 54 55 cur = XFixesGetCursorImage(dpy); 56 if (cur == NULL) 57 return 1; 58 59 printf("Cursor on display '%s': %dx%d, (hotspot %dx%d)\n", 60 DisplayString(dpy), 61 cur->width, cur->height, 62 cur->xhot, cur->yhot); 63 64 if (1) { 65 int x, y; 66 67 src = cur->pixels; 68 for (y = 0; y < cur->height; y++) { 69 for (x = 0; x < cur->width; x++) { 70 if (x == cur->xhot && y == cur->yhot) 71 printf("+"); 72 else 73 printf("%c", *src ? *src >> 24 >= 127 ? 'x' : '.' : ' '); 74 src++; 75 } 76 printf("\n"); 77 } 78 } 79 80 file = fopen("cursor.png", "wb"); 81 if (file == NULL) 82 return 2; 83 84 png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 85 info = png_create_info_struct(png); 86 png_init_io(png, file); 87 png_set_IHDR(png, info, 88 cur->width, cur->height, 8, 89 PNG_COLOR_TYPE_RGB_ALPHA, 90 PNG_INTERLACE_NONE, 91 PNG_COMPRESSION_TYPE_DEFAULT, 92 PNG_FILTER_TYPE_DEFAULT); 93 png_write_info(png, info); 94 95 src = cur->pixels; 96 rows = malloc(cur->height*sizeof(png_byte*)); 97 if (rows == NULL) 98 return 3; 99 100 for (y = 0; y < cur->height; y++) { 101 rows[y] = malloc(cur->width * 4); 102 for (x = 0; x < cur->width; x++) { 103 uint32_t p = *src++; 104 uint8_t r = p >> 0; 105 uint8_t g = p >> 8; 106 uint8_t b = p >> 16; 107 uint8_t a = p >> 24; 108 109 if (a > 0x00 && a < 0xff) { 110 r = (r * 0xff + a /2) / a; 111 g = (g * 0xff + a /2) / a; 112 b = (b * 0xff + a /2) / a; 113 } 114 115 rows[y][4*x + 0] = b; 116 rows[y][4*x + 1] = g; 117 rows[y][4*x + 2] = r; 118 rows[y][4*x + 3] = a; 119 } 120 } 121 122 png_write_image(png, rows); 123 png_write_end(png, NULL); 124 fclose(file); 125 126 return 0; 127} 128