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