libxputty 0.1
Loading...
Searching...
No Matches
xwidget_private.c
Go to the documentation of this file.
1/*
2 * 0BSD
3 *
4 * BSD Zero Clause License
5 *
6 * Copyright (c) 2019 Hermann Meyer
7 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted.
10
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21#include "xwidget_private.h"
22
23
24void _scroll_event(Widget_t * wid, int direction) {
25 Adjustment_t *adj = NULL;
26 if (wid->adj_y) {
27 adj = wid->adj_y;
28 } else if(wid->adj_x) {
29 adj = wid->adj_x;
30 }
31 if (adj) {
32 float value = adj->value;
33 switch(adj->type) {
34 case (CL_LOGSCALE):
35 case (CL_LOGARITHMIC):
36 case (CL_CONTINUOS):
37 value = min(adj->max_value,max(adj->min_value,
38 adj->value + (adj->step * direction)));
39 break;
40 case (CL_VIEWPORT):
41 case (CL_VIEWPORTSLIDER):
42 case (CL_ENUM):
43 value = min(adj->max_value,max(adj->min_value,
44 adj->value + (adj->step * -direction)));
45 break;
46 case (CL_TOGGLE):
47 // value = adj->value ? 1.0 : 0.0;
48 break;
49 default:
50 break;
51 }
52 check_value_changed(adj, &value);
53 }
54}
55
57 Adjustment_t *adj = NULL;
58 if (wid->adj_y) {
59 adj = wid->adj_y;
60 } else if(wid->adj_x) {
61 adj = wid->adj_x;
62 }
63 if (adj && adj->type != CL_TOGGLE) {
65 }
66}
67
68void _check_enum(Widget_t * wid, XButtonEvent *xbutton) {
69 if (wid->flags & HAS_POINTER && xbutton->button == Button1) {
70 Adjustment_t *adj = NULL;
71 if (wid->adj_y) {
72 adj = wid->adj_y;
73 } else if(wid->adj_x) {
74 adj = wid->adj_x;
75 }
76 if (adj && adj->type == CL_ENUM) {
77 float value = adj->value;
78 value = adj->value + 1.0;
79 if (value>adj->max_value) value = adj->min_value;
80 check_value_changed(adj, &value);
81 }
82 }
83}
84
85void _button_press(Widget_t * wid, XButtonEvent *xbutton, void* user_data) {
86 if(wid->app->hold_grab != NULL) {
87 int ch = childlist_has_child(wid->childlist);
88 if (ch>1 && wid->app->key_snooper == NULL) {
89 if (xbutton->window == wid->app->hold_grab->childlist->childs[1]->widget) {
90 wid->app->is_grab = true;
91 } else {
92 wid->app->is_grab = false;
93 }
94 }
95
96 }
97 switch(xbutton->button) {
98 case Button1:
99 wid->state = 2;
100 _has_pointer(wid, xbutton);
101 wid->pos_x = xbutton->x;
102 wid->pos_y = xbutton->y;
103 _toggle_event(wid);
104 wid->func.button_press_callback(wid, xbutton, user_data);
105 break;
106 case Button2:
107 debug_print("Button2 \n");
108 _has_pointer(wid, xbutton);
109 wid->func.button_press_callback(wid, xbutton, user_data);
110 break;
111 case Button3:
112 debug_print("Button3 \n");
113 _has_pointer(wid, xbutton);
114 wid->func.button_press_callback(wid, xbutton, user_data);
115 break;
116 case Button4:
117 _scroll_event(wid, 1);
118 break;
119 case Button5:
120 _scroll_event(wid, -1);
121 break;
122 default:
123 break;
124 }
125}
126
127void _check_grab(Widget_t * wid, XButtonEvent *xbutton, Xputty *main) {
128 if(main->hold_grab != NULL && main->hold_grab->flags & IS_POPUP) {
129 if (main->is_grab) {
130 main->is_grab = false;
131 return;
132 }
134 Widget_t *slider = main->hold_grab->childlist->childs[1];
135 if (xbutton->window == slider->widget) {
136 return;
137 }
138 }
139 Widget_t *view_port = main->hold_grab->childlist->childs[0];
140 if(xbutton->button == Button1) {
141 //if (xbutton->window == view_port->widget) return;
142#ifdef _WIN32 //SetCaptureDisabled//XUngrabPointer
143 //ReleaseCapture(); // SetCapture() is currently disabled in pop_menu_show()
144#else
145 XUngrabPointer(main->dpy,CurrentTime);
146#endif
147 int i = view_port->childlist->elem-1;
148 for(;i>-1;i--) {
149 Widget_t *w = view_port->childlist->childs[i];
150 if (xbutton->window == w->widget) {
151 const char *l = view_port->childlist->childs[i]->label;
153 (main->hold_grab, &i, &l);
154 break;
155 }
156 }
157 widget_hide(main->hold_grab);
158 main->hold_grab = NULL;
159
160 } /*else if(xbutton->button == Button4) {
161 _scroll_event(view_port, 1);
162 } else if(xbutton->button == Button5) {
163 _scroll_event(view_port, -1);
164 }*/ // done in _button_press() anyway
165 } else if(main->hold_grab != NULL) {
166 main->hold_grab->func.button_release_callback(main->hold_grab, xbutton, NULL);
167 }
168}
169
170void _check_submenu(Widget_t * wid, XButtonEvent *xbutton, Xputty *main) {
171 if(main->submenu != NULL) {
172 Widget_t *view_port = main->submenu->childlist->childs[0];
173 if(xbutton->button == Button1) {
174 //if (xbutton->window == view_port->widget) return;
175 int i = view_port->childlist->elem-1;
176 for(;i>-1;i--) {
177 Widget_t *w = view_port->childlist->childs[i];
178 if (xbutton->window == w->widget) {
179 const char *l = view_port->childlist->childs[i]->label;
181 (main->submenu, &i, &l);
182 break;
183 }
184 }
185 widget_hide(main->submenu);
186 main->submenu = NULL;
187
188 } else if(xbutton->button == Button4) {
189 _scroll_event(view_port, 1);
190 } else if(xbutton->button == Button5) {
191 _scroll_event(view_port, -1);
192 }
193 }
194}
195
197
198 if (childlist_has_child(wid->childlist)) {
199 int i = 0;
200 for(;i<wid->childlist->elem;i++) {
201 Widget_t *w = wid->childlist->childs[i];
202 if ( w->flags & NO_PROPAGATE) continue;
203 if (w->flags & USE_TRANSPARENCY) {
204 if(w->flags & FAST_REDRAW)
205#ifdef __linux__ //ForceRedraw
206 transparent_draw(w, NULL);
207#else
208 expose_widget(w);
209#endif
210 else expose_widget(w);
211 }
212 }
213 }
214}
215
216void _check_keymap (void *w_ ,XKeyEvent xkey) {
217 Widget_t *wid = (Widget_t*)w_;
218 int n = 1;
219 int i = 0;
220 for(;i<wid->childlist->elem;i++) {
221 Widget_t *w = wid->childlist->childs[i];
222 if(w->flags & HAS_FOCUS && w->state != 4) {
223 wid=w;
224 break;
225 }
226 }
227 if(wid->app->hold_grab != NULL) {
228 wid = wid->app->hold_grab->childlist->childs[0];
229 n = -1;
230 }
231 int nk = key_mapping(wid->app->dpy, &xkey);
232 if (nk) {
233 switch (nk) {
234 case 3: _set_adj_value(wid, false, 1*n);
235 break;
236 case 4: _set_adj_value(wid, true, 1*n);
237 break;
238 case 5: _set_adj_value(wid, false, -1*n);
239 break;
240 case 6: _set_adj_value(wid, true, -1*n);
241 break;
242 case 10:
243 {
244 int i = 0;
245 for(;i<wid->childlist->elem;i++) {
246 Widget_t *w = wid->childlist->childs[i];
247 if(w->flags & HAS_FOCUS && w->state != 4) {
248 wid=w;
249 break;
250 }
251 }
254 }
255 break;
256 default:
257 break;
258 }
259 }
260}
261
263 int i = 0;
264 for(;i<wid->app->childlist->elem;i++) {
265 Widget_t *w = wid->app->childlist->childs[i];
266 if (w->flags & IS_TOOLTIP) {
267 widget_hide(w);
268 }
269 }
270}
271
273 Metrics_t metrics;
274 os_get_window_metrics(w, &metrics);
275
276 if ((button->x<metrics.width && button->y<metrics.height) &&
277 (button->x>0 && button->y>0)){
278 w->flags |= HAS_POINTER;
279 } else {
280 w->flags &= ~HAS_POINTER;
281 }
282}
283
284void _set_adj_value(void *w_, bool x, int direction) {
285 Widget_t *wid = (Widget_t*)w_;
286 Adjustment_t *adj = NULL;
287 if (x && wid->adj_x) {
288 adj = wid->adj_x;
289 } else if (!x && wid->adj_y) {
290 adj = wid->adj_y;
291 }
292 if (adj) {
293 float value = adj->value;
294 switch(adj->type) {
295 case (CL_VIEWPORT):
296 case (CL_VIEWPORTSLIDER):
297 value = min(adj->max_value,max(adj->min_value,
298 adj->value + (adj->step * -direction)));
299 break;
300 default:
301 value = min(adj->max_value,max(adj->min_value,
302 adj->value + (adj->step * direction)));
303 break;
304 }
305 check_value_changed(adj, &value);
306 }
307}
308
309void _dummy1_callback(void *w_, void* _data, void* user_data) {
310 debug_print("Widget_t _dummy callback\n");
311}
312
313void _dummy_callback(void *w_, void* user_data) {
314 debug_print("Widget_t _dummy callback\n");
315}
316
317void _resize_surface(Widget_t *wid, int width, int height) {
318 wid->width = width;
319 wid->height = height;
320 os_set_widget_surface_size(wid, wid->width, wid->height);
321 cairo_font_face_t *ff = cairo_get_font_face(wid->crb);
322 cairo_destroy(wid->crb);
323 cairo_surface_destroy(wid->buffer);
324 wid->buffer = cairo_surface_create_similar (wid->surface,
325 CAIRO_CONTENT_COLOR_ALPHA, width, height);
326 assert(cairo_surface_status(wid->buffer) == CAIRO_STATUS_SUCCESS);
327 wid->crb = cairo_create (wid->buffer);
328 cairo_set_font_face(wid->crb, ff);
329}
330
332 if(!childlist_has_child(wid->childlist)) return;
333 int i = 0;
334 for(;i<wid->childlist->elem;i++) {
335 Widget_t *w = wid->childlist->childs[i];
336 switch(w->scale.gravity) {
337 case(NORTHWEST):
338 os_resize_window (wid->app->dpy, w, max(1,
339 w->scale.init_width - (wid->scale.scale_x)),
340 max(1,w->scale.init_height - (wid->scale.scale_y)));
341 break;
342 case(NORTHEAST):
343 os_resize_window (wid->app->dpy, w, max(1,
344 w->scale.init_width - (wid->scale.scale_x)), w->height);
345 break;
346 case(SOUTHWEST):
348 w->scale.init_y-wid->scale.scale_y);
349 break;
350 case(SOUTHEAST):
351 os_move_window(wid->app->dpy,w,w->scale.init_x,
352 w->scale.init_y-wid->scale.scale_y);
353 break;
354 case(SOUTHCENTER):
355 os_move_window(wid->app->dpy,w,w->scale.init_x,
356 w->scale.init_y / wid->scale.cscale_y);
357 os_resize_window (wid->app->dpy, w, max(1,
358 w->scale.init_width - (wid->scale.scale_x)),
359 max(1,w->scale.init_height / (wid->scale.cscale_y)));
360 break;
361 case(EASTWEST):
362 os_move_window(wid->app->dpy,w,w->scale.init_x,
363 w->scale.init_y-wid->scale.scale_y);
364 break;
365 case(EASTNORTH):
367 max(1,w->scale.init_height - (wid->scale.scale_y)));
368 break;
369 case(EASTSOUTH):
370 os_move_window(wid->app->dpy,w,w->scale.init_x,
371 w->scale.init_y-wid->scale.scale_y);
372 os_resize_window (wid->app->dpy, w, max(1,
373 w->scale.init_width - (wid->scale.scale_x)), w->height);
374 break;
375 case(WESTNORTH):
377 w->scale.init_y);
378 break;
379 case(WESTSOUTH):
381 w->scale.init_y);
383 max(1,w->scale.init_height - (wid->scale.scale_y)));
384 break;
385 case(CENTER):
386 os_move_window(wid->app->dpy,w,w->scale.init_x /
387 wid->scale.cscale_x,w->scale.init_y / wid->scale.cscale_y);
388 os_resize_window (wid->app->dpy, w, max(1,
389 w->scale.init_width / (wid->scale.cscale_x)),
390 max(1,w->scale.init_height / (wid->scale.cscale_y)));
391 break;
392 case(ASPECT):
393 os_move_window(wid->app->dpy,w,(
394 (w->scale.init_x + w->scale.init_width*0.5) /
395 wid->scale.cscale_x) - w->width*0.5,
396 ((w->scale.init_y + w->scale.init_height*0.5) /
397 wid->scale.cscale_y)- w->height*0.5) ;
398 os_resize_window (wid->app->dpy, w, max(1,
399 w->scale.init_width / (wid->scale.ascale)),
400 max(1,w->scale.init_height / (wid->scale.ascale)));
401 break;
402 case(FIXEDSIZE):
403 os_move_window(wid->app->dpy,w,(
404 (w->scale.init_x + w->scale.init_width*0.5) /
405 wid->scale.cscale_x) - w->width*0.5,
406 ((w->scale.init_y + w->scale.init_height*0.5) /
407 wid->scale.cscale_y)- w->height*0.5) ;
408 break;
409 case(MENUITEM):
410 os_resize_window (wid->app->dpy, w, max(1,
411 w->scale.init_width - (wid->scale.scale_x)-5), w->scale.init_height);
412 break;
413 case(NONE):
414 break;
415 default:
416 break;
417 }
419 }
420}
Adjustment_t - struct to hold a controller adjustment.
Definition xadjustment.h:82
float min_value
Definition xadjustment.h:90
float max_value
Definition xadjustment.h:92
Widget_t ** childs
Definition xchildlist.h:51
xevfunc configure_notify_callback
Definition xwidget.h:93
evfunc button_release_callback
Definition xwidget.h:101
evfunc button_press_callback
Definition xwidget.h:100
Metrics_t - struct to receive window size, position & visibility Pass this struct to os_get_window_...
int init_height
Definition xwidget.h:355
float scale_y
Definition xwidget.h:359
float ascale
Definition xwidget.h:369
float cscale_y
Definition xwidget.h:363
Gravity gravity
Definition xwidget.h:347
float cscale_x
Definition xwidget.h:361
int init_width
Definition xwidget.h:353
int init_y
Definition xwidget.h:351
int init_x
Definition xwidget.h:349
float scale_x
Definition xwidget.h:357
Widget_t - struct to hold the basic Widget_t info.
Definition xwidget.h:457
Resize_t scale
Definition xwidget.h:525
Adjustment_t * adj_y
Definition xwidget.h:495
Adjustment_t * adj_x
Definition xwidget.h:493
int width
Definition xwidget.h:521
Window widget
Definition xwidget.h:469
int pos_y
Definition xwidget.h:515
cairo_surface_t * surface
Definition xwidget.h:483
cairo_surface_t * buffer
Definition xwidget.h:487
cairo_t * crb
Definition xwidget.h:489
int state
Definition xwidget.h:511
Childlist_t * childlist
Definition xwidget.h:499
int pos_x
Definition xwidget.h:513
long long flags
Definition xwidget.h:461
const char * label
Definition xwidget.h:463
int height
Definition xwidget.h:523
Func_t func
Definition xwidget.h:481
Xputty * app
Definition xwidget.h:465
int button
Window window
Xputty - the main struct. It should be declared before any other call to a Xputty function....
Definition xputty.h:228
bool is_grab
Definition xputty.h:258
Display * dpy
Definition xputty.h:232
Widget_t * hold_grab
Definition xputty.h:238
Childlist_t * childlist
Definition xputty.h:230
Widget_t * submenu
Definition xputty.h:242
Widget_t * key_snooper
Definition xputty.h:240
void check_value_changed(Adjustment_t *adj, float *value)
check_value_changed - check if Adjustment_t value have changed and send value_changed_callback (VALUE...
void adj_set_start_value(void *w)
adj_set_start_value - internal use to store the value when pointer movment starts
@ CL_TOGGLE
Definition xadjustment.h:51
@ CL_CONTINUOS
Definition xadjustment.h:49
@ CL_VIEWPORT
Definition xadjustment.h:57
@ CL_LOGARITHMIC
Definition xadjustment.h:61
@ CL_ENUM
Definition xadjustment.h:55
@ CL_LOGSCALE
Definition xadjustment.h:63
@ CL_VIEWPORTSLIDER
Definition xadjustment.h:65
int childlist_has_child(Childlist_t *childlist)
childlist_has_child - check if a Widget_t Childlist_t contain a child
Definition xchildlist.c:89
void os_get_window_metrics(Widget_t *w, Metrics_t *metrics)
os_get_window_metrics - Get the Merics_t struct related to a Widget_t
void os_set_widget_surface_size(Widget_t *w, int width, int height)
os_set_widget_surface_size - set the size of a Widget_t cairo surface
void os_resize_window(Display *dpy, Widget_t *w, int x, int y)
os_resize_window - Resize a Widget_t
void os_move_window(Display *dpy, Widget_t *w, int x, int y)
os_move_window - Move a Widget_t
int key_mapping(Display *dpy, XKeyEvent *xkey)
_key_mapping - modifier key's mapped to a integer value
Definition xwidget.c:37
void expose_widget(Widget_t *w)
expose_widgets - send a expose event (EXPOSE) to a Widget_t
Definition xwidget.c:445
void send_button_release_event(Widget_t *w)
send_button_release_event - send ButtonRelease event to Widget_t simulate a BUTTON_RELEASE Event
Definition xwidget.c:518
@ SOUTHEAST
Definition xwidget.h:306
@ CENTER
Definition xwidget.h:320
@ EASTSOUTH
Definition xwidget.h:314
@ WESTSOUTH
Definition xwidget.h:318
@ EASTWEST
Definition xwidget.h:310
@ SOUTHWEST
Definition xwidget.h:304
@ MENUITEM
Definition xwidget.h:326
@ SOUTHCENTER
Definition xwidget.h:308
@ ASPECT
Definition xwidget.h:322
@ FIXEDSIZE
Definition xwidget.h:324
@ NORTHEAST
Definition xwidget.h:302
@ NONE
Definition xwidget.h:328
@ NORTHWEST
Definition xwidget.h:300
@ WESTNORTH
Definition xwidget.h:316
@ EASTNORTH
Definition xwidget.h:312
@ IS_TOOLTIP
Definition xwidget.h:396
@ FAST_REDRAW
Definition xwidget.h:410
@ HAS_POINTER
Definition xwidget.h:402
@ USE_TRANSPARENCY
Definition xwidget.h:398
@ HAS_FOCUS
Definition xwidget.h:400
@ NO_PROPAGATE
Definition xwidget.h:416
@ IS_POPUP
Definition xwidget.h:392
void widget_hide(Widget_t *w)
widget_hide - unmap/hide a Widget_t
Definition xwidget.c:368
void transparent_draw(void *wid, void *user_data)
transparent_draw - copy parent surface to child surface you usaualy didn't need to call this,...
Definition xwidget.c:449
void send_button_press_event(Widget_t *w)
send_button_press_event - send ButtonPress event to Widget_t simulate a BUTTON_PRESS Event
Definition xwidget.c:514
void _resize_surface(Widget_t *wid, int width, int height)
_resize_surface - intern check if a Widget_t surfaces needs resizing
void _resize_childs(Widget_t *wid)
_resize_childs - intern check if child widgets needs resizing
void _set_adj_value(void *w_, bool x, int direction)
_set_adj_value - set value to adjustment from key event
void _scroll_event(Widget_t *wid, int direction)
_scroll_event - internal check which Adjustment_t change it's value on a motion event (POINTER_MOTION...
void _toggle_event(Widget_t *wid)
_toggle_event - internal check which Adjustment_t change it's value on a Button press event (BUTTON_P...
void _hide_all_tooltips(Widget_t *wid)
_hide_all_tooltips - hide all active tooltips
void _check_enum(Widget_t *wid, XButtonEvent *xbutton)
_check_enum - internal check if Adjustment_t is of type CL_ENUM and handle events acordingly
void _check_grab(Widget_t *wid, XButtonEvent *xbutton, Xputty *main)
_check_grab - internal check if a Widgt_t holds a grab when a BUTTON_PRESS event occur....
void _button_press(Widget_t *wid, XButtonEvent *xbutton, void *user_data)
_button_press - internal check which button is pressed (BUTTON_PRESS)
void _dummy_callback(void *w_, void *user_data)
_dummy1_callback - default debuging callback for xevfunc's
void _propagate_child_expose(Widget_t *wid)
_propagate_child_expose - send expose to any child Widget_t
void _check_submenu(Widget_t *wid, XButtonEvent *xbutton, Xputty *main)
_check_submenu - internal check if a Widgt_t is a submenu when a BUTTON_PRESS event occur....
void _dummy1_callback(void *w_, void *_data, void *user_data)
_dummy1_callback - default debuging callback for evfunc's
void _check_keymap(void *w_, XKeyEvent xkey)
_check_keymap - check if key is in map, send requests if so
void _has_pointer(Widget_t *w, XButtonEvent *button)
_has_pointer - check if the widget has the pointer
This file contains private function definitions used on all platforms.