parent
							
								
									ab063c3936
								
							
						
					
					
						commit
						7486263f7e
					
				| @ -0,0 +1,66 @@ | |||||||
|  | /*
 | ||||||
|  |  * Copyright © 2012 Intel Corporation | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice (including the | ||||||
|  |  * next paragraph) shall be included in all copies or substantial | ||||||
|  |  * portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  |  * SOFTWARE. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This is adapted from wayland-cursor, but with the wl_shm client stuff removed | ||||||
|  |  * so we can use it on the compositor, too. | ||||||
|  |  */ | ||||||
|  | #ifndef _WLR_XCURSOR_H | ||||||
|  | #define _WLR_XCURSOR_H | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | struct wlr_cursor_image { | ||||||
|  | 	uint32_t width;		/* actual width */ | ||||||
|  | 	uint32_t height;	/* actual height */ | ||||||
|  | 	uint32_t hotspot_x;	/* hot spot x (must be inside image) */ | ||||||
|  | 	uint32_t hotspot_y;	/* hot spot y (must be inside image) */ | ||||||
|  | 	uint32_t delay;		/* animation delay to next frame (ms) */ | ||||||
|  | 	uint8_t *buffer; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct wlr_cursor { | ||||||
|  | 	unsigned int image_count; | ||||||
|  | 	struct wlr_cursor_image **images; | ||||||
|  | 	char *name; | ||||||
|  | 	uint32_t total_delay; /* length of the animation in ms */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct wlr_cursor_theme { | ||||||
|  | 	unsigned int cursor_count; | ||||||
|  | 	struct wlr_cursor **cursors; | ||||||
|  | 	char *name; | ||||||
|  | 	int size; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct wlr_cursor_theme *wlr_cursor_theme_load(const char *name, int size); | ||||||
|  | 
 | ||||||
|  | void wlr_cursor_theme_destroy(struct wlr_cursor_theme *theme); | ||||||
|  | 
 | ||||||
|  | struct wlr_cursor *wlr_cursor_theme_get_cursor( | ||||||
|  | 		struct wlr_cursor_theme *theme, const char *name); | ||||||
|  | 
 | ||||||
|  | int wlr_cursor_frame(struct wlr_cursor *cursor, uint32_t time); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -0,0 +1,554 @@ | |||||||
|  | /*
 | ||||||
|  | * Copyright 1999 SuSE, Inc. | ||||||
|  | * | ||||||
|  | * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  | * a copy of this software and associated documentation files (the | ||||||
|  | * "Software"), to deal in the Software without restriction, including | ||||||
|  | * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  | * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  | * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  | * the following conditions: | ||||||
|  | * | ||||||
|  | * The above copyright notice and this permission notice (including the | ||||||
|  | * next paragraph) shall be included in all copies or substantial | ||||||
|  | * portions of the Software. | ||||||
|  | * | ||||||
|  | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  | * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  | * SOFTWARE. | ||||||
|  | * | ||||||
|  | * Author:  Keith Packard, SuSE, Inc. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | static uint32_t cursor_data[] = { | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0xffffffff, 0xff000000, 0xffffffff, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0x00000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0xff000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, | ||||||
|  | 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, | ||||||
|  | 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||||||
|  | 	0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, | ||||||
|  | 	0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0x00000000, 0x00000000, | ||||||
|  | 	0x00000000, 0x00000000, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct cursor_metadata { | ||||||
|  | 	char *name; | ||||||
|  | 	int width, height; | ||||||
|  | 	int hotspot_x, hotspot_y; | ||||||
|  | 	size_t offset; | ||||||
|  | } cursor_metadata[] = { | ||||||
|  | 	{ "bottom_left_corner", 16, 16, 1, 14, 0 }, | ||||||
|  | 	{ "bottom_right_corner", 16, 16, 14, 14, 256 }, | ||||||
|  | 	{ "bottom_side", 15, 16, 7, 14, 512 }, | ||||||
|  | 	{ "grabbing", 16, 16, 8, 8, 752 }, | ||||||
|  | 	{ "left_ptr", 10, 16, 1, 1, 1008 }, | ||||||
|  | 	{ "left_side", 16, 15, 1, 7, 1168 }, | ||||||
|  | 	{ "right_side", 16, 15, 14, 7, 1408 }, | ||||||
|  | 	{ "top_left_corner", 16, 16, 1, 1, 1648 }, | ||||||
|  | 	{ "top_right_corner", 16, 16, 14, 1, 1904 }, | ||||||
|  | 	{ "top_side", 15, 16, 7, 1, 2160 }, | ||||||
|  | 	{ "xterm", 9, 16, 4, 8, 2400 }, | ||||||
|  | 	{ "hand1", 13, 16, 12, 0, 2544 }, | ||||||
|  | 	{ "watch", 16, 16, 15, 9, 2752 }, | ||||||
|  | }; | ||||||
| @ -0,0 +1,65 @@ | |||||||
|  | /*
 | ||||||
|  |  * Copyright © 2002 Keith Packard | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice (including the | ||||||
|  |  * next paragraph) shall be included in all copies or substantial | ||||||
|  |  * portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  |  * SOFTWARE. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef XCURSOR_H | ||||||
|  | #define XCURSOR_H | ||||||
|  | 
 | ||||||
|  | typedef int		XcursorBool; | ||||||
|  | typedef unsigned int	XcursorUInt; | ||||||
|  | 
 | ||||||
|  | typedef XcursorUInt	XcursorDim; | ||||||
|  | typedef XcursorUInt	XcursorPixel; | ||||||
|  | 
 | ||||||
|  | typedef struct _XcursorImage { | ||||||
|  |     XcursorUInt	    version;	/* version of the image data */ | ||||||
|  |     XcursorDim	    size;	/* nominal size for matching */ | ||||||
|  |     XcursorDim	    width;	/* actual width */ | ||||||
|  |     XcursorDim	    height;	/* actual height */ | ||||||
|  |     XcursorDim	    xhot;	/* hot spot x (must be inside image) */ | ||||||
|  |     XcursorDim	    yhot;	/* hot spot y (must be inside image) */ | ||||||
|  |     XcursorUInt	    delay;	/* animation delay to next frame (ms) */ | ||||||
|  |     XcursorPixel    *pixels;	/* pointer to pixels */ | ||||||
|  | } XcursorImage; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Other data structures exposed by the library API | ||||||
|  |  */ | ||||||
|  | typedef struct _XcursorImages { | ||||||
|  |     int		    nimage;	/* number of images */ | ||||||
|  |     XcursorImage    **images;	/* array of XcursorImage pointers */ | ||||||
|  |     char	    *name;	/* name used to load images */ | ||||||
|  | } XcursorImages; | ||||||
|  | 
 | ||||||
|  | XcursorImages * | ||||||
|  | XcursorLibraryLoadImages (const char *file, const char *theme, int size); | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | XcursorImagesDestroy (XcursorImages *images); | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | xcursor_load_theme(const char *theme, int size, | ||||||
|  | 		    void (*load_callback)(XcursorImages *, void *), | ||||||
|  | 		    void *user_data); | ||||||
|  | #endif | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | wlr_files += files( | ||||||
|  |     'xcursor.c', | ||||||
|  |     'wlr_cursor.c', | ||||||
|  | ) | ||||||
| @ -0,0 +1,317 @@ | |||||||
|  | /*
 | ||||||
|  |  * Copyright © 2012 Intel Corporation | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice (including the | ||||||
|  |  * next paragraph) shall be included in all copies or substantial | ||||||
|  |  * portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  |  * SOFTWARE. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define _XOPEN_SOURCE 500 | ||||||
|  | #include <wlr/render.h> | ||||||
|  | #include <wlr/xcursor.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include "xcursor/xcursor.h" | ||||||
|  | 
 | ||||||
|  | static void wlr_cursor_destroy(struct wlr_cursor *cursor) { | ||||||
|  | 	for (size_t i = 0; i < cursor->image_count; i++) { | ||||||
|  | 		free(cursor->images[i]->buffer); | ||||||
|  | 		free(cursor->images[i]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	free(cursor->images); | ||||||
|  | 	free(cursor->name); | ||||||
|  | 	free(cursor); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #include "xcursor/cursor_data.h" | ||||||
|  | 
 | ||||||
|  | static struct wlr_cursor *wlr_cursor_create_from_data( | ||||||
|  | 		struct cursor_metadata *metadata, struct wlr_cursor_theme *theme) { | ||||||
|  | 	struct wlr_cursor *cursor; | ||||||
|  | 	struct wlr_cursor_image *image; | ||||||
|  | 	int size; | ||||||
|  | 
 | ||||||
|  | 	cursor = malloc(sizeof(*cursor)); | ||||||
|  | 	if (!cursor) { | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cursor->image_count = 1; | ||||||
|  | 	cursor->images = malloc(sizeof(*cursor->images)); | ||||||
|  | 	if (!cursor->images) { | ||||||
|  | 		goto err_free_cursor; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cursor->name = strdup(metadata->name); | ||||||
|  | 	cursor->total_delay = 0; | ||||||
|  | 
 | ||||||
|  | 	image = malloc(sizeof(*image)); | ||||||
|  | 	if (!image) { | ||||||
|  | 		goto err_free_images; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cursor->images[0] = image; | ||||||
|  | 	image->buffer = NULL; | ||||||
|  | 	image->width = metadata->width; | ||||||
|  | 	image->height = metadata->height; | ||||||
|  | 	image->hotspot_x = metadata->hotspot_x; | ||||||
|  | 	image->hotspot_y = metadata->hotspot_y; | ||||||
|  | 	image->delay = 0; | ||||||
|  | 
 | ||||||
|  | 	size = metadata->width * metadata->height * sizeof(uint32_t); | ||||||
|  | 	image->buffer = malloc(size); | ||||||
|  | 
 | ||||||
|  | 	if (!image->buffer) { | ||||||
|  | 		goto err_free_image; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	memcpy(image->buffer, cursor_data + metadata->offset, size); | ||||||
|  | 
 | ||||||
|  | 	return cursor; | ||||||
|  | 
 | ||||||
|  | err_free_image: | ||||||
|  | 	free(image); | ||||||
|  | 
 | ||||||
|  | err_free_images: | ||||||
|  | 	free(cursor->name); | ||||||
|  | 	free(cursor->images); | ||||||
|  | 
 | ||||||
|  | err_free_cursor: | ||||||
|  | 	free(cursor); | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void load_default_theme(struct wlr_cursor_theme *theme) { | ||||||
|  | 	uint32_t i; | ||||||
|  | 
 | ||||||
|  | 	free(theme->name); | ||||||
|  | 	theme->name = strdup("default"); | ||||||
|  | 
 | ||||||
|  | 	theme->cursor_count = sizeof(cursor_metadata) / sizeof(cursor_metadata[0]); | ||||||
|  | 	theme->cursors = malloc(theme->cursor_count * sizeof(*theme->cursors)); | ||||||
|  | 
 | ||||||
|  | 	if (theme->cursors == NULL) { | ||||||
|  | 		theme->cursor_count = 0; | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < theme->cursor_count; ++i) { | ||||||
|  | 		theme->cursors[i] = | ||||||
|  | 			wlr_cursor_create_from_data(&cursor_metadata[i], theme); | ||||||
|  | 
 | ||||||
|  | 		if (theme->cursors[i] == NULL) { | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	theme->cursor_count = i; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static struct wlr_cursor *wlr_cursor_create_from_xcursor_images( | ||||||
|  | 		XcursorImages *images, struct wlr_cursor_theme *theme) { | ||||||
|  | 	struct wlr_cursor *cursor; | ||||||
|  | 	struct wlr_cursor_image *image; | ||||||
|  | 	int i, size; | ||||||
|  | 
 | ||||||
|  | 	cursor = malloc(sizeof(*cursor)); | ||||||
|  | 	if (!cursor) { | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cursor->images = malloc(images->nimage * sizeof(cursor->images[0])); | ||||||
|  | 	if (!cursor->images) { | ||||||
|  | 		free(cursor); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cursor->name = strdup(images->name); | ||||||
|  | 	cursor->total_delay = 0; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < images->nimage; i++) { | ||||||
|  | 		image = malloc(sizeof(*image)); | ||||||
|  | 		if (image == NULL) { | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		image->buffer = NULL; | ||||||
|  | 
 | ||||||
|  | 		image->width = images->images[i]->width; | ||||||
|  | 		image->height = images->images[i]->height; | ||||||
|  | 		image->hotspot_x = images->images[i]->xhot; | ||||||
|  | 		image->hotspot_y = images->images[i]->yhot; | ||||||
|  | 		image->delay = images->images[i]->delay; | ||||||
|  | 
 | ||||||
|  | 		size = image->width * image->height * 4; | ||||||
|  | 		image->buffer = malloc(size); | ||||||
|  | 		if (!image->buffer) { | ||||||
|  | 			free(image); | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* copy pixels to shm pool */ | ||||||
|  | 		memcpy(image->buffer, images->images[i]->pixels, size); | ||||||
|  | 		cursor->total_delay += image->delay; | ||||||
|  | 		cursor->images[i] = image; | ||||||
|  | 	} | ||||||
|  | 	cursor->image_count = i; | ||||||
|  | 
 | ||||||
|  | 	if (cursor->image_count == 0) { | ||||||
|  | 		free(cursor->name); | ||||||
|  | 		free(cursor->images); | ||||||
|  | 		free(cursor); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return cursor; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void load_callback(XcursorImages *images, void *data) { | ||||||
|  | 	struct wlr_cursor_theme *theme = data; | ||||||
|  | 	struct wlr_cursor *cursor; | ||||||
|  | 
 | ||||||
|  | 	if (wlr_cursor_theme_get_cursor(theme, images->name)) { | ||||||
|  | 		XcursorImagesDestroy(images); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	cursor = wlr_cursor_create_from_xcursor_images(images, theme); | ||||||
|  | 
 | ||||||
|  | 	if (cursor) { | ||||||
|  | 		theme->cursor_count++; | ||||||
|  | 		theme->cursors = | ||||||
|  | 			realloc(theme->cursors, | ||||||
|  | 				theme->cursor_count * sizeof(theme->cursors[0])); | ||||||
|  | 
 | ||||||
|  | 		if (theme->cursors == NULL) { | ||||||
|  | 			theme->cursor_count--; | ||||||
|  | 			free(cursor); | ||||||
|  | 		} else { | ||||||
|  | 			theme->cursors[theme->cursor_count - 1] = cursor; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	XcursorImagesDestroy(images); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct wlr_cursor_theme *wlr_cursor_theme_load(const char *name, int size) { | ||||||
|  | 	struct wlr_cursor_theme *theme; | ||||||
|  | 
 | ||||||
|  | 	theme = malloc(sizeof(*theme)); | ||||||
|  | 	if (!theme) { | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!name) { | ||||||
|  | 		name = "default"; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	theme->name = strdup(name); | ||||||
|  | 	if (!theme->name) { | ||||||
|  | 		goto out_error_name; | ||||||
|  | 	} | ||||||
|  | 	theme->size = size; | ||||||
|  | 	theme->cursor_count = 0; | ||||||
|  | 	theme->cursors = NULL; | ||||||
|  | 
 | ||||||
|  | 	xcursor_load_theme(name, size, load_callback, theme); | ||||||
|  | 
 | ||||||
|  | 	if (theme->cursor_count == 0) { | ||||||
|  | 		load_default_theme(theme); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return theme; | ||||||
|  | 
 | ||||||
|  | out_error_name: | ||||||
|  | 	free(theme); | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void wlr_cursor_theme_destroy(struct wlr_cursor_theme *theme) { | ||||||
|  | 	unsigned int i; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < theme->cursor_count; i++) { | ||||||
|  | 		wlr_cursor_destroy(theme->cursors[i]); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	free(theme->name); | ||||||
|  | 	free(theme->cursors); | ||||||
|  | 	free(theme); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct wlr_cursor *wlr_cursor_theme_get_cursor(struct wlr_cursor_theme *theme, | ||||||
|  | 		   const char *name) { | ||||||
|  | 	unsigned int i; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < theme->cursor_count; i++) { | ||||||
|  | 		if (strcmp(name, theme->cursors[i]->name) == 0) { | ||||||
|  | 			return theme->cursors[i]; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int wlr_cursor_frame_and_duration(struct wlr_cursor *cursor, | ||||||
|  | 		uint32_t time, uint32_t *duration) { | ||||||
|  | 	uint32_t t; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	if (cursor->image_count == 1) { | ||||||
|  | 		if (duration) { | ||||||
|  | 			*duration = 0; | ||||||
|  | 		} | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	i = 0; | ||||||
|  | 	t = time % cursor->total_delay; | ||||||
|  | 
 | ||||||
|  | 	/* If there is a 0 delay in the image set then this
 | ||||||
|  | 	 * loop breaks on it and we display that cursor until | ||||||
|  | 	 * time % cursor->total_delay wraps again. | ||||||
|  | 	 * Since a 0 delay is silly, and we've never actually | ||||||
|  | 	 * seen one in a cursor file, we haven't bothered to | ||||||
|  | 	 * "fix" this. | ||||||
|  | 	 */ | ||||||
|  | 	while (t - cursor->images[i]->delay < t) { | ||||||
|  | 		t -= cursor->images[i++]->delay; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!duration) { | ||||||
|  | 		return i; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* Make sure we don't accidentally tell the caller this is
 | ||||||
|  | 	 * a static cursor image. | ||||||
|  | 	 */ | ||||||
|  | 	if (t >= cursor->images[i]->delay) { | ||||||
|  | 		*duration = 1; | ||||||
|  | 	} else { | ||||||
|  | 		*duration = cursor->images[i]->delay - t; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return i; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int wlr_cursor_frame(struct wlr_cursor *_cursor, uint32_t time) { | ||||||
|  | 	return wlr_cursor_frame_and_duration(_cursor, time, NULL); | ||||||
|  | } | ||||||
| @ -0,0 +1,970 @@ | |||||||
|  | /*
 | ||||||
|  |  * Copyright © 2002 Keith Packard | ||||||
|  |  * | ||||||
|  |  * Permission is hereby granted, free of charge, to any person obtaining | ||||||
|  |  * a copy of this software and associated documentation files (the | ||||||
|  |  * "Software"), to deal in the Software without restriction, including | ||||||
|  |  * without limitation the rights to use, copy, modify, merge, publish, | ||||||
|  |  * distribute, sublicense, and/or sell copies of the Software, and to | ||||||
|  |  * permit persons to whom the Software is furnished to do so, subject to | ||||||
|  |  * the following conditions: | ||||||
|  |  * | ||||||
|  |  * The above copyright notice and this permission notice (including the | ||||||
|  |  * next paragraph) shall be included in all copies or substantial | ||||||
|  |  * portions of the Software. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  |  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  |  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  |  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  |  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  |  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  |  * SOFTWARE. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define _DEFAULT_SOURCE | ||||||
|  | #include "xcursor/xcursor.h" | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <dirent.h> | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * From libXcursor/include/X11/extensions/Xcursor.h | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define XcursorTrue	1 | ||||||
|  | #define XcursorFalse	0 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Cursor files start with a header.  The header | ||||||
|  |  * contains a magic number, a version number and a | ||||||
|  |  * table of contents which has type and offset information | ||||||
|  |  * for the remaining tables in the file. | ||||||
|  |  * | ||||||
|  |  * File minor versions increment for compatible changes | ||||||
|  |  * File major versions increment for incompatible changes (never, we hope) | ||||||
|  |  * | ||||||
|  |  * Chunks of the same type are always upward compatible.  Incompatible | ||||||
|  |  * changes are made with new chunk types; the old data can remain under | ||||||
|  |  * the old type.  Upward compatible changes can add header data as the | ||||||
|  |  * header lengths are specified in the file. | ||||||
|  |  * | ||||||
|  |  *  File: | ||||||
|  |  *	FileHeader | ||||||
|  |  *	LISTofChunk | ||||||
|  |  * | ||||||
|  |  *  FileHeader: | ||||||
|  |  *	CARD32		magic	    magic number | ||||||
|  |  *	CARD32		header	    bytes in file header | ||||||
|  |  *	CARD32		version	    file version | ||||||
|  |  *	CARD32		ntoc	    number of toc entries | ||||||
|  |  *	LISTofFileToc   toc	    table of contents | ||||||
|  |  * | ||||||
|  |  *  FileToc: | ||||||
|  |  *	CARD32		type	    entry type | ||||||
|  |  *	CARD32		subtype	    entry subtype (size for images) | ||||||
|  |  *	CARD32		position    absolute file position | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define XCURSOR_MAGIC	0x72756358  /* "Xcur" LSBFirst */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Current Xcursor version number.  Will be substituted by configure | ||||||
|  |  * from the version in the libXcursor configure.ac file. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define XCURSOR_LIB_MAJOR 1 | ||||||
|  | #define XCURSOR_LIB_MINOR 1 | ||||||
|  | #define XCURSOR_LIB_REVISION 13 | ||||||
|  | #define XCURSOR_LIB_VERSION	((XCURSOR_LIB_MAJOR * 10000) + \ | ||||||
|  | 				 (XCURSOR_LIB_MINOR * 100) + \ | ||||||
|  | 				 (XCURSOR_LIB_REVISION)) | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This version number is stored in cursor files; changes to the | ||||||
|  |  * file format require updating this version number | ||||||
|  |  */ | ||||||
|  | #define XCURSOR_FILE_MAJOR	1 | ||||||
|  | #define XCURSOR_FILE_MINOR	0 | ||||||
|  | #define XCURSOR_FILE_VERSION	((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR)) | ||||||
|  | #define XCURSOR_FILE_HEADER_LEN	(4 * 4) | ||||||
|  | #define XCURSOR_FILE_TOC_LEN	(3 * 4) | ||||||
|  | 
 | ||||||
|  | typedef struct _XcursorFileToc { | ||||||
|  |     XcursorUInt	    type;	/* chunk type */ | ||||||
|  |     XcursorUInt	    subtype;	/* subtype (size for images) */ | ||||||
|  |     XcursorUInt	    position;	/* absolute position in file */ | ||||||
|  | } XcursorFileToc; | ||||||
|  | 
 | ||||||
|  | typedef struct _XcursorFileHeader { | ||||||
|  |     XcursorUInt	    magic;	/* magic number */ | ||||||
|  |     XcursorUInt	    header;	/* byte length of header */ | ||||||
|  |     XcursorUInt	    version;	/* file version number */ | ||||||
|  |     XcursorUInt	    ntoc;	/* number of toc entries */ | ||||||
|  |     XcursorFileToc  *tocs;	/* table of contents */ | ||||||
|  | } XcursorFileHeader; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * The rest of the file is a list of chunks, each tagged by type | ||||||
|  |  * and version. | ||||||
|  |  * | ||||||
|  |  *  Chunk: | ||||||
|  |  *	ChunkHeader | ||||||
|  |  *	<extra type-specific header fields> | ||||||
|  |  *	<type-specific data> | ||||||
|  |  * | ||||||
|  |  *  ChunkHeader: | ||||||
|  |  *	CARD32	    header	bytes in chunk header + type header | ||||||
|  |  *	CARD32	    type	chunk type | ||||||
|  |  *	CARD32	    subtype	chunk subtype | ||||||
|  |  *	CARD32	    version	chunk type version | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define XCURSOR_CHUNK_HEADER_LEN    (4 * 4) | ||||||
|  | 
 | ||||||
|  | typedef struct _XcursorChunkHeader { | ||||||
|  |     XcursorUInt	    header;	/* bytes in chunk header */ | ||||||
|  |     XcursorUInt	    type;	/* chunk type */ | ||||||
|  |     XcursorUInt	    subtype;	/* chunk subtype (size for images) */ | ||||||
|  |     XcursorUInt	    version;	/* version of this type */ | ||||||
|  | } XcursorChunkHeader; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Here's a list of the known chunk types | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Comments consist of a 4-byte length field followed by | ||||||
|  |  * UTF-8 encoded text | ||||||
|  |  * | ||||||
|  |  *  Comment: | ||||||
|  |  *	ChunkHeader header	chunk header | ||||||
|  |  *	CARD32	    length	bytes in text | ||||||
|  |  *	LISTofCARD8 text	UTF-8 encoded text | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define XCURSOR_COMMENT_TYPE	    0xfffe0001 | ||||||
|  | #define XCURSOR_COMMENT_VERSION	    1 | ||||||
|  | #define XCURSOR_COMMENT_HEADER_LEN  (XCURSOR_CHUNK_HEADER_LEN + (1 *4)) | ||||||
|  | #define XCURSOR_COMMENT_COPYRIGHT   1 | ||||||
|  | #define XCURSOR_COMMENT_LICENSE	    2 | ||||||
|  | #define XCURSOR_COMMENT_OTHER	    3 | ||||||
|  | #define XCURSOR_COMMENT_MAX_LEN	    0x100000 | ||||||
|  | 
 | ||||||
|  | typedef struct _XcursorComment { | ||||||
|  |     XcursorUInt	    version; | ||||||
|  |     XcursorUInt	    comment_type; | ||||||
|  |     char	    *comment; | ||||||
|  | } XcursorComment; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Each cursor image occupies a separate image chunk. | ||||||
|  |  * The length of the image header follows the chunk header | ||||||
|  |  * so that future versions can extend the header without | ||||||
|  |  * breaking older applications | ||||||
|  |  * | ||||||
|  |  *  Image: | ||||||
|  |  *	ChunkHeader	header	chunk header | ||||||
|  |  *	CARD32		width	actual width | ||||||
|  |  *	CARD32		height	actual height | ||||||
|  |  *	CARD32		xhot	hot spot x | ||||||
|  |  *	CARD32		yhot	hot spot y | ||||||
|  |  *	CARD32		delay	animation delay | ||||||
|  |  *	LISTofCARD32	pixels	ARGB pixels | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #define XCURSOR_IMAGE_TYPE    	    0xfffd0002 | ||||||
|  | #define XCURSOR_IMAGE_VERSION	    1 | ||||||
|  | #define XCURSOR_IMAGE_HEADER_LEN    (XCURSOR_CHUNK_HEADER_LEN + (5*4)) | ||||||
|  | #define XCURSOR_IMAGE_MAX_SIZE	    0x7fff	/* 32767x32767 max cursor size */ | ||||||
|  | 
 | ||||||
|  | typedef struct _XcursorFile XcursorFile; | ||||||
|  | 
 | ||||||
|  | struct _XcursorFile { | ||||||
|  |     void    *closure; | ||||||
|  |     int	    (*read)  (XcursorFile *file, unsigned char *buf, int len); | ||||||
|  |     int	    (*write) (XcursorFile *file, unsigned char *buf, int len); | ||||||
|  |     int	    (*seek)  (XcursorFile *file, long offset, int whence); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | typedef struct _XcursorComments { | ||||||
|  |     int		    ncomment;	/* number of comments */ | ||||||
|  |     XcursorComment  **comments;	/* array of XcursorComment pointers */ | ||||||
|  | } XcursorComments; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * From libXcursor/src/file.c | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | static XcursorImage * | ||||||
|  | XcursorImageCreate (int width, int height) | ||||||
|  | { | ||||||
|  |     XcursorImage    *image; | ||||||
|  | 
 | ||||||
|  |     image = malloc (sizeof (XcursorImage) + | ||||||
|  | 		    width * height * sizeof (XcursorPixel)); | ||||||
|  |     if (!image) | ||||||
|  | 	return NULL; | ||||||
|  |     image->version = XCURSOR_IMAGE_VERSION; | ||||||
|  |     image->pixels = (XcursorPixel *) (image + 1); | ||||||
|  |     image->size = width > height ? width : height; | ||||||
|  |     image->width = width; | ||||||
|  |     image->height = height; | ||||||
|  |     image->delay = 0; | ||||||
|  |     return image; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | XcursorImageDestroy (XcursorImage *image) | ||||||
|  | { | ||||||
|  |     free (image); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorImages * | ||||||
|  | XcursorImagesCreate (int size) | ||||||
|  | { | ||||||
|  |     XcursorImages   *images; | ||||||
|  | 
 | ||||||
|  |     images = malloc (sizeof (XcursorImages) + | ||||||
|  | 		     size * sizeof (XcursorImage *)); | ||||||
|  |     if (!images) | ||||||
|  | 	return NULL; | ||||||
|  |     images->nimage = 0; | ||||||
|  |     images->images = (XcursorImage **) (images + 1); | ||||||
|  |     images->name = NULL; | ||||||
|  |     return images; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | XcursorImagesDestroy (XcursorImages *images) | ||||||
|  | { | ||||||
|  |     int	n; | ||||||
|  | 
 | ||||||
|  |     if (!images) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     for (n = 0; n < images->nimage; n++) | ||||||
|  | 	XcursorImageDestroy (images->images[n]); | ||||||
|  |     if (images->name) | ||||||
|  | 	free (images->name); | ||||||
|  |     free (images); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | XcursorImagesSetName (XcursorImages *images, const char *name) | ||||||
|  | { | ||||||
|  |     char    *new; | ||||||
|  | 
 | ||||||
|  |     if (!images || !name) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     new = malloc (strlen (name) + 1); | ||||||
|  | 
 | ||||||
|  |     if (!new) | ||||||
|  | 	return; | ||||||
|  | 
 | ||||||
|  |     strcpy (new, name); | ||||||
|  |     if (images->name) | ||||||
|  | 	free (images->name); | ||||||
|  |     images->name = new; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorBool | ||||||
|  | _XcursorReadUInt (XcursorFile *file, XcursorUInt *u) | ||||||
|  | { | ||||||
|  |     unsigned char   bytes[4]; | ||||||
|  | 
 | ||||||
|  |     if (!file || !u) | ||||||
|  |         return XcursorFalse; | ||||||
|  | 
 | ||||||
|  |     if ((*file->read) (file, bytes, 4) != 4) | ||||||
|  | 	return XcursorFalse; | ||||||
|  |     *u = ((bytes[0] << 0) | | ||||||
|  | 	  (bytes[1] << 8) | | ||||||
|  | 	  (bytes[2] << 16) | | ||||||
|  | 	  (bytes[3] << 24)); | ||||||
|  |     return XcursorTrue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | _XcursorFileHeaderDestroy (XcursorFileHeader *fileHeader) | ||||||
|  | { | ||||||
|  |     free (fileHeader); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorFileHeader * | ||||||
|  | _XcursorFileHeaderCreate (int ntoc) | ||||||
|  | { | ||||||
|  |     XcursorFileHeader	*fileHeader; | ||||||
|  | 
 | ||||||
|  |     if (ntoc > 0x10000) | ||||||
|  | 	return NULL; | ||||||
|  |     fileHeader = malloc (sizeof (XcursorFileHeader) + | ||||||
|  | 			 ntoc * sizeof (XcursorFileToc)); | ||||||
|  |     if (!fileHeader) | ||||||
|  | 	return NULL; | ||||||
|  |     fileHeader->magic = XCURSOR_MAGIC; | ||||||
|  |     fileHeader->header = XCURSOR_FILE_HEADER_LEN; | ||||||
|  |     fileHeader->version = XCURSOR_FILE_VERSION; | ||||||
|  |     fileHeader->ntoc = ntoc; | ||||||
|  |     fileHeader->tocs = (XcursorFileToc *) (fileHeader + 1); | ||||||
|  |     return fileHeader; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorFileHeader * | ||||||
|  | _XcursorReadFileHeader (XcursorFile *file) | ||||||
|  | { | ||||||
|  |     XcursorFileHeader	head, *fileHeader; | ||||||
|  |     XcursorUInt		skip; | ||||||
|  |     unsigned int	n; | ||||||
|  | 
 | ||||||
|  |     if (!file) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|  |     if (!_XcursorReadUInt (file, &head.magic)) | ||||||
|  | 	return NULL; | ||||||
|  |     if (head.magic != XCURSOR_MAGIC) | ||||||
|  | 	return NULL; | ||||||
|  |     if (!_XcursorReadUInt (file, &head.header)) | ||||||
|  | 	return NULL; | ||||||
|  |     if (!_XcursorReadUInt (file, &head.version)) | ||||||
|  | 	return NULL; | ||||||
|  |     if (!_XcursorReadUInt (file, &head.ntoc)) | ||||||
|  | 	return NULL; | ||||||
|  |     skip = head.header - XCURSOR_FILE_HEADER_LEN; | ||||||
|  |     if (skip) | ||||||
|  | 	if ((*file->seek) (file, skip, SEEK_CUR) == EOF) | ||||||
|  | 	    return NULL; | ||||||
|  |     fileHeader = _XcursorFileHeaderCreate (head.ntoc); | ||||||
|  |     if (!fileHeader) | ||||||
|  | 	return NULL; | ||||||
|  |     fileHeader->magic = head.magic; | ||||||
|  |     fileHeader->header = head.header; | ||||||
|  |     fileHeader->version = head.version; | ||||||
|  |     fileHeader->ntoc = head.ntoc; | ||||||
|  |     for (n = 0; n < fileHeader->ntoc; n++) | ||||||
|  |     { | ||||||
|  | 	if (!_XcursorReadUInt (file, &fileHeader->tocs[n].type)) | ||||||
|  | 	    break; | ||||||
|  | 	if (!_XcursorReadUInt (file, &fileHeader->tocs[n].subtype)) | ||||||
|  | 	    break; | ||||||
|  | 	if (!_XcursorReadUInt (file, &fileHeader->tocs[n].position)) | ||||||
|  | 	    break; | ||||||
|  |     } | ||||||
|  |     if (n != fileHeader->ntoc) | ||||||
|  |     { | ||||||
|  | 	_XcursorFileHeaderDestroy (fileHeader); | ||||||
|  | 	return NULL; | ||||||
|  |     } | ||||||
|  |     return fileHeader; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorBool | ||||||
|  | _XcursorSeekToToc (XcursorFile		*file, | ||||||
|  | 		   XcursorFileHeader	*fileHeader, | ||||||
|  | 		   int			toc) | ||||||
|  | { | ||||||
|  |     if (!file || !fileHeader || \ | ||||||
|  |         (*file->seek) (file, fileHeader->tocs[toc].position, SEEK_SET) == EOF) | ||||||
|  | 	return XcursorFalse; | ||||||
|  |     return XcursorTrue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorBool | ||||||
|  | _XcursorFileReadChunkHeader (XcursorFile	*file, | ||||||
|  | 			     XcursorFileHeader	*fileHeader, | ||||||
|  | 			     int		toc, | ||||||
|  | 			     XcursorChunkHeader	*chunkHeader) | ||||||
|  | { | ||||||
|  |     if (!file || !fileHeader || !chunkHeader) | ||||||
|  |         return XcursorFalse; | ||||||
|  |     if (!_XcursorSeekToToc (file, fileHeader, toc)) | ||||||
|  | 	return XcursorFalse; | ||||||
|  |     if (!_XcursorReadUInt (file, &chunkHeader->header)) | ||||||
|  | 	return XcursorFalse; | ||||||
|  |     if (!_XcursorReadUInt (file, &chunkHeader->type)) | ||||||
|  | 	return XcursorFalse; | ||||||
|  |     if (!_XcursorReadUInt (file, &chunkHeader->subtype)) | ||||||
|  | 	return XcursorFalse; | ||||||
|  |     if (!_XcursorReadUInt (file, &chunkHeader->version)) | ||||||
|  | 	return XcursorFalse; | ||||||
|  |     /* sanity check */ | ||||||
|  |     if (chunkHeader->type != fileHeader->tocs[toc].type || | ||||||
|  | 	chunkHeader->subtype != fileHeader->tocs[toc].subtype) | ||||||
|  | 	return XcursorFalse; | ||||||
|  |     return XcursorTrue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define dist(a,b)   ((a) > (b) ? (a) - (b) : (b) - (a)) | ||||||
|  | 
 | ||||||
|  | static XcursorDim | ||||||
|  | _XcursorFindBestSize (XcursorFileHeader *fileHeader, | ||||||
|  | 		      XcursorDim	size, | ||||||
|  | 		      int		*nsizesp) | ||||||
|  | { | ||||||
|  |     unsigned int n; | ||||||
|  |     int		nsizes = 0; | ||||||
|  |     XcursorDim	bestSize = 0; | ||||||
|  |     XcursorDim	thisSize; | ||||||
|  | 
 | ||||||
|  |     if (!fileHeader || !nsizesp) | ||||||
|  |         return 0; | ||||||
|  | 
 | ||||||
|  |     for (n = 0; n < fileHeader->ntoc; n++) | ||||||
|  |     { | ||||||
|  | 	if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE) | ||||||
|  | 	    continue; | ||||||
|  | 	thisSize = fileHeader->tocs[n].subtype; | ||||||
|  | 	if (!bestSize || dist (thisSize, size) < dist (bestSize, size)) | ||||||
|  | 	{ | ||||||
|  | 	    bestSize = thisSize; | ||||||
|  | 	    nsizes = 1; | ||||||
|  | 	} | ||||||
|  | 	else if (thisSize == bestSize) | ||||||
|  | 	    nsizes++; | ||||||
|  |     } | ||||||
|  |     *nsizesp = nsizes; | ||||||
|  |     return bestSize; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | _XcursorFindImageToc (XcursorFileHeader	*fileHeader, | ||||||
|  | 		      XcursorDim	size, | ||||||
|  | 		      int		count) | ||||||
|  | { | ||||||
|  |     unsigned int	toc; | ||||||
|  |     XcursorDim		thisSize; | ||||||
|  | 
 | ||||||
|  |     if (!fileHeader) | ||||||
|  |         return 0; | ||||||
|  | 
 | ||||||
|  |     for (toc = 0; toc < fileHeader->ntoc; toc++) | ||||||
|  |     { | ||||||
|  | 	if (fileHeader->tocs[toc].type != XCURSOR_IMAGE_TYPE) | ||||||
|  | 	    continue; | ||||||
|  | 	thisSize = fileHeader->tocs[toc].subtype; | ||||||
|  | 	if (thisSize != size) | ||||||
|  | 	    continue; | ||||||
|  | 	if (!count) | ||||||
|  | 	    break; | ||||||
|  | 	count--; | ||||||
|  |     } | ||||||
|  |     if (toc == fileHeader->ntoc) | ||||||
|  | 	return -1; | ||||||
|  |     return toc; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorImage * | ||||||
|  | _XcursorReadImage (XcursorFile		*file, | ||||||
|  | 		   XcursorFileHeader	*fileHeader, | ||||||
|  | 		   int			toc) | ||||||
|  | { | ||||||
|  |     XcursorChunkHeader	chunkHeader; | ||||||
|  |     XcursorImage	head; | ||||||
|  |     XcursorImage	*image; | ||||||
|  |     int			n; | ||||||
|  |     XcursorPixel	*p; | ||||||
|  | 
 | ||||||
|  |     if (!file || !fileHeader) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|  |     if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader)) | ||||||
|  | 	return NULL; | ||||||
|  |     if (!_XcursorReadUInt (file, &head.width)) | ||||||
|  | 	return NULL; | ||||||
|  |     if (!_XcursorReadUInt (file, &head.height)) | ||||||
|  | 	return NULL; | ||||||
|  |     if (!_XcursorReadUInt (file, &head.xhot)) | ||||||
|  | 	return NULL; | ||||||
|  |     if (!_XcursorReadUInt (file, &head.yhot)) | ||||||
|  | 	return NULL; | ||||||
|  |     if (!_XcursorReadUInt (file, &head.delay)) | ||||||
|  | 	return NULL; | ||||||
|  |     /* sanity check data */ | ||||||
|  |     if (head.width >= 0x10000 || head.height > 0x10000) | ||||||
|  | 	return NULL; | ||||||
|  |     if (head.width == 0 || head.height == 0) | ||||||
|  | 	return NULL; | ||||||
|  |     if (head.xhot > head.width || head.yhot > head.height) | ||||||
|  | 	return NULL; | ||||||
|  | 
 | ||||||
|  |     /* Create the image and initialize it */ | ||||||
|  |     image = XcursorImageCreate (head.width, head.height); | ||||||
|  |     if (image == NULL) | ||||||
|  | 	    return NULL; | ||||||
|  |     if (chunkHeader.version < image->version) | ||||||
|  | 	image->version = chunkHeader.version; | ||||||
|  |     image->size = chunkHeader.subtype; | ||||||
|  |     image->xhot = head.xhot; | ||||||
|  |     image->yhot = head.yhot; | ||||||
|  |     image->delay = head.delay; | ||||||
|  |     n = image->width * image->height; | ||||||
|  |     p = image->pixels; | ||||||
|  |     while (n--) | ||||||
|  |     { | ||||||
|  | 	if (!_XcursorReadUInt (file, p)) | ||||||
|  | 	{ | ||||||
|  | 	    XcursorImageDestroy (image); | ||||||
|  | 	    return NULL; | ||||||
|  | 	} | ||||||
|  | 	p++; | ||||||
|  |     } | ||||||
|  |     return image; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorImages * | ||||||
|  | XcursorXcFileLoadImages (XcursorFile *file, int size) | ||||||
|  | { | ||||||
|  |     XcursorFileHeader	*fileHeader; | ||||||
|  |     XcursorDim		bestSize; | ||||||
|  |     int			nsize; | ||||||
|  |     XcursorImages	*images; | ||||||
|  |     int			n; | ||||||
|  |     int			toc; | ||||||
|  | 
 | ||||||
|  |     if (!file || size < 0) | ||||||
|  | 	return NULL; | ||||||
|  |     fileHeader = _XcursorReadFileHeader (file); | ||||||
|  |     if (!fileHeader) | ||||||
|  | 	return NULL; | ||||||
|  |     bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize); | ||||||
|  |     if (!bestSize) | ||||||
|  |     { | ||||||
|  |         _XcursorFileHeaderDestroy (fileHeader); | ||||||
|  | 	return NULL; | ||||||
|  |     } | ||||||
|  |     images = XcursorImagesCreate (nsize); | ||||||
|  |     if (!images) | ||||||
|  |     { | ||||||
|  |         _XcursorFileHeaderDestroy (fileHeader); | ||||||
|  | 	return NULL; | ||||||
|  |     } | ||||||
|  |     for (n = 0; n < nsize; n++) | ||||||
|  |     { | ||||||
|  | 	toc = _XcursorFindImageToc (fileHeader, bestSize, n); | ||||||
|  | 	if (toc < 0) | ||||||
|  | 	    break; | ||||||
|  | 	images->images[images->nimage] = _XcursorReadImage (file, fileHeader, | ||||||
|  | 							    toc); | ||||||
|  | 	if (!images->images[images->nimage]) | ||||||
|  | 	    break; | ||||||
|  | 	images->nimage++; | ||||||
|  |     } | ||||||
|  |     _XcursorFileHeaderDestroy (fileHeader); | ||||||
|  |     if (images->nimage != nsize) | ||||||
|  |     { | ||||||
|  | 	XcursorImagesDestroy (images); | ||||||
|  | 	images = NULL; | ||||||
|  |     } | ||||||
|  |     return images; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | _XcursorStdioFileRead (XcursorFile *file, unsigned char *buf, int len) | ||||||
|  | { | ||||||
|  |     FILE    *f = file->closure; | ||||||
|  |     return fread (buf, 1, len, f); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | _XcursorStdioFileWrite (XcursorFile *file, unsigned char *buf, int len) | ||||||
|  | { | ||||||
|  |     FILE    *f = file->closure; | ||||||
|  |     return fwrite (buf, 1, len, f); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | _XcursorStdioFileSeek (XcursorFile *file, long offset, int whence) | ||||||
|  | { | ||||||
|  |     FILE    *f = file->closure; | ||||||
|  |     return fseek (f, offset, whence); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | _XcursorStdioFileInitialize (FILE *stdfile, XcursorFile *file) | ||||||
|  | { | ||||||
|  |     file->closure = stdfile; | ||||||
|  |     file->read = _XcursorStdioFileRead; | ||||||
|  |     file->write = _XcursorStdioFileWrite; | ||||||
|  |     file->seek = _XcursorStdioFileSeek; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static XcursorImages * | ||||||
|  | XcursorFileLoadImages (FILE *file, int size) | ||||||
|  | { | ||||||
|  |     XcursorFile	f; | ||||||
|  | 
 | ||||||
|  |     if (!file) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|  |     _XcursorStdioFileInitialize (file, &f); | ||||||
|  |     return XcursorXcFileLoadImages (&f, size); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * From libXcursor/src/library.c | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #ifndef ICONDIR | ||||||
|  | #define ICONDIR "/usr/X11R6/lib/X11/icons" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef XCURSORPATH | ||||||
|  | #define XCURSORPATH "~/.icons:/usr/share/icons:/usr/share/pixmaps:~/.cursors:/usr/share/cursors/xorg-x11:"ICONDIR | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static const char * | ||||||
|  | XcursorLibraryPath (void) | ||||||
|  | { | ||||||
|  |     static const char	*path; | ||||||
|  | 
 | ||||||
|  |     if (!path) | ||||||
|  |     { | ||||||
|  | 	path = getenv ("XCURSOR_PATH"); | ||||||
|  | 	if (!path) | ||||||
|  | 	    path = XCURSORPATH; | ||||||
|  |     } | ||||||
|  |     return path; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static  void | ||||||
|  | _XcursorAddPathElt (char *path, const char *elt, int len) | ||||||
|  | { | ||||||
|  |     int	    pathlen = strlen (path); | ||||||
|  | 
 | ||||||
|  |     /* append / if the path doesn't currently have one */ | ||||||
|  |     if (path[0] == '\0' || path[pathlen - 1] != '/') | ||||||
|  |     { | ||||||
|  | 	strcat (path, "/"); | ||||||
|  | 	pathlen++; | ||||||
|  |     } | ||||||
|  |     if (len == -1) | ||||||
|  | 	len = strlen (elt); | ||||||
|  |     /* strip leading slashes */ | ||||||
|  |     while (len && elt[0] == '/') | ||||||
|  |     { | ||||||
|  | 	elt++; | ||||||
|  | 	len--; | ||||||
|  |     } | ||||||
|  |     strncpy (path + pathlen, elt, len); | ||||||
|  |     path[pathlen + len] = '\0'; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char * | ||||||
|  | _XcursorBuildThemeDir (const char *dir, const char *theme) | ||||||
|  | { | ||||||
|  |     const char	    *colon; | ||||||
|  |     const char	    *tcolon; | ||||||
|  |     char	    *full; | ||||||
|  |     char	    *home; | ||||||
|  |     int		    dirlen; | ||||||
|  |     int		    homelen; | ||||||
|  |     int		    themelen; | ||||||
|  |     int		    len; | ||||||
|  | 
 | ||||||
|  |     if (!dir || !theme) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|  |     colon = strchr (dir, ':'); | ||||||
|  |     if (!colon) | ||||||
|  | 	colon = dir + strlen (dir); | ||||||
|  | 
 | ||||||
|  |     dirlen = colon - dir; | ||||||
|  | 
 | ||||||
|  |     tcolon = strchr (theme, ':'); | ||||||
|  |     if (!tcolon) | ||||||
|  | 	tcolon = theme + strlen (theme); | ||||||
|  | 
 | ||||||
|  |     themelen = tcolon - theme; | ||||||
|  | 
 | ||||||
|  |     home = NULL; | ||||||
|  |     homelen = 0; | ||||||
|  |     if (*dir == '~') | ||||||
|  |     { | ||||||
|  | 	home = getenv ("HOME"); | ||||||
|  | 	if (!home) | ||||||
|  | 	    return NULL; | ||||||
|  | 	homelen = strlen (home); | ||||||
|  | 	dir++; | ||||||
|  | 	dirlen--; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * add space for any needed directory separators, one per component, | ||||||
|  |      * and one for the trailing null | ||||||
|  |      */ | ||||||
|  |     len = 1 + homelen + 1 + dirlen + 1 + themelen + 1; | ||||||
|  | 
 | ||||||
|  |     full = malloc (len); | ||||||
|  |     if (!full) | ||||||
|  | 	return NULL; | ||||||
|  |     full[0] = '\0'; | ||||||
|  | 
 | ||||||
|  |     if (home) | ||||||
|  | 	_XcursorAddPathElt (full, home, -1); | ||||||
|  |     _XcursorAddPathElt (full, dir, dirlen); | ||||||
|  |     _XcursorAddPathElt (full, theme, themelen); | ||||||
|  |     return full; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static char * | ||||||
|  | _XcursorBuildFullname (const char *dir, const char *subdir, const char *file) | ||||||
|  | { | ||||||
|  |     char    *full; | ||||||
|  | 
 | ||||||
|  |     if (!dir || !subdir || !file) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|  |     full = malloc (strlen (dir) + 1 + strlen (subdir) + 1 + strlen (file) + 1); | ||||||
|  |     if (!full) | ||||||
|  | 	return NULL; | ||||||
|  |     full[0] = '\0'; | ||||||
|  |     _XcursorAddPathElt (full, dir, -1); | ||||||
|  |     _XcursorAddPathElt (full, subdir, -1); | ||||||
|  |     _XcursorAddPathElt (full, file, -1); | ||||||
|  |     return full; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const char * | ||||||
|  | _XcursorNextPath (const char *path) | ||||||
|  | { | ||||||
|  |     char    *colon = strchr (path, ':'); | ||||||
|  | 
 | ||||||
|  |     if (!colon) | ||||||
|  | 	return NULL; | ||||||
|  |     return colon + 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define XcursorWhite(c)	((c) == ' ' || (c) == '\t' || (c) == '\n') | ||||||
|  | #define XcursorSep(c) ((c) == ';' || (c) == ',') | ||||||
|  | 
 | ||||||
|  | static char * | ||||||
|  | _XcursorThemeInherits (const char *full) | ||||||
|  | { | ||||||
|  |     char    line[8192]; | ||||||
|  |     char    *result = NULL; | ||||||
|  |     FILE    *f; | ||||||
|  | 
 | ||||||
|  |     if (!full) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|  |     f = fopen (full, "r"); | ||||||
|  |     if (f) | ||||||
|  |     { | ||||||
|  | 	while (fgets (line, sizeof (line), f)) | ||||||
|  | 	{ | ||||||
|  | 	    if (!strncmp (line, "Inherits", 8)) | ||||||
|  | 	    { | ||||||
|  | 		char    *l = line + 8; | ||||||
|  | 		char    *r; | ||||||
|  | 		while (*l == ' ') l++; | ||||||
|  | 		if (*l != '=') continue; | ||||||
|  | 		l++; | ||||||
|  | 		while (*l == ' ') l++; | ||||||
|  | 		result = malloc (strlen (l) + 1); | ||||||
|  | 		if (result) | ||||||
|  | 		{ | ||||||
|  | 		    r = result; | ||||||
|  | 		    while (*l) | ||||||
|  | 		    { | ||||||
|  | 			while (XcursorSep(*l) || XcursorWhite (*l)) l++; | ||||||
|  | 			if (!*l) | ||||||
|  | 			    break; | ||||||
|  | 			if (r != result) | ||||||
|  | 			    *r++ = ':'; | ||||||
|  | 			while (*l && !XcursorWhite(*l) && | ||||||
|  | 			       !XcursorSep(*l)) | ||||||
|  | 			    *r++ = *l++; | ||||||
|  | 		    } | ||||||
|  | 		    *r++ = '\0'; | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  | 	fclose (f); | ||||||
|  |     } | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static FILE * | ||||||
|  | XcursorScanTheme (const char *theme, const char *name) | ||||||
|  | { | ||||||
|  |     FILE	*f = NULL; | ||||||
|  |     char	*full; | ||||||
|  |     char	*dir; | ||||||
|  |     const char  *path; | ||||||
|  |     char	*inherits = NULL; | ||||||
|  |     const char	*i; | ||||||
|  | 
 | ||||||
|  |     if (!theme || !name) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * Scan this theme | ||||||
|  |      */ | ||||||
|  |     for (path = XcursorLibraryPath (); | ||||||
|  | 	 path && f == NULL; | ||||||
|  | 	 path = _XcursorNextPath (path)) | ||||||
|  |     { | ||||||
|  | 	dir = _XcursorBuildThemeDir (path, theme); | ||||||
|  | 	if (dir) | ||||||
|  | 	{ | ||||||
|  | 	    full = _XcursorBuildFullname (dir, "cursors", name); | ||||||
|  | 	    if (full) | ||||||
|  | 	    { | ||||||
|  | 		f = fopen (full, "r"); | ||||||
|  | 		free (full); | ||||||
|  | 	    } | ||||||
|  | 	    if (!f && !inherits) | ||||||
|  | 	    { | ||||||
|  | 		full = _XcursorBuildFullname (dir, "", "index.theme"); | ||||||
|  | 		if (full) | ||||||
|  | 		{ | ||||||
|  | 		    inherits = _XcursorThemeInherits (full); | ||||||
|  | 		    free (full); | ||||||
|  | 		} | ||||||
|  | 	    } | ||||||
|  | 	    free (dir); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     /*
 | ||||||
|  |      * Recurse to scan inherited themes | ||||||
|  |      */ | ||||||
|  |     for (i = inherits; i && f == NULL; i = _XcursorNextPath (i)) | ||||||
|  | 	f = XcursorScanTheme (i, name); | ||||||
|  |     if (inherits != NULL) | ||||||
|  | 	free (inherits); | ||||||
|  |     return f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | XcursorImages * | ||||||
|  | XcursorLibraryLoadImages (const char *file, const char *theme, int size) | ||||||
|  | { | ||||||
|  |     FILE	    *f = NULL; | ||||||
|  |     XcursorImages   *images = NULL; | ||||||
|  | 
 | ||||||
|  |     if (!file) | ||||||
|  |         return NULL; | ||||||
|  | 
 | ||||||
|  |     if (theme) | ||||||
|  | 	f = XcursorScanTheme (theme, file); | ||||||
|  |     if (!f) | ||||||
|  | 	f = XcursorScanTheme ("default", file); | ||||||
|  |     if (f) | ||||||
|  |     { | ||||||
|  | 	images = XcursorFileLoadImages (f, size); | ||||||
|  | 	if (images) | ||||||
|  | 	    XcursorImagesSetName (images, file); | ||||||
|  | 	fclose (f); | ||||||
|  |     } | ||||||
|  |     return images; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | load_all_cursors_from_dir(const char *path, int size, | ||||||
|  | 			  void (*load_callback)(XcursorImages *, void *), | ||||||
|  | 			  void *user_data) | ||||||
|  | { | ||||||
|  | 	FILE *f; | ||||||
|  | 	DIR *dir = opendir(path); | ||||||
|  | 	struct dirent *ent; | ||||||
|  | 	char *full; | ||||||
|  | 	XcursorImages *images; | ||||||
|  | 
 | ||||||
|  | 	if (!dir) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	for(ent = readdir(dir); ent; ent = readdir(dir)) { | ||||||
|  | 		if (ent->d_type != DT_UNKNOWN && | ||||||
|  | 		    (ent->d_type != DT_REG && ent->d_type != DT_LNK)) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		full = _XcursorBuildFullname(path, "", ent->d_name); | ||||||
|  | 		if (!full) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		f = fopen(full, "r"); | ||||||
|  | 		if (!f) { | ||||||
|  | 			free(full); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		images = XcursorFileLoadImages(f, size); | ||||||
|  | 
 | ||||||
|  | 		if (images) { | ||||||
|  | 			XcursorImagesSetName(images, ent->d_name); | ||||||
|  | 			load_callback(images, user_data); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		fclose (f); | ||||||
|  | 		free(full); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	closedir(dir); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Load all the cursor of a theme
 | ||||||
|  |  * | ||||||
|  |  * This function loads all the cursor images of a given theme and its | ||||||
|  |  * inherited themes. Each cursor is loaded into an XcursorImages object | ||||||
|  |  * which is passed to the caller's load callback. If a cursor appears | ||||||
|  |  * more than once across all the inherited themes, the load callback | ||||||
|  |  * will be called multiple times, with possibly different XcursorImages | ||||||
|  |  * object which have the same name. The user is expected to destroy the | ||||||
|  |  * XcursorImages objects passed to the callback with | ||||||
|  |  * XcursorImagesDestroy(). | ||||||
|  |  * | ||||||
|  |  * \param theme The name of theme that should be loaded | ||||||
|  |  * \param size The desired size of the cursor images | ||||||
|  |  * \param load_callback A callback function that will be called | ||||||
|  |  * for each cursor loaded. The first parameter is the XcursorImages | ||||||
|  |  * object representing the loaded cursor and the second is a pointer | ||||||
|  |  * to data provided by the user. | ||||||
|  |  * \param user_data The data that should be passed to the load callback | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | xcursor_load_theme(const char *theme, int size, | ||||||
|  | 		    void (*load_callback)(XcursorImages *, void *), | ||||||
|  | 		    void *user_data) | ||||||
|  | { | ||||||
|  | 	char *full, *dir; | ||||||
|  | 	char *inherits = NULL; | ||||||
|  | 	const char *path, *i; | ||||||
|  | 
 | ||||||
|  | 	if (!theme) | ||||||
|  | 		theme = "default"; | ||||||
|  | 
 | ||||||
|  | 	for (path = XcursorLibraryPath(); | ||||||
|  | 	     path; | ||||||
|  | 	     path = _XcursorNextPath(path)) { | ||||||
|  | 		dir = _XcursorBuildThemeDir(path, theme); | ||||||
|  | 		if (!dir) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		full = _XcursorBuildFullname(dir, "cursors", ""); | ||||||
|  | 
 | ||||||
|  | 		if (full) { | ||||||
|  | 			load_all_cursors_from_dir(full, size, load_callback, | ||||||
|  | 						  user_data); | ||||||
|  | 			free(full); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!inherits) { | ||||||
|  | 			full = _XcursorBuildFullname(dir, "", "index.theme"); | ||||||
|  | 			if (full) { | ||||||
|  | 				inherits = _XcursorThemeInherits(full); | ||||||
|  | 				free(full); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		free(dir); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for (i = inherits; i; i = _XcursorNextPath(i)) | ||||||
|  | 		xcursor_load_theme(i, size, load_callback, user_data); | ||||||
|  | 
 | ||||||
|  | 	if (inherits) | ||||||
|  | 		free(inherits); | ||||||
|  | } | ||||||
					Loading…
					
					
				
		Reference in new issue