1 /* Copyright © 2014 Manuel Bachmann */
3 #include <linux/input.h>
9 #include "text-client-protocol.h"
10 #include "libwlmessage.h"
14 struct message_window {
15 struct window *window;
16 struct widget *widget;
17 cairo_surface_t *surface;
21 int frame_type; /* for titlebuttons */
23 cairo_surface_t *icon;
24 struct progressbar *progressbar;
27 struct wl_list button_list;
29 struct wlmessage *wlmessage;
33 struct widget *widget;
40 struct message_window *message_window;
44 struct widget *widget;
47 struct wl_text_input *text_input;
53 struct message_window *message_window;
57 struct widget *widget;
62 struct message_window *message_window;
66 struct display *display;
67 struct message_window *message_window;
68 struct wl_text_input_manager *text_input_manager;
69 void (*progress_callback) (struct wlmessage *wlmessage, void *data);
75 /* ---------------------------------------- */
77 /* -- HELPER FUNCTIONS -- */
80 get_number_of_lines (char *text)
84 gchar **lines = g_strsplit (text, "\n", -1);
87 while ((lines[lines_num] != NULL) && (lines_num < MAX_LINES))
96 get_max_length_of_lines (char *text)
101 gchar **lines = g_strsplit (text, "\n", -1);
104 while ((lines[lines_num] != NULL) && (lines_num < MAX_LINES)) {
105 if (strlen (lines[lines_num]) > length)
106 length = strlen (lines[lines_num]);
116 get_lines (char *text)
118 gchar **lines = g_strsplit (text, "\n", -1);
124 update_window (struct window *window)
126 struct rectangle allocation;
128 window_get_allocation (window, &allocation);
129 window_schedule_resize (window, allocation.width, allocation.height);
132 /* ---------------------------------------- */
134 /* -- VIRTUAL KEYBOARD FUNCTIONS -- */
137 text_input_enter(void *data,
138 struct wl_text_input *text_input,
139 struct wl_surface *surface)
144 text_input_leave(void *data,
145 struct wl_text_input *text_input)
150 text_input_modifiers_map(void *data,
151 struct wl_text_input *text_input,
152 struct wl_array *map)
157 text_input_input_panel_state(void *data,
158 struct wl_text_input *text_input,
164 text_input_preedit_string(void *data,
165 struct wl_text_input *text_input,
170 struct entry *entry = data;
173 if (strlen(entry->text) >= 18)
176 /* workaround to prevent using Backspace for now */
177 if (strlen(text) < entry->last_vkb_len) {
178 entry->last_vkb_len = strlen(text);
181 entry->last_vkb_len = strlen(text);
184 new_text = malloc (strlen(entry->text) + 1 + 1);
185 strncpy (new_text, entry->text, entry->cursor_pos);
186 strcpy (new_text+entry->cursor_pos, text+(strlen(text)-1));
187 strcpy (new_text+entry->cursor_pos+1, entry->text+entry->cursor_pos);
189 entry->text = new_text;
192 widget_schedule_redraw (entry->widget);
196 text_input_preedit_styling(void *data,
197 struct wl_text_input *text_input,
205 text_input_preedit_cursor(void *data,
206 struct wl_text_input *text_input,
212 text_input_commit_string(void *data,
213 struct wl_text_input *text_input,
220 text_input_cursor_position(void *data,
221 struct wl_text_input *text_input,
228 text_input_keysym(void *data,
229 struct wl_text_input *text_input,
236 struct entry *entry = data;
239 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
242 /* use Tab as Backspace until I figure this out */
243 if (sym == XKB_KEY_Tab) {
244 if (entry->cursor_pos != 0) {
245 new_text = malloc (strlen(entry->text));
246 strncpy (new_text, entry->text, entry->cursor_pos - 1);
247 strcpy (new_text+entry->cursor_pos-1, entry->text+entry->cursor_pos);
249 entry->text = new_text;
254 if (sym == XKB_KEY_Left) {
255 if (entry->cursor_pos != 0)
259 if (sym == XKB_KEY_Right) {
260 if (entry->cursor_pos != strlen (entry->text))
264 if (sym == XKB_KEY_Return) {
265 display_exit (entry->message_window->wlmessage->display);
268 widget_schedule_redraw (entry->widget);
272 text_input_language(void *data,
273 struct wl_text_input *text_input,
275 const char *language)
280 text_input_text_direction(void *data,
281 struct wl_text_input *text_input,
287 static const struct wl_text_input_listener text_input_listener = {
290 text_input_modifiers_map,
291 text_input_input_panel_state,
292 text_input_preedit_string,
293 text_input_preedit_styling,
294 text_input_preedit_cursor,
295 text_input_commit_string,
296 text_input_cursor_position,
300 text_input_text_direction
303 /* ---------------------------------------- */
309 entry_click_handler(struct widget *widget,
310 struct input *input, uint32_t time,
312 enum wl_pointer_button_state state, void *data)
314 struct entry *entry = data;
316 widget_schedule_redraw (widget);
318 if (state == WL_POINTER_BUTTON_STATE_PRESSED && button == BTN_LEFT) {
319 if (!entry->text_input) {
320 entry->text_input = wl_text_input_manager_create_text_input (entry->message_window->wlmessage->text_input_manager);
321 wl_text_input_add_listener (entry->text_input, &text_input_listener, entry);
324 struct wl_seat *seat = input_get_seat (input);
325 struct wl_surface *surface = window_get_wl_surface (entry->message_window->window);
326 wl_text_input_show_input_panel (entry->text_input);
327 wl_text_input_activate (entry->text_input, seat, surface);
334 entry_touch_handler(struct widget *widget, struct input *input,
335 uint32_t serial, uint32_t time, int32_t id,
336 float tx, float ty, void *data)
338 struct entry *entry = data;
340 widget_schedule_redraw (widget);
342 if (!entry->text_input) {
343 entry->text_input = wl_text_input_manager_create_text_input (entry->message_window->wlmessage->text_input_manager);
344 wl_text_input_add_listener (entry->text_input, &text_input_listener, entry);
347 struct wl_seat *seat = input_get_seat (input);
348 struct wl_surface *surface = window_get_wl_surface (entry->message_window->window);
349 wl_text_input_show_input_panel (entry->text_input);
350 wl_text_input_activate (entry->text_input, seat, surface);
356 entry_motion_handler(struct widget *widget,
357 struct input *input, uint32_t time,
358 float x, float y, void *data)
364 progressbar_redraw_handler (struct widget *widget, void *data)
366 struct progressbar *progressbar = data;
367 struct rectangle allocation;
369 cairo_text_extents_t extents;
371 widget_get_allocation (widget, &allocation);
373 cr = widget_cairo_create (progressbar->message_window->widget);
374 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
380 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
385 allocation.width * progressbar->progress,
387 cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
389 cairo_set_line_width (cr, 1);
395 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
396 cairo_stroke_preserve(cr);
398 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
399 cairo_select_font_face (cr, "sans",
400 CAIRO_FONT_SLANT_ITALIC,
401 CAIRO_FONT_WEIGHT_NORMAL);
402 cairo_set_font_size (cr, 12);
403 cairo_text_extents (cr, progressbar->text, &extents);
404 cairo_move_to (cr, allocation.x + (allocation.width - extents.width)/2,
405 allocation.y + (allocation.height - extents.height)/2 + 8);
406 cairo_show_text (cr, progressbar->text);
412 entry_redraw_handler (struct widget *widget, void *data)
414 struct entry *entry = data;
415 struct rectangle allocation;
417 cairo_text_extents_t extents;
418 cairo_text_extents_t leftp_extents;
422 widget_get_allocation (widget, &allocation);
424 cr = widget_cairo_create (entry->message_window->widget);
425 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
431 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
433 cairo_set_line_width (cr, 1);
440 cairo_set_source_rgb (cr, 0.0, 0.0, 1.0);
442 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
443 cairo_stroke_preserve(cr);
445 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
446 cairo_select_font_face (cr, "sans",
447 CAIRO_FONT_SLANT_NORMAL,
448 CAIRO_FONT_WEIGHT_NORMAL);
449 cairo_set_font_size (cr, 14);
450 cairo_text_extents (cr, entry->text, &extents);
451 char_pos = strlen(entry->text) -1; /* for spaces at the end */
452 while (char_pos >= 0 && entry->text[char_pos] == ' ') {
453 extents.width += 5.0;
456 cairo_move_to (cr, allocation.x + (allocation.width - extents.width)/2,
457 allocation.y + (allocation.height - extents.height)/2 + 10);
458 cairo_show_text (cr, entry->text);
461 leftp_text = malloc (entry->cursor_pos + 1);
462 strncpy (leftp_text, entry->text, entry->cursor_pos);
463 leftp_text[entry->cursor_pos] = '\0';
464 cairo_text_extents (cr, leftp_text, &leftp_extents);
465 char_pos = strlen(leftp_text) -1;
466 while (char_pos >= 0 && leftp_text[char_pos] == ' ') {
467 leftp_extents.width += 5.0;
472 cairo_move_to (cr, allocation.x + (allocation.width - extents.width)/2 + leftp_extents.width,
473 allocation.y + (allocation.height - extents.height)/2 + 15);
474 cairo_line_to(cr, allocation.x + (allocation.width - extents.width)/2 + leftp_extents.width,
475 allocation.y + (allocation.height - extents.height)/2 - 5);
483 button_send_activate (struct button *button)
485 button->message_window->wlmessage->return_value = button->value;
487 display_exit (button->message_window->wlmessage->display);
491 button_click_handler(struct widget *widget,
492 struct input *input, uint32_t time,
494 enum wl_pointer_button_state state, void *data)
496 struct button *button = data;
498 widget_schedule_redraw (widget);
500 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
504 button_send_activate (button);
509 button_touch_down_handler(struct widget *widget, struct input *input,
510 uint32_t serial, uint32_t time, int32_t id,
511 float tx, float ty, void *data)
513 struct button *button = data;
516 widget_schedule_redraw (widget);
520 button_touch_up_handler(struct widget *widget, struct input *input,
521 uint32_t serial, uint32_t time, int32_t id,
524 struct button *button = data;
527 widget_schedule_redraw (widget);
529 button_send_activate (button);
533 button_enter_handler(struct widget *widget, struct input *input,
534 float x, float y, void *data)
536 struct button *button = data;
539 widget_schedule_redraw (widget);
541 return CURSOR_LEFT_PTR;
545 button_leave_handler(struct widget *widget,
546 struct input *input, void *data)
548 struct button *button = data;
551 widget_schedule_redraw (widget);
555 button_redraw_handler (struct widget *widget, void *data)
557 struct button *button = data;
558 struct rectangle allocation;
560 cairo_text_extents_t extents;
562 widget_get_allocation (widget, &allocation);
563 if (button->pressed) {
568 cr = widget_cairo_create (button->message_window->widget);
569 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
576 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
578 cairo_set_source_rgb (cr, 0.9, 0.9, 0.9);
580 cairo_set_line_width (cr, 1);
586 cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
587 cairo_stroke_preserve(cr);
588 cairo_select_font_face (cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
589 cairo_set_font_size (cr, 14);
590 cairo_text_extents (cr, button->caption, &extents);
591 cairo_move_to (cr, allocation.x + (allocation.width - extents.width)/2,
592 allocation.y + (allocation.height - extents.height)/2 + 10);
593 cairo_show_text (cr, button->caption);
598 keyboard_focus_handler(struct window *window, struct input *input, void *data)
600 struct message_window *message_window = data;
602 window_schedule_redraw(message_window->window);
606 key_handler (struct window *window, struct input *input, uint32_t time,
607 uint32_t key, uint32_t sym, enum wl_keyboard_key_state state,
610 struct message_window *message_window = data;
611 struct entry *entry = message_window->entry;
615 if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
618 if (sym == XKB_KEY_Return || sym == XKB_KEY_KP_Enter)
619 display_exit (message_window->wlmessage->display);
621 if (entry && entry->active) {
623 case XKB_KEY_BackSpace:
624 if (entry->cursor_pos == 0)
626 new_text = malloc (strlen(entry->text));
627 strncpy (new_text, entry->text, entry->cursor_pos - 1);
628 strcpy (new_text+entry->cursor_pos-1, entry->text+entry->cursor_pos);
630 entry->text = new_text;
634 if (entry->cursor_pos == strlen (entry->text))
636 new_text = malloc (strlen(entry->text));
637 strncpy (new_text, entry->text, entry->cursor_pos);
638 strcpy (new_text+entry->cursor_pos, entry->text+entry->cursor_pos+1);
640 entry->text = new_text;
643 if (entry->cursor_pos != 0)
647 if (entry->cursor_pos != strlen (entry->text))
653 if (strlen(entry->text) >= 18)
655 if (xkb_keysym_to_utf8 (sym, text, sizeof(text)) <= 0)
657 if (strlen(text) > 1) /* dismiss non-ASCII characters for now */
659 new_text = malloc (strlen(entry->text) + strlen(text) + 1);
660 strncpy (new_text, entry->text, entry->cursor_pos);
661 strcpy (new_text+entry->cursor_pos, text);
662 strcpy (new_text+entry->cursor_pos+strlen(text), entry->text+entry->cursor_pos);
664 entry->text = new_text;
667 widget_schedule_redraw(entry->widget);
672 resize_handler (struct widget *widget, int32_t width, int32_t height, void *data)
674 struct message_window *message_window = data;
675 struct progressbar *progressbar;
677 struct button *button;
678 struct rectangle allocation;
679 int buttons_width, extended_width;
682 widget_get_allocation (widget, &allocation);
684 x = allocation.x + (width - 240)/2;
686 if (message_window->progressbar) {
687 progressbar = message_window->progressbar;
688 widget_set_allocation (progressbar->widget, x - 20, allocation.y + height - 16*2 - 32*2 - 28,
690 /* do not draw the entry and buttons if there is a callback */
691 if (message_window->wlmessage->progress_callback)
695 if (message_window->entry) {
696 entry = message_window->entry;
697 widget_set_allocation (entry->widget, x, allocation.y + height - 16*2 - 32*2,
702 wl_list_for_each (button, &message_window->button_list, link) {
703 extended_width = strlen(button->caption) - 5;
704 if (extended_width < 0) extended_width = 0;
705 buttons_width += 60 + extended_width*10;
708 x = allocation.x + (width - buttons_width)/2
709 - (message_window->buttons_nb-1)*10;
711 wl_list_for_each (button, &message_window->button_list, link) {
712 extended_width = strlen(button->caption) - 5;
713 if (extended_width < 0) extended_width = 0;
714 widget_set_allocation (button->widget, x, allocation.y + height - 16 - 32,
715 60 + extended_width*10, 32);
716 x += 60 + extended_width*10 + 10;
721 redraw_handler (struct widget *widget, void *data)
723 struct message_window *message_window = data;
724 struct wlmessage *wlmessage = message_window->wlmessage;
725 struct rectangle allocation;
726 cairo_surface_t *surface;
728 cairo_text_extents_t extents;
732 /* we launch the callback, and update the window to redraw again */
733 if (wlmessage->progress_callback) {
734 wlmessage->progress_callback (wlmessage,
735 wlmessage->progress_data);
736 update_window (message_window->window);
739 widget_get_allocation (message_window->widget, &allocation);
741 surface = window_get_surface (message_window->window);
742 cr = cairo_create (surface);
743 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
749 cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 1.0);
752 if (message_window->icon) {
753 cairo_set_source_surface (cr, message_window->icon,
754 allocation.x + (allocation.width - 64.0)/2,
756 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
758 cairo_set_source_surface (cr, surface, 0.0, 0.0);
761 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
762 cairo_select_font_face (cr, "sans",
763 CAIRO_FONT_SLANT_NORMAL,
764 CAIRO_FONT_WEIGHT_NORMAL);
765 cairo_set_font_size (cr, 18);
767 lines_nb = get_number_of_lines (message_window->message);
768 lines = get_lines (message_window->message);
771 for (i = 0; i < lines_nb; i++) {
772 cairo_text_extents (cr, lines[i], &extents);
773 cairo_move_to (cr, allocation.x + (allocation.width - extents.width)/2,
774 allocation.y + (allocation.height - lines_nb * extents.height)/2
775 + i*(extents.height+10)
776 + (!message_window->icon ? 0 : 32)
777 - (!message_window->progressbar ? 0 : 24)
778 - (!message_window->entry ? 0 : 32)
779 - (!message_window->buttons_nb ? 0 : 32));
780 cairo_show_text (cr, lines[i]);
789 global_handler(struct display *display, uint32_t name,
790 const char *interface, uint32_t version, void *data)
792 struct wlmessage *wlmessage = data;
794 if (!strcmp(interface, "wl_text_input_manager")) {
795 wlmessage->text_input_manager = display_bind (display, name,
796 &wl_text_input_manager_interface, 1);
800 /* ---------------------------------------- */
803 wlmessage_set_title (struct wlmessage *wlmessage, char *title)
805 if ((!wlmessage) || (!title))
808 struct message_window *message_window = wlmessage->message_window;
810 if (message_window->title)
811 free (message_window->title);
813 message_window->title = strdup (title);
817 wlmessage_get_title (struct wlmessage *wlmessage)
822 struct message_window *message_window = wlmessage->message_window;
824 return message_window->title;
828 wlmessage_set_titlebuttons (struct wlmessage *wlmessage, enum wlmessage_titlebutton titlebuttons)
833 struct message_window *message_window = wlmessage->message_window;
835 message_window->frame_type = FRAME_NONE;
837 if (titlebuttons && WLMESSAGE_TITLEBUTTON_MINIMIZE)
838 message_window->frame_type = message_window->frame_type | FRAME_MINIMIZE;
839 if (titlebuttons && WLMESSAGE_TITLEBUTTON_MAXIMIZE)
840 message_window->frame_type = message_window->frame_type | FRAME_MAXIMIZE;
841 if (titlebuttons && WLMESSAGE_TITLEBUTTON_CLOSE)
842 message_window->frame_type = message_window->frame_type | FRAME_CLOSE;
845 enum wlmessage_titlebutton
846 wlmessage_get_titlebuttons (struct wlmessage *wlmessage)
851 struct message_window *message_window = wlmessage->message_window;
852 enum wlmessage_titlebutton titlebuttons;
854 titlebuttons = WLMESSAGE_TITLEBUTTON_NONE;
856 if (message_window->frame_type && FRAME_MINIMIZE)
857 titlebuttons = titlebuttons | WLMESSAGE_TITLEBUTTON_MINIMIZE;
858 if (message_window->frame_type && FRAME_MAXIMIZE)
859 titlebuttons = titlebuttons | WLMESSAGE_TITLEBUTTON_MAXIMIZE;
860 if (message_window->frame_type && FRAME_CLOSE)
861 titlebuttons = titlebuttons | WLMESSAGE_TITLEBUTTON_CLOSE;
867 wlmessage_set_noresize (struct wlmessage *wlmessage, unsigned int not_resizable)
872 struct message_window *message_window = wlmessage->message_window;
874 message_window->resizable = !not_resizable;
878 wlmessage_get_noresize (struct wlmessage *wlmessage)
883 struct message_window *message_window = wlmessage->message_window;
885 return !message_window->resizable;
889 wlmessage_set_icon (struct wlmessage *wlmessage, char *icon_path)
891 if ((!wlmessage) || (!icon_path))
894 struct message_window *message_window = wlmessage->message_window;
895 cairo_surface_t *icon;
896 cairo_status_t status;
898 icon = cairo_image_surface_create_from_png (icon_path);
899 status = cairo_surface_status (icon);
901 if (status == CAIRO_STATUS_SUCCESS) {
902 message_window->icon = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 64, 64);
903 cairo_t *icon_cr = cairo_create (message_window->icon);
904 /* rescale to 64x64 */
905 int width = cairo_image_surface_get_width (icon);
906 int height = cairo_image_surface_get_height (icon);
907 if ((width != 64) && (height != 64)) {
908 double ratio = ((64.0/width) < (64.0/height) ? (64.0/width) : (64.0/height));
909 cairo_scale (icon_cr, ratio, ratio);
911 cairo_set_source_surface (icon_cr, icon, 0.0, 0.0);
912 cairo_paint (icon_cr);
913 cairo_destroy (icon_cr);
914 cairo_surface_destroy (icon);
920 wlmessage_set_message (struct wlmessage *wlmessage, char *message)
922 if ((!wlmessage) || (!message))
925 struct message_window *message_window = wlmessage->message_window;
927 if (message_window->message)
928 free (message_window->message);
930 message_window->message = strdup (message);
934 wlmessage_get_message (struct wlmessage *wlmessage)
939 struct message_window *message_window = wlmessage->message_window;
941 return message_window->message;
945 wlmessage_set_message_file (struct wlmessage *wlmessage, char *file_path)
947 if ((!wlmessage) || (!file_path))
950 struct message_window *message_window = wlmessage->message_window;
955 file = fopen (file_path, "r");
960 text = malloc (sizeof(char));
964 realloc (text, (i+1)*sizeof(char));
969 realloc (text, (i+1)*sizeof(char));
974 if (message_window->message)
975 free (message_window->message);
977 message_window->message = text;
981 wlmessage_add_button (struct wlmessage *wlmessage, unsigned int index, char *caption)
983 if ((!wlmessage) || (!caption))
986 struct message_window *message_window = wlmessage->message_window;
987 struct button *button;
989 button = xzalloc (sizeof *button);
990 button->caption = strdup (caption);
991 button->value = index;
992 button->message_window = message_window;
994 message_window->buttons_nb++;
995 wl_list_insert (message_window->button_list.prev, &button->link);
999 wlmessage_delete_button (struct wlmessage *wlmessage, unsigned int index)
1004 struct message_window *message_window = wlmessage->message_window;
1006 struct button *button, *tmp;
1007 wl_list_for_each_safe (button, tmp, &message_window->button_list, link) {
1008 if (button->value == index) {
1009 wl_list_remove (&button->link);
1010 widget_destroy (button->widget);
1011 free (button->caption);
1013 message_window->buttons_nb--;
1019 wlmessage_set_default_button (struct wlmessage *wlmessage, unsigned int index)
1024 struct message_window *message_window = wlmessage->message_window;
1025 struct button *button;
1027 wl_list_for_each (button, &message_window->button_list, link) {
1028 if (button->value == index)
1029 wlmessage->return_value = button->value;
1034 wlmessage_set_textfield (struct wlmessage *wlmessage, char *default_text)
1036 if ((!wlmessage) || (!default_text))
1039 struct message_window *message_window = wlmessage->message_window;
1040 struct entry *entry;
1042 entry = xzalloc (sizeof *entry);
1043 entry->text = strdup (default_text);
1044 entry->cursor_pos = strlen (entry->text);
1045 entry->cursor_anchor = entry->cursor_pos;
1046 entry->last_vkb_len = 0;
1048 entry->message_window = message_window;
1050 message_window->entry = entry;
1054 wlmessage_get_textfield (struct wlmessage *wlmessage)
1059 struct message_window *message_window = wlmessage->message_window;
1061 if (!message_window->entry)
1064 return message_window->entry->text;
1068 wlmessage_set_progress_callback (struct wlmessage *wlmessage, void (*callback) (struct wlmessage *wlmessage, void *data), void *data)
1073 wlmessage->progress_callback = callback;
1074 wlmessage->progress_data = data;
1078 wlmessage_set_progress (struct wlmessage *wlmessage, float progress)
1082 if ((progress < 0.0) || (progress > 1.0))
1085 struct message_window *message_window = wlmessage->message_window;
1086 struct progressbar *progressbar;
1088 if (message_window->progressbar) {
1089 progressbar = message_window->progressbar;
1090 free (progressbar->text);
1092 progressbar = xzalloc (sizeof *progressbar);
1093 progressbar->message_window = message_window;
1095 progressbar->text = g_strdup_printf ("%d %%", (int)(progress*100.0));
1096 progressbar->progress = progress;
1098 message_window->progressbar = progressbar;
1102 wlmessage_get_progress (struct wlmessage *wlmessage)
1107 struct message_window *message_window = wlmessage->message_window;
1109 if (!message_window->progressbar)
1112 return message_window->progressbar->progress;
1116 wlmessage_set_timeout (struct wlmessage *wlmessage, unsigned int timeout)
1121 wlmessage->timeout = timeout;
1125 wlmessage_get_timeout (struct wlmessage *wlmessage)
1130 return wlmessage->timeout;
1134 wlmessage_show (struct wlmessage *wlmessage, char **input_text)
1139 struct message_window *message_window = wlmessage->message_window;
1140 struct progressbar *progressbar = NULL;
1141 struct entry *entry = NULL;
1142 struct button *button = NULL;
1143 int extended_width = 0;
1146 wlmessage->display = NULL;
1147 wlmessage->display = display_create (NULL, NULL);
1148 if (!wlmessage->display) {
1149 fprintf (stderr, "Failed to connect to a Wayland compositor !\n");
1153 if (wlmessage->timeout)
1154 display_set_timeout (wlmessage->display, wlmessage->timeout);
1156 message_window->window = window_create (wlmessage->display);
1157 message_window->widget = window_frame_create (message_window->window,
1158 message_window->frame_type,
1159 message_window->resizable, message_window);
1160 window_set_title (message_window->window, message_window->title);
1162 /* add progressbar */
1163 if (message_window->progressbar) {
1164 progressbar = message_window->progressbar;
1165 progressbar->widget = widget_add_widget (message_window->widget, progressbar);
1166 widget_set_redraw_handler (progressbar->widget, progressbar_redraw_handler);
1170 if (message_window->entry) {
1171 entry = message_window->entry;
1172 entry->widget = widget_add_widget (message_window->widget, entry);
1173 widget_set_redraw_handler (entry->widget, entry_redraw_handler);
1174 widget_set_motion_handler (entry->widget, entry_motion_handler);
1175 widget_set_button_handler (entry->widget, entry_click_handler);
1176 widget_set_touch_down_handler (entry->widget, entry_touch_handler);
1180 wl_list_for_each (button, &message_window->button_list, link) {
1181 button->widget = widget_add_widget (message_window->widget, button);
1182 widget_set_redraw_handler (button->widget, button_redraw_handler);
1183 widget_set_enter_handler (button->widget, button_enter_handler);
1184 widget_set_leave_handler (button->widget, button_leave_handler);
1185 widget_set_button_handler (button->widget, button_click_handler);
1186 widget_set_touch_down_handler (button->widget, button_touch_down_handler);
1187 widget_set_touch_up_handler (button->widget, button_touch_up_handler);
1190 /* do not draw the entry and buttons if there is a callback */
1191 if (wlmessage->progress_callback) {
1193 widget_set_redraw_handler (entry->widget, NULL);
1194 wl_list_for_each (button, &message_window->button_list, link)
1195 widget_set_redraw_handler (button->widget, NULL);
1198 extended_width = (get_max_length_of_lines (message_window->message)) - 35;
1199 if (extended_width < 0) extended_width = 0;
1200 lines_nb = get_number_of_lines (message_window->message);
1202 window_set_user_data (message_window->window, message_window);
1203 window_set_keyboard_focus_handler(message_window->window, keyboard_focus_handler);
1204 window_set_key_handler (message_window->window, key_handler);
1205 widget_set_redraw_handler (message_window->widget, redraw_handler);
1206 widget_set_resize_handler (message_window->widget, resize_handler);
1208 window_schedule_resize (message_window->window,
1209 480 + extended_width*10,
1210 280 + lines_nb*24 + (!message_window->progressbar ? 0 : 1)*24
1211 + (!message_window->entry ? 0 : 1)*32
1212 + (!message_window->buttons_nb ? 0 : 1)*32);
1214 display_set_user_data (wlmessage->display, wlmessage);
1215 display_set_global_handler (wlmessage->display, global_handler);
1216 display_run (wlmessage->display);
1218 display_destroy (wlmessage->display);
1220 if (input_text && message_window->entry)
1221 *input_text = strdup (message_window->entry->text);
1222 return wlmessage->return_value;
1228 struct wlmessage *wlmessage;
1230 wlmessage = xzalloc (sizeof *wlmessage);
1231 wlmessage->progress_callback = NULL;
1232 wlmessage->progress_data = NULL;
1233 wlmessage->return_value = 0;
1234 wlmessage->timeout = 0;
1236 wlmessage->message_window = xzalloc (sizeof *wlmessage->message_window);
1237 wlmessage->message_window->title = strdup ("wlmessage");
1238 wlmessage->message_window->frame_type = FRAME_ALL;
1239 wlmessage->message_window->resizable = 1;
1240 wlmessage->message_window->icon = NULL;
1241 wlmessage->message_window->message = NULL;
1242 wlmessage->message_window->progressbar = NULL;
1243 wlmessage->message_window->entry = NULL;
1244 wlmessage->message_window->buttons_nb = 0;
1245 wl_list_init (&wlmessage->message_window->button_list);
1246 wlmessage->message_window->wlmessage = wlmessage;
1252 wlmessage_destroy (struct wlmessage *wlmessage)
1256 if (wlmessage->progress_callback) {
1257 wlmessage->progress_callback = NULL;
1258 display_exit (wlmessage->display);
1262 struct message_window *message_window = wlmessage->message_window;
1264 if (message_window->surface)
1265 cairo_surface_destroy (message_window->surface);
1266 if (message_window->icon)
1267 cairo_surface_destroy (message_window->icon);
1268 if (message_window->widget)
1269 widget_destroy (message_window->widget);
1270 if (message_window->window)
1271 window_destroy (message_window->window);
1272 if (message_window->title)
1273 free (message_window->title);
1274 if (message_window->message)
1275 free (message_window->message);
1276 free (message_window);
1281 /* ---------------------------------------- */