clients: add ime-keyboard(input_method), text-entry(text_input)
[platform/core/uifw/libds-tizen.git] / clients / text-entry.c
1 /*
2  * Copyright © 2011 Benjamin Franzke
3  * Copyright © 2010 Intel Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdbool.h>
30 #include <assert.h>
31 #include <unistd.h>
32 #include <sys/mman.h>
33 #include <signal.h>
34 #include <errno.h>
35
36 #include <wayland-client.h>
37 #include <wayland-tbm-client.h>
38 #include <tbm_surface.h>
39 #include <tbm_surface_internal.h>
40 #include "xdg-shell-client-protocol.h"
41 #include <text-client-protocol.h>
42 #include <xkbcommon/xkbcommon.h>
43
44 static uint64_t buffer_info_key;
45 #define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key)
46
47 struct display {
48         struct wl_display *display;
49         struct wl_registry *registry;
50         struct wl_compositor *compositor;
51         struct xdg_wm_base *wm_base;
52         struct wl_shm *shm;
53         struct wl_seat *seat;
54     struct wayland_tbm_client *wl_tbm;
55         bool has_xrgb;
56
57         struct wl_text_input_manager *text_input_mgr;
58         int notified;
59         bool blocked;
60         struct wl_surface *entered_surface;
61
62         struct text_entry *entry;
63 };
64
65 struct window {
66         struct display *display;
67         int width, height;
68         struct wl_surface *surface;
69         struct xdg_surface *xdg_surface;
70         struct xdg_toplevel *xdg_toplevel;
71         struct wl_callback *callback;
72     tbm_surface_queue_h surface_queue;
73         bool wait_for_configure;
74 };
75
76 struct buffer_info {
77     struct window *window;
78     struct wl_buffer *wl_buffer;
79 };
80
81 struct text_entry {
82         char *text;
83         int active;
84         bool panel_visible;
85         uint32_t cursor;
86         uint32_t anchor;
87         struct {
88                 char *text;
89                 int32_t cursor;
90                 char *commit;
91         } preedit;
92         struct {
93                 int32_t cursor;
94         } preedit_info;
95         struct {
96                 int32_t cursor;
97                 int32_t anchor;
98                 uint32_t delete_index;
99                 uint32_t delete_length;
100                 bool invalid_delete;
101         } pending_commit;
102         struct wl_text_input *text_input;
103         struct {
104                 xkb_mod_mask_t shift_mask;
105         } keysym;
106         uint32_t serial;
107         uint32_t reset_serial;
108         uint32_t content_purpose;
109         bool click_to_show;
110         char *preferred_language;
111         bool button_pressed;
112 };
113
114 struct rectangle {
115         int32_t x;
116         int32_t y;
117         int32_t width;
118         int32_t height;
119 };
120
121 static int running = 1;
122
123 static void
124 redraw(void *data, struct wl_callback *callback, uint32_t time);
125 static void
126 text_entry_activate(struct display *d);
127 static void
128 text_entry_deactivate(struct display *d);
129
130 static void
131 handle_xdg_surface_configure(void *data, struct xdg_surface *surface,
132                              uint32_t serial)
133 {
134         struct window *window = data;
135
136         xdg_surface_ack_configure(surface, serial);
137
138         if (window->wait_for_configure) {
139                 redraw(window, NULL, 0);
140                 window->wait_for_configure = false;
141         }
142 }
143
144 static const struct xdg_surface_listener xdg_surface_listener = {
145         handle_xdg_surface_configure,
146 };
147
148 static void
149 handle_xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
150                               int32_t width, int32_t height,
151                               struct wl_array *state)
152 {
153 }
154
155 static void
156 handle_xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
157 {
158         running = 0;
159 }
160
161 static const struct xdg_toplevel_listener xdg_toplevel_listener = {
162         handle_xdg_toplevel_configure,
163         handle_xdg_toplevel_close,
164 };
165
166 static struct window *
167 create_window(struct display *display, int width, int height)
168 {
169         struct window *window;
170
171         window = calloc(1, sizeof *window);
172         if (!window)
173                 return NULL;
174
175         window->callback = NULL;
176         window->display = display;
177         window->width = width;
178         window->height = height;
179         window->surface = wl_compositor_create_surface(display->compositor);
180
181         if (display->wm_base) {
182                 window->xdg_surface =
183                         xdg_wm_base_get_xdg_surface(display->wm_base,
184                                                     window->surface);
185                 assert(window->xdg_surface);
186                 xdg_surface_add_listener(window->xdg_surface,
187                                          &xdg_surface_listener, window);
188
189                 window->xdg_toplevel =
190                         xdg_surface_get_toplevel(window->xdg_surface);
191                 assert(window->xdg_toplevel);
192                 xdg_toplevel_add_listener(window->xdg_toplevel,
193                                           &xdg_toplevel_listener, window);
194
195                 xdg_toplevel_set_title(window->xdg_toplevel, "simple-tbm");
196                 wl_surface_commit(window->surface);
197                 window->wait_for_configure = true;
198         } else {
199                 assert(0);
200         }
201
202     window->surface_queue =
203         wayland_tbm_client_create_surface_queue(display->wl_tbm,
204                 window->surface,
205                 3,
206                 width,
207                 height,
208                 TBM_FORMAT_XRGB8888);
209     assert(window->surface_queue);
210
211         return window;
212 }
213
214 static void
215 destroy_window(struct window *window)
216 {
217     tbm_surface_queue_destroy(window->surface_queue);
218
219         if (window->callback)
220                 wl_callback_destroy(window->callback);
221
222         if (window->xdg_toplevel)
223                 xdg_toplevel_destroy(window->xdg_toplevel);
224         if (window->xdg_surface)
225                 xdg_surface_destroy(window->xdg_surface);
226         wl_surface_destroy(window->surface);
227         free(window);
228 }
229
230 static void
231 paint_pixels(void *image, int padding, int width, int height, uint32_t time)
232 {
233         const int halfh = padding + (height - padding * 2) / 2;
234         const int halfw = padding + (width  - padding * 2) / 2;
235         int ir, or;
236         uint32_t *pixel = image;
237         int y;
238
239         /* squared radii thresholds */
240         or = (halfw < halfh ? halfw : halfh) - 8;
241         ir = or - 32;
242         or *= or;
243         ir *= ir;
244
245         pixel += padding * width;
246         for (y = padding; y < height - padding; y++) {
247                 int x;
248                 int y2 = (y - halfh) * (y - halfh);
249
250                 pixel += padding;
251                 for (x = padding; x < width - padding; x++) {
252                         uint32_t v;
253
254                         /* squared distance from center */
255                         int r2 = (x - halfw) * (x - halfw) + y2;
256
257                         if (r2 < ir)
258                                 v = (r2 / 32 + time / 64) * 0x0080401;
259                         else if (r2 < or)
260                                 v = (y + time / 32) * 0x0080401;
261                         else
262                                 v = (x + time / 16) * 0x0080401;
263                         v &= 0x00ffffff;
264
265                         /* cross if compositor uses X from XRGB as alpha */
266                         if (abs(x - y) > 6 && abs(x + y - height) > 6)
267                                 v |= 0xff000000;
268
269                         *pixel++ = v;
270                 }
271
272                 pixel += padding;
273         }
274 }
275
276 static void
277 buffer_info_free_cb(void *data)
278 {
279     struct buffer_info *buffer_info = data;
280
281     if (!buffer_info)
282         return;
283
284     wayland_tbm_client_destroy_buffer(buffer_info->window->display->wl_tbm,
285             buffer_info->wl_buffer);
286     free(buffer_info);
287 }
288
289 static void
290 buffer_handle_release(void *data, struct wl_buffer *wl_buffer)
291 {
292     tbm_surface_h surface = data;
293     struct buffer_info *buffer_info;
294
295     tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY,
296             (void **)&buffer_info);
297     if (buffer_info)
298         tbm_surface_queue_release(buffer_info->window->surface_queue, surface);
299 }
300
301 static const struct wl_buffer_listener buffer_listener = {
302     .release = buffer_handle_release,
303 };
304
305 static const struct wl_callback_listener frame_listener;
306
307 static void
308 redraw(void *data, struct wl_callback *callback, uint32_t time)
309 {
310         struct window *window = data;
311     struct buffer_info *buffer_info = NULL;
312     tbm_surface_h surface = NULL;
313     tbm_surface_info_s surface_info;
314
315     if (!tbm_surface_queue_can_dequeue(window->surface_queue, 0))
316         return;
317
318     tbm_surface_queue_dequeue(window->surface_queue, &surface);
319     assert(surface);
320
321     tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY,
322             (void **)&buffer_info);
323     if (!buffer_info) {
324         buffer_info = calloc(1, sizeof *buffer_info);
325         assert(buffer_info);
326
327         tbm_surface_internal_add_user_data(surface, BUFFER_INFO_KEY, buffer_info_free_cb);
328         tbm_surface_internal_set_user_data(surface, BUFFER_INFO_KEY, buffer_info);
329
330         buffer_info->wl_buffer =
331             wayland_tbm_client_create_buffer(window->display->wl_tbm, surface);
332         assert(buffer_info->wl_buffer);
333
334         wl_buffer_add_listener(buffer_info->wl_buffer, &buffer_listener,
335                 surface);
336
337         buffer_info->window = window;
338     }
339
340     tbm_surface_map(surface, TBM_SURF_OPTION_WRITE, &surface_info);
341
342         paint_pixels(surface_info.planes[0].ptr, 20,
343             (surface_info.planes[0].stride/4), surface_info.height, time);
344
345     tbm_surface_unmap(surface);
346
347         wl_surface_attach(window->surface, buffer_info->wl_buffer, 0, 0);
348         wl_surface_damage(window->surface,
349                           20, 20, window->width - 40, window->height - 40);
350
351         if (callback)
352                 wl_callback_destroy(callback);
353
354         window->callback = wl_surface_frame(window->surface);
355         wl_callback_add_listener(window->callback, &frame_listener, window);
356         wl_surface_commit(window->surface);
357 }
358
359 static const struct wl_callback_listener frame_listener = {
360         redraw
361 };
362
363 static void
364 shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
365 {
366         struct display *d = data;
367
368         if (format == WL_SHM_FORMAT_XRGB8888)
369                 d->has_xrgb = true;
370 }
371
372 struct wl_shm_listener shm_listener = {
373         shm_format
374 };
375
376 static void
377 xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
378 {
379         xdg_wm_base_pong(shell, serial);
380 }
381
382 static const struct xdg_wm_base_listener xdg_wm_base_listener = {
383         xdg_wm_base_ping,
384 };
385
386 static void pointer_handle_button(void *data, struct wl_pointer *pointer,
387         uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
388 {
389     struct display *d = data;
390
391     if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
392         fprintf(stderr, "pointer_handle_button: PRESSED\n");
393
394         text_entry_activate(d);
395     }
396     else {
397         fprintf(stderr, "pointer_handle_button: RELEASED\n");
398
399         text_entry_deactivate(d);
400     }
401 }
402
403 static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
404         uint32_t serial, struct wl_surface *surface,
405         wl_fixed_t surface_x, wl_fixed_t surface_y)
406 {
407     struct display *d = data;
408
409     fprintf(stderr, "pointer_handle_enter surface_x:%d, surface_y:%d\n",
410             wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y));
411     d->entered_surface = surface;
412 }
413
414 static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
415         uint32_t serial, struct wl_surface *surface)
416 {
417     fprintf(stderr, "pointer_handle_leave\n");
418 }
419
420 static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
421         uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y)
422 {
423     fprintf(stderr, "pointer_handle_motion surface_x:%d, surface_y:%d\n",
424             wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y));
425 }
426
427 static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer)
428 {
429     fprintf(stderr, "pointer_handle_frame\n");
430 }
431
432 static struct wl_pointer_listener pointer_listener = {
433     .enter = pointer_handle_enter,
434     .leave = pointer_handle_leave,
435     .motion = pointer_handle_motion,
436     .button = pointer_handle_button,
437     .axis = NULL,
438     .frame = pointer_handle_frame,
439     .axis_source = NULL,
440     .axis_stop = NULL,
441     .axis_discrete = NULL,
442 };
443
444 static void touch_handle_down(void *data, struct wl_touch *wl_touch,
445         uint32_t serial, uint32_t time, struct wl_surface *surface,
446         int32_t id, wl_fixed_t x, wl_fixed_t y)
447 {
448     fprintf(stderr, "touch_handle_down id:%d, x:%d, y:%d\n",
449             id, wl_fixed_to_int(x), wl_fixed_to_int(y));
450 }
451
452 static void touch_handle_up(void *data, struct wl_touch *wl_touch,
453         uint32_t serial, uint32_t time, int32_t id)
454 {
455     fprintf(stderr, "touch_handle_up id:%d\n", id);
456 }
457
458 static void touch_handle_motion(void *data, struct wl_touch *wl_touch,
459         uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y)
460 {
461     fprintf(stderr, "touch_handle_motion id:%d, x:%d, y:%d\n",
462             id, wl_fixed_to_int(x), wl_fixed_to_int(y));
463 }
464
465 static void touch_handle_frame(void *data, struct wl_touch *wl_touch)
466 {
467     fprintf(stderr, "touch_handle_frame\n");
468 }
469
470 static struct wl_touch_listener touch_listener = {
471     .down = touch_handle_down,
472     .up = touch_handle_up,
473     .motion = touch_handle_motion,
474     .frame = touch_handle_frame,
475     .cancel = NULL,
476     .shape = NULL,
477     .orientation = NULL,
478 };
479
480 static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
481         uint32_t format, int32_t fd, uint32_t size)
482 {
483     fprintf(stderr, "keyboard_handle_keymap\n");
484 }
485 static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
486         uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
487 {
488     fprintf(stderr, "keyboard_handle_enter\n");
489 }
490 static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
491         uint32_t serial, struct wl_surface *surface)
492 {
493     fprintf(stderr, "keyboard_handle_leave\n");
494 }
495 static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
496         uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
497         uint32_t mods_locked, uint32_t group)
498 {
499     fprintf(stderr, "keyboard_handle_modifiers\n");
500 }
501 static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
502         int32_t rate, int32_t delay)
503 {
504     fprintf(stderr, "keyboard_handle_repeat_info\n");
505 }
506
507 static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
508         uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
509 {
510     if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
511         fprintf(stderr, "keyboard_handle_key: key:%d, PRESSED\n", key);
512     } else {
513         fprintf(stderr, "keyboard_handle_key: key:%d, RELEASED\n", key);
514     }
515 }
516
517 static struct wl_keyboard_listener keyboard_listener = {
518     .keymap = keyboard_handle_keymap,
519     .enter = keyboard_handle_enter,
520     .leave = keyboard_handle_leave,
521     .key = keyboard_handle_key,
522     .modifiers = keyboard_handle_modifiers,
523     .repeat_info = keyboard_handle_repeat_info,
524 };
525
526 static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
527         enum wl_seat_capability caps)
528 {
529         struct display *d = data;
530     if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
531         struct wl_keyboard *keyboard = wl_seat_get_keyboard(wl_seat);
532         wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL);
533         fprintf(stderr, "seat_handle_capabilities: keyboard\n");
534     }
535     if ((caps & WL_SEAT_CAPABILITY_POINTER)) {
536         struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat);
537         wl_pointer_add_listener(pointer, &pointer_listener, d);
538         fprintf(stderr, "seat_handle_capabilities: pointer\n");
539     }
540     if ((caps & WL_SEAT_CAPABILITY_TOUCH)) {
541         struct wl_touch *touch = wl_seat_get_touch(wl_seat);
542         wl_touch_add_listener(touch, &touch_listener, d);
543         fprintf(stderr, "seat_handle_capabilities: touch\n");
544     }
545 }
546
547 static void seat_handle_name(void *data, struct wl_seat *wl_seat,
548         const char *name)
549 {
550     fprintf(stderr, "seat_handle_name name:%s\n", name);
551 }
552
553 const struct wl_seat_listener seat_listener = {
554     .capabilities = seat_handle_capabilities,
555     .name = seat_handle_name,
556 };
557
558 static void
559 text_entry_get_cursor_rectangle(struct text_entry *entry, struct rectangle *rectangle)
560 {
561         if (entry->preedit.text && entry->preedit.cursor < 0) {
562                 rectangle->x = 0;
563                 rectangle->y = 0;
564                 rectangle->width = 0;
565                 rectangle->height = 0;
566                 return;
567         }
568
569         rectangle->x = 10;
570         rectangle->y = 20;
571         rectangle->width = 50;
572         rectangle->height = 50;
573 }
574
575 static void
576 text_entry_update(struct text_entry *entry)
577 {
578         struct rectangle cursor_rectangle;
579
580         fprintf(stderr, "text_entry_update()\n");
581
582         wl_text_input_set_content_type(entry->text_input,
583                                            WL_TEXT_INPUT_CONTENT_HINT_NONE,
584                                            entry->content_purpose);
585
586         if (entry->preferred_language)
587                 wl_text_input_set_preferred_language(entry->text_input,
588                                                          entry->preferred_language);
589
590         text_entry_get_cursor_rectangle(entry, &cursor_rectangle);
591         wl_text_input_set_cursor_rectangle(entry->text_input,
592                                                cursor_rectangle.x,
593                                                cursor_rectangle.y,
594                                                cursor_rectangle.width,
595                                                cursor_rectangle.height);
596
597         wl_text_input_commit_state(entry->text_input, ++entry->serial);
598 }
599
600 static void
601 text_entry_reset_preedit(struct text_entry *entry)
602 {
603     fprintf(stderr, "text_entry_reset_preedit()\n");
604         entry->preedit.cursor = 0;
605
606         free(entry->preedit.text);
607         entry->preedit.text = NULL;
608
609         free(entry->preedit.commit);
610         entry->preedit.commit = NULL;
611 }
612
613 static void
614 text_entry_insert_at_cursor(struct text_entry *entry, const char *text,
615                             int32_t cursor, int32_t anchor)
616 {
617         fprintf(stderr, "text_entry_insert_at_cursor()\n");
618         char *new_text = malloc(strlen(entry->text) + strlen(text) + 1);
619         if (new_text == NULL) {
620                 fprintf(stderr, "alloc fail");
621                 return;
622         }
623
624         strncpy(new_text, entry->text, entry->cursor);
625         strcpy(new_text + entry->cursor, text);
626         strcpy(new_text + entry->cursor + strlen(text),
627                entry->text + entry->cursor);
628
629         free(entry->text);
630         entry->text = new_text;
631         if (anchor >= 0)
632                 entry->anchor = entry->cursor + strlen(text) + anchor;
633         else
634                 entry->anchor = entry->cursor + 1 + anchor;
635
636         if (cursor >= 0)
637                 entry->cursor += strlen(text) + cursor;
638         else
639                 entry->cursor += 1 + cursor;
640
641         text_entry_update(entry);
642 }
643
644 static void
645 text_entry_commit_and_reset(struct text_entry *entry)
646 {
647         char *commit = NULL;
648
649         fprintf(stderr, "text_entry_commit_and_reset()\n");
650
651         if (entry->preedit.commit)
652                 commit = strdup(entry->preedit.commit);
653
654         text_entry_reset_preedit(entry);
655         if (commit) {
656                 text_entry_insert_at_cursor(entry, commit, 0, 0);
657                 free(commit);
658         }
659
660         wl_text_input_reset(entry->text_input);
661         text_entry_update(entry);
662         entry->reset_serial = entry->serial;
663 }
664
665 static void
666 text_input_enter(void *data, struct wl_text_input *text_input,
667     struct wl_surface    *surface)
668 {
669     fprintf(stderr, "text_input_enter()\n");
670
671         struct display *d = data;
672         struct text_entry *entry = d->entry;
673
674         entry->active++;
675
676         text_entry_update(entry);
677         entry->reset_serial = entry->serial;
678 }
679 static void
680 text_input_leave(void *data, struct wl_text_input *text_input)
681 {
682     fprintf(stderr, "text_input_leave()\n");
683
684         struct display *d = data;
685         struct text_entry *entry = d->entry;
686
687     text_entry_commit_and_reset(entry);
688         d->entry->active--;
689
690         if (!entry->active) {
691                 wl_text_input_hide_input_panel(text_input);
692                 entry->panel_visible = false;
693         }
694 }
695
696 static void
697 text_input_modifiers_map(void *data, struct wl_text_input *text_input,
698     struct wl_array *map)
699 {
700     fprintf(stderr, "text_input_modifiers_map()\n");
701 }
702
703 static void
704 text_input_input_panel_state(void *data, struct wl_text_input *text_input,
705     uint32_t state)
706 {
707     fprintf(stderr, "text_input_input_panel_state() state:%u\n", state);
708 }
709
710 static void
711 text_input_preedit_string(void *data, struct wl_text_input *text_input,
712     uint32_t serial, const char *text, const char *commit)
713 {
714     fprintf(stderr, "text_input_preedit_string() serial(%u), text(%s), commit(%s)\n", serial, text, commit);
715 }
716
717 static void
718 text_input_preedit_styling(void *data, struct wl_text_input *text_input,
719     uint32_t index, uint32_t length, uint32_t style)
720 {
721     fprintf(stderr, "text_input_preedit_styling() index(%u), length(%u), style(%u)\n", index, length, style);
722 }
723
724 static void
725 text_input_preedit_cursor(void *data, struct wl_text_input *text_input,
726     int32_t index)
727 {
728     fprintf(stderr, "text_input_preedit_cursor() index(%u)\n", index);
729 }
730
731 static void
732 text_input_commit_string(void *data, struct wl_text_input *text_input,
733     uint32_t serial, const char *text)
734 {
735     fprintf(stderr, "text_input_commit_string() serial(%u), text(%s)\n", serial, text);
736 }
737
738 static void
739 text_input_cursor_position(void *data, struct wl_text_input *text_input,
740     int32_t index, int32_t anchor)
741 {
742     fprintf(stderr, "text_input_cursor_position() index(%d), anchor(%d)\n", index, anchor);
743 }
744
745 static void
746 text_input_delete_surrounding_text(void *data,
747     struct wl_text_input *text_input, int32_t index, uint32_t length)
748 {
749     fprintf(stderr, "text_input_delete_surrounding_text() index(%d), length(%u)\n", index, length);
750 }
751
752 static void
753 text_input_keysym(void *data, struct wl_text_input *text_input,
754     uint32_t serial, uint32_t time, uint32_t sym, uint32_t state,
755     uint32_t modifiers)
756 {
757     fprintf(stderr, "text_input_keysym() serial(%u), time(%u), sym(%u), state(%u), modifiers(%u)\n",
758             serial, time, sym, state, modifiers);
759 }
760
761 static void
762 text_input_language(void *data, struct wl_text_input *text_input,
763     uint32_t serial, const char *language)
764 {
765     fprintf(stderr, "text_input_language() serial(%u), language(%s)\n", serial, language);
766 }
767
768 static void
769 text_input_text_direction(void *data, struct wl_text_input *text_input,
770     uint32_t serial, uint32_t direction)
771 {
772     fprintf(stderr, "text_input_text_direction() serial(%d), direction(%d)\n", serial, direction);
773 }
774
775 static const struct wl_text_input_listener text_input_listener = {
776     .enter = text_input_enter,
777     .leave = text_input_leave,
778     .modifiers_map = text_input_modifiers_map,
779     .input_panel_state = text_input_input_panel_state,
780     .preedit_string = text_input_preedit_string,
781     .preedit_styling = text_input_preedit_styling,
782     .preedit_cursor = text_input_preedit_cursor,
783     .commit_string = text_input_commit_string,
784     .cursor_position = text_input_cursor_position,
785     .delete_surrounding_text = text_input_delete_surrounding_text,
786     .keysym = text_input_keysym,
787     .language = text_input_language,
788     .text_direction = text_input_text_direction,
789     // TIZEN_ONLY(20150918): Support to set the selection region
790     .selection_region = NULL,
791     .private_command = NULL,
792     .input_panel_geometry = NULL,
793     .input_panel_data = NULL,
794     .get_selection_text = NULL,
795     .get_surrounding_text = NULL,
796     .filter_key_event_done = NULL,
797     .hide_permission = NULL,
798     .recapture_string = NULL,
799     .input_panel_event = NULL,
800     .commit_content = NULL,
801     //
802 };
803
804 static void
805 text_entry_activate(struct display *d)
806 {
807         struct wl_surface *surface = d->entered_surface;
808         struct text_entry *entry = d->entry;
809
810     fprintf(stderr, "text_entry_activate\n");
811         if (entry->click_to_show && entry->active) {
812                 entry->panel_visible = !entry->panel_visible;
813
814                 if (entry->panel_visible)
815                         wl_text_input_show_input_panel(entry->text_input);
816                 else
817                         wl_text_input_hide_input_panel(entry->text_input);
818
819                 return;
820         }
821
822         if (!entry->click_to_show)
823                 wl_text_input_show_input_panel(entry->text_input);
824
825         wl_text_input_activate(entry->text_input,
826                                    d->seat,
827                                    surface);
828 }
829
830 static void
831 text_entry_deactivate(struct display *d)
832 {
833         struct text_entry *entry = d->entry;
834
835     fprintf(stderr, "text_entry_deactivate\n");
836         wl_text_input_deactivate(entry->text_input,
837                                      d->seat);
838 }
839
840 static void
841 text_entry_destroy(struct display *d)
842 {
843         struct text_entry *entry;
844
845         entry = d->entry;
846         d->entry = NULL;
847
848         wl_text_input_destroy(entry->text_input);
849         free(entry->text);
850         free(entry->preferred_language);
851         free(entry);
852 }
853
854 static struct text_entry*
855 text_entry_create(struct display *d, const char *text)
856 {
857         struct text_entry *entry;
858
859         entry = calloc(1, sizeof *entry);
860         if (!entry)
861             return NULL;
862
863         entry->text = strdup(text);
864         entry->active = 0;
865         entry->panel_visible = false;
866         entry->cursor = strlen(text);
867         entry->anchor = entry->cursor;
868         entry->click_to_show = true;
869         entry->text_input =
870                 wl_text_input_manager_create_text_input(d->text_input_mgr);
871         wl_text_input_add_listener(entry->text_input,
872                                        &text_input_listener, d);
873
874     d->entry = entry;
875     fprintf(stderr, "text_entry_create() entry(%p) created.\n", entry);
876
877         return entry;
878 }
879
880 static void
881 registry_handle_global(void *data, struct wl_registry *registry,
882                        uint32_t id, const char *interface, uint32_t version)
883 {
884         struct display *d = data;
885
886         if (strcmp(interface, "wl_compositor") == 0) {
887                 d->compositor =
888                         wl_registry_bind(registry,
889                                          id, &wl_compositor_interface, 1);
890         } else if (strcmp(interface, "xdg_wm_base") == 0) {
891                 d->wm_base = wl_registry_bind(registry,
892                                               id, &xdg_wm_base_interface, 1);
893                 xdg_wm_base_add_listener(d->wm_base, &xdg_wm_base_listener, d);
894         } else if (strcmp(interface, "wl_shm") == 0) {
895                 d->shm = wl_registry_bind(registry,
896                                           id, &wl_shm_interface, 1);
897                 wl_shm_add_listener(d->shm, &shm_listener, d);
898         } else if (strcmp(interface, "wl_seat") == 0) {
899                 d->seat = wl_registry_bind(registry,
900                                           id, &wl_seat_interface, 7);
901                 wl_seat_add_listener(d->seat, &seat_listener, d);
902                 fprintf(stderr, "wl_seat bound!\n");
903         } else if (strcmp(interface, "wl_text_input_manager") == 0) {
904                 d->text_input_mgr = wl_registry_bind(registry,
905                                           id, &wl_text_input_manager_interface, version);
906                 fprintf(stderr, "wl_text_input_manager bound!\n");
907
908                 text_entry_create(d, "Entry");
909     }
910 }
911
912 static void
913 registry_handle_global_remove(void *data, struct wl_registry *registry,
914                               uint32_t name)
915 {
916 }
917
918 static const struct wl_registry_listener registry_listener = {
919         registry_handle_global,
920         registry_handle_global_remove
921 };
922
923 static struct display *
924 create_display(void)
925 {
926         struct display *display;
927
928         display = calloc(1, sizeof *display);
929         if (display == NULL) {
930                 fprintf(stderr, "out of memory\n");
931                 exit(1);
932         }
933         display->display = wl_display_connect(NULL);
934         assert(display->display);
935
936         display->has_xrgb = false;
937         display->registry = wl_display_get_registry(display->display);
938         wl_registry_add_listener(display->registry,
939                                  &registry_listener, display);
940         wl_display_roundtrip(display->display);
941         if (display->shm == NULL) {
942                 fprintf(stderr, "No wl_shm global\n");
943                 exit(1);
944         }
945
946         wl_display_roundtrip(display->display);
947
948         /*
949          * Why do we need two roundtrips here?
950          *
951          * wl_display_get_registry() sends a request to the server, to which
952          * the server replies by emitting the wl_registry.global events.
953          * The first wl_display_roundtrip() sends wl_display.sync. The server
954          * first processes the wl_display.get_registry which includes sending
955          * the global events, and then processes the sync. Therefore when the
956          * sync (roundtrip) returns, we are guaranteed to have received and
957          * processed all the global events.
958          *
959          * While we are inside the first wl_display_roundtrip(), incoming
960          * events are dispatched, which causes registry_handle_global() to
961          * be called for each global. One of these globals is wl_shm.
962          * registry_handle_global() sends wl_registry.bind request for the
963          * wl_shm global. However, wl_registry.bind request is sent after
964          * the first wl_display.sync, so the reply to the sync comes before
965          * the initial events of the wl_shm object.
966          *
967          * The initial events that get sent as a reply to binding to wl_shm
968          * include wl_shm.format. These tell us which pixel formats are
969          * supported, and we need them before we can create buffers. They
970          * don't change at runtime, so we receive them as part of init.
971          *
972          * When the reply to the first sync comes, the server may or may not
973          * have sent the initial wl_shm events. Therefore we need the second
974          * wl_display_roundtrip() call here.
975          *
976          * The server processes the wl_registry.bind for wl_shm first, and
977          * the second wl_display.sync next. During our second call to
978          * wl_display_roundtrip() the initial wl_shm events are received and
979          * processed. Finally, when the reply to the second wl_display.sync
980          * arrives, it guarantees we have processed all wl_shm initial events.
981          *
982          * This sequence contains two examples on how wl_display_roundtrip()
983          * can be used to guarantee, that all reply events to a request
984          * have been received and processed. This is a general Wayland
985          * technique.
986          */
987
988         if (!display->has_xrgb) {
989                 fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n");
990                 exit(1);
991         }
992
993     display->wl_tbm = wayland_tbm_client_init(display->display);
994     if (!display->wl_tbm) {
995         fprintf(stderr, "failed wayland_tbm_client_init()\n");
996         exit(1);
997     }
998
999         display->notified = -1;
1000
1001         return display;
1002 }
1003
1004 static void
1005 destroy_display(struct display *display)
1006 {
1007         text_entry_destroy(display);
1008
1009         if (display->text_input_mgr)
1010             wl_text_input_manager_destroy(display->text_input_mgr);
1011
1012         if (display->seat)
1013             wl_seat_destroy(display->seat);
1014
1015         if (display->shm)
1016                 wl_shm_destroy(display->shm);
1017
1018         if (display->wm_base)
1019                 xdg_wm_base_destroy(display->wm_base);
1020
1021         if (display->compositor)
1022                 wl_compositor_destroy(display->compositor);
1023
1024     wayland_tbm_client_deinit(display->wl_tbm);
1025         wl_registry_destroy(display->registry);
1026         wl_display_flush(display->display);
1027         wl_display_disconnect(display->display);
1028         free(display);
1029 }
1030
1031 static void
1032 signal_int(int signum)
1033 {
1034         running = 0;
1035 }
1036
1037 int
1038 main(int argc, char **argv)
1039 {
1040         struct sigaction sigint;
1041         struct display *display;
1042         struct window *window;
1043         int ret = 0;
1044
1045         display = create_display();
1046         window = create_window(display, 250, 250);
1047         if (!window)
1048                 return 1;
1049
1050         sigint.sa_handler = signal_int;
1051         sigemptyset(&sigint.sa_mask);
1052         sigint.sa_flags = SA_RESETHAND;
1053         sigaction(SIGINT, &sigint, NULL);
1054
1055         /* Initialise damage to full surface, so the padding gets painted */
1056         wl_surface_damage(window->surface, 0, 0,
1057                           window->width, window->height);
1058
1059         if (!window->wait_for_configure)
1060                 redraw(window, NULL, 0);
1061
1062         while (running && ret != -1)
1063                 ret = wl_display_dispatch(display->display);
1064
1065         fprintf(stderr, "simple-shm exiting\n");
1066
1067         destroy_window(window);
1068         destroy_display(display);
1069
1070         return 0;
1071 }