libxputty  0.1
A damn tiny abstraction Layer to create X11 window/widgets with cairo surfaces
xwidget.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 
22 #include "xwidget.h"
23 #include "xwidget_private.h"
24 
25 
26 int key_mapping(Display *dpy, XKeyEvent *xkey) {
27  if (xkey->keycode == XKeysymToKeycode(dpy,XK_Tab))
28  return (xkey->state == ShiftMask) ? 1 : 2;
29  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_Up))
30  return 3;
31  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_Right))
32  return 4;
33  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_Down))
34  return 5;
35  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_Left))
36  return 6;
37  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_Home))
38  return 7;
39  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_Insert))
40  return 8;
41  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_End))
42  return 9;
43  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_Return))
44  return 10;
45  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_BackSpace))
46  return 11;
47  // keypad
48  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Subtract))
49  return 1;
50  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Add))
51  return 2;
52  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Up))
53  return 3;
54  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Right))
55  return 4;
56  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Down))
57  return 5;
58  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Left))
59  return 6;
60  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Home))
61  return 7;
62  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Insert))
63  return 8;
64  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_End))
65  return 9;
66  else if (xkey->keycode == XKeysymToKeycode(dpy,XK_KP_Enter))
67  return 10;
68  else return 0;
69 }
70 
71 void destroy_widget(Widget_t * w, Xputty *main) {
72  int count = childlist_find_child(main->childlist, w);
73  if (count == 0 && main->run == true) {
74  quit(w);
75  } else if(childlist_find_child(main->childlist, w)>=0) {
76  if(w->flags & REUSE_IMAGE) {
77  w->image = NULL;
78  }
79  if(w->flags & HAS_MEM) {
80  w->func.mem_free_callback(w, NULL);
81  }
83  int ch = childlist_has_child(w->childlist);
84  if (ch) {
85  int i = ch;
86  for(;i>0;i--) {
87  destroy_widget(w->childlist->childs[i-1],main);
88  }
89  destroy_widget(w,main);
90  }
91  if(w->flags & IS_WIDGET) {
92  Widget_t *p = (Widget_t *) w->parent;
94  }
98  cairo_surface_destroy(w->image);
99  cairo_destroy(w->crb);
100  cairo_surface_destroy(w->buffer);
101  cairo_destroy(w->cr);
102  cairo_surface_destroy(w->surface);
103 
104  XDestroyIC(w->xic);
105  XCloseIM(w->xim);
106  XUnmapWindow(w->app->dpy, w->widget);
107  XDestroyWindow(w->app->dpy, w->widget);
108  free(w->childlist);
109  free(w);
110  w = NULL;
111  }
112 }
113 
114 void configure_event(void *w_, void* user_data) {
115  Widget_t *wid = (Widget_t*)w_;
116  XWindowAttributes attrs;
117  XGetWindowAttributes(wid->app->dpy, (Window)wid->widget, &attrs);
118  if (wid->width != attrs.width || wid->height != attrs.height) {
119  wid->scale.scale_x = (float)wid->scale.init_width - attrs.width;
120  wid->scale.scale_y = (float)wid->scale.init_height - attrs.height;
121  wid->scale.cscale_x = (float)((float)wid->scale.init_width/(float)attrs.width);
122  wid->scale.cscale_y = (float)((float)wid->scale.init_height/(float)attrs.height);
123  wid->scale.rcscale_x = (float)((float)attrs.width/(float)wid->scale.init_width);
124  wid->scale.rcscale_y = (float)((float)attrs.height/(float)wid->scale.init_height);
125  wid->scale.ascale = wid->scale.cscale_x < wid->scale.cscale_y ?
126  wid->scale.cscale_y : wid->scale.cscale_x;
127 
128  _resize_surface(wid, attrs.width, attrs.height);
129 
130  debug_print("Widget_t configure callback width %i height %i\n", attrs.width, attrs.height);
131 
132  _resize_childs(wid);
133  }
134  wid->func.configure_notify_callback(wid,NULL);
135 }
136 
138  cairo_scale(w->crb, w->scale.cscale_x,w->scale.cscale_y);
139 }
140 
142  cairo_scale(w->crb, w->scale.rcscale_x,w->scale.rcscale_y);
143 }
144 
145 Widget_t *create_window(Xputty *app, Window win,
146  int x, int y, int width, int height) {
147 
148  Widget_t *w = (Widget_t*)malloc(sizeof(Widget_t));
149  assert(w != NULL);
150  debug_print("assert(w)\n");
151  XSetWindowAttributes attributes;
152  attributes.save_under = True;
153  attributes.override_redirect = 0;
154 
155  long event_mask = StructureNotifyMask|ExposureMask|KeyPressMask
156  |EnterWindowMask|LeaveWindowMask|ButtonReleaseMask
157  |ButtonPressMask|Button1MotionMask;
158 
159 
160 
161  w->widget = XCreateWindow(app->dpy, win , x, y, width, height, 0,
162  CopyFromParent, InputOutput, CopyFromParent,
163  CopyFromParent, &attributes);
164  debug_print("XCreateWindow\n");
165 
166  XSetLocaleModifiers("");
167  w->xim = XOpenIM(app->dpy, 0, 0, 0);
168  if(!w->xim){
169  XSetLocaleModifiers("@im=none");
170  w->xim = XOpenIM(app->dpy, 0, 0, 0);
171  }
172 
173  w->xic = XCreateIC(w->xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
174  XNClientWindow, w->widget, XNFocusWindow, w->widget, NULL);
175 
176  XSetICFocus(w->xic);
177 
178  XSelectInput(app->dpy, w->widget, event_mask);
179 
180  XSizeHints* win_size_hints;
181  win_size_hints = XAllocSizeHints();
182  win_size_hints->flags = PMinSize|PBaseSize|PWinGravity;
183  win_size_hints->min_width = width/2;
184  win_size_hints->min_height = height/2;
185  win_size_hints->base_width = width;
186  win_size_hints->base_height = height;
187  win_size_hints->win_gravity = CenterGravity;
188  XSetWMNormalHints(app->dpy, w->widget, win_size_hints);
189  XFree(win_size_hints);
190 
191  w->surface = cairo_xlib_surface_create (app->dpy, w->widget,
192  DefaultVisual(app->dpy, DefaultScreen(app->dpy)), width, height);
193 
194  assert(cairo_surface_status(w->surface) == CAIRO_STATUS_SUCCESS);
195  w->cr = cairo_create(w->surface);
196  cairo_select_font_face (w->cr, "Roboto", CAIRO_FONT_SLANT_NORMAL,
197  CAIRO_FONT_WEIGHT_NORMAL);
198 
199  w->buffer = cairo_surface_create_similar (w->surface,
200  CAIRO_CONTENT_COLOR_ALPHA, width, height);
201  assert(cairo_surface_status(w->buffer) == CAIRO_STATUS_SUCCESS);
202  w->crb = cairo_create (w->buffer);
203  cairo_select_font_face (w->crb, "Roboto", CAIRO_FONT_SLANT_NORMAL,
204  CAIRO_FONT_WEIGHT_NORMAL);
205 
206  w->image = NULL;
207 
208  w->flags = IS_WINDOW;
209  w->flags &= ~NO_AUTOREPEAT;
210  w->flags &= ~FAST_REDRAW;
211  w->flags &= ~HIDE_ON_DELETE;
212  w->flags &= ~REUSE_IMAGE;
213  w->flags &= ~NO_PROPAGATE;
214  w->app = app;
215  w->parent = &win;
216  w->parent_struct = NULL;
217  w->label = NULL;
218  memset(w->input_label, 0, 32 * (sizeof w->input_label[0]));
219  w->state = 0;
220  w->data = 0;
221  w->x = x;
222  w->y = y;
223  w->width = width;
224  w->height = height;
225  w->scale.init_x = x;
226  w->scale.init_y = y;
227  w->scale.init_width = width;
228  w->scale.init_height = height;
229  w->scale.scale_x = 0.0;
230  w->scale.scale_y = 0.0;
231  w->scale.cscale_x = 1.0;
232  w->scale.cscale_y = 1.0;
233  w->scale.rcscale_x = 1.0;
234  w->scale.rcscale_y = 1.0;
235  w->scale.ascale = 1.0;
236  w->scale.gravity = CENTER;
237  w->adj_x = NULL;
238  w->adj_y = NULL;
239  w->adj = NULL;
240  w->childlist = (Childlist_t*)malloc(sizeof(Childlist_t));
241  assert(w->childlist != NULL);
261 
263  //XMapWindow(app->dpy, w->widget);
264  debug_print("size of Func_t = %lu\n", sizeof(w->func)/sizeof(void*));
265  return w;
266 }
267 
269  int x, int y, int width, int height) {
270 
271  Widget_t *w = (Widget_t*)malloc(sizeof(Widget_t));
272  assert(w != NULL);
273  debug_print("assert(w)\n");
274  XSetWindowAttributes attributes;
275  attributes.save_under = True;
276  attributes.override_redirect = True;
277 
278  long event_mask = StructureNotifyMask|ExposureMask|KeyPressMask
279  |EnterWindowMask|LeaveWindowMask|ButtonReleaseMask
280  |ButtonPressMask|Button1MotionMask;
281 
282 
283 
284  w->widget = XCreateWindow(app->dpy, parent->widget , x, y, width, height, 0,
285  CopyFromParent, InputOutput, CopyFromParent,
286  CopyFromParent|CWOverrideRedirect, &attributes);
287  debug_print("XCreateWindow\n");
288 
289  XSetLocaleModifiers("");
290  w->xim = XOpenIM(app->dpy, 0, 0, 0);
291  if(!w->xim){
292  XSetLocaleModifiers("@im=none");
293  w->xim = XOpenIM(app->dpy, 0, 0, 0);
294  }
295 
296  w->xic = XCreateIC(w->xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
297  XNClientWindow, w->widget, XNFocusWindow, w->widget, NULL);
298 
299  XSetICFocus(w->xic);
300 
301  XSelectInput(app->dpy, w->widget, event_mask);
302 
303  w->surface = cairo_xlib_surface_create (app->dpy, w->widget,
304  DefaultVisual(app->dpy, DefaultScreen(app->dpy)), width, height);
305  assert(cairo_surface_status(w->surface) == CAIRO_STATUS_SUCCESS);
306  w->cr = cairo_create(w->surface);
307  cairo_select_font_face (w->cr, "Roboto", CAIRO_FONT_SLANT_NORMAL,
308  CAIRO_FONT_WEIGHT_NORMAL);
309 
310  w->buffer = cairo_surface_create_similar (w->surface,
311  CAIRO_CONTENT_COLOR_ALPHA, width, height);
312  assert(cairo_surface_status(w->buffer) == CAIRO_STATUS_SUCCESS);
313  w->crb = cairo_create (w->buffer);
314  cairo_select_font_face (w->crb, "Roboto", CAIRO_FONT_SLANT_NORMAL,
315  CAIRO_FONT_WEIGHT_NORMAL);
316 
317  w->image = NULL;
318 
320  w->flags &= ~NO_AUTOREPEAT;
321  w->flags &= ~FAST_REDRAW;
322  w->flags &= ~HIDE_ON_DELETE;
323  w->flags &= ~REUSE_IMAGE;
324  w->flags &= ~NO_PROPAGATE;
325  w->app = app;
326  w->parent = parent;
327  w->parent_struct = NULL;
328  w->label = NULL;
329  memset(w->input_label, 0, 32 * (sizeof w->input_label[0]));
330  w->state = 0;
331  w->data = 0;
332  w->x = x;
333  w->y = y;
334  w->width = width;
335  w->height = height;
336  w->scale.gravity = CENTER;
337  w->scale.init_width = width;
338  w->scale.init_height = height;
339  w->scale.init_x = x;
340  w->scale.init_y = y;
341  w->scale.scale_x = 0.0;
342  w->scale.scale_y = 0.0;
343  w->scale.cscale_x = 1.0;
344  w->scale.cscale_y = 1.0;
345  w->scale.rcscale_x = 1.0;
346  w->scale.rcscale_y = 1.0;
347  w->scale.ascale = 1.0;
348  w->adj_x = NULL;
349  w->adj_y = NULL;
350  w->adj = NULL;
351  w->childlist = (Childlist_t*)malloc(sizeof(Childlist_t));
352  assert(w->childlist != NULL);
354  childlist_add_child(parent->childlist, w);
373 
375  //XMapWindow(app->dpy, w->widget);
376  debug_print("size of Widget_t = %ld\n", sizeof(struct Widget_t));
377  return w;
378 }
379 
380 void connect_func(void (**event)(), void (*handler)()) {
381  debug_print("address of a is: %p\n", (void*)event);
382  debug_print("address of b is: %p\n", (void*)handler);
383  *event = handler;
384  debug_print("address of a is: %p\n", (void*)(*event));
385 }
386 
387 void widget_set_title(Widget_t *w, const char *title) {
388  XStoreName(w->app->dpy, w->widget, title);
389 }
390 
392  w->func.map_notify_callback(w, NULL);
393  XMapWindow(w->app->dpy, w->widget);
394 }
395 
397  int i=0;
398  for(;i<w->childlist->elem;i++) {
399  widget_hide(w->childlist->childs[i]);
400  }
401  w->func.unmap_notify_callback(w, NULL);
402  XUnmapWindow(w->app->dpy, w->widget);
403 }
404 
406  if (w->flags & IS_POPUP || w->flags & IS_TOOLTIP) {
407  return;
408  } else {
409  w->func.map_notify_callback(w, NULL);
410  XMapWindow(w->app->dpy, w->widget);
411  int i=0;
412  for(;i<w->childlist->elem;i++) {
414  }
415  }
416 }
417 
419  w->func.map_notify_callback(w, NULL);
420  XMapWindow(w->app->dpy, w->widget);
421  int i=0;
422  for(;i<w->childlist->elem;i++) {
424  }
425 }
426 
427 void show_tooltip(Widget_t *wid) {
428  int i = 0;
429  for(;i<wid->childlist->elem;i++) {
430  Widget_t *w = wid->childlist->childs[i];
431  if (w->flags & IS_TOOLTIP) {
432  unsigned int mask;
433  int x, y, rx, ry;
434  Window child, root;
435  XQueryPointer(wid->app->dpy, wid->widget, &root, &child, &rx, &ry, &x, &y, &mask);
436  int x1, y1;
437  XTranslateCoordinates( wid->app->dpy, wid->widget, DefaultRootWindow(wid->app->dpy),
438  x, y, &x1, &y1, &child );
439  XMoveWindow(w->app->dpy,w->widget,x1+10, y1-10);
440  widget_show(w);
441  break;
442  }
443  }
444 }
445 
446 void hide_tooltip(Widget_t *wid) {
447  int i = 0;
448  for(;i<wid->childlist->elem;i++) {
449  Widget_t *w = wid->childlist->childs[i];
450  if (w->flags & IS_TOOLTIP) {
451  widget_hide(w);
452  break;
453  }
454  }
455 }
456 
458  return main->childlist->childs[0];
459 }
460 
462  XEvent exp;
463  memset(&exp, 0, sizeof(exp));
464  exp.type = Expose;
465  exp.xexpose.window = w->widget;
466  XSendEvent(w->app->dpy, w->widget, False, ExposureMask, (XEvent *)&exp);
467 }
468 
469 void transparent_draw(void * w_, void* user_data) {
470  Widget_t *wid = (Widget_t*)w_;
471 
472  cairo_push_group (wid->cr);
473 
474  if (wid->flags & USE_TRANSPARENCY) {
475  Widget_t *parent = (Widget_t*)wid->parent;
476  XWindowAttributes attrs;
477  XGetWindowAttributes(wid->app->dpy, wid->widget, &attrs);
478 
479  debug_print("Widget_t _transparency \n");
480  cairo_set_source_surface (wid->crb, parent->buffer, -attrs.x, -attrs.y);
481  cairo_paint (wid->crb);
482  }
483 
484  cairo_push_group (wid->crb);
485  wid->func.expose_callback(wid, user_data);
486  cairo_pop_group_to_source (wid->crb);
487  cairo_paint (wid->crb);
488 
489  cairo_set_source_surface (wid->cr, wid->buffer,0,0);
490  cairo_paint (wid->cr);
491 
492  cairo_pop_group_to_source (wid->cr);
493  cairo_paint (wid->cr);
495 }
496 
497 void widget_event_loop(void *w_, void* event, Xputty *main, void* user_data) {
498  Widget_t *wid = (Widget_t*)w_;
499  XEvent *xev = (XEvent*)event;
500 
501  switch(xev->type) {
502  case ConfigureNotify:
503  wid->func.configure_callback(w_, user_data);
504  //transparent_draw(w_, user_data);
505  debug_print("Widget_t ConfigureNotify \n");
506  break;
507 
508  case Expose:
509  if (xev->xexpose.count == 0) {
510  transparent_draw(w_, user_data);
511  debug_print("Widget_t Expose \n");
512  }
513  break;
514 
515  case ButtonPress:
516  if (wid->state == 4) break;
517  if (wid->flags & HAS_TOOLTIP) hide_tooltip(wid);
518  _button_press(wid, &xev->xbutton, user_data);
519  debug_print("Widget_t ButtonPress %i\n", xev->xbutton.button);
520  break;
521 
522  case ButtonRelease:
523  _check_grab(wid, &xev->xbutton, main);
524  if (wid->state == 4) break;
525  _has_pointer(wid, &xev->xbutton);
526  if(wid->flags & HAS_POINTER) wid->state = 1;
527  else wid->state = 0;
528  _check_enum(wid, &xev->xbutton);
529  wid->func.button_release_callback(w_, &xev->xbutton, user_data);
530  debug_print("Widget_t ButtonRelease %i\n", xev->xbutton.button);
531  break;
532 
533  case KeyPress:
534  if (wid->state == 4) break;
535  _check_keymap(wid, xev->xkey);
536  wid->func.key_press_callback(w_, &xev->xkey, user_data);
537  debug_print("Widget_t KeyPress %u\n", xev->xkey.keycode);
538  break;
539 
540  case KeyRelease:
541  if (wid->state == 4) break;
542  {
543  unsigned short is_retriggered = 0;
544  if(wid->flags & NO_AUTOREPEAT) {
545  if (XEventsQueued(main->dpy, QueuedAlready)) {
546  XEvent nev;
547  XPeekEvent(main->dpy, &nev);
548  if (nev.type == KeyPress && nev.xkey.time == xev->xkey.time &&
549  nev.xkey.keycode == xev->xkey.keycode &&
550  (nev.xkey.keycode > 119 || nev.xkey.keycode < 110)) {
551  XNextEvent (main->dpy, xev);
552  is_retriggered = 1;
553  }
554  }
555  }
556  if (!is_retriggered) {
557  wid->func.key_release_callback(w_, &xev->xkey, user_data);
558  debug_print("Widget_t KeyRelease %u\n", xev->xkey.keycode);
559  }
560  }
561  break;
562 
563  case LeaveNotify:
564  wid->flags &= ~HAS_FOCUS;
565  if (wid->state == 4) break;
566  if(!(xev->xcrossing.state & Button1Mask)) {
567  wid->state = 0;
568  wid->func.leave_callback(w_, user_data);
569  }
570  if (wid->flags & HAS_TOOLTIP) hide_tooltip(wid);
571  debug_print("Widget_t LeaveNotify \n");
572  break;
573 
574  case EnterNotify:
575  wid->flags |= HAS_FOCUS;
576  if (wid->state == 4) break;
577  if(!(xev->xcrossing.state & Button1Mask)) {
578  wid->state = 1;
579  wid->func.enter_callback(w_, user_data);
580  if (wid->flags & HAS_TOOLTIP) show_tooltip(wid);
581  else _hide_all_tooltips(wid);
582  }
583  debug_print("Widget_t EnterNotify \n");
584  break;
585 
586  case MotionNotify:
587  if (wid->state == 4) break;
588  adj_set_motion_state(wid, xev->xmotion.x, xev->xmotion.y);
589  wid->func.motion_callback(w_,&xev->xmotion, user_data);
590  debug_print("Widget_t MotionNotify x = %i Y = %i \n",xev->xmotion.x,xev->xmotion.y );
591  break;
592 
593  case ClientMessage:
594  if (xev->xclient.message_type == XInternAtom(wid->app->dpy, "WIDGET_DESTROY", 1)) {
595  int ch = childlist_has_child(wid->childlist);
596  if (ch) {
597  int i = ch;
598  for(;i>0;i--) {
599  quit_widget(wid->childlist->childs[i-1]);
600  }
601  quit_widget(wid);
602  } else {
603  destroy_widget(wid,main);
604  }
605  }
606 
607  default:
608  break;
609  }
610 }
611 
612 void send_configure_event(Widget_t *w,int x, int y, int width, int height) {
613  XConfigureEvent notify;
614  memset(&notify, 0, sizeof(notify));
615  notify.type = ConfigureNotify;
616  notify.display = w->app->dpy;
617  notify.send_event = True;
618  notify.event = w->widget;
619  notify.window = w->widget;
620  notify.x = x;
621  notify.y = y;
622  notify.width = width;
623  notify.height = height;
624  notify.border_width = 0;
625  notify.above = None;
626  notify.override_redirect = 1;
627  XSendEvent( w->app->dpy, w->widget, true, StructureNotifyMask, (XEvent*)&notify );
628 }
629 
631  XEvent event;
632  memset(&event, 0, sizeof(XEvent));
633  XWindowAttributes attr;
634  XGetWindowAttributes(w->app->dpy, w->widget, &attr);
635  event.type = ButtonPress;
636  event.xbutton.same_screen = true;
637  event.xbutton.root = None;
638  event.xbutton.window = w->widget;
639  event.xbutton.subwindow = None;
640  event.xbutton.x = 1;
641  event.xbutton.y = 1;
642  event.xbutton.x_root = attr.x;
643  event.xbutton.y_root = attr.y;
644  event.xbutton.state = 0;
645  event.xbutton.button = Button1;
646  XSendEvent(w->app->dpy, PointerWindow, True, ButtonPressMask, &event);
647 }
648 
650  XEvent event;
651  memset(&event, 0, sizeof(XEvent));
652  XWindowAttributes attr;
653  XGetWindowAttributes(w->app->dpy, w->widget, &attr);
654  event.type = ButtonRelease;
655  event.xbutton.same_screen = true;
656  event.xbutton.root = None;
657  event.xbutton.window = w->widget;
658  event.xbutton.subwindow = None;
659  event.xbutton.x = 1;
660  event.xbutton.y = 1;
661  event.xbutton.x_root = attr.x;
662  event.xbutton.y_root = attr.y;
663  event.xbutton.state = 0;
664  event.xbutton.button = Button1;
665  XSendEvent(w->app->dpy, PointerWindow, True, ButtonReleaseMask, &event);
666 }
667 
669  XEvent event;
670  Screen *xscreen;
671  char buf[256];
672  buf[0]=0;
673 
674  xscreen=DefaultScreenOfDisplay(w->app->dpy);
675  sprintf(buf,"_NET_SYSTEM_TRAY_S%d",XScreenNumberOfScreen (xscreen));
676  Atom selection_atom = XInternAtom (w->app->dpy,buf,0);
677 
678  Window tray = XGetSelectionOwner (w->app->dpy,selection_atom);
679  Atom visualatom = XInternAtom(w->app->dpy, "_NET_SYSTEM_TRAY_VISUAL", False);
680  VisualID value = XVisualIDFromVisual(DefaultVisual(w->app->dpy, DefaultScreen(w->app->dpy)));
681  XChangeProperty(w->app->dpy, w->widget, visualatom, XA_VISUALID, 32,
682  PropModeReplace, (unsigned char*)&value, 1);
683 
684  if ( tray != None)
685  XSelectInput (w->app->dpy,tray,StructureNotifyMask);
686 
687  memset(&event, 0, sizeof(event));
688  event.xclient.type = ClientMessage;
689  event.xclient.window = tray;
690  event.xclient.message_type = XInternAtom (w->app->dpy, "_NET_SYSTEM_TRAY_OPCODE", False );
691  event.xclient.format = 32;
692  event.xclient.data.l[0] = CurrentTime;
693  event.xclient.data.l[1] = SYSTEM_TRAY_REQUEST_DOCK;
694  event.xclient.data.l[2] = w->widget;
695  event.xclient.data.l[3] = 0;
696  event.xclient.data.l[4] = 0;
697 
698  XSendEvent(w->app->dpy, tray, False, NoEventMask, &event);
699 }
700 
701 void quit(Widget_t *w) {
702  Atom WM_DELETE_WINDOW = XInternAtom(w->app->dpy, "WM_DELETE_WINDOW", True);
703  XClientMessageEvent xevent;
704  xevent.type = ClientMessage;
705  xevent.message_type = WM_DELETE_WINDOW;
706  xevent.display = w->app->dpy;
707  xevent.window = get_toplevel_widget(w->app)->widget;
708  xevent.format = 16;
709  xevent.data.l[0] = WM_DELETE_WINDOW;
710  XSendEvent(w->app->dpy, w->widget, 0, 0, (XEvent *)&xevent);
711 }
712 
714  Atom QUIT_WIDGET = XInternAtom(w->app->dpy, "WIDGET_DESTROY", False);
715  XClientMessageEvent xevent;
716  xevent.type = ClientMessage;
717  xevent.message_type = QUIT_WIDGET;
718  xevent.display = w->app->dpy;
719  xevent.window = w->widget;
720  xevent.format = 16;
721  xevent.data.l[0] = 1;
722  XSendEvent(w->app->dpy, w->widget, 0, 0, (XEvent *)&xevent);
723 }
724 
_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
Func_t::leave_callback
xevfunc leave_callback
Definition: xwidget.h:83
HAS_TOOLTIP
@ HAS_TOOLTIP
Definition: xwidget.h:249
Func_t::enter_callback
xevfunc enter_callback
Definition: xwidget.h:82
connect_func
void connect_func(void(**event)(), void(*handler)())
connect_func - connect a event with a handler without type check. For supported events see: Func_t
Definition: xwidget.c:380
Xputty
Xputty - the main struct. It should be declared before any other call to a Xputty function....
Definition: xputty.h:177
Widget_t::y
int y
Definition: xwidget.h:350
pop_widget_show_all
void pop_widget_show_all(Widget_t *w)
pop_widget_show_all - map/show popup widget with all it's childs
Definition: xwidget.c:418
Resize_t::scale_x
float scale_x
Definition: xwidget.h:202
Func_t::configure_callback
xevfunc configure_callback
Definition: xwidget.h:81
Widget_t::width
int width
Definition: xwidget.h:352
Resize_t::gravity
Gravity gravity
Definition: xwidget.h:192
configure_event
void configure_event(void *w_, void *user_data)
Definition: xwidget.c:114
Resize_t::init_x
int init_x
Definition: xwidget.h:194
Xputty::childlist
Childlist_t * childlist
Definition: xputty.h:179
Widget_t::image
cairo_surface_t * image
Definition: xwidget.h:320
Resize_t::scale_y
float scale_y
Definition: xwidget.h:204
_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_set_scale
void widget_set_scale(Widget_t *w)
widget_set_scale - set scaling mode to scale a image surface to the size of the Widget_t surface
Definition: xwidget.c:141
key_mapping
int key_mapping(Display *dpy, XKeyEvent *xkey)
_key_mapping - modifier key's mapped to a integer value
Definition: xwidget.c:26
_resize_childs
void _resize_childs(Widget_t *wid)
_resize_childs - intern check if child widgets needs resizing
Definition: xwidget_private.c:260
quit_widget
void quit_widget(Widget_t *w)
quit_widget - remove a widget from the processing loop
Definition: xwidget.c:713
Widget_t::data
int data
Definition: xwidget.h:322
childlist_init
void childlist_init(Childlist_t *childlist)
childlist_init - internal use to allocate the array to min size You usually didn't need to call thi...
Definition: xchildlist.c:25
_dummy_callback
void _dummy_callback(void *w_, void *user_data)
_dummy1_callback - default debuging callback for xevfunc's
Definition: xwidget_private.c:242
quit
void quit(Widget_t *w)
quit - exit the main loop
Definition: xwidget.c:701
Resize_t::cscale_y
float cscale_y
Definition: xwidget.h:208
widget_reset_scale
void widget_reset_scale(Widget_t *w)
widget_reset_scale - used to reset scaling mode after a image surface is drawn to the Widget_t surfac...
Definition: xwidget.c:137
_hide_all_tooltips
void _hide_all_tooltips(Widget_t *wid)
_hide_all_tooltips - hide all active tooltips
Definition: xwidget_private.c:201
Widget_t::parent_struct
void * parent_struct
Definition: xwidget.h:306
REUSE_IMAGE
@ REUSE_IMAGE
Definition: xwidget.h:259
Childlist_t::childs
Widget_t ** childs
Definition: xchildlist.h:51
Xputty::run
bool run
Definition: xputty.h:187
childlist_add_child
void childlist_add_child(Childlist_t *childlist, Widget_t *child)
childlist_add_child - internal use to add a child to the Childlist_t You usually didn't need to cal...
Definition: xchildlist.c:42
Func_t::key_release_callback
evfunc key_release_callback
Definition: xwidget.h:97
NO_AUTOREPEAT
@ NO_AUTOREPEAT
Definition: xwidget.h:253
adj_set_motion_state
void adj_set_motion_state(void *w, float x, float y)
adj_set_motion_state - internal use to set value and state of the Adjustment_t on mouse pointer movme...
Definition: xadjustment.c:187
Func_t::expose_callback
xevfunc expose_callback
Definition: xwidget.h:80
CENTER
@ CENTER
Definition: xwidget.h:165
IS_WINDOW
@ IS_WINDOW
Definition: xwidget.h:235
send_systray_message
void send_systray_message(Widget_t *w)
send_systray_message - request a systray icon for Widget_t currently not working
Definition: xwidget.c:668
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
Resize_t::rcscale_y
float rcscale_y
Definition: xwidget.h:212
_has_pointer
void _has_pointer(Widget_t *w, XButtonEvent *button)
_has_pointer - check if the widget has the pointer
Definition: xwidget_private.c:211
Func_t::user_callback
xevfunc user_callback
Definition: xwidget.h:86
Func_t::motion_callback
evfunc motion_callback
Definition: xwidget.h:95
Widget_t::flags
long long flags
Definition: xwidget.h:324
SYSTEM_TRAY_REQUEST_DOCK
#define SYSTEM_TRAY_REQUEST_DOCK
Definition: xwidget.h:38
Widget_t::adj
Adjustment_t * adj
Definition: xwidget.h:334
transparent_draw
void transparent_draw(void *w_, void *user_data)
transparent_draw - copy parent surface to child surface you usaualy didn't need to call this,...
Definition: xwidget.c:469
HIDE_ON_DELETE
@ HIDE_ON_DELETE
Definition: xwidget.h:257
Func_t::unmap_notify_callback
xevfunc unmap_notify_callback
Definition: xwidget.h:90
Widget_t::cr
cairo_t * cr
Definition: xwidget.h:314
Widget_t::scale
Resize_t scale
Definition: xwidget.h:356
xwidget.h
Func_t::key_press_callback
evfunc key_press_callback
Definition: xwidget.h:96
widget_hide
void widget_hide(Widget_t *w)
widget_hide - unmap/hide a Widget_t
Definition: xwidget.c:396
create_widget
Widget_t * create_widget(Xputty *app, Widget_t *parent, int x, int y, int width, int height)
*create_widget - create a widget A Widget_t could only be created as child of a other Widget_t To...
Definition: xwidget.c:268
HAS_MEM
@ HAS_MEM
Definition: xwidget.h:251
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
delete_adjustment
void * delete_adjustment(Adjustment_t *adj)
delete_adjustment - freeing the memory of the Adjustment_t You usually don't need to call this,...
Definition: xadjustment.c:133
USE_TRANSPARENCY
@ USE_TRANSPARENCY
Definition: xwidget.h:243
destroy_widget
void destroy_widget(Widget_t *w, Xputty *main)
destroy_widget - destroy a widget When a Widget_t receive a destroy_widget() call,...
Definition: xwidget.c:71
expose_widget
void expose_widget(Widget_t *w)
expose_widgets - send a expose event (EXPOSE) to a Widget_t
Definition: xwidget.c:461
Widget_t::state
int state
Definition: xwidget.h:342
Resize_t::ascale
float ascale
Definition: xwidget.h:214
Func_t::map_notify_callback
xevfunc map_notify_callback
Definition: xwidget.h:89
NO_PROPAGATE
@ NO_PROPAGATE
Definition: xwidget.h:261
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
Widget_t
Widget_t - struct to hold the basic Widget_t info.
Definition: xwidget.h:298
Resize_t::rcscale_x
float rcscale_x
Definition: xwidget.h:210
Childlist_t
Childlist_t - struct to hold a Widget_t child list Xputty main holds a list of any Widget_t created...
Definition: xchildlist.h:49
Widget_t::xic
XIC xic
Definition: xwidget.h:338
widget_show_all
void widget_show_all(Widget_t *w)
widget_show_all - map/show Widget_t with all childs
Definition: xwidget.c:405
Widget_t::surface
cairo_surface_t * surface
Definition: xwidget.h:312
IS_POPUP
@ IS_POPUP
Definition: xwidget.h:237
Func_t::mem_free_callback
xevfunc mem_free_callback
Definition: xwidget.h:87
Widget_t::height
int height
Definition: xwidget.h:354
childlist_destroy
void childlist_destroy(Childlist_t *childlist)
childlist_destroy - internal use to free the Childlist_t You usually didn't need to call this
Definition: xchildlist.c:38
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
Func_t::button_release_callback
evfunc button_release_callback
Definition: xwidget.h:94
IS_WIDGET
@ IS_WIDGET
Definition: xwidget.h:233
Widget_t::childlist
Childlist_t * childlist
Definition: xwidget.h:336
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
IS_TOOLTIP
@ IS_TOOLTIP
Definition: xwidget.h:241
Func_t::adj_callback
xevfunc adj_callback
Definition: xwidget.h:84
childlist_find_child
int childlist_find_child(Childlist_t *childlist, Widget_t *child)
childlist_find_child - find a child in a the Childlist_t this could be sued to check if a Widget_t is...
Definition: xchildlist.c:71
FAST_REDRAW
@ FAST_REDRAW
Definition: xwidget.h:255
Childlist_t::elem
int elem
Definition: xchildlist.h:57
_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
Widget_t::input_label
char input_label[32]
Definition: xwidget.h:328
widget_set_title
void widget_set_title(Widget_t *w, const char *title)
widget_set_title - set window title for a Widget_t
Definition: xwidget.c:387
Widget_t::adj_y
Adjustment_t * adj_y
Definition: xwidget.h:332
create_window
Widget_t * create_window(Xputty *app, Window win, int x, int y, int width, int height)
*create_window - create a Window You need to create as least minimun one Window to get started....
Definition: xwidget.c:145
Widget_t::func
Func_t func
Definition: xwidget.h:310
_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
xwidget_private.h
Widget_t::xim
XIM xim
Definition: xwidget.h:340
childlist_remove_child
void childlist_remove_child(Childlist_t *childlist, Widget_t *child)
childlist_remove_child - internal use to remove a child from the childlist You usually didn't need ...
Definition: xchildlist.c:57
_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
_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
Func_t::configure_notify_callback
xevfunc configure_notify_callback
Definition: xwidget.h:88
widget_event_loop
void widget_event_loop(void *w_, void *event, Xputty *main, void *user_data)
widget_event_loop - the internal widget event loop
Definition: xwidget.c:497
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
Widget_t::parent
void * parent
Definition: xwidget.h:304
Widget_t::event_callback
vfunc event_callback
Definition: xwidget.h:308
get_toplevel_widget
Widget_t * get_toplevel_widget(Xputty *main)
*get_toplevel_widget - get pointer to the top level Widget_t
Definition: xwidget.c:457
Widget_t::label
const char * label
Definition: xwidget.h:326
Func_t::value_changed_callback
xevfunc value_changed_callback
Definition: xwidget.h:85
Widget_t::x
int x
Definition: xwidget.h:348
show_tooltip
void show_tooltip(Widget_t *wid)
show_tooltip - check if a Widget_t have a tooltip, and show it, if a tooltip is available.
Definition: xwidget.c:427
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
Resize_t::init_height
int init_height
Definition: xwidget.h:200
hide_tooltip
void hide_tooltip(Widget_t *wid)
hide_tooltip - check if a Widget_t have a tooltip, and hide it, if a tooltip is mapped.
Definition: xwidget.c:446
send_configure_event
void send_configure_event(Widget_t *w, int x, int y, int width, int height)
send_configure_event - send a ConfigureNotify to Widget_t used to resize a Widget_t
Definition: xwidget.c:612
_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
Func_t::dialog_callback
xevfunc dialog_callback
Definition: xwidget.h:91
widget_show
void widget_show(Widget_t *w)
widget_show - map/show widget
Definition: xwidget.c:391