libxputty  0.1
A damn tiny abstraction Layer to create X11 window/widgets with cairo surfaces
xputty.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 "xputty.h"
22 
23 
24 void main_init(Xputty *main) {
25  main->dpy = XOpenDisplay(0);
26  assert(main->dpy);
27  main->childlist = (Childlist_t*)malloc(sizeof(Childlist_t));
28  assert(main->childlist);
30  main->color_scheme = (XColor_t*)malloc(sizeof(XColor_t));
31  assert(main->color_scheme);
32  set_dark_theme(main);
33  main->hold_grab = NULL;
34  main->run = true;
35  main->small_font = 10;
36  main->normal_font = 12;
37  main->big_font = 16;
38 }
39 
40 void main_run(Xputty *main) {
41  Widget_t * wid = main->childlist->childs[0];
42  Atom WM_DELETE_WINDOW;
43  WM_DELETE_WINDOW = XInternAtom(wid->app->dpy, "WM_DELETE_WINDOW", True);
44  XSetWMProtocols(wid->app->dpy, wid->widget, &WM_DELETE_WINDOW, 1);
45 
46  XEvent xev;
47  int ew;
48 
49  while (main->run && (XNextEvent(main->dpy, &xev)>=0)) {
50  if (XFilterEvent(&xev, None)) continue;
51  ew = childlist_find_widget(main->childlist, xev.xany.window);
52  if(ew >= 0) {
53  Widget_t * w = main->childlist->childs[ew];
54  w->event_callback(w, &xev, main, NULL);
55  }
56 
57  switch (xev.type) {
58  case ButtonPress:
59  if(main->hold_grab != NULL) {
60  Widget_t *view_port = main->hold_grab->childlist->childs[0];
61  bool is_item = False;
62  int i = view_port->childlist->elem-1;
63  for(;i>-1;i--) {
64  Widget_t *w = view_port->childlist->childs[i];
65  if (xev.xbutton.window == w->widget) {
66  is_item = True;
67  break;
68  }
69  }
70  if (xev.xbutton.window == view_port->widget) is_item = True;
71  if (!is_item) {
72  XUngrabPointer(main->dpy,CurrentTime);
73  widget_hide(main->hold_grab);
74  main->hold_grab = NULL;
75  }
76  }
77  break;
78  case ClientMessage:
79  /* delete window event */
80  if (xev.xclient.data.l[0] == (long int)WM_DELETE_WINDOW &&
81  xev.xclient.window == wid->widget) {
82  main->run = false;
83  } else {
84  int i = childlist_find_widget(main->childlist, xev.xclient.window);
85  if(i<1) return;
86  Widget_t *w = main->childlist->childs[i];
87  if(w->flags & HIDE_ON_DELETE) widget_hide(w);
88  else destroy_widget(main->childlist->childs[i],main);
89  }
90  break;
91  }
92  }
93 }
94 
95 void run_embedded(Xputty *main) {
96 
97  XEvent xev;
98  int ew = -1;
99 
100  while (XPending(main->dpy) > 0) {
101  XNextEvent(main->dpy, &xev);
102  ew = childlist_find_widget(main->childlist, xev.xany.window);
103  if(ew >= 0) {
104  Widget_t * w = main->childlist->childs[ew];
105  w->event_callback(w, &xev, main, NULL);
106  }
107  switch (xev.type) {
108  case ButtonPress:
109  if(main->hold_grab != NULL) {
110  Widget_t *view_port = main->hold_grab->childlist->childs[0];
111  bool is_item = False;
112  int i = view_port->childlist->elem-1;
113  for(;i>-1;i--) {
114  Widget_t *w = view_port->childlist->childs[i];
115  if (xev.xbutton.window == w->widget) {
116  is_item = True;
117  break;
118  }
119  }
120  if (xev.xbutton.window == view_port->widget) is_item = True;
121  if (!is_item) {
122  XUngrabPointer(main->dpy,CurrentTime);
123  widget_hide(main->hold_grab);
124  main->hold_grab = NULL;
125  }
126  }
127  break;
128  case ClientMessage:
129  /* delete window event */
130  if (xev.xclient.data.l[0] == (long int)XInternAtom(main->dpy, "WM_DELETE_WINDOW", True) ) {
131  int i = childlist_find_widget(main->childlist, xev.xclient.window);
132  if(i<1) return;
133  Widget_t *w = main->childlist->childs[i];
134  if(w->flags & HIDE_ON_DELETE) widget_hide(w);
135  else destroy_widget(w, main);
136  }
137  break;
138  }
139  }
140 }
141 
142 void main_quit(Xputty *main) {
143  int i = main->childlist->elem-1;
144  for(;i>-1;i--) {
145  Widget_t *w = main->childlist->childs[i];
146  destroy_widget(w, main);
147  }
149  free(main->childlist);
150  free(main->color_scheme);
151  XCloseDisplay(main->dpy);
152  debug_print("quit\n");
153 }
Xputty::big_font
int big_font
Definition: xputty.h:193
Xputty
Xputty - the main struct. It should be declared before any other call to a Xputty function....
Definition: xputty.h:177
Xputty::childlist
Childlist_t * childlist
Definition: xputty.h:179
set_dark_theme
void set_dark_theme(Xputty *main)
set_dark_theme - init the XColor_t struct to the default dark theme
Definition: xcolor.c:24
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
main_quit
void main_quit(Xputty *main)
main_quit - destroy all remaining Widget_t's from the main->childlist. Free all resources which may...
Definition: xputty.c:142
Childlist_t::childs
Widget_t ** childs
Definition: xchildlist.h:51
Xputty::run
bool run
Definition: xputty.h:187
run_embedded
void run_embedded(Xputty *main)
run_embedded - the main event loop to run embedded UI's. It should be start after your Widget_t's b...
Definition: xputty.c:95
main_init
void main_init(Xputty *main)
main_init - open the Display and init the main->childlist. Set the bool run to true....
Definition: xputty.c:24
main_run
void main_run(Xputty *main)
main_run - start the main event loop. It should be start after your Widget_t's been created....
Definition: xputty.c:40
Xputty::normal_font
int normal_font
Definition: xputty.h:191
XColor_t
XColor_t - the Widget_t Color struct XColor_t could be used for theming you Widget_t set.
Definition: xcolor.h:88
Widget_t::flags
long long flags
Definition: xwidget.h:324
HIDE_ON_DELETE
@ HIDE_ON_DELETE
Definition: xwidget.h:257
xputty.h
Xputty::hold_grab
Widget_t * hold_grab
Definition: xputty.h:185
Widget_t::app
Xputty * app
Definition: xwidget.h:300
Xputty::dpy
Display * dpy
Definition: xputty.h:181
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
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
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
Xputty::small_font
int small_font
Definition: xputty.h:189
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
Widget_t::childlist
Childlist_t * childlist
Definition: xwidget.h:336
Childlist_t::elem
int elem
Definition: xchildlist.h:57
childlist_find_widget
int childlist_find_widget(Childlist_t *childlist, Window child_window)
childlist_find_widget - find a child Widget_t in a the childlist by given the Window id
Definition: xchildlist.c:81
Xputty::color_scheme
XColor_t * color_scheme
Definition: xputty.h:183
Widget_t::event_callback
vfunc event_callback
Definition: xwidget.h:308
widget_hide
void widget_hide(Widget_t *w)
widget_hide - unmap/hide a Widget_t
Definition: xwidget.c:396