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 #pragma once
22 
23 #ifndef XPUTTY1_H_
24 #define XPUTTY1_H_
25 
26 #include <string.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdbool.h>
30 #include <stddef.h>
31 #include <assert.h>
32 #include <limits.h>
33 
34 #include <math.h>
35 #include <cairo.h>
36 #include <cairo-xlib.h>
37 #include <X11/Xutil.h>
38 #include <X11/keysym.h>
39 #include <X11/Xatom.h>
40 #include <X11/cursorfont.h>
41 
42 #ifdef ENABLE_NLS
43 #include <libintl.h>
44 #include <locale.h>
45 #define _(S) gettext(S)
46 #else
47 #define _(S) S
48 #endif
49 
50 
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54 
55 #define DND_STATUS_ACCEPT(e) ((e)->xclient.data.l[1] & 0x1L)
56 #define DND_VERSION(e) ((e)->xclient.data.l[1] >> 24)
57 #define DND_SOURCE_WIN(e) ((e)->xclient.data.l[0])
58 #define DND_DROP_TIME(e) ((e)->xclient.data.l[2])
59 
60 
61 /*---------------------------------------------------------------------
62 -----------------------------------------------------------------------
63                     define debug print
64 -----------------------------------------------------------------------
65 ----------------------------------------------------------------------*/
66 
67 #ifndef DEBUG
68 #define DEBUG 0
69 #ifndef NDEBUG
70 #define NDEBUG // switch of assertion checks
71 #endif
72 #endif
73 
74 /**
75  * @brief debug_print         - print out state messages when compiled with
76  * the -DDEBUG flag
77  */
78 
79 #define debug_print(...) \
80             ((void)((DEBUG) ? fprintf(stderr, __VA_ARGS__) : 0))
81 
82 /*---------------------------------------------------------------------
83 -----------------------------------------------------------------------
84                 define min/max if not defined already
85 -----------------------------------------------------------------------
86 ----------------------------------------------------------------------*/
87 
88 /**
89  * @brief min         - set a maximal value (x) as return value
90  */
91 
92 #ifndef min
93 #define min(x, y) ((x) < (y) ? (x) : (y))
94 #endif
95 
96 /**
97  * @brief max         - set a minimal value (x) as return value
98  */
99 
100 #ifndef max
101 #define max(x, y) ((x) < (y) ? (y) : (x))
102 #endif
103 
104 /*---------------------------------------------------------------------
105 -----------------------------------------------------------------------
106                     define check if char holds UTF 8 string
107 -----------------------------------------------------------------------
108 ----------------------------------------------------------------------*/
109 
110 /**
111  * @brief IS_UTF8         - check if a char contain UTF 8 formated signs
112  */
113 
114 #define IS_UTF8(c) (((c)&0xc0)==0xc0)
115 
116 /*---------------------------------------------------------------------
117 -----------------------------------------------------------------------
118                 forward declareted structs
119 -----------------------------------------------------------------------
120 ----------------------------------------------------------------------*/
121 
122 /**
123  * @brief Childlist_t       - maintain a Widget_t list of childs for a Widget_t
124  */
125 
126 typedef struct Childlist_t Childlist_t;
127 
128 /**
129  * @brief Adjustment_t       - Adjustment_t for a Widget_t
130  */
131 
132 typedef struct Adjustment_t Adjustment_t ;
133 
134 /**
135  * @brief Widget_t           - the Widget_t base struct
136  */
137 
138 typedef struct Widget_t Widget_t;
139 
140 /**
141  * @brief XColor_t           - the Widget_t Color struct
142  */
143 
144 typedef struct XColor_t XColor_t;
145 
146 /**
147  * @brief  Xputty          - the main struct.It should be declared
148  * before any other call to a Xputty function.
149  */
150 
151 typedef struct Xputty Xputty;
152 
153 /**
154  * @brief *xfunc       - function pointer to connect XEvents from a Widget_t to a event handler
155  * @param *widget      - void pointer to the widget
156  * @param *user_data   - void pointer to attached user_data, maybe NULL
157  * @return void
158  */
159 
160 typedef void (*xfunc)(void * widget, void* user_data);
161 
162 #ifdef __cplusplus
163 }
164 #endif
165 
166 /*---------------------------------------------------------------------
167 -----------------------------------------------------------------------
168                 xputty library headers
169 -----------------------------------------------------------------------
170 ----------------------------------------------------------------------*/
171 
172 // library header
173 #include "xwidget.h"
174 #include "xadjustment.h"
175 #include "xchildlist.h"
176 #include "xcolor.h"
177 #include "xpngloader.h"
178 
179 
180 #ifdef __cplusplus
181 extern "C" {
182 #endif
183 
184 /**
185  * @brief Xputty             - the main struct.
186  * \n It should be declared before any other call to a Xputty function.
187  * \n Xputty store a pointer in the childlist,
188  *  to any Widget_t related to this instance of libxputty.
189  * \n The first created Widget_t is the toplevel window.
190  * \n When the toplevel window call destroy_widget(), Xputty call
191  * destroy_widget() for all remaining Widget_t's in the main childlist.
192  * \n So any allocated memory should be released before the
193  * toplevel window finaly close.
194  * @param *childlist         - pointer to the main childlist
195  * @param *dpy               - pointer to the display in use
196  * @param run                - bool to quit the main loop
197  * @param *color_scheme      - theming scheme for all Widget_t
198  * @param *hold_grab         - pointer to a modal Widget_t
199  */
200 
201 struct Xputty{
202 /** pointer to the main childlist */
203     Childlist_t *childlist;
204 /** pointer to the display in use */
205     Display *dpy;
206 /** theming scheme for all Widget_t */
207     XColor_t *color_scheme;
208 /** pointer to a modal Widget_t */
209     Widget_t *hold_grab;
210 /** pointer to a modal sub Widget_t */
211     Widget_t *submenu;
212 /** bool to quit the main loop */
213     bool run;
214 /** small fontsize for all Widget_t*/
215     int small_font;
216 /** normal fontsize  for all Widget_t*/
217     int normal_font;
218 /** big fontsize  for all Widget_t*/
219     int big_font;
220 /** size of the textbuffer for copy/paste */
221     int csize;
222 /** pointer to the textbuffer for copy/paste */
223     unsigned char *ctext;
224 /** Atoms for handling drag and drop */
225     int dnd_version;
226     Window dnd_source_window;
227     Atom XdndAware;
228     Atom XdndTypeList;
229     Atom XdndSelection;
230     Atom XdndStatus;
231     Atom XdndEnter;
232     Atom XdndPosition;
233     Atom XdndLeave;
234     Atom XdndDrop;
235     Atom XdndActionCopy;
236     Atom XdndFinished;
237 
238     Atom dnd_type_text;
239     Atom dnd_type_uri;
240     Atom dnd_type_utf8;
241     Atom dnd_type;
242 
243     Atom selection;
244     Atom targets_atom;
245     Atom text_atom;
246     Atom UTF8;
247 };
248 
249 /**
250  * @brief main_init         - open the Display and init the
251  * main->childlist.
252  * \n Set the bool run to true.
253  * \n The bool run is used to terminate the main event loop.
254  * \n main_init() should be called directly after the declaration of Xputty
255  * before the first Widget_t get created.
256  * \n Any Widget_t created afterwards will be added to the main childlist.
257  * \n The main childlist is used to check if a Widget_t is valid to receive a Event.
258  * \n Xputty check if a Widget_t is registerd in the main childlist, and only forward
259  * events when it found the Widget_t in the list.
260  * \n When a Widget_t call destroy_widget() any childs of this Widget_t receive
261  * a call to destroy_widget() to release there memory, they get removed from the main childlist
262  * and finaly the Widget_t itself will be removed from the main childlist as well.
263  * On main_quit() any remaining Widget_t from the main childlist will be destroyed,
264  * to ensure that we leave the memory clean.
265  * @param *main             - pointer to the main Xputty struct
266  * @return void
267  */
268 
269 void main_init(Xputty *main);
270 
271 /**
272  * @brief main_run          - start the main event loop.
273  * \n It should be start after your Widget_t's been created.
274  * \n You could create and destroy additional Widget_t's
275  * at any time later during run.
276  * @param *main             - pointer to the main Xputty struct
277  * @return void
278  */
279 
280 void main_run(Xputty *main);
281 
282 /**
283  * @brief run_embedded      - the main event loop to run embedded UI's.
284  * \n It should be start after your Widget_t's been created.
285  * \n You could create and destroy additional Widget_t's
286  * at any time later during run.
287  * @param *main             - pointer to the main Xputty struct
288  * @return void
289  */
290 
291 void run_embedded(Xputty *main);
292 
293 /**
294  * @brief main_quit         - destroy all remaining Widget_t's from the
295  * main->childlist.
296  * \n Free all resources which may be allocated between init
297  * and quit.
298  * \n It should be called after main_run()/run_embedded();
299  * @param *main             - pointer to the main Xputty struct
300  * @return void
301  */
302 
303 void main_quit(Xputty *main);
304 
305 #ifdef __cplusplus
306 }
307 #endif
308 
309 #endif //XPUTTY_H_
310 
311