libxputty  0.1
A damn tiny abstraction Layer to create X11 window/widgets with cairo surfaces
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 
24 void _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_ENUM):
42  value = min(adj->max_value,max(adj->min_value,
43  adj->value + (adj->step * -direction)));
44  break;
45  case (CL_TOGGLE):
46  // value = adj->value ? 1.0 : 0.0;
47  break;
48  default:
49  break;
50  }
51  check_value_changed(adj, &value);
52  }
53 }
54 
55 void _toggle_event(Widget_t * wid) {
56  Adjustment_t *adj = NULL;
57  if (wid->adj_y) {
58  adj = wid->adj_y;
59  } else if(wid->adj_x) {
60  adj = wid->adj_x;
61  }
62  if (adj && adj->type != CL_TOGGLE) {
64  }
65 }
66 
67 void _check_enum(Widget_t * wid, XButtonEvent *xbutton) {
68  if (wid->flags & HAS_POINTER && xbutton->button == Button1) {
69  Adjustment_t *adj = NULL;
70  if (wid->adj_y) {
71  adj = wid->adj_y;
72  } else if(wid->adj_x) {
73  adj = wid->adj_x;
74  }
75  if (adj && adj->type == CL_ENUM) {
76  float value = adj->value;
77  value = adj->value + 1.0;
78  if (value>adj->max_value) value = adj->min_value;
79  check_value_changed(adj, &value);
80  }
81  }
82 }
83 
84 void _button_press(Widget_t * wid, XButtonEvent *xbutton, void* user_data) {
85  switch(xbutton->button) {
86  case Button1:
87  wid->state = 2;
88  _has_pointer(wid, xbutton);
89  wid->pos_x = xbutton->x;
90  wid->pos_y = xbutton->y;
91  _toggle_event(wid);
92  wid->func.button_press_callback(wid, xbutton, user_data);
93  break;
94  case Button2:
95  debug_print("Button2 \n");
96  break;
97  case Button3:
98  debug_print("Button3 \n");
99  wid->func.button_press_callback(wid, xbutton, user_data);
100  break;
101  case Button4:
102  _scroll_event(wid, 1);
103  break;
104  case Button5:
105  _scroll_event(wid, -1);
106  break;
107  default:
108  break;
109  }
110 }
111 
112 void _check_grab(Widget_t * wid, XButtonEvent *xbutton, Xputty *main) {
113  if(main->hold_grab != NULL) {
114  Widget_t *view_port = main->hold_grab->childlist->childs[0];
115  if(xbutton->button == Button1) {
116  //if (xbutton->window == view_port->widget) return;
117  XUngrabPointer(main->dpy,CurrentTime);
118  int i = view_port->childlist->elem-1;
119  for(;i>-1;i--) {
120  Widget_t *w = view_port->childlist->childs[i];
121  if (xbutton->window == w->widget) {
122  const char *l = view_port->childlist->childs[i]->label;
124  (main->hold_grab, &i, &l);
125  break;
126  }
127  }
128  widget_hide(main->hold_grab);
129  main->hold_grab = NULL;
130 
131  } else if(xbutton->button == Button4) {
132  _scroll_event(view_port, 1);
133  } else if(xbutton->button == Button5) {
134  _scroll_event(view_port, -1);
135  }
136  }
137 }
138 
140 
141  if (childlist_has_child(wid->childlist)) {
142  int i = 0;
143  for(;i<wid->childlist->elem;i++) {
144  Widget_t *w = wid->childlist->childs[i];
145  if ( w->flags & NO_PROPAGATE) continue;
146  if (w->flags & USE_TRANSPARENCY) {
147  if(w->flags & FAST_REDRAW)
148  transparent_draw(w, NULL);
149  else expose_widget(w);
150  }
151  }
152  }
153 }
154 
155 void _check_keymap (void *w_ ,XKeyEvent xkey) {
156  Widget_t *wid = (Widget_t*)w_;
157  int n = 1;
158  int i = 0;
159  for(;i<wid->childlist->elem;i++) {
160  Widget_t *w = wid->childlist->childs[i];
161  if(w->flags & HAS_FOCUS && w->state != 4) {
162  wid=w;
163  break;
164  }
165  }
166  if(wid->app->hold_grab != NULL) {
167  wid = wid->app->hold_grab->childlist->childs[0];
168  n = -1;
169  }
170  int nk = key_mapping(wid->app->dpy, &xkey);
171  if (nk) {
172  switch (nk) {
173  case 3: _set_adj_value(wid, false, 1*n);
174  break;
175  case 4: _set_adj_value(wid, true, 1*n);
176  break;
177  case 5: _set_adj_value(wid, false, -1*n);
178  break;
179  case 6: _set_adj_value(wid, true, -1*n);
180  break;
181  case 10:
182  {
183  int i = 0;
184  for(;i<wid->childlist->elem;i++) {
185  Widget_t *w = wid->childlist->childs[i];
186  if(w->flags & HAS_FOCUS && w->state != 4) {
187  wid=w;
188  break;
189  }
190  }
193  }
194  break;
195  default:
196  break;
197  }
198  }
199 }
200 
202  int i = 0;
203  for(;i<wid->app->childlist->elem;i++) {
204  Widget_t *w = wid->app->childlist->childs[i];
205  if (w->flags & IS_TOOLTIP) {
206  widget_hide(w);
207  }
208  }
209 }
210 
211 void _has_pointer(Widget_t *w, XButtonEvent *button) {
212  XWindowAttributes attrs;
213  XGetWindowAttributes(w->app->dpy, (Window)w->widget, &attrs);
214 
215  if ((button->x<attrs.width && button->y<attrs.height) &&
216  (button->x>0 && button->y>0)){
217  w->flags |= HAS_POINTER;
218  } else {
219  w->flags &= ~HAS_POINTER;
220  }
221 }
222 
223 void _set_adj_value(void *w_, bool x, int direction) {
224  Widget_t *wid = (Widget_t*)w_;
225  Adjustment_t *adj = NULL;
226  if (x && wid->adj_x) {
227  adj = wid->adj_x;
228  } else if (!x && wid->adj_y) {
229  adj = wid->adj_y;
230  }
231  if (adj) {
232  float value = min(adj->max_value,max(adj->min_value,
233  adj->value + (adj->step * direction)));
234  check_value_changed(adj, &value);
235  }
236 }
237 
238 void _dummy1_callback(void *w_, void* _data, void* user_data) {
239  debug_print("Widget_t _dummy callback\n");
240 }
241 
242 void _dummy_callback(void *w_, void* user_data) {
243  debug_print("Widget_t _dummy callback\n");
244 }
245 
246 void _resize_surface(Widget_t *wid, int width, int height) {
247  wid->width = width;
248  wid->height = height;
249  cairo_xlib_surface_set_size( wid->surface, wid->width, wid->height);
250  cairo_font_face_t *ff = cairo_get_font_face(wid->crb);
251  cairo_destroy(wid->crb);
252  cairo_surface_destroy(wid->buffer);
253  wid->buffer = cairo_surface_create_similar (wid->surface,
254  CAIRO_CONTENT_COLOR_ALPHA, width, height);
255  assert(cairo_surface_status(wid->buffer) == CAIRO_STATUS_SUCCESS);
256  wid->crb = cairo_create (wid->buffer);
257  cairo_set_font_face(wid->crb, ff);
258 }
259 
261  if(!childlist_has_child(wid->childlist)) return;
262  int i = 0;
263  for(;i<wid->childlist->elem;i++) {
264  Widget_t *w = wid->childlist->childs[i];
265  switch(w->scale.gravity) {
266  case(NORTHWEST):
267  XResizeWindow (wid->app->dpy, w->widget, max(1,
268  w->scale.init_width - (wid->scale.scale_x)),
269  max(1,w->scale.init_height - (wid->scale.scale_y)));
270  break;
271  case(NORTHEAST):
272  XResizeWindow (wid->app->dpy, w->widget, max(1,
273  w->scale.init_width - (wid->scale.scale_x)), w->height);
274  break;
275  case(SOUTHWEST):
276  XMoveWindow(wid->app->dpy,w->widget,w->scale.init_x-wid->scale.scale_x,
277  w->scale.init_y-wid->scale.scale_y);
278 
279  break;
280  case(SOUTHEAST):
281  XMoveWindow(wid->app->dpy,w->widget,w->scale.init_x,
282  w->scale.init_y-wid->scale.scale_y);
283  break;
284  case(CENTER):
285  XMoveWindow(wid->app->dpy,w->widget,w->scale.init_x /
286  wid->scale.cscale_x,w->scale.init_y / wid->scale.cscale_y);
287  XResizeWindow (wid->app->dpy, w->widget, max(1,
288  w->scale.init_width / (wid->scale.cscale_x)),
289  max(1,w->scale.init_height / (wid->scale.cscale_y)));
290  break;
291  case(ASPECT):
292  XMoveWindow(wid->app->dpy,w->widget,(
293  (w->scale.init_x + w->scale.init_width*0.5) /
294  wid->scale.cscale_x) - w->width*0.5,
295  ((w->scale.init_y + w->scale.init_height*0.5) /
296  wid->scale.cscale_y)- w->height*0.5) ;
297  XResizeWindow (wid->app->dpy, w->widget, max(1,
298  w->scale.init_width / (wid->scale.ascale)),
299  max(1,w->scale.init_height / (wid->scale.ascale)));
300  break;
301  case(FIXEDSIZE):
302  XMoveWindow(wid->app->dpy,w->widget,(
303  (w->scale.init_x + w->scale.init_width*0.5) /
304  wid->scale.cscale_x) - w->width*0.5,
305  ((w->scale.init_y + w->scale.init_height*0.5) /
306  wid->scale.cscale_y)- w->height*0.5) ;
307  break;
308  case(MENUITEM):
309  XResizeWindow (wid->app->dpy, w->widget, max(1,
310  w->scale.init_width - (wid->scale.scale_x)-5), w->scale.init_height);
311  break;
312  case(NONE):
313  break;
314  default:
315  break;
316  }
317  w->func.configure_notify_callback(w,NULL);
318  }
319 }
Xputty
Xputty - the main struct. It should be declared before any other call to a Xputty function....
Definition: xputty.h:177
send_button_press_event
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:630
NORTHWEST
@ NORTHWEST
Definition: xwidget.h:157
adj_set_start_value
void adj_set_start_value(void *w)
adj_set_start_value - internal use to store the value when pointer movment starts
Definition: xadjustment.c:173
CL_TOGGLE
@ CL_TOGGLE
Definition: xadjustment.h:51
expose_widget
void expose_widget(Widget_t *w)
expose_widgets - send a expose event (EXPOSE) to a Widget_t
Definition: xwidget.c:461
Resize_t::scale_x
float scale_x
Definition: xwidget.h:202
SOUTHWEST
@ SOUTHWEST
Definition: xwidget.h:161
_propagate_child_expose
void _propagate_child_expose(Widget_t *wid)
_propagate_child_expose - send expose to any child Widget_t
Definition: xwidget_private.c:139
Widget_t::width
int width
Definition: xwidget.h:352
Resize_t::gravity
Gravity gravity
Definition: xwidget.h:192
Resize_t::init_x
int init_x
Definition: xwidget.h:194
Xputty::childlist
Childlist_t * childlist
Definition: xputty.h:179
Resize_t::scale_y
float scale_y
Definition: xwidget.h:204
MENUITEM
@ MENUITEM
Definition: xwidget.h:171
Adjustment_t::value
float value
Definition: xadjustment.h:86
Resize_t::cscale_y
float cscale_y
Definition: xwidget.h:208
key_mapping
int key_mapping(Display *dpy, XKeyEvent *xkey)
_key_mapping - modifier key's mapped to a integer value
Definition: xwidget.c:26
CL_LOGARITHMIC
@ CL_LOGARITHMIC
Definition: xadjustment.h:61
min
#define min(x, y)
min - set a maximal value (x) as return value
Definition: xputty.h:78
NONE
@ NONE
Definition: xwidget.h:173
Childlist_t::childs
Widget_t ** childs
Definition: xchildlist.h:51
_dummy1_callback
void _dummy1_callback(void *w_, void *_data, void *user_data)
_dummy1_callback - default debuging callback for evfunc's
Definition: xwidget_private.c:238
CL_ENUM
@ CL_ENUM
Definition: xadjustment.h:55
send_button_release_event
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:649
transparent_draw
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:469
Widget_t::pos_y
int pos_y
Definition: xwidget.h:346
CENTER
@ CENTER
Definition: xwidget.h:165
Adjustment_t::type
CL_type type
Definition: xadjustment.h:98
HAS_POINTER
@ HAS_POINTER
Definition: xwidget.h:247
Widget_t::crb
cairo_t * crb
Definition: xwidget.h:318
HAS_FOCUS
@ HAS_FOCUS
Definition: xwidget.h:245
Widget_t::flags
long long flags
Definition: xwidget.h:324
_dummy_callback
void _dummy_callback(void *w_, void *user_data)
_dummy1_callback - default debuging callback for xevfunc's
Definition: xwidget_private.c:242
Widget_t::scale
Resize_t scale
Definition: xwidget.h:356
CL_VIEWPORT
@ CL_VIEWPORT
Definition: xadjustment.h:57
Xputty::hold_grab
Widget_t * hold_grab
Definition: xputty.h:185
Widget_t::pos_x
int pos_x
Definition: xwidget.h:344
Widget_t::app
Xputty * app
Definition: xwidget.h:300
Resize_t::init_y
int init_y
Definition: xwidget.h:196
Func_t::button_press_callback
evfunc button_press_callback
Definition: xwidget.h:93
Xputty::dpy
Display * dpy
Definition: xputty.h:181
USE_TRANSPARENCY
@ USE_TRANSPARENCY
Definition: xwidget.h:243
Widget_t::state
int state
Definition: xwidget.h:342
Resize_t::ascale
float ascale
Definition: xwidget.h:214
CL_LOGSCALE
@ CL_LOGSCALE
Definition: xadjustment.h:63
_resize_surface
void _resize_surface(Widget_t *wid, int width, int height)
_resize_surface - intern check if a Widget_t surfaces needs resizing
Definition: xwidget_private.c:246
_check_enum
void _check_enum(Widget_t *wid, XButtonEvent *xbutton)
_check_enum - internal check if Adjustment_t is of type CL_ENUM and handle events acordingly
Definition: xwidget_private.c:67
NO_PROPAGATE
@ NO_PROPAGATE
Definition: xwidget.h:261
Adjustment_t
Adjustment_t - struct to hold a controller adjustment.
Definition: xadjustment.h:80
Widget_t::widget
Window widget
Definition: xwidget.h:302
debug_print
#define debug_print(...)
debug_print - print out state messages when compiled with the -DDEBUG flag
Definition: xputty.h:64
FIXEDSIZE
@ FIXEDSIZE
Definition: xwidget.h:169
Widget_t
Widget_t - struct to hold the basic Widget_t info.
Definition: xwidget.h:298
_check_keymap
void _check_keymap(void *w_, XKeyEvent xkey)
_check_keymap - check if key is in map, send requests if so
Definition: xwidget_private.c:155
ASPECT
@ ASPECT
Definition: xwidget.h:167
Widget_t::surface
cairo_surface_t * surface
Definition: xwidget.h:312
_button_press
void _button_press(Widget_t *wid, XButtonEvent *xbutton, void *user_data)
_button_press - internal check which button is pressed (BUTTON_PRESS)
Definition: xwidget_private.c:84
Widget_t::height
int height
Definition: xwidget.h:354
_toggle_event
void _toggle_event(Widget_t *wid)
_toggle_event - internal check which Adjustment_t change it's value on a Button press event (BUTTON_P...
Definition: xwidget_private.c:55
Func_t::button_release_callback
evfunc button_release_callback
Definition: xwidget.h:94
Widget_t::childlist
Childlist_t * childlist
Definition: xwidget.h:336
IS_TOOLTIP
@ IS_TOOLTIP
Definition: xwidget.h:241
_has_pointer
void _has_pointer(Widget_t *w, XButtonEvent *button)
_has_pointer - check if the widget has the pointer
Definition: xwidget_private.c:211
Adjustment_t::max_value
float max_value
Definition: xadjustment.h:90
_hide_all_tooltips
void _hide_all_tooltips(Widget_t *wid)
_hide_all_tooltips - hide all active tooltips
Definition: xwidget_private.c:201
FAST_REDRAW
@ FAST_REDRAW
Definition: xwidget.h:255
Childlist_t::elem
int elem
Definition: xchildlist.h:57
Widget_t::adj_y
Adjustment_t * adj_y
Definition: xwidget.h:332
Widget_t::func
Func_t func
Definition: xwidget.h:310
_set_adj_value
void _set_adj_value(void *w_, bool x, int direction)
_set_adj_value - set value to adjustment from key event
Definition: xwidget_private.c:223
xwidget_private.h
Func_t::configure_notify_callback
xevfunc configure_notify_callback
Definition: xwidget.h:88
childlist_has_child
int childlist_has_child(Childlist_t *childlist)
childlist_has_child - check if a Widget_t Childlist_t contain a child
Definition: xchildlist.c:91
Widget_t::buffer
cairo_surface_t * buffer
Definition: xwidget.h:316
max
#define max(x, y)
max - set a minimal value (x) as return value
Definition: xputty.h:86
_resize_childs
void _resize_childs(Widget_t *wid)
_resize_childs - intern check if child widgets needs resizing
Definition: xwidget_private.c:260
check_value_changed
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...
Definition: xadjustment.c:241
Widget_t::label
const char * label
Definition: xwidget.h:326
Adjustment_t::step
float step
Definition: xadjustment.h:92
widget_hide
void widget_hide(Widget_t *w)
widget_hide - unmap/hide a Widget_t
Definition: xwidget.c:396
Adjustment_t::min_value
float min_value
Definition: xadjustment.h:88
_scroll_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...
Definition: xwidget_private.c:24
Widget_t::adj_x
Adjustment_t * adj_x
Definition: xwidget.h:330
Resize_t::cscale_x
float cscale_x
Definition: xwidget.h:206
Resize_t::init_width
int init_width
Definition: xwidget.h:198
NORTHEAST
@ NORTHEAST
Definition: xwidget.h:159
CL_CONTINUOS
@ CL_CONTINUOS
Definition: xadjustment.h:49
Resize_t::init_height
int init_height
Definition: xwidget.h:200
SOUTHEAST
@ SOUTHEAST
Definition: xwidget.h:163
_check_grab
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....
Definition: xwidget_private.c:112