diff options
Diffstat (limited to 'libraries/ecore/src/lib/ecore_wayland')
-rw-r--r-- | libraries/ecore/src/lib/ecore_wayland/ecore_wl_dnd.c | 189 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_wayland/ecore_wl_input.c | 658 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_wayland/ecore_wl_output.c | 79 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore_wayland/ecore_wl_window.c | 440 |
4 files changed, 1366 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_wayland/ecore_wl_dnd.c b/libraries/ecore/src/lib/ecore_wayland/ecore_wl_dnd.c new file mode 100644 index 0000000..5d81225 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_wayland/ecore_wl_dnd.c | |||
@@ -0,0 +1,189 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include "Ecore.h" | ||
6 | #include "ecore_private.h" | ||
7 | #include "ecore_wl_private.h" | ||
8 | #include "Ecore_Wayland.h" | ||
9 | |||
10 | /* local function prototypes */ | ||
11 | static void _ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer __UNUSED__, const char *type); | ||
12 | static void _ecore_wl_dnd_cb_enter_free(void *data __UNUSED__, void *event); | ||
13 | |||
14 | /* wayland listeners */ | ||
15 | static const struct wl_data_offer_listener _ecore_wl_data_offer_listener = | ||
16 | { | ||
17 | _ecore_wl_dnd_offer, | ||
18 | }; | ||
19 | |||
20 | void | ||
21 | _ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device, unsigned int id) | ||
22 | { | ||
23 | Ecore_Wl_Dnd_Source *source; | ||
24 | |||
25 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
26 | |||
27 | if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source)))) return; | ||
28 | wl_array_init(&source->types); | ||
29 | source->refcount = 1; | ||
30 | source->input = input; | ||
31 | /* FIXME: Change this when wayland has typesafe wrapper for it */ | ||
32 | source->offer = (struct wl_data_offer *) | ||
33 | wl_proxy_create_for_id((struct wl_proxy *)data_device, | ||
34 | id, &wl_data_offer_interface); | ||
35 | wl_data_offer_add_listener(source->offer, | ||
36 | &_ecore_wl_data_offer_listener, source); | ||
37 | } | ||
38 | |||
39 | void | ||
40 | _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer) | ||
41 | { | ||
42 | Ecore_Wl_Event_Dnd_Enter *event; | ||
43 | Ecore_Wl_Input *input; | ||
44 | Ecore_Wl_Window *win; | ||
45 | char **p; | ||
46 | |||
47 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
48 | |||
49 | if (!(input = data)) return; | ||
50 | |||
51 | input->drag_source = wl_data_offer_get_user_data(offer); | ||
52 | |||
53 | win = wl_surface_get_user_data(surface); | ||
54 | // input->pointer_focus = win; | ||
55 | |||
56 | p = wl_array_add(&input->drag_source->types, sizeof(*p)); | ||
57 | *p = NULL; | ||
58 | |||
59 | if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return; | ||
60 | |||
61 | event->win = win->id; | ||
62 | event->source = input->drag_source->input->keyboard_focus->id; | ||
63 | event->position.x = x; | ||
64 | event->position.y = y; | ||
65 | event->num_types = input->drag_source->types.size; | ||
66 | event->types = input->drag_source->types.data; | ||
67 | |||
68 | ecore_event_add(ECORE_WL_EVENT_DND_ENTER, event, | ||
69 | _ecore_wl_dnd_cb_enter_free, NULL); | ||
70 | } | ||
71 | |||
72 | void | ||
73 | _ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device __UNUSED__) | ||
74 | { | ||
75 | Ecore_Wl_Input *input; | ||
76 | |||
77 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
78 | |||
79 | if (!(input = data)) return; | ||
80 | _ecore_wl_dnd_del(input->drag_source); | ||
81 | input->drag_source = NULL; | ||
82 | } | ||
83 | |||
84 | void | ||
85 | _ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, int x, int y) | ||
86 | { | ||
87 | Ecore_Wl_Event_Dnd_Position *event; | ||
88 | Ecore_Wl_Input *input; | ||
89 | |||
90 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
91 | |||
92 | if (!(input = data)) return; | ||
93 | |||
94 | input->sx = x; | ||
95 | input->sy = y; | ||
96 | |||
97 | if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return; | ||
98 | |||
99 | event->win = input->drag_source->input->pointer_focus->id; | ||
100 | event->source = input->drag_source->input->keyboard_focus->id; | ||
101 | event->position.x = x; | ||
102 | event->position.y = y; | ||
103 | |||
104 | ecore_event_add(ECORE_WL_EVENT_DND_POSITION, event, NULL, NULL); | ||
105 | } | ||
106 | |||
107 | void | ||
108 | _ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device __UNUSED__) | ||
109 | { | ||
110 | Ecore_Wl_Event_Dnd_Drop *event; | ||
111 | Ecore_Wl_Input *input; | ||
112 | |||
113 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
114 | |||
115 | if (!(input = data)) return; | ||
116 | |||
117 | if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return; | ||
118 | |||
119 | event->win = input->drag_source->input->pointer_focus->id; | ||
120 | event->source = input->drag_source->input->keyboard_focus->id; | ||
121 | event->position.x = input->sx; | ||
122 | event->position.y = input->sy; | ||
123 | |||
124 | ecore_event_add(ECORE_WL_EVENT_DND_DROP, event, NULL, NULL); | ||
125 | } | ||
126 | |||
127 | void | ||
128 | _ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device __UNUSED__, struct wl_data_offer *offer) | ||
129 | { | ||
130 | Ecore_Wl_Input *input; | ||
131 | |||
132 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
133 | |||
134 | if (!(input = data)) return; | ||
135 | if (input->selection_source) _ecore_wl_dnd_del(input->selection_source); | ||
136 | input->selection_source = NULL; | ||
137 | if (offer) | ||
138 | { | ||
139 | char **p; | ||
140 | |||
141 | input->selection_source = wl_data_offer_get_user_data(offer); | ||
142 | p = wl_array_add(&input->selection_source->types, sizeof(*p)); | ||
143 | *p = NULL; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | void | ||
148 | _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source) | ||
149 | { | ||
150 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
151 | |||
152 | if (!source) return; | ||
153 | source->refcount--; | ||
154 | if (source->refcount == 0) | ||
155 | { | ||
156 | char **p; | ||
157 | |||
158 | wl_data_offer_destroy(source->offer); | ||
159 | for (p = source->types.data; *p; p++) | ||
160 | free(*p); | ||
161 | wl_array_release(&source->types); | ||
162 | free(source); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | /* local functions */ | ||
167 | static void | ||
168 | _ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer __UNUSED__, const char *type) | ||
169 | { | ||
170 | Ecore_Wl_Dnd_Source *source; | ||
171 | char **p; | ||
172 | |||
173 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
174 | |||
175 | if (!(source = data)) return; | ||
176 | p = wl_array_add(&source->types, sizeof(*p)); | ||
177 | *p = strdup(type); | ||
178 | } | ||
179 | |||
180 | static void | ||
181 | _ecore_wl_dnd_cb_enter_free(void *data __UNUSED__, void *event) | ||
182 | { | ||
183 | Ecore_Wl_Event_Dnd_Enter *ev; | ||
184 | |||
185 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
186 | |||
187 | if (!(ev = event)) return; | ||
188 | free(ev); | ||
189 | } | ||
diff --git a/libraries/ecore/src/lib/ecore_wayland/ecore_wl_input.c b/libraries/ecore/src/lib/ecore_wayland/ecore_wl_input.c new file mode 100644 index 0000000..d44daa7 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_wayland/ecore_wl_input.c | |||
@@ -0,0 +1,658 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include "Ecore.h" | ||
6 | #include "ecore_private.h" | ||
7 | #include "Ecore_Input.h" | ||
8 | #include "ecore_wl_private.h" | ||
9 | #include "Ecore_Wayland.h" | ||
10 | |||
11 | /* FIXME: This gives BTN_LEFT/RIGHT/MIDDLE for linux systems ... | ||
12 | * What about other OSs ?? */ | ||
13 | #ifdef __linux__ | ||
14 | # include <linux/input.h> | ||
15 | #else | ||
16 | # define BTN_LEFT 0x110 | ||
17 | # define BTN_RIGHT 0x111 | ||
18 | # define BTN_MIDDLE 0x112 | ||
19 | # define BTN_SIDE 0x113 | ||
20 | # define BTN_EXTRA 0x114 | ||
21 | # define BTN_FORWARD 0x115 | ||
22 | # define BTN_BACK 0x116 | ||
23 | #endif | ||
24 | |||
25 | /* local function prototypes */ | ||
26 | static void _ecore_wl_input_cb_motion(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int sx, int sy); | ||
27 | static void _ecore_wl_input_cb_button(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, unsigned int button, unsigned int state); | ||
28 | static void _ecore_wl_input_cb_key(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp __UNUSED__, unsigned int key, unsigned int state); | ||
29 | static void _ecore_wl_input_cb_pointer_enter(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface, int sx, int sy); | ||
30 | static void _ecore_wl_input_cb_pointer_leave(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface __UNUSED__); | ||
31 | static void _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface, struct wl_array *keys); | ||
32 | static void _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface __UNUSED__); | ||
33 | static void _ecore_wl_input_cb_touch_down(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface __UNUSED__, int id __UNUSED__, int x, int y); | ||
34 | static void _ecore_wl_input_cb_touch_up(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int id __UNUSED__); | ||
35 | static void _ecore_wl_input_cb_touch_motion(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int id __UNUSED__, int x, int y); | ||
36 | static void _ecore_wl_input_cb_touch_frame(void *data __UNUSED__, struct wl_input_device *input_device __UNUSED__); | ||
37 | static void _ecore_wl_input_cb_touch_cancel(void *data __UNUSED__, struct wl_input_device *input_device __UNUSED__); | ||
38 | static void _ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, unsigned int id); | ||
39 | static void _ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer); | ||
40 | static void _ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device); | ||
41 | static void _ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, int x, int y); | ||
42 | static void _ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device); | ||
43 | static void _ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer); | ||
44 | |||
45 | static void _ecore_wl_input_keyboard_focus_remove(Ecore_Wl_Input *input, unsigned int timestamp); | ||
46 | static void _ecore_wl_input_pointer_focus_remove(Ecore_Wl_Input *input, unsigned int timestamp); | ||
47 | static void _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, unsigned int timestamp); | ||
48 | static void _ecore_wl_input_cb_mouse_move_free(void *data __UNUSED__, void *event); | ||
49 | static void _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, unsigned int timestamp); | ||
50 | static void _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, unsigned int timestamp); | ||
51 | static void _ecore_wl_input_focus_in_send(Ecore_Wl_Input *input, unsigned int timestamp); | ||
52 | static void _ecore_wl_input_focus_out_send(Ecore_Wl_Input *input, unsigned int timestamp); | ||
53 | static void _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, unsigned int timestamp); | ||
54 | static void _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, unsigned int timestamp); | ||
55 | |||
56 | /* wayland interfaces */ | ||
57 | static const struct wl_input_device_listener _ecore_wl_input_listener = | ||
58 | { | ||
59 | _ecore_wl_input_cb_motion, | ||
60 | _ecore_wl_input_cb_button, | ||
61 | _ecore_wl_input_cb_key, | ||
62 | _ecore_wl_input_cb_pointer_enter, | ||
63 | _ecore_wl_input_cb_pointer_leave, | ||
64 | _ecore_wl_input_cb_keyboard_enter, | ||
65 | _ecore_wl_input_cb_keyboard_leave, | ||
66 | _ecore_wl_input_cb_touch_down, | ||
67 | _ecore_wl_input_cb_touch_up, | ||
68 | _ecore_wl_input_cb_touch_motion, | ||
69 | _ecore_wl_input_cb_touch_frame, | ||
70 | _ecore_wl_input_cb_touch_cancel | ||
71 | }; | ||
72 | |||
73 | static const struct wl_data_device_listener _ecore_wl_data_listener = | ||
74 | { | ||
75 | _ecore_wl_input_cb_data_offer, | ||
76 | _ecore_wl_input_cb_data_enter, | ||
77 | _ecore_wl_input_cb_data_leave, | ||
78 | _ecore_wl_input_cb_data_motion, | ||
79 | _ecore_wl_input_cb_data_drop, | ||
80 | _ecore_wl_input_cb_data_selection | ||
81 | }; | ||
82 | |||
83 | /* local variables */ | ||
84 | static int _pointer_x, _pointer_y; | ||
85 | |||
86 | void | ||
87 | _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id) | ||
88 | { | ||
89 | Ecore_Wl_Input *input; | ||
90 | |||
91 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
92 | |||
93 | if (!(input = malloc(sizeof(Ecore_Wl_Input)))) return; | ||
94 | |||
95 | memset(input, 0, sizeof(Ecore_Wl_Input)); | ||
96 | |||
97 | input->display = ewd; | ||
98 | input->pointer_focus = NULL; | ||
99 | input->keyboard_focus = NULL; | ||
100 | |||
101 | input->input_device = | ||
102 | wl_display_bind(ewd->wl.display, id, &wl_input_device_interface); | ||
103 | wl_list_insert(ewd->inputs.prev, &input->link); | ||
104 | wl_input_device_add_listener(input->input_device, | ||
105 | &_ecore_wl_input_listener, input); | ||
106 | wl_input_device_set_user_data(input->input_device, input); | ||
107 | |||
108 | input->data_device = | ||
109 | wl_data_device_manager_get_data_device(ewd->wl.data_device_manager, | ||
110 | input->input_device); | ||
111 | wl_data_device_add_listener(input->data_device, | ||
112 | &_ecore_wl_data_listener, input); | ||
113 | } | ||
114 | |||
115 | void | ||
116 | _ecore_wl_input_del(Ecore_Wl_Input *input) | ||
117 | { | ||
118 | if (!input) return; | ||
119 | |||
120 | _ecore_wl_input_keyboard_focus_remove(input, 0); | ||
121 | _ecore_wl_input_pointer_focus_remove(input, 0); | ||
122 | |||
123 | if (input->drag_source) _ecore_wl_dnd_del(input->drag_source); | ||
124 | input->drag_source = NULL; | ||
125 | |||
126 | if (input->selection_source) _ecore_wl_dnd_del(input->selection_source); | ||
127 | input->selection_source = NULL; | ||
128 | |||
129 | if (input->data_device) wl_data_device_destroy(input->data_device); | ||
130 | if (input->input_device) wl_input_device_destroy(input->input_device); | ||
131 | wl_list_remove(&input->link); | ||
132 | free(input); | ||
133 | } | ||
134 | |||
135 | void | ||
136 | _ecore_wl_input_pointer_xy_get(int *x, int *y) | ||
137 | { | ||
138 | if (x) *x = _pointer_x; | ||
139 | if (y) *y = _pointer_y; | ||
140 | } | ||
141 | |||
142 | /* local functions */ | ||
143 | static void | ||
144 | _ecore_wl_input_cb_motion(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int sx, int sy) | ||
145 | { | ||
146 | Ecore_Wl_Input *input; | ||
147 | |||
148 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
149 | |||
150 | if (!(input = data)) return; | ||
151 | |||
152 | _pointer_x = sx; | ||
153 | _pointer_y = sy; | ||
154 | |||
155 | input->sx = sx; | ||
156 | input->sy = sy; | ||
157 | |||
158 | /* TODO: FIXME: NB: Weston window code has set pointer image here also */ | ||
159 | _ecore_wl_input_mouse_move_send(input, timestamp); | ||
160 | } | ||
161 | |||
162 | static void | ||
163 | _ecore_wl_input_cb_button(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, unsigned int button, unsigned int state) | ||
164 | { | ||
165 | Ecore_Wl_Input *input; | ||
166 | |||
167 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
168 | |||
169 | if (!(input = data)) return; | ||
170 | |||
171 | input->timestamp = timestamp; | ||
172 | |||
173 | _ecore_wl_input_mouse_move_send(input, timestamp); | ||
174 | |||
175 | if ((button >= BTN_SIDE) && (button <= BTN_BACK)) | ||
176 | { | ||
177 | /* TODO: raise mouse wheel */ | ||
178 | printf("Raise Mouse Wheel Event\n"); | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | if (state) | ||
183 | { | ||
184 | input->button = button; | ||
185 | _ecore_wl_input_mouse_down_send(input, timestamp); | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | _ecore_wl_input_mouse_up_send(input, timestamp); | ||
190 | input->button = 0; | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static void | ||
196 | _ecore_wl_input_cb_key(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp __UNUSED__, unsigned int key, unsigned int state) | ||
197 | { | ||
198 | Ecore_Wl_Input *input; | ||
199 | Ecore_Wl_Window *win; | ||
200 | unsigned int keycode = 0; | ||
201 | |||
202 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
203 | |||
204 | if (!(input = data)) return; | ||
205 | |||
206 | win = input->keyboard_focus; | ||
207 | if ((!win) || (win->keyboard_device != input)) return; | ||
208 | |||
209 | /* FIXME: NB: I believe this should be min_key_code rather than 8, | ||
210 | * but weston code has it like this */ | ||
211 | keycode = key + 8; | ||
212 | |||
213 | /* if ((input->modifiers & XKB_COMMON_SHIFT_MASK) && */ | ||
214 | /* (XkbKeyGroupWidth(_ecore_wl_disp->xkb, keycode, 0) > 1)) */ | ||
215 | /* level = 1; */ | ||
216 | /* keysym = XkbKeySymEntry(_ecore_wl_disp->xkb, keycode, level, 0); */ | ||
217 | |||
218 | if (state) | ||
219 | input->modifiers |= _ecore_wl_disp->xkb->map->modmap[keycode]; | ||
220 | else | ||
221 | input->modifiers &= ~_ecore_wl_disp->xkb->map->modmap[keycode]; | ||
222 | } | ||
223 | |||
224 | static void | ||
225 | _ecore_wl_input_cb_pointer_enter(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface, int sx, int sy) | ||
226 | { | ||
227 | Ecore_Wl_Input *input; | ||
228 | Ecore_Wl_Window *win = NULL; | ||
229 | |||
230 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
231 | |||
232 | if (!(input = data)) return; | ||
233 | |||
234 | input->sx = sx; | ||
235 | input->sy = sy; | ||
236 | |||
237 | _ecore_wl_input_mouse_move_send(input, timestamp); | ||
238 | |||
239 | win = input->pointer_focus; | ||
240 | if ((win) && (win->surface != surface)) | ||
241 | { | ||
242 | if (!input->button) | ||
243 | _ecore_wl_input_pointer_focus_remove(input, timestamp); | ||
244 | } | ||
245 | |||
246 | if (surface) | ||
247 | { | ||
248 | if ((win = wl_surface_get_user_data(surface))) | ||
249 | { | ||
250 | input->pointer_focus = win; | ||
251 | win->pointer_device = input; | ||
252 | } | ||
253 | if (input->button) | ||
254 | { | ||
255 | _ecore_wl_input_mouse_up_send(input, timestamp); | ||
256 | input->button = 0; | ||
257 | } | ||
258 | else | ||
259 | _ecore_wl_input_mouse_in_send(input, timestamp); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | static void | ||
264 | _ecore_wl_input_cb_pointer_leave(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface __UNUSED__) | ||
265 | { | ||
266 | Ecore_Wl_Input *input; | ||
267 | |||
268 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
269 | |||
270 | if (!(input = data)) return; | ||
271 | _ecore_wl_input_pointer_focus_remove(input, timestamp); | ||
272 | } | ||
273 | |||
274 | static void | ||
275 | _ecore_wl_input_cb_keyboard_enter(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface, struct wl_array *keys) | ||
276 | { | ||
277 | Ecore_Wl_Input *input; | ||
278 | Ecore_Wl_Window *win = NULL; | ||
279 | unsigned int *k, *end; | ||
280 | |||
281 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
282 | |||
283 | if (!(input = data)) return; | ||
284 | |||
285 | end = keys->data + keys->size; | ||
286 | input->modifiers = 0; | ||
287 | for (k = keys->data; k < end; k++) | ||
288 | input->modifiers |= _ecore_wl_disp->xkb->map->modmap[*k]; | ||
289 | |||
290 | if (surface) | ||
291 | { | ||
292 | if ((win = wl_surface_get_user_data(surface))) | ||
293 | { | ||
294 | input->keyboard_focus = win; | ||
295 | win->keyboard_device = input; | ||
296 | } | ||
297 | else | ||
298 | input->keyboard_focus = NULL; | ||
299 | _ecore_wl_input_focus_in_send(input, timestamp); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | static void | ||
304 | _ecore_wl_input_cb_keyboard_leave(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface __UNUSED__) | ||
305 | { | ||
306 | Ecore_Wl_Input *input; | ||
307 | |||
308 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
309 | |||
310 | if (!(input = data)) return; | ||
311 | _ecore_wl_input_keyboard_focus_remove(input, timestamp); | ||
312 | } | ||
313 | |||
314 | static void | ||
315 | _ecore_wl_input_cb_touch_down(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, struct wl_surface *surface __UNUSED__, int id __UNUSED__, int x, int y) | ||
316 | { | ||
317 | Ecore_Wl_Input *input; | ||
318 | |||
319 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
320 | |||
321 | if (!(input = data)) return; | ||
322 | |||
323 | /* FIXME: NB: Not sure yet if input->timestamp should be set here. | ||
324 | * This needs to be tested with an actual touch device */ | ||
325 | /* input->timestamp = timestamp; */ | ||
326 | input->button = 0; | ||
327 | input->sx = x; | ||
328 | input->sy = y; | ||
329 | _ecore_wl_input_mouse_down_send(input, timestamp); | ||
330 | } | ||
331 | |||
332 | static void | ||
333 | _ecore_wl_input_cb_touch_up(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int id __UNUSED__) | ||
334 | { | ||
335 | Ecore_Wl_Input *input; | ||
336 | |||
337 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
338 | |||
339 | if (!(input = data)) return; | ||
340 | |||
341 | /* FIXME: NB: Not sure yet if input->timestamp should be set here. | ||
342 | * This needs to be tested with an actual touch device */ | ||
343 | /* input->timestamp = timestamp; */ | ||
344 | input->button = 0; | ||
345 | _ecore_wl_input_mouse_up_send(input, timestamp); | ||
346 | } | ||
347 | |||
348 | static void | ||
349 | _ecore_wl_input_cb_touch_motion(void *data, struct wl_input_device *input_device __UNUSED__, unsigned int timestamp, int id __UNUSED__, int x, int y) | ||
350 | { | ||
351 | Ecore_Wl_Input *input; | ||
352 | |||
353 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
354 | |||
355 | if (!(input = data)) return; | ||
356 | |||
357 | /* FIXME: NB: Not sure yet if input->timestamp should be set here. | ||
358 | * This needs to be tested with an actual touch device */ | ||
359 | /* input->timestamp = timestamp; */ | ||
360 | input->sx = x; | ||
361 | input->sy = y; | ||
362 | |||
363 | _ecore_wl_input_mouse_move_send(input, timestamp); | ||
364 | } | ||
365 | |||
366 | static void | ||
367 | _ecore_wl_input_cb_touch_frame(void *data __UNUSED__, struct wl_input_device *input_device __UNUSED__) | ||
368 | { | ||
369 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
370 | } | ||
371 | |||
372 | static void | ||
373 | _ecore_wl_input_cb_touch_cancel(void *data __UNUSED__, struct wl_input_device *input_device __UNUSED__) | ||
374 | { | ||
375 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
376 | } | ||
377 | |||
378 | static void | ||
379 | _ecore_wl_input_cb_data_offer(void *data, struct wl_data_device *data_device, unsigned int id) | ||
380 | { | ||
381 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
382 | |||
383 | _ecore_wl_dnd_add(data, data_device, id); | ||
384 | } | ||
385 | |||
386 | static void | ||
387 | _ecore_wl_input_cb_data_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer) | ||
388 | { | ||
389 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
390 | |||
391 | _ecore_wl_dnd_enter(data, data_device, timestamp, surface, x, y, offer); | ||
392 | } | ||
393 | |||
394 | static void | ||
395 | _ecore_wl_input_cb_data_leave(void *data, struct wl_data_device *data_device) | ||
396 | { | ||
397 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
398 | |||
399 | _ecore_wl_dnd_leave(data, data_device); | ||
400 | } | ||
401 | |||
402 | static void | ||
403 | _ecore_wl_input_cb_data_motion(void *data, struct wl_data_device *data_device, unsigned int timestamp, int x, int y) | ||
404 | { | ||
405 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
406 | |||
407 | _ecore_wl_dnd_motion(data, data_device, timestamp, x, y); | ||
408 | } | ||
409 | |||
410 | static void | ||
411 | _ecore_wl_input_cb_data_drop(void *data, struct wl_data_device *data_device) | ||
412 | { | ||
413 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
414 | |||
415 | _ecore_wl_dnd_drop(data, data_device); | ||
416 | } | ||
417 | |||
418 | static void | ||
419 | _ecore_wl_input_cb_data_selection(void *data, struct wl_data_device *data_device, struct wl_data_offer *offer) | ||
420 | { | ||
421 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
422 | |||
423 | _ecore_wl_dnd_selection(data, data_device, offer); | ||
424 | } | ||
425 | |||
426 | static void | ||
427 | _ecore_wl_input_keyboard_focus_remove(Ecore_Wl_Input *input, unsigned int timestamp) | ||
428 | { | ||
429 | Ecore_Wl_Window *win; | ||
430 | |||
431 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
432 | |||
433 | _ecore_wl_input_focus_out_send(input, timestamp); | ||
434 | if ((win = input->keyboard_focus)) | ||
435 | win->keyboard_device = NULL; | ||
436 | input->keyboard_focus = NULL; | ||
437 | } | ||
438 | |||
439 | static void | ||
440 | _ecore_wl_input_pointer_focus_remove(Ecore_Wl_Input *input, unsigned int timestamp) | ||
441 | { | ||
442 | Ecore_Wl_Window *win; | ||
443 | |||
444 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
445 | |||
446 | if (!input->button) | ||
447 | _ecore_wl_input_mouse_out_send(input, timestamp); | ||
448 | |||
449 | if ((win = input->pointer_focus)) | ||
450 | win->pointer_device = NULL; | ||
451 | input->pointer_focus = NULL; | ||
452 | } | ||
453 | |||
454 | static void | ||
455 | _ecore_wl_input_mouse_move_send(Ecore_Wl_Input *input, unsigned int timestamp) | ||
456 | { | ||
457 | Ecore_Event_Mouse_Move *ev; | ||
458 | Ecore_Event *event; | ||
459 | |||
460 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
461 | |||
462 | if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Move)))) return; | ||
463 | |||
464 | ev->timestamp = timestamp; | ||
465 | ev->x = input->sx; | ||
466 | ev->y = input->sy; | ||
467 | ev->modifiers = input->modifiers; | ||
468 | ev->multi.device = 0; | ||
469 | ev->multi.radius = 1; | ||
470 | ev->multi.radius_x = 1; | ||
471 | ev->multi.radius_y = 1; | ||
472 | ev->multi.pressure = 1.0; | ||
473 | ev->multi.angle = 0.0; | ||
474 | ev->multi.x = input->sx; | ||
475 | ev->multi.y = input->sy; | ||
476 | |||
477 | if (input->pointer_focus) | ||
478 | { | ||
479 | ev->window = input->pointer_focus->id; | ||
480 | ev->event_window = input->pointer_focus->id; | ||
481 | } | ||
482 | |||
483 | event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, ev, | ||
484 | _ecore_wl_input_cb_mouse_move_free, NULL); | ||
485 | } | ||
486 | |||
487 | static void | ||
488 | _ecore_wl_input_cb_mouse_move_free(void *data __UNUSED__, void *event) | ||
489 | { | ||
490 | Ecore_Event_Mouse_Move *ev; | ||
491 | |||
492 | if ((ev = event)) free(ev); | ||
493 | } | ||
494 | |||
495 | static void | ||
496 | _ecore_wl_input_mouse_in_send(Ecore_Wl_Input *input, unsigned int timestamp) | ||
497 | { | ||
498 | Ecore_Wl_Event_Mouse_In *ev; | ||
499 | Ecore_Event *event; | ||
500 | |||
501 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
502 | |||
503 | if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_In)))) return; | ||
504 | |||
505 | ev->x = input->sx; | ||
506 | ev->y = input->sy; | ||
507 | ev->modifiers = input->modifiers; | ||
508 | ev->timestamp = timestamp; | ||
509 | |||
510 | if (input->pointer_focus) | ||
511 | { | ||
512 | ev->win = input->pointer_focus->id; | ||
513 | ev->event_win = input->pointer_focus->id; | ||
514 | } | ||
515 | |||
516 | event = ecore_event_add(ECORE_WL_EVENT_MOUSE_IN, ev, NULL, NULL); | ||
517 | } | ||
518 | |||
519 | static void | ||
520 | _ecore_wl_input_mouse_out_send(Ecore_Wl_Input *input, unsigned int timestamp) | ||
521 | { | ||
522 | Ecore_Wl_Event_Mouse_Out *ev; | ||
523 | |||
524 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
525 | |||
526 | if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Mouse_Out)))) return; | ||
527 | |||
528 | ev->x = input->sx; | ||
529 | ev->y = input->sy; | ||
530 | ev->modifiers = input->modifiers; | ||
531 | ev->timestamp = timestamp; | ||
532 | |||
533 | if (input->pointer_focus) | ||
534 | { | ||
535 | ev->win = input->pointer_focus->id; | ||
536 | ev->event_win = input->pointer_focus->id; | ||
537 | } | ||
538 | |||
539 | ecore_event_add(ECORE_WL_EVENT_MOUSE_OUT, ev, NULL, NULL); | ||
540 | } | ||
541 | |||
542 | static void | ||
543 | _ecore_wl_input_focus_in_send(Ecore_Wl_Input *input, unsigned int timestamp) | ||
544 | { | ||
545 | Ecore_Wl_Event_Focus_In *ev; | ||
546 | |||
547 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
548 | |||
549 | if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_In)))) return; | ||
550 | ev->timestamp = timestamp; | ||
551 | if (input->keyboard_focus) | ||
552 | ev->win = input->keyboard_focus->id; | ||
553 | ecore_event_add(ECORE_WL_EVENT_FOCUS_IN, ev, NULL, NULL); | ||
554 | } | ||
555 | |||
556 | static void | ||
557 | _ecore_wl_input_focus_out_send(Ecore_Wl_Input *input, unsigned int timestamp) | ||
558 | { | ||
559 | Ecore_Wl_Event_Focus_Out *ev; | ||
560 | |||
561 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
562 | |||
563 | if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Focus_Out)))) return; | ||
564 | ev->timestamp = timestamp; | ||
565 | if (input->keyboard_focus) | ||
566 | ev->win = input->keyboard_focus->id; | ||
567 | ecore_event_add(ECORE_WL_EVENT_FOCUS_OUT, ev, NULL, NULL); | ||
568 | } | ||
569 | |||
570 | static void | ||
571 | _ecore_wl_input_mouse_down_send(Ecore_Wl_Input *input, unsigned int timestamp) | ||
572 | { | ||
573 | Ecore_Event_Mouse_Button *ev; | ||
574 | |||
575 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
576 | |||
577 | if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return; | ||
578 | |||
579 | if (input->button == BTN_LEFT) | ||
580 | ev->buttons = 1; | ||
581 | else if (input->button == BTN_MIDDLE) | ||
582 | ev->buttons = 2; | ||
583 | else if (input->button == BTN_RIGHT) | ||
584 | ev->buttons = 3; | ||
585 | else | ||
586 | ev->buttons = input->button; | ||
587 | |||
588 | ev->timestamp = timestamp; | ||
589 | ev->x = input->sx; | ||
590 | ev->y = input->sy; | ||
591 | ev->modifiers = input->modifiers; | ||
592 | |||
593 | /* FIXME: Need to get these from wayland somehow */ | ||
594 | ev->double_click = 0; | ||
595 | ev->triple_click = 0; | ||
596 | |||
597 | ev->multi.device = 0; | ||
598 | ev->multi.radius = 1; | ||
599 | ev->multi.radius_x = 1; | ||
600 | ev->multi.radius_y = 1; | ||
601 | ev->multi.pressure = 1.0; | ||
602 | ev->multi.angle = 0.0; | ||
603 | ev->multi.x = input->sx; | ||
604 | ev->multi.y = input->sy; | ||
605 | |||
606 | if (input->pointer_focus) | ||
607 | { | ||
608 | ev->window = input->pointer_focus->id; | ||
609 | ev->event_window = input->pointer_focus->id; | ||
610 | } | ||
611 | |||
612 | ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL); | ||
613 | } | ||
614 | |||
615 | static void | ||
616 | _ecore_wl_input_mouse_up_send(Ecore_Wl_Input *input, unsigned int timestamp) | ||
617 | { | ||
618 | Ecore_Event_Mouse_Button *ev; | ||
619 | |||
620 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
621 | |||
622 | if (!(ev = malloc(sizeof(Ecore_Event_Mouse_Button)))) return; | ||
623 | |||
624 | if (input->button == BTN_LEFT) | ||
625 | ev->buttons = 1; | ||
626 | else if (input->button == BTN_MIDDLE) | ||
627 | ev->buttons = 2; | ||
628 | else if (input->button == BTN_RIGHT) | ||
629 | ev->buttons = 3; | ||
630 | else | ||
631 | ev->buttons = input->button; | ||
632 | |||
633 | ev->timestamp = timestamp; | ||
634 | ev->x = input->sx; | ||
635 | ev->y = input->sy; | ||
636 | ev->modifiers = input->modifiers; | ||
637 | |||
638 | /* FIXME: Need to get these from wayland somehow */ | ||
639 | ev->double_click = 0; | ||
640 | ev->triple_click = 0; | ||
641 | |||
642 | ev->multi.device = 0; | ||
643 | ev->multi.radius = 1; | ||
644 | ev->multi.radius_x = 1; | ||
645 | ev->multi.radius_y = 1; | ||
646 | ev->multi.pressure = 1.0; | ||
647 | ev->multi.angle = 0.0; | ||
648 | ev->multi.x = input->sx; | ||
649 | ev->multi.y = input->sy; | ||
650 | |||
651 | if (input->pointer_focus) | ||
652 | { | ||
653 | ev->window = input->pointer_focus->id; | ||
654 | ev->event_window = input->pointer_focus->id; | ||
655 | } | ||
656 | |||
657 | ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL); | ||
658 | } | ||
diff --git a/libraries/ecore/src/lib/ecore_wayland/ecore_wl_output.c b/libraries/ecore/src/lib/ecore_wayland/ecore_wl_output.c new file mode 100644 index 0000000..9f540d4 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_wayland/ecore_wl_output.c | |||
@@ -0,0 +1,79 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include "Ecore.h" | ||
6 | #include "ecore_private.h" | ||
7 | #include "ecore_wl_private.h" | ||
8 | #include "Ecore_Wayland.h" | ||
9 | |||
10 | /* local function prototypes */ | ||
11 | static void _ecore_wl_output_cb_geometry(void *data, struct wl_output *wl_output __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__); | ||
12 | static void _ecore_wl_output_cb_mode(void *data, struct wl_output *wl_output __UNUSED__, unsigned int flags, int w, int h, int refresh __UNUSED__); | ||
13 | |||
14 | /* wayland listeners */ | ||
15 | static const struct wl_output_listener _ecore_wl_output_listener = | ||
16 | { | ||
17 | _ecore_wl_output_cb_geometry, | ||
18 | _ecore_wl_output_cb_mode | ||
19 | }; | ||
20 | |||
21 | void | ||
22 | _ecore_wl_output_add(Ecore_Wl_Display *ewd, unsigned int id) | ||
23 | { | ||
24 | Ecore_Wl_Output *output; | ||
25 | |||
26 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
27 | |||
28 | if (!(output = malloc(sizeof(Ecore_Wl_Output)))) return; | ||
29 | |||
30 | memset(output, 0, sizeof(Ecore_Wl_Output)); | ||
31 | |||
32 | output->display = ewd; | ||
33 | |||
34 | output->output = wl_display_bind(ewd->wl.display, id, &wl_output_interface); | ||
35 | wl_list_insert(ewd->outputs.prev, &output->link); | ||
36 | wl_output_add_listener(output->output, &_ecore_wl_output_listener, output); | ||
37 | } | ||
38 | |||
39 | void | ||
40 | _ecore_wl_output_del(Ecore_Wl_Output *output) | ||
41 | { | ||
42 | if (!output) return; | ||
43 | if (output->destroy) (*output->destroy)(output, output->data); | ||
44 | if (output->output) wl_output_destroy(output->output); | ||
45 | wl_list_remove(&output->link); | ||
46 | free(output); | ||
47 | } | ||
48 | |||
49 | /* local functions */ | ||
50 | static void | ||
51 | _ecore_wl_output_cb_geometry(void *data, struct wl_output *wl_output __UNUSED__, int x, int y, int w __UNUSED__, int h __UNUSED__, int subpixel __UNUSED__, const char *make __UNUSED__, const char *model __UNUSED__) | ||
52 | { | ||
53 | Ecore_Wl_Output *output; | ||
54 | |||
55 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
56 | |||
57 | output = data; | ||
58 | output->allocation.x = x; | ||
59 | output->allocation.y = y; | ||
60 | } | ||
61 | |||
62 | static void | ||
63 | _ecore_wl_output_cb_mode(void *data, struct wl_output *wl_output __UNUSED__, unsigned int flags, int w, int h, int refresh __UNUSED__) | ||
64 | { | ||
65 | Ecore_Wl_Output *output; | ||
66 | Ecore_Wl_Display *ewd; | ||
67 | |||
68 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
69 | |||
70 | output = data; | ||
71 | ewd = output->display; | ||
72 | if (flags & WL_OUTPUT_MODE_CURRENT) | ||
73 | { | ||
74 | output->allocation.w = w; | ||
75 | output->allocation.h = h; | ||
76 | _ecore_wl_disp->output = output; | ||
77 | if (ewd->output_configure) (*ewd->output_configure)(output, ewd->data); | ||
78 | } | ||
79 | } | ||
diff --git a/libraries/ecore/src/lib/ecore_wayland/ecore_wl_window.c b/libraries/ecore/src/lib/ecore_wayland/ecore_wl_window.c new file mode 100644 index 0000000..e8a8bfb --- /dev/null +++ b/libraries/ecore/src/lib/ecore_wayland/ecore_wl_window.c | |||
@@ -0,0 +1,440 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include "Ecore.h" | ||
6 | #include "ecore_private.h" | ||
7 | #include "ecore_wl_private.h" | ||
8 | #include "Ecore_Wayland.h" | ||
9 | |||
10 | /* local function prototypes */ | ||
11 | static void _ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface __UNUSED__, unsigned int timestamp, unsigned int edges, int w, int h); | ||
12 | static void _ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface __UNUSED__); | ||
13 | static void _ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h, unsigned int timestamp); | ||
14 | |||
15 | /* local variables */ | ||
16 | static Eina_Hash *_windows = NULL; | ||
17 | |||
18 | /* wayland listeners */ | ||
19 | static const struct wl_shell_surface_listener _ecore_wl_shell_surface_listener = | ||
20 | { | ||
21 | _ecore_wl_window_cb_configure, | ||
22 | _ecore_wl_window_cb_popup_done | ||
23 | }; | ||
24 | |||
25 | /* internal functions */ | ||
26 | void | ||
27 | _ecore_wl_window_init(void) | ||
28 | { | ||
29 | if (!_windows) _windows = eina_hash_pointer_new(free); | ||
30 | } | ||
31 | |||
32 | void | ||
33 | _ecore_wl_window_shutdown(void) | ||
34 | { | ||
35 | eina_hash_free(_windows); | ||
36 | _windows = NULL; | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * @defgroup Ecore_Wl_Window_Group Wayland Library Init and Shutdown Functions | ||
41 | * | ||
42 | * Functions that can be used to create a Wayland window. | ||
43 | */ | ||
44 | |||
45 | /** | ||
46 | * Creates a new window | ||
47 | * | ||
48 | * @param parent The parent window to use. If @p parent is @c 0, the root window | ||
49 | * of the default display is used. | ||
50 | * @param x X Position | ||
51 | * @param y Y position | ||
52 | * @param w Width | ||
53 | * @param h Height | ||
54 | * | ||
55 | * @return The new window | ||
56 | * | ||
57 | * @ingroup Ecore_Wl_Window_Group | ||
58 | * @since 1.2 | ||
59 | */ | ||
60 | EAPI Ecore_Wl_Window * | ||
61 | ecore_wl_window_new(Ecore_Wl_Window *parent, int x, int y, int w, int h, int buffer_type) | ||
62 | { | ||
63 | Ecore_Wl_Window *win; | ||
64 | static int _win_id = 1; | ||
65 | |||
66 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
67 | |||
68 | if (!(win = malloc(sizeof(Ecore_Wl_Window)))) | ||
69 | { | ||
70 | ERR("Failed to allocate an Ecore Wayland Window"); | ||
71 | return NULL; | ||
72 | } | ||
73 | |||
74 | memset(win, 0, sizeof(Ecore_Wl_Window)); | ||
75 | |||
76 | win->display = _ecore_wl_disp; | ||
77 | win->parent = parent; | ||
78 | win->allocation.x = x; | ||
79 | win->allocation.y = y; | ||
80 | win->allocation.w = w; | ||
81 | win->allocation.h = h; | ||
82 | win->saved_allocation = win->allocation; | ||
83 | win->transparent = EINA_TRUE; | ||
84 | win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; | ||
85 | win->buffer_type = buffer_type; | ||
86 | win->id = _win_id++; | ||
87 | |||
88 | eina_hash_add(_windows, &win->id, win); | ||
89 | return win; | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * Deletes the given window | ||
94 | * | ||
95 | * @param win The given window | ||
96 | * | ||
97 | * @ingroup Ecore_Wl_Window_Group | ||
98 | * @since 1.2 | ||
99 | */ | ||
100 | EAPI void | ||
101 | ecore_wl_window_free(Ecore_Wl_Window *win) | ||
102 | { | ||
103 | Ecore_Wl_Input *input; | ||
104 | |||
105 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
106 | |||
107 | if (!win) return; | ||
108 | |||
109 | eina_hash_del(_windows, &win->id, NULL); | ||
110 | |||
111 | wl_list_for_each(input, &_ecore_wl_disp->inputs, link) | ||
112 | { | ||
113 | if ((input->pointer_focus) && (input->pointer_focus == win)) | ||
114 | input->pointer_focus = NULL; | ||
115 | if ((input->keyboard_focus) && (input->keyboard_focus == win)) | ||
116 | input->keyboard_focus = NULL; | ||
117 | } | ||
118 | |||
119 | if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface); | ||
120 | win->shell_surface = NULL; | ||
121 | |||
122 | if (win->surface) wl_surface_destroy(win->surface); | ||
123 | win->surface = NULL; | ||
124 | |||
125 | // free(win); | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * Signals for Wayland to initiate a window move. | ||
130 | * | ||
131 | * The position requested (@p x, @p y) is not honored by Wayland because | ||
132 | * Wayland does not allow specific window placement to be set. | ||
133 | * | ||
134 | * @param win The window to move. | ||
135 | * @param x X Position | ||
136 | * @param y Y Position | ||
137 | * | ||
138 | * @ingroup Ecore_Wl_Window_Group | ||
139 | * @since 1.2 | ||
140 | */ | ||
141 | EAPI void | ||
142 | ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y) | ||
143 | { | ||
144 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
145 | |||
146 | if (!win) return; | ||
147 | win->allocation.x = x; | ||
148 | win->allocation.y = y; | ||
149 | if (win->shell_surface) | ||
150 | { | ||
151 | Ecore_Wl_Input *input; | ||
152 | |||
153 | input = win->keyboard_device; | ||
154 | wl_shell_surface_move(win->shell_surface, input->input_device, | ||
155 | input->timestamp); | ||
156 | } | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * Signals for Wayland to initiate a window resize. | ||
161 | * | ||
162 | * The size requested (@p w, @p h) is not honored by Wayland because | ||
163 | * Wayland does not allow specific window sizes to be set. | ||
164 | * | ||
165 | * @param win The window to resize. | ||
166 | * @param w Width | ||
167 | * @param h Height | ||
168 | * @param location The edge of the window from where the resize should start. | ||
169 | * | ||
170 | * @ingroup Ecore_Wl_Window_Group | ||
171 | * @since 1.2 | ||
172 | */ | ||
173 | EAPI void | ||
174 | ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location) | ||
175 | { | ||
176 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
177 | |||
178 | if (!win) return; | ||
179 | win->allocation.w = w; | ||
180 | win->allocation.h = h; | ||
181 | if (win->shell_surface) | ||
182 | { | ||
183 | Ecore_Wl_Input *input; | ||
184 | |||
185 | input = win->keyboard_device; | ||
186 | wl_shell_surface_resize(win->shell_surface, input->input_device, | ||
187 | input->timestamp, location); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | EAPI void | ||
192 | ecore_wl_window_damage(Ecore_Wl_Window *win, int x, int y, int w, int h) | ||
193 | { | ||
194 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
195 | |||
196 | if (!win) return; | ||
197 | if (win->surface) | ||
198 | wl_surface_damage(win->surface, x, y, w, h); | ||
199 | } | ||
200 | |||
201 | EAPI void | ||
202 | ecore_wl_window_buffer_attach(Ecore_Wl_Window *win, struct wl_buffer *buffer, int x, int y) | ||
203 | { | ||
204 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
205 | |||
206 | if (!win) return; | ||
207 | if ((win->surface) && (buffer)) | ||
208 | wl_surface_attach(win->surface, buffer, x, y); | ||
209 | } | ||
210 | |||
211 | /** | ||
212 | * Shows a window | ||
213 | * | ||
214 | * Synonymous to "mapping" a window in Wayland System terminology. | ||
215 | * | ||
216 | * @param win The window to show. | ||
217 | * | ||
218 | * @ingroup Ecore_Wl_Window_Group | ||
219 | * @since 1.2 | ||
220 | */ | ||
221 | EAPI void | ||
222 | ecore_wl_window_show(Ecore_Wl_Window *win) | ||
223 | { | ||
224 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
225 | |||
226 | if (!win) return; | ||
227 | if (win->surface) return; | ||
228 | |||
229 | win->surface = wl_compositor_create_surface(_ecore_wl_disp->wl.compositor); | ||
230 | wl_surface_set_user_data(win->surface, win); | ||
231 | |||
232 | win->shell_surface = | ||
233 | wl_shell_get_shell_surface(_ecore_wl_disp->wl.shell, win->surface); | ||
234 | wl_shell_surface_add_listener(win->shell_surface, | ||
235 | &_ecore_wl_shell_surface_listener, win); | ||
236 | |||
237 | switch (win->type) | ||
238 | { | ||
239 | case ECORE_WL_WINDOW_TYPE_FULLSCREEN: | ||
240 | wl_shell_surface_set_fullscreen(win->shell_surface, | ||
241 | WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, | ||
242 | 0, NULL); | ||
243 | break; | ||
244 | case ECORE_WL_WINDOW_TYPE_MAXIMIZED: | ||
245 | wl_shell_surface_set_maximized(win->shell_surface, NULL); | ||
246 | break; | ||
247 | case ECORE_WL_WINDOW_TYPE_TRANSIENT: | ||
248 | wl_shell_surface_set_transient(win->shell_surface, | ||
249 | win->parent->shell_surface, | ||
250 | win->allocation.x, win->allocation.y, 0); | ||
251 | break; | ||
252 | case ECORE_WL_WINDOW_TYPE_MENU: | ||
253 | wl_shell_surface_set_popup(win->shell_surface, | ||
254 | win->pointer_device->input_device, | ||
255 | win->pointer_device->timestamp, | ||
256 | win->parent->shell_surface, | ||
257 | win->allocation.x, win->allocation.y, 0); | ||
258 | break; | ||
259 | case ECORE_WL_WINDOW_TYPE_TOPLEVEL: | ||
260 | default: | ||
261 | wl_shell_surface_set_toplevel(win->shell_surface); | ||
262 | break; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | /** | ||
267 | * Hides a window | ||
268 | * | ||
269 | * Synonymous to "unmapping" a window in Wayland System terminology. | ||
270 | * | ||
271 | * @param win The window to hide. | ||
272 | * | ||
273 | * @ingroup Ecore_Wl_Window_Group | ||
274 | * @since 1.2 | ||
275 | */ | ||
276 | EAPI void | ||
277 | ecore_wl_window_hide(Ecore_Wl_Window *win) | ||
278 | { | ||
279 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
280 | |||
281 | if (!win) return; | ||
282 | if (win->shell_surface) wl_shell_surface_destroy(win->shell_surface); | ||
283 | win->shell_surface = NULL; | ||
284 | if (win->surface) wl_surface_destroy(win->surface); | ||
285 | win->surface = NULL; | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * Raises a window | ||
290 | * | ||
291 | * @param win The window to raise. | ||
292 | * | ||
293 | * @ingroup Ecore_Wl_Window_Group | ||
294 | * @since 1.2 | ||
295 | */ | ||
296 | EAPI void | ||
297 | ecore_wl_window_raise(Ecore_Wl_Window *win) | ||
298 | { | ||
299 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
300 | |||
301 | if (!win) return; | ||
302 | if (win->shell_surface) | ||
303 | wl_shell_surface_set_toplevel(win->shell_surface); | ||
304 | } | ||
305 | |||
306 | EAPI void | ||
307 | ecore_wl_window_maximized_set(Ecore_Wl_Window *win, Eina_Bool maximized) | ||
308 | { | ||
309 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
310 | |||
311 | if (!win) return; | ||
312 | if ((win->type == ECORE_WL_WINDOW_TYPE_MAXIMIZED) == maximized) return; | ||
313 | if (win->type == ECORE_WL_WINDOW_TYPE_TOPLEVEL) | ||
314 | { | ||
315 | win->saved_allocation = win->allocation; | ||
316 | if (win->shell_surface) | ||
317 | wl_shell_surface_set_maximized(win->shell_surface, NULL); | ||
318 | win->type = ECORE_WL_WINDOW_TYPE_MAXIMIZED; | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | Ecore_Wl_Input *input; | ||
323 | |||
324 | input = win->keyboard_device; | ||
325 | |||
326 | if (win->shell_surface) | ||
327 | wl_shell_surface_set_toplevel(win->shell_surface); | ||
328 | win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; | ||
329 | win->allocation = win->saved_allocation; | ||
330 | _ecore_wl_window_configure_send(win, win->allocation.w, | ||
331 | win->allocation.h, input->timestamp); | ||
332 | } | ||
333 | } | ||
334 | |||
335 | EAPI void | ||
336 | ecore_wl_window_fullscreen_set(Ecore_Wl_Window *win, Eina_Bool fullscreen) | ||
337 | { | ||
338 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
339 | |||
340 | if (!win) return; | ||
341 | if ((win->type == ECORE_WL_WINDOW_TYPE_FULLSCREEN) == fullscreen) return; | ||
342 | if (fullscreen) | ||
343 | { | ||
344 | win->type = ECORE_WL_WINDOW_TYPE_FULLSCREEN; | ||
345 | win->saved_allocation = win->allocation; | ||
346 | if (win->shell_surface) | ||
347 | wl_shell_surface_set_fullscreen(win->shell_surface, | ||
348 | WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, | ||
349 | 0, NULL); | ||
350 | } | ||
351 | else | ||
352 | { | ||
353 | Ecore_Wl_Input *input; | ||
354 | |||
355 | input = win->keyboard_device; | ||
356 | |||
357 | if (win->shell_surface) | ||
358 | wl_shell_surface_set_toplevel(win->shell_surface); | ||
359 | win->type = ECORE_WL_WINDOW_TYPE_TOPLEVEL; | ||
360 | win->allocation = win->saved_allocation; | ||
361 | _ecore_wl_window_configure_send(win, win->allocation.w, | ||
362 | win->allocation.h, input->timestamp); | ||
363 | } | ||
364 | } | ||
365 | |||
366 | EAPI void | ||
367 | ecore_wl_window_update_size(Ecore_Wl_Window *win, int w, int h) | ||
368 | { | ||
369 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
370 | |||
371 | if (!win) return; | ||
372 | win->allocation.w = w; | ||
373 | win->allocation.h = h; | ||
374 | } | ||
375 | |||
376 | EAPI struct wl_surface * | ||
377 | ecore_wl_window_surface_get(Ecore_Wl_Window *win) | ||
378 | { | ||
379 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
380 | |||
381 | if (!win) return NULL; | ||
382 | return win->surface; | ||
383 | } | ||
384 | |||
385 | EAPI Ecore_Wl_Window * | ||
386 | ecore_wl_window_find(unsigned int id) | ||
387 | { | ||
388 | Ecore_Wl_Window *win; | ||
389 | |||
390 | if (!id) return NULL; | ||
391 | win = eina_hash_find(_windows, &id); | ||
392 | if (win) return win; | ||
393 | return NULL; | ||
394 | } | ||
395 | |||
396 | /* local functions */ | ||
397 | static void | ||
398 | _ecore_wl_window_cb_configure(void *data, struct wl_shell_surface *shell_surface __UNUSED__, unsigned int timestamp, unsigned int edges, int w, int h) | ||
399 | { | ||
400 | Ecore_Wl_Window *win; | ||
401 | |||
402 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
403 | |||
404 | if (!(win = data)) return; | ||
405 | if ((w <= 0) || (h <= 0)) return; | ||
406 | |||
407 | win->edges = edges; | ||
408 | win->allocation.w = w; | ||
409 | win->allocation.h = h; | ||
410 | _ecore_wl_window_configure_send(win, w, h, timestamp); | ||
411 | } | ||
412 | |||
413 | static void | ||
414 | _ecore_wl_window_cb_popup_done(void *data, struct wl_shell_surface *shell_surface __UNUSED__) | ||
415 | { | ||
416 | Ecore_Wl_Window *win; | ||
417 | |||
418 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
419 | |||
420 | if (!(win = data)) return; | ||
421 | /* TODO: handle popup destroy */ | ||
422 | } | ||
423 | |||
424 | static void | ||
425 | _ecore_wl_window_configure_send(Ecore_Wl_Window *win, int w, int h, unsigned int timestamp) | ||
426 | { | ||
427 | Ecore_Wl_Event_Window_Configure *ev; | ||
428 | |||
429 | LOGFN(__FILE__, __LINE__, __FUNCTION__); | ||
430 | |||
431 | if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Window_Configure)))) return; | ||
432 | ev->win = win->id; | ||
433 | ev->event_win = win->id; | ||
434 | ev->x = win->allocation.x; | ||
435 | ev->y = win->allocation.y; | ||
436 | ev->w = w; | ||
437 | ev->h = h; | ||
438 | ev->timestamp = timestamp; | ||
439 | ecore_event_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL); | ||
440 | } | ||