window: use libwayland-cursor instead of libXcursor
[platform/upstream/weston.git] / clients / eventdemo.c
1 /*
2  * Copyright © 2011 Tim Wiederhake
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 /**
24  * \file eventdemo.c
25  * \brief Demonstrate the use of Wayland's toytoolkit.
26  *
27  * Heavily commented demo program that can report all events that are
28  * dispatched to the window. For other functionality, eg. opengl/egl,
29  * drag and drop, etc. have a look at the other demos.
30  * \author Tim Wiederhake
31  */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35
36 #include <cairo.h>
37
38 #include <wayland-cursor.h>
39 #include "window.h"
40
41 /** window title */
42 static char *title = "EventDemo";
43
44 /** window width */
45 static int width = 500;
46
47 /** window height */
48 static int height = 400;
49
50 /** set if window has no borders */
51 static int noborder = 0;
52
53 /** if non-zero, maximum window width */
54 static int width_max = 0;
55
56 /** if non-zero, maximum window height */
57 static int height_max = 0;
58
59 /** set to log redrawing */
60 static int log_redraw = 0;
61
62 /** set to log resizing */
63 static int log_resize = 0;
64
65 /** set to log keyboard focus */
66 static int log_focus = 0;
67
68 /** set to log key events */
69 static int log_key = 0;
70
71 /** set to log button events */
72 static int log_button = 0;
73
74 /** set to log motion events */
75 static int log_motion = 0;
76
77 /**
78  * \struct eventdemo
79  * \brief Holds all data the program needs per window
80  *
81  * In this demo the struct holds the position of a
82  * red rectangle that is drawn in the window's area.
83  */
84 struct eventdemo {
85         struct window *window;
86         struct widget *widget;
87         struct display *display;
88
89         int x, y, w, h;
90 };
91
92 /**
93  * \brief CALLBACK function, Wayland requests the window to redraw.
94  * \param window window to be redrawn
95  * \param data user data associated to the window
96  *
97  * Draws a red rectangle as demonstration of per-window data.
98  */
99 static void
100 redraw_handler(struct widget *widget, void *data)
101 {
102         struct eventdemo *e = data;
103         cairo_surface_t *surface;
104         cairo_t *cr;
105         struct rectangle rect;
106
107         if (log_redraw)
108                 printf("redraw\n");
109
110         widget_get_allocation(e->widget, &rect);
111         surface = window_get_surface(e->window);
112
113         cr = cairo_create(surface);
114         cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
115
116         cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height);
117         cairo_set_source_rgba(cr, 0, 0, 0, 0.8);
118         cairo_fill(cr);
119
120         cairo_rectangle(cr, e->x, e->y, e->w, e->h);
121         cairo_set_source_rgba(cr, 1.0, 0, 0, 1);
122         cairo_fill(cr);
123
124         cairo_destroy(cr);
125         cairo_surface_destroy(surface);
126 }
127
128 /**
129  * \brief CALLBACK function, Wayland requests the window to resize.
130  * \param window window to be resized
131  * \param width desired width
132  * \param height desired height
133  * \param data user data associated to the window
134  */
135
136 static void
137 resize_handler(struct widget *widget,
138                int32_t width, int32_t height, void *data)
139 {
140         struct eventdemo *e = data;
141         if (log_resize)
142                 printf("resize width: %d, height: %d\n", width, height);
143
144         /* if a maximum width is set, constrain to it */
145         if (width_max && width_max < width)
146                 width = width_max;
147
148         /* if a maximum height is set, constrain to it */
149         if (height_max && height_max < height)
150                 height = height_max;
151
152         /* set the new window dimensions */
153         widget_set_size(e->widget, width, height);
154 }
155
156 /**
157  * \brief CALLBACK function, Wayland informs about keyboard focus change
158  * \param window window
159  * \param device device that caused the focus change
160  * \param data user data associated to the window
161  */
162 static void
163 keyboard_focus_handler(struct window *window,
164                        struct input *device, void *data)
165 {
166         int32_t x, y;
167         struct eventdemo *e = data;
168
169         if(log_focus) {
170                 if(device) {
171                         input_get_position(device, &x, &y);
172                         printf("focus x: %d, y: %d\n", x, y);
173                 } else {
174                         printf("focus lost\n");
175                 }
176         }
177
178         window_schedule_redraw(e->window);
179 }
180
181 /**
182  * \brief CALLBACK function, Wayland informs about key event
183  * \param window window
184  * \param key keycode
185  * \param unicode associated character
186  * \param state pressed or released
187  * \param modifiers modifiers: ctrl, alt, meta etc.
188  * \param data user data associated to the window
189  */
190 static void
191 key_handler(struct window *window, struct input *input, uint32_t time,
192             uint32_t key, uint32_t unicode, uint32_t state, void *data)
193 {
194         uint32_t modifiers = input_get_modifiers(input);
195
196         if(!log_key)
197                 return;
198
199         printf("key key: %d, unicode: %d, state: %d, modifiers: %d\n",
200                key, unicode, state, modifiers);
201 }
202
203 /**
204  * \brief CALLBACK function, Wayland informs about button event
205  * \param window window
206  * \param input input device that caused the button event
207  * \param time time the event happend
208  * \param button button
209  * \param state pressed or released
210  * \param data user data associated to the window
211  */
212 static void
213 button_handler(struct widget *widget, struct input *input, uint32_t time,
214                uint32_t button, uint32_t state, void *data)
215 {
216         int32_t x, y;
217
218         if (!log_button)
219                 return;
220
221         input_get_position(input, &x, &y);
222         printf("button time: %d, button: %d, state: %d, x: %d, y: %d\n",
223                time, button, state, x, y);
224 }
225
226 /**
227  * \brief CALLBACK function, Waylands informs about pointer motion
228  * \param window window
229  * \param input input device that caused the motion event
230  * \param time time the event happend
231  * \param x absolute x position
232  * \param y absolute y position
233  * \param sx x position relative to the window
234  * \param sy y position relative to the window
235  * \param data user data associated to the window
236  *
237  * Demonstrates the use of different cursors
238  */
239 static int
240 motion_handler(struct widget *widget, struct input *input, uint32_t time,
241                float x, float y, void *data)
242 {
243         struct eventdemo *e = data;
244
245         if (log_motion) {
246                 printf("motion time: %d, x: %f, y: %f\n", time, x, y);
247         }
248
249         if (x > e->x && x < e->x + e->w)
250                 if (y > e->y && y < e->y + e->h)
251                         return WL_CURSOR_HAND1;
252
253         return WL_CURSOR_LEFT_PTR;
254 }
255
256 /**
257  * \brief Create and initialise a new eventdemo window.
258  * \param d associated display
259  */
260 static struct eventdemo *
261 eventdemo_create(struct display *d)
262 {
263         struct eventdemo *e;
264
265         e = malloc(sizeof (struct eventdemo));
266         if(e == NULL)
267                 return NULL;
268
269         e->window = window_create(d);
270         e->widget = frame_create(e->window, e);
271         window_set_title(e->window, title);
272         e->display = d;
273
274         /* The eventdemo window draws a red rectangle as a demonstration
275          * of per-window data. The dimensions of that rectangle are set
276          * here.
277          */
278         e->x = width * 1.0 / 4.0;
279         e->w = width * 2.0 / 4.0;
280         e->y = height * 1.0 / 4.0;
281         e->h = height * 2.0 / 4.0;
282
283         /* Connect the user data to the window */
284         window_set_user_data(e->window, e);
285
286         /* Set the callback redraw handler for the window */
287         widget_set_redraw_handler(e->widget, redraw_handler);
288
289         /* Set the callback resize handler for the window */
290         widget_set_resize_handler(e->widget, resize_handler);
291
292         /* Set the callback focus handler for the window */
293         window_set_keyboard_focus_handler(e->window,
294                                           keyboard_focus_handler);
295
296         /* Set the callback key handler for the window */
297         window_set_key_handler(e->window, key_handler);
298
299         /* Set the callback button handler for the window */
300         widget_set_button_handler(e->widget, button_handler);
301
302         /* Set the callback motion handler for the window */
303         widget_set_motion_handler(e->widget, motion_handler);
304
305         /* Demonstrate how to create a borderless window.
306            Move windows with META + left mouse button.
307          */
308         if (noborder) {
309         }
310
311         /* Initial drawing of the window */
312         window_schedule_resize(e->window, width, height);
313
314         return e;
315 }
316 /**
317  * \brief command line options for eventdemo
318  */
319 static const struct weston_option eventdemo_options[] = {
320         { WESTON_OPTION_STRING, "title", 0, &title },
321         { WESTON_OPTION_INTEGER, "width", 'w', &width },
322         { WESTON_OPTION_INTEGER, "height", 'h', &height },
323         { WESTON_OPTION_INTEGER, "max-width", 0, &width_max },
324         { WESTON_OPTION_INTEGER, "max-height", 0, &height_max },
325         { WESTON_OPTION_BOOLEAN, "no-border", 'b', &noborder },
326         { WESTON_OPTION_BOOLEAN, "log-redraw", '0', &log_redraw },
327         { WESTON_OPTION_BOOLEAN, "log-resize", '0', &log_resize },
328         { WESTON_OPTION_BOOLEAN, "log-focus", '0', &log_focus },
329         { WESTON_OPTION_BOOLEAN, "log-key", '0', &log_key },
330         { WESTON_OPTION_BOOLEAN, "log-button", '0', &log_button },
331         { WESTON_OPTION_BOOLEAN, "log-motion", '0', &log_motion },
332 };
333
334 /**
335  * \brief Connects to the display, creates the window and hands over
336  * to the main loop.
337  */
338 int
339 main(int argc, char *argv[])
340 {
341         struct display *d;
342         struct eventdemo *e;
343
344         argc = parse_options(eventdemo_options,
345                              ARRAY_LENGTH(eventdemo_options), argc, argv);
346
347         /* Connect to the display and have the arguments parsed */
348         d = display_create(argc, argv);
349         if (d == NULL) {
350                 fprintf(stderr, "failed to create display: %m\n");
351                 return -1;
352         }
353
354         /* Create new eventdemo window */
355         e = eventdemo_create(d);
356         if (e == NULL) {
357                 fprintf(stderr, "failed to create eventdemo: %m\n");
358                 return -1;
359         }
360
361         display_run(d);
362
363         return 0;
364 }