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