Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 1 | #include <stdint.h> |
| 2 | #include <stdio.h> |
| 3 | #include <stdlib.h> |
| 4 | #include <string.h> |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 5 | #include <fcntl.h> |
| 6 | #include <unistd.h> |
| 7 | #include <math.h> |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 8 | #include <cairo.h> |
Kristian Høgsberg | 1cbaa6a | 2008-11-07 15:54:48 -0500 | [diff] [blame] | 9 | #include <glib.h> |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 10 | |
| 11 | #include "wayland-client.h" |
Kristian Høgsberg | 1cbaa6a | 2008-11-07 15:54:48 -0500 | [diff] [blame] | 12 | #include "wayland-glib.h" |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 13 | |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 14 | #include "cairo-util.h" |
| 15 | |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 16 | static const char gem_device[] = "/dev/dri/card0"; |
| 17 | static const char socket_name[] = "\0wayland"; |
| 18 | |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 19 | static void |
| 20 | pointer_path(cairo_t *cr, int x, int y) |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 21 | { |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 22 | const int end = 4, tx = 2, ty = 7, dx = 3, dy = 5; |
| 23 | const int width = 16, height = 16; |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 24 | |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 25 | cairo_move_to(cr, x, y); |
| 26 | cairo_line_to(cr, x + tx, y + ty); |
| 27 | cairo_line_to(cr, x + dx, y + dy); |
| 28 | cairo_line_to(cr, x + width - end, y + height); |
| 29 | cairo_line_to(cr, x + width, y + height - end); |
| 30 | cairo_line_to(cr, x + dy, y + dx); |
| 31 | cairo_line_to(cr, x + ty, y + tx); |
| 32 | cairo_close_path(cr); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 33 | } |
| 34 | |
| 35 | static void * |
| 36 | draw_pointer(int width, int height) |
| 37 | { |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 38 | const int hotspot_x = 16, hotspot_y = 16; |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 39 | cairo_surface_t *surface; |
| 40 | cairo_t *cr; |
| 41 | |
| 42 | surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, |
| 43 | width, height); |
| 44 | |
| 45 | cr = cairo_create(surface); |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 46 | pointer_path(cr, hotspot_x + 3, hotspot_y + 2); |
| 47 | cairo_set_line_width (cr, 2); |
Kristian Høgsberg | 3074942 | 2008-11-08 16:01:59 -0500 | [diff] [blame] | 48 | cairo_set_source_rgb(cr, 0, 0, 0); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 49 | cairo_stroke_preserve(cr); |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 50 | cairo_fill(cr); |
| 51 | blur_surface(surface); |
| 52 | |
| 53 | pointer_path(cr, hotspot_x, hotspot_y); |
| 54 | cairo_stroke_preserve(cr); |
Kristian Høgsberg | 3074942 | 2008-11-08 16:01:59 -0500 | [diff] [blame] | 55 | cairo_set_source_rgb(cr, 1, 1, 1); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 56 | cairo_fill(cr); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 57 | cairo_destroy(cr); |
| 58 | |
| 59 | return surface; |
| 60 | } |
| 61 | |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 62 | struct pointer { |
| 63 | int width, height; |
| 64 | struct wl_surface *surface; |
| 65 | }; |
| 66 | |
Kristian Høgsberg | 3074942 | 2008-11-08 16:01:59 -0500 | [diff] [blame] | 67 | static void |
| 68 | event_handler(struct wl_display *display, |
| 69 | uint32_t opcode, |
| 70 | uint32_t arg1, uint32_t arg2, void *data) |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 71 | { |
| 72 | struct pointer *pointer = data; |
| 73 | |
Kristian Høgsberg | 2a20d83 | 2008-11-02 17:22:39 -0500 | [diff] [blame] | 74 | if (opcode == 0) |
| 75 | wl_surface_map(pointer->surface, arg1, arg2, pointer->width, pointer->height); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | int main(int argc, char *argv[]) |
| 79 | { |
| 80 | struct wl_display *display; |
| 81 | struct pointer pointer; |
| 82 | int fd; |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 83 | cairo_surface_t *s; |
Kristian Høgsberg | 1cbaa6a | 2008-11-07 15:54:48 -0500 | [diff] [blame] | 84 | GMainLoop *loop; |
| 85 | GSource *source; |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 86 | struct buffer *buffer; |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 87 | |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 88 | fd = open(gem_device, O_RDWR); |
| 89 | if (fd < 0) { |
| 90 | fprintf(stderr, "drm open failed: %m\n"); |
| 91 | return -1; |
| 92 | } |
| 93 | |
Kristian Høgsberg | fb59084 | 2008-11-07 14:27:23 -0500 | [diff] [blame] | 94 | display = wl_display_create(socket_name); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 95 | if (display == NULL) { |
| 96 | fprintf(stderr, "failed to create display: %m\n"); |
| 97 | return -1; |
| 98 | } |
Kristian Høgsberg | 1cbaa6a | 2008-11-07 15:54:48 -0500 | [diff] [blame] | 99 | |
| 100 | loop = g_main_loop_new(NULL, FALSE); |
| 101 | source = wayland_source_new(display); |
| 102 | g_source_attach(source, NULL); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 103 | |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 104 | pointer.width = 48; |
| 105 | pointer.height = 48; |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 106 | pointer.surface = wl_display_create_surface(display); |
| 107 | |
| 108 | s = draw_pointer(pointer.width, pointer.height); |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 109 | buffer = buffer_create_from_cairo_surface(fd, s); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 110 | |
Kristian Høgsberg | 2f2cfae | 2008-11-08 22:46:30 -0500 | [diff] [blame^] | 111 | wl_surface_attach(pointer.surface, buffer->name, |
| 112 | buffer->width, buffer->height, buffer->stride); |
Kristian Høgsberg | 2a20d83 | 2008-11-02 17:22:39 -0500 | [diff] [blame] | 113 | wl_surface_map(pointer.surface, 512, 384, pointer.width, pointer.height); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 114 | |
| 115 | wl_display_set_event_handler(display, event_handler, &pointer); |
| 116 | |
Kristian Høgsberg | 1cbaa6a | 2008-11-07 15:54:48 -0500 | [diff] [blame] | 117 | g_main_loop_run(loop); |
Kristian Høgsberg | 5a27f3e | 2008-11-02 10:55:25 -0500 | [diff] [blame] | 118 | |
| 119 | return 0; |
| 120 | } |