├── .gitignore ├── README.txt ├── hgui.c ├── hgui.h ├── hguidemo ├── diagram.c ├── hguidemo.c ├── icon.xpm ├── makefile ├── robodance.anim ├── screensav.c └── simplewin.c └── makefile /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | hguidemo/diagram 5 | hguidemo/hguidemo 6 | hguidemo/hguidemsh 7 | hguidemo/screensav 8 | hguidemo/simplewin 9 | hguidemo/simplewsh 10 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | HermitGUI 1.0 readme 3 | ======================================================================== 4 | 5 | Introduction: 6 | ------------- 7 | HermitGUI ( abbreviated: 'hgui' ) is a GUI-toolkit for the X11 8 | graphic environment (Xorg) for Linux/Unix operating systems. 9 | (Cross-platform (Win/OSX), framebuffer(fbterm/kmscon), SDL, SVGAlib,xcb, 10 | alternative-X (nanoX/DirectFB/Wayland) support might come in the future 11 | utilizing more macros in 'hgui.c' and additional codes split by #ifdef.) 12 | 13 | You can easily make graphic programs with hgui in very small size. 14 | (Dynamically linked programs depending on stripped 70k shared libhgui.so 15 | weight minimally around 6kbyte, statically linked programs can be as 16 | small as 25kB if only some widgets are compiled in, but with all widgets 17 | included their minimum size is around 60 kilobytes. 18 | Nice, eh? These would still fit even into a Commodore 64's memory. :) 19 | 20 | My main motivation to spend those 3 weeks writing this toolkit was to 21 | have a basic GUI in my upcoming linux distribution for system settings 22 | and utilities, that doesn't depend on much libraries and isn't as big as 23 | current Fox/GTK/Qt. For small daily used applications like calculator, 24 | text-editor,etc. there should be a tiny toolkit for tiny linux distros, 25 | and size/scalability is an important thing to me. Though there were some 26 | fairly small toolkits to choose from (libGx,tekUI,GraphApp,XForms,FLTK), 27 | in the end I came to the conclusion that they're aren't as small as I 28 | wished for (below 200kbyte), and aren't looking/working the way I like. 29 | That's the strange story how HermitGUI was born... 30 | 31 | On the other hand I want a GUI toolkit that has a wrapper for BASH too. 32 | I know, BASH shell is not the best for GUI application development, but 33 | it has direct access already to the system commands and is already in 34 | there, not needing extra libraries like Lua/tinypy/TCL/etc. The idea 35 | is something like in Puppy Linux, where 'gtkdialog'/'xdialog' is used in 36 | conjuction with BASH script, and many Puppy-appliactions are made this 37 | way. Why is it better than coding apps in C? Of course the CPU-intensive 38 | tasks still should be done in C (or even better Assembly) but for simple 39 | frontends to the powerful commandline tools, a scripting might be the 40 | best way. E.g. modifying the code to the user's needs gets as simple as 41 | editing a text file containing a BASH script... 42 | 43 | Building & Installing HermitGUI: 44 | -------------------------------- 45 | The building procedure is simple: you only need the basic development 46 | toolchain (binutils, 'gcc' toolchain and GNU 'make'), C standard-library 47 | (stdlib.h,stdio.h) and the Xorg libraries (Xlib/libX11) in the places 48 | '/usr/include/X11' (for headers) and '/usr/lib' (shared dynamic libs), 49 | and you can build HermitGUI by entering to its directory and typing: 50 | 51 | make 52 | 53 | The shared library libhgui.so, and libhgui.a will be created. Also some 54 | demo-programs get created in 'hguidemo' folder (dynamic & static ver.). 55 | To install HermitGUI system-wide, the usual command is to be typed: 56 | 57 | make install 58 | 59 | (Not much is done, just libhgui.so(.1) and libhgui.a gets copied to 60 | /usr/lib/ and the header file hgui.h to /usr/include/ ) 61 | 62 | Cleaning these source-folders from intermediate binaries created can be 63 | done with 'make clean', while removing the system files can be done 64 | by 'make uninstall'. To remove everything created, type: 'make purge' 65 | 66 | Using HermitGUI in your project: 67 | -------------------------------- 68 | As mentioned above, you have two ways to build HermitGUI applications: 69 | Static build, which includes all the sources of the toolkit in your app, 70 | and therefore GUI won't have dependencies other than X & libc libraries. 71 | The other method is the Dynamic build, which uses the shared library, 72 | libhgui.so at runtime, which is in /usr/lib (or .. rpath folder below). 73 | For both methods you need to #include header-file. Check out 74 | hgui.h, the makefile and hguidemo.c in hguidemo folder as an example... 75 | (Especially how -D gcc directives can be used to omit unneeded widgets.) 76 | 77 | The documentation for the Window / Widget related functions is 'hgui.h' 78 | header-file itself. I hope it's self-explanatory enough for programmers. 79 | (Probably the only thing that differs from most of the toolkits is that 80 | negative coordinates are interpreted as coordinates relative to the 81 | right/bottom edge of the created window. That way many widgets can be 82 | moved/scaled dynamically according to the window-size in a simple run.) 83 | A short note about fonts: currently no XFT + fontconfig is supported, 84 | only the non-antialiased server-side Xorg 'core' font engine, so you can 85 | use only the XLFD (and aliases in 'fonts.alias' like '6x13' and 'fixed') 86 | as font-names in the widget adder functions. (If a font is not found on 87 | the system,e.g. /usr/share/fonts/fonts.dir doesn't contain the fontname, 88 | hgui will warn and use Xorg's built-in 6x13 fixed font as fallback... 89 | Tip for a considerably good looking and small font: Bitstream Vera Sans) 90 | 91 | ToDo?textedit/inputfield,list/pulldown/menu(bar),tab/panel/frame,dialog, 92 | -----statusbar,tickboxes/radiobuttons,tooltips,filedialog,colorchooser, 93 | numberbox, table, scrollable window, toolbar, divider/separator 94 | UTF8,selection/copy-paste, mousex/y/button anytime, 95 | scrollbar:make more precise, knob dragging/gripping (outside too) 96 | button-hold/repeat/release/toggle, widget-member convenience-func., 97 | maximize/fullscreen fucks up refresh coordinates (border/mov+resiz) 98 | 99 | Closing Words: 100 | -------------- 101 | HermitGUI is under WTF-license:Do what the fukk you want with this code. 102 | I hope you'll enjoy using HermitGUI and will have success with it. 103 | 104 | In case you need support, have an idea or want to contribute, don't 105 | hesitate to contact me via messagebox at: 106 | http://hermit.sidrip.com 107 | 108 | Hermit (Mihaly Horvath) , July 2015 109 | 110 | ======================================================================== 111 | -------------------------------------------------------------------------------- /hgui.c: -------------------------------------------------------------------------------- 1 | // Hermit simple GUI toolkit (with C and Bash support), mainly for Herminux 2 | //========================================================================= 3 | 4 | //------------------------ included libraries -------------------------- 5 | #include //C standard library 6 | #include //printf,sprintf,fprintf,etc. 7 | #include 8 | #include //operations like strlen() 9 | //#include 10 | //#include 11 | #include 12 | #include //libX11 13 | #include //minimize system-dependencies 14 | #include //XWMHints,XChangeProperty,etc. 15 | #include //key symbols 16 | #include //X11 predefined atoms & properties (e.g. size-hints) 17 | #include //Internationalization and Unicode support (better doing it with freetype2 library) 18 | //#ifdef USE_XFT 19 | // #include 20 | // XftDraw *xftdraw; XftColor xftcolor; XRenderColor xrcolor; XftFont *xftfont; 21 | //#endif 22 | 23 | #include "hgui.h" 24 | 25 | #if defined(__cplusplus) 26 | extern "C" 27 | { 28 | #endif 29 | 30 | //window definition aliases/dependencies 31 | #define NOICONIFY NOTASKBAR 32 | #define NOMAXIMIZE NORESIZE //nomaximize is an alias to noresize, means: no maximize-button, which is straightforward in case of non-resizable window 33 | 34 | //handle internal widget dependencies 35 | #ifdef HGUI_BUTTONS 36 | #define HGUI_TEXTLINES 37 | #endif 38 | #ifdef HGUI_PICBUTTONS 39 | #define HGUI_BUTTONS 40 | #define HGUI_PICTURES 41 | #endif 42 | #ifdef HGUI_TEXTBLOCKS 43 | #define HGUI_TEXTLINES 44 | #endif 45 | #ifdef HGUI_TEXTBOXES 46 | #define HGUI_TEXTLINES 47 | #define HGUI_TEXTBLOCKS 48 | #define HGUI_BLOCKS 49 | #define HGUI_SCROLLBARS 50 | #endif 51 | #ifdef HGUI_SCROLLBARS 52 | #define HGUI_BLOCKS 53 | #endif 54 | #ifdef HGUI_PICANIMS 55 | #define HGUI_PICTURES 56 | #endif 57 | #ifdef HGUI_TEXTANIMS 58 | #define HGUI_TEXTLINES 59 | #endif 60 | #if defined(HGUI_SLIDERS) || defined(HGUI_PROGBARS) 61 | #define HGUI_TEXTLINES //for caption 62 | #endif 63 | //#if defined(HGUI_FILEBROWSER) || defined(HGUI_COLORCHOOSER) 64 | // #define HGUI_CHILDWINDOWS 65 | // #define HGUI_CHILDWIN_COMPOSITES 66 | //#endif 67 | 68 | //handle internal widget-groups 69 | #if defined (HGUI_TEXTBUTTONS) || defined(HGUI_PICBUTTONS) 70 | #define HGUI_BUTTONS 71 | #endif 72 | #if defined(HGUI_TEXTLINES) || defined(HGUI_TEXTBLOCKS) || defined(HGUI_TEXTBOXES) || defined(HGUI_TEXTANIMS) 73 | #define HGUI_TEXTFIELDS 74 | #endif 75 | #if defined(HGUI_TEXTANIMS) || defined(HGUI_PICANIMS) 76 | #define HGUI_ANIMATIONS 77 | #endif 78 | 79 | 80 | //----------------internal program constants and settings--------------- 81 | //some EWMH (Extended Window Manager Hints) values 82 | #define _NET_WM_STATE_REMOVE 0 83 | #define _NET_WM_STATE_ADD 1 84 | #define _NET_WM_STATE_TOGGLE 2 85 | #define SOURCE_INDICATION_NO_OLD 0 86 | #define SOURCE_INDICATION_NORMAL 1 87 | #define SOURCE_INDICATION_PAGERS 2 88 | //#define DEBUG True //debug mode 89 | #define EXIT_OK 0 90 | #define EXIT_ERROR 1 91 | #define EXIT_OUTOFMEM 2 92 | #define RET_ERR -1 93 | #define LINESIZE_MAX 1024 //maximum width of a text-line (in conversion) 94 | #define TEXTSIZE_MAX 1000000 //maximum amount (bytes) of text to display in a textbox/textblock 95 | #define XPM_DEPTH 32 //not the colour-depth, but the representation in memory 96 | #define REFRESHRATE 100 //Hz the maximum frequency to refresh window-contents in case of destructive resizing / moving / covering (Expose-event) 97 | #define REFRESHDELAY 1000000/REFRESHRATE 98 | #define CHILDWIN_AMOUNT_MAX 64 //64 99 | #define WIDGET_AMOUNT_MAX 1024 100 | //#define POLYGON_MAX_POINTS 256 (using 'char' type prevents problems aready) 101 | #define ANIM_AMOUNT_MAX WIDGET_AMOUNT_MAX 102 | #define SCROLLTEXTWIDTH_MAX 1024 //max.length of a scrolltext-bar in characters 103 | #define PROPSIZE_MAX 64 //Window-Manager property text max. size 104 | //#define XBUILTINFONT "-*-fixed-medium-r-*-*-13-*-*-*-c-*-*-*" //"fixed" //"6x13" //probably built into every Xorg-servers, if no font described, this comes into play 105 | #define XBUILTINFONT_WIDTH 6 //if the OS has a different font as default, these settings should be changed or loading XBUILTINFONT will be necessary at window-creation 106 | #define XBUILTINFONT_HEIGHT 13 107 | #define XBUILTINFONT_ASCENT 10 108 | #define XBUILTINFONT_DESCENT XBUILTINFONT_HEIGHT-XBUILTINFONT_ASCENT 109 | #define TABSIZE 4 110 | #define BORDERSIZE 2 111 | #define TRANSPCOLOR 0x808080 //fallback when no background-colour is given for transparency-supported XPM 112 | #define BUTTFADE 0.1 113 | 114 | //default theme (used for simple/automatic routines not having all inputs): 115 | #define CONTRAST 0.4 //0.0 to 1.0 116 | #define BGCOLOR 0xCEC8CA 117 | #define FGCOLOR 0x001000 118 | //#define DEFAULTFONT XBUILTINFONT //e.g. "-*-arial-medium-r-*-*-17-*-*-*-p-*-*-*" 119 | #define HOLECOLOR 0x001100 120 | #define BUTTBGCOL 0x10D428 121 | #define BUTTFGCOL 0x202020 122 | #define BUTTBEVEL 2 123 | #define BUTTBORDER 1 124 | #define BUTTBORDCOL HOLECOLOR 125 | #define TEXTBGCOL 0xE0F0E0 126 | #define TEXTFGCOL 0x203010 127 | #define PROGBGCOL 0x80E0C0 128 | #define PROGFGCOL 0x1020E0 129 | #define PROGBEVEL BUTTBEVEL 130 | #define PROGTEXTCOL 0xFFFFFF 131 | #define SLIDERHOLE 2 132 | #define SLIDSCALEW 20 //slide-scalemark-width should be automatic depending on horizontal knob-size 133 | //#define SLIDEMARG 10 //should be automatic depending on vertical knob-size (which is derived from horizontal knobsize) 134 | #define SLIDKNOBSIZE 16 135 | #define SLIDBGCOL 0xC0E0D0 136 | #define SLIDFGCOL 0x20C080 137 | #define SLIDKNOBCOL 0xC020E0 138 | #define SCROLLBGCOL 0xC0A080 139 | #define SCROLLFGCOL 0x624050 140 | #define SCROLLKNOBCOL 0xD8D0D4 141 | #define SCROLLBUTTSIZE 14 142 | #define ANIMDELAY 4 //in frames 143 | #define SCROLLSPEEDY 1 //4 character-rows to jump on scrolloffsetheel in textbox 144 | #define SCROLLSPEEDX 8 //pixel-rows to jump with horizontal scrolling 145 | 146 | enum WidgetTypes { BUTTON,BUTTONDYN,BUTTONXPM,VSLIDER,HSLIDER,TEXTLINE,TEXTCENTER,TEXTBLOCK,TEXTBOX,HPROGBAR,VPROGBAR,VSCROLL,HSCROLL,BLOCK,BLOCKFILL,PICTURE,XPM,ANIM,ANIMXPM,TEXTSCROLL, 147 | POINT,LINE,RECT,RECTFILL,ARC,ARCFILL,CIRCLE,CIRCLEFILL,ELLIPSE,ELLIPSEFILL,POLYGON,FILLSOLID 148 | }; 149 | 150 | 151 | //---------------- macros (for readability and going towards cross-platform/framebuf(fbterm,kmscon)/SDL/alternative-X(nanoX,DirectFB) support) -------------- 152 | #ifdef __unix__ //X11 Xorg (note: space is not allowed between macro-function-name and left curly brace) 153 | #define SETBGCOL(col) ( XSetBackground(hw->d,hw->gc,col) ) 154 | #define SETDRAWCOL(col) ( XSetForeground(hw->d,hw->gc,col) ) 155 | #define DRAWPOINT(x,y,col) ( SETDRAWCOL(col), XDrawPoint(hw->d,hw->w,hw->gc,x,y) ) 156 | #define DRAWLINE(x1,y1,x2,y2) ( XDrawLine(hw->d,hw->w,hw->gc,x1,y1,x2,y2) ) 157 | #define DRAWRECT(x1,y1,x2,y2) ( XDrawRectangle(hw->d,hw->w,hw->gc,x1,y1,x2,y2) ) 158 | #define DRAWRECTFILL(x1,y1,x2,y2) ( XFillRectangle(hw->d,hw->w,hw->gc,x1,y1,x2,y2) ) 159 | #define DRAWARC(x,y,wi,h,startdeg,extentdeg) ( XDrawArc(hw->d,hw->w,hw->gc,x,y,wi,h,startdeg*64,extentdeg*64) ) 160 | #define DRAWARCFILL(x,y,wi,h,startdeg,extentdeg) ( XFillArc(hw->d,hw->w,hw->gc,x,y,wi,h,startdeg*64,extentdeg*64) ) 161 | #define DRAWSTRINGN(x,y,text,col,font,len) ( XDrawString(hw->d,hw->w,setFontGC(hw,hw->bgcol,col,font), x, y, text, len) ) 162 | #define DRAWSTRING(x,y,text,col,font) ( XDrawString(hw->d,hw->w,setFontGC(hw,hw->bgcol,col,font), x, y, text, strlen(text)) ) 163 | #endif 164 | //#ifdef __WIN32__ 165 | // #define SETDRAWCOL(col) ( ?! ) 166 | // #define DRAWPOINT(x,y,color) \ ( ? ) 167 | // #define DRAWLINE(x1,y1,x2,y2) \ ( ? ) 168 | // .... 169 | //#endif 170 | 171 | 172 | //------------------------- type and struct definitions ---------------- 173 | typedef struct Widget { //this is the common struct for widgets, 174 | 175 | //1st public part: structure should match exactly to the 1st part of specific structs in hgui.h (like Button,VScroll,etc.)) 176 | union { 177 | int x,x1; 178 | } ; 179 | union { 180 | int y,y1; 181 | } ; 182 | union { 183 | int x2w,x2,w,r,rx; 184 | } ; 185 | union { 186 | int y2h,y2,h,ry; 187 | } ; 188 | union { 189 | int zh,hpos,border,knobsize,depth,startdeg,scrollpixcnt; 190 | } ; 191 | union { 192 | long zv,vpos,bevel,scalewidth,degree,scrollindex; 193 | } ; 194 | union { 195 | unsigned long bgcol,color,transpcol; 196 | } ; 197 | union { 198 | unsigned long fgcol,textcol; 199 | } ; 200 | union { 201 | unsigned long knobcol,progtextcol,vpixsize,scrolldisplen; 202 | } ; 203 | union { 204 | unsigned long captcol,vpixpos,scrolloffset; 205 | } ; 206 | union { 207 | void *data,*text,*content,*title,*caption,*pixdata,*xpm,*xpmlist; 208 | } ; 209 | union { 210 | float pos; 211 | } ; 212 | union { 213 | float ratio,scale; 214 | } ; 215 | union { 216 | char opt1,wrap,framedelay; 217 | } ; 218 | union { 219 | char opt2,scrollbars,spdcnt; 220 | } ; 221 | union { 222 | char opt3,pixstep,autofit; 223 | } ; //char modeswitches; an alternative parametering method for one-bit mode-switches like wrap/scrollbars/autofit/edit/readonly/etc. 224 | union { 225 | char state,buttonstate,framecount,scrollendstate; 226 | } ; 227 | int actx1,acty1,actx2,acty2; //read-only (writing could fuck up the GUI) 228 | 229 | //2nd private part: this must be hidden from the outside wordld, the following members are for internal use only. if needed, write function to get/set them 230 | union { 231 | void *fsp, *font, *fontstruct; 232 | } ; //XFontStruct pointer 233 | void (*callback)(); //callback-routine pointer 234 | char grabbed; 235 | int margin; 236 | union { 237 | int knobx1,knoby1; 238 | } ; 239 | union { 240 | int hpixsize,knobx2,knoby2; 241 | }; //active-area is calculated by widget-drawing routines in drawWidget() 242 | char type; 243 | int id; 244 | void* parenthw; 245 | void* argptr; //'id' is set by addWidget() 246 | union { 247 | void *child1,*vscroll; 248 | } ; 249 | union { 250 | void *parentbox,*child2,*hscroll; 251 | } ; //link parent (e.g. textbox) with children (e.g.scrollbars) 252 | 253 | } Widget; 254 | 255 | 256 | //#undef hWindow 257 | typedef struct hWindow { 258 | //1st more public part: structure should match the one in hgui.h if exists 259 | unsigned long bgcol; 260 | float contrast; 261 | int eventx,eventy; 262 | char eventbutton; 263 | int width, height; 264 | //2nd private part for internal use 265 | int orig_width,orig_height; 266 | //int norm_x,norm_y, norm_width,norm_height; //fullscreen status and position+dimensions before going to fullscreen state (restoring window-size/position should be handled by window-manager) 267 | char options; 268 | char *title; 269 | void (*exitCallback)(); 270 | void *parenthw; //hWindow* 271 | void* Child[CHILDWIN_AMOUNT_MAX]; 272 | int ChildAmount; 273 | Widget W[WIDGET_AMOUNT_MAX]; 274 | int WidgetAmount; //'W':widget-array, WidgetAmount counts added items, used for Widget-ID 275 | int AnimID[ANIM_AMOUNT_MAX]; 276 | int AnimAmount; //so no need to look up all widget-array to check if animations are added 277 | Display *d; 278 | int fd; /*Drawable*/ Window w; 279 | int s; 280 | GC gc, defgc; 281 | Atom wm_protocols,delete_window; 282 | char dragging; 283 | int exposecnt, resizecnt, exitsig; 284 | int id; 285 | } hWindow; 286 | 287 | 288 | typedef struct TextDim { 289 | int x,y; 290 | long w; 291 | short h, ascent,descent; 292 | } TextDim; 293 | typedef struct TextBoxDim { 294 | long w, h, rowcount, vpixpos; 295 | } TextBoxDim; 296 | 297 | 298 | //----------------- global (preferably constant) content --------------- 299 | const char ErrPfx[]="ERROR(hgui): ", WarnPfx[]="WARNING(hgui): "; 300 | const char ERRORTXT_OUTOFMEM[]="Out of memory!", EmptyString[]=""; 301 | Widget eWidget; 302 | void* EmptyWidget=&eWidget; 303 | XFontStruct eFontStruct; 304 | XFontStruct* EmptyFontStruct=&eFontStruct; 305 | XFontStruct *xfont=NULL; //built-in Xorg font 306 | short DownArrowPoints[]= {-4,5, 5,5, 0,10}, UpArrowPoints[]= {-5,9, 5,9, 0,3}; 307 | short RightArrowPoints[]= {5,-5, 5,5, 10,0}, LeftArrowPoints[]= {9,-5, 9,5, 4,0}; 308 | 309 | 310 | //--------------------- internal function prototypes ------------------- 311 | //(public functions are prototyped in the header-file, local functions are in dependency-order) 312 | int dynCoordX(hWindow *hw, int x); 313 | int dynCoordY(hWindow *hw, int y); 314 | TextDim drawTextScrollFrame(hWindow *hw, Widget *wp, int x1, int y1, int x2, int y2, char *text); 315 | void cleanUpRect(hWindow *hw, int x1o, int y1o, int x2o, int y2o, int x1, int y1, int x2, int y2); 316 | void refreshWidget(Widget *w); 317 | Bool putAnimXPMframe(hWindow *hw, int id, int x, int y, unsigned long transpcol, void* xpmlist[], int framenumber ); 318 | 319 | //------------------------- basic GUI routines ------------------------- 320 | XPMstruct XPMtoPixels(char* source[], unsigned long bgcol) //only suitable for XPMs with around max. 50 colours (single-character colour-lookups) 321 | { 322 | int i,j,k,sourceindex,pixdataindex,width,height,colours,charpix,transpchar=0xff; 323 | unsigned int colr[256],colg[256],colb[256]; 324 | XPMstruct xpms; 325 | unsigned char colchar[256], colcode,colindex, transpr=(bgcol&0xFF0000)/65536,transpg=(bgcol&0xFF00)/256,transpb=bgcol&0xFF; 326 | sscanf(source[0],"%d %d %d %d",&width,&height,&colours,&charpix); //printf("width:%d, height:%d, colours:%d, charpix:%d",width,height,colours,charpix); 327 | unsigned char *pixdata = malloc (width*height*XPM_DEPTH/8); //32 is sure to have enough room 328 | for (i=0; id,data,False); 364 | XChangeProperty(hw->d,hw->w, XInternAtom(hw->d,property,False), XA_ATOM, 32,overwrite?PropModeReplace:PropModeAppend, (unsigned char*) &wmatom, 1); 365 | return wmatom; 366 | } 367 | 368 | void setWindowType(hWindow *hw, char *type) 369 | { 370 | //called when creating window, preferably not called afterwards 371 | char prop[PROPSIZE_MAX]; 372 | sprintf(prop,"_NET_WM_WINDOW_TYPE_%s",type); //printf("Setting window as type %s\n",type); 373 | changeWMprop(hw,"_NET_WM_WINDOW_TYPE",prop,True); 374 | } 375 | 376 | Atom addWindowState(hWindow *hw, char *type) 377 | { 378 | char prop[PROPSIZE_MAX]; 379 | sprintf(prop,"_NET_WM_STATE_%s",type); //printf("Setting window to state %s\n",type); 380 | return changeWMprop(hw,"_NET_WM_STATE",prop,False); 381 | } 382 | 383 | void sendStateClientMessage(hWindow *hw, char *type, char action) 384 | { 385 | //informs the window-manager about the state-change 386 | char prop[PROPSIZE_MAX]; 387 | sprintf(prop,"_NET_WM_STATE_%s",type); 388 | Atom msgtypeatom=XInternAtom(hw->d,"_NET_WM_STATE",False), stateatom=XInternAtom(hw->d,prop,False); 389 | XEvent stev; 390 | stev.xclient.type=ClientMessage; 391 | stev.xclient.serial=0; 392 | stev.xclient.send_event=True; 393 | stev.xclient.message_type=msgtypeatom; 394 | stev.xclient.window=hw->w; 395 | stev.xclient.format=32; 396 | stev.xclient.data.l[0]=action; 397 | stev.xclient.data.l[1]=stateatom; 398 | stev.xclient.data.l[2]=0; 399 | stev.xclient.data.l[3]=SOURCE_INDICATION_NORMAL; 400 | stev.xclient.data.l[4]=0; 401 | XSendEvent(hw->d, RootWindow(hw->d,hw->s), True, StructureNotifyMask | SubstructureNotifyMask | SubstructureRedirectMask , &stev); 402 | XSync(hw->d,True); 403 | } 404 | 405 | void setWindowStates(hWindow *hw) //all-at-once, starting from empty to avoid accumulation/duplication 406 | { 407 | //based on current value of hw->options //XWMHints *hints = XAllocWMHints(); hints->flags=StateHint; hints->initial_state=IconicState; XSetWMHints(hw->d,hw->w,hints); 408 | Atom msgtypeatom=XInternAtom(hw->d,"_NET_WM_STATE",False); 409 | XDeleteProperty(hw->d,hw->w,msgtypeatom); 410 | if (hw->options&NOTASKBAR) addWindowState(hw,"SKIP_TASKBAR"); 411 | if (hw->options&ALWAYSONTOP) addWindowState(hw,"ABOVE"); 412 | if (hw->options&MODALWIN) addWindowState(hw,"MODAL"); 413 | if (hw->options&FULLSCREEN) addWindowState(hw,"FULLSCREEN"); 414 | //sendStateClientMessage should be called after these changes to inform window-manager with XSendEvent() 415 | } 416 | 417 | void setWinTypeToOptions(hWindow *hw, short options) 418 | { 419 | //at the moment I don't know about distinct properties (other than nonstandard _MOTIF_WM_HINTS) for titlebar-button-selection / window-decoration-disabling, until that this function is handy 420 | if (options==NOMAXIMIZE) setWindowType(hw,"UTILITY"); 421 | else if ((options&NODECOR && options&ALWAYSONTOP) || (options&TRAYAPP)) setWindowType(hw,"DOCK"); //DOCKAPP needs proper initialization afterwards (not to seen in taskbar, but be seen in system-tray) 422 | else if (options&NOTASKBAR) { 423 | if (options&NODECOR) setWindowType(hw,"NOTIFICATION"); 424 | else if (options&NOICONIFY) setWindowType(hw,"DIALOG"); //NOICONIFY is only relevant if there's NOTASKBAR, vice-versa, and is more important (not to have minimize-icon) than NOMAXIMIZE, ALWAYSONTOP can be set later 425 | else if (options&NOMAXIMIZE) { 426 | if (options&ALWAYSONTOP) setWindowType(hw,"TOOLBAR"); 427 | else setWindowType(hw,"MENU"); 428 | } 429 | } else if (options&NODECOR) setWindowType(hw,"SPLASH"); 430 | else setWindowType(hw,"NORMAL"); //printf("%d\n",options); 431 | } 432 | 433 | hWindow* createAndSetWindow(hWindow *hw, hWindow *parenthw, Window *rootw, int x, int y, int w, int h, char *title, unsigned long bgcol, unsigned long fgcol, int minwidth, int minheight, short options, char* xpmicon[], void* exitCallback, int argc, char **argv ) 434 | { 435 | if(hw==NULL) return NULL; 436 | Pixmap icon=None; 437 | hw->exitsig=0; 438 | hw->orig_width=w; 439 | hw->orig_height=h; 440 | hw->bgcol=bgcol; //hw->norm_x=x; hw->norm_y=y; hw->norm_width=w; hw->norm_height=h; 441 | if (options&NORESIZE) { 442 | minwidth=w; 443 | minheight=h; 444 | }; 445 | hw->exitCallback=exitCallback; 446 | hw->w=XCreateSimpleWindow(hw->d,*rootw,x,y,w,h,(options&(NODECOR||NOWINMAN))?0:BORDERSIZE,BlackPixel(hw->d,hw->s),bgcol); 447 | hw->options=options; 448 | hw->gc=XCreateGC(hw->d,hw->w,0,NULL); 449 | hw->defgc=XCreateGC(hw->d,hw->w,0,NULL); //DefaultGC(hw->d,hw->s); //3rd parameter for XCreateGC could be (GCFont|GCForeground|GCBackground), 4th is &XGCValues 450 | XSizeHints *sizehints=XAllocSizeHints(); 451 | sizehints->flags=PPosition|PMinSize; 452 | sizehints->min_width=minwidth; 453 | sizehints->min_height=minheight; 454 | if (options&NORESIZE) { 455 | sizehints->flags|=PMaxSize; 456 | sizehints->max_width=minwidth; 457 | sizehints->max_height=minheight; 458 | } 459 | if (xpmicon!=NULL) { 460 | XPMstruct xpms=XPMtoPixels(xpmicon,TRANSPCOLOR); 461 | XImage *iconimg = XCreateImage(hw->d,CopyFromParent,DefaultDepth(hw->d,hw->s),ZPixmap,0,xpms.pixdata,xpms.width,xpms.height,XPM_DEPTH,0); 462 | XInitImage(iconimg); //Pixmap icon=XCreatePixmapFromBitmapData(hw->d,hw->w,icon_pixels,ICON_WIDTH,ICON_HEIGHT,0x001122,0xFFEECC,XPM_DEPTH); 463 | icon=XCreatePixmap(hw->d,hw->w,xpms.width,xpms.height,DefaultDepth(hw->d,hw->s)); 464 | XPutImage(hw->d,icon,hw->gc,iconimg,0,0,0,0,xpms.width,xpms.height); 465 | XDestroyImage(iconimg); 466 | } 467 | XSetStandardProperties(hw->d,hw->w,title,title,icon,argv,argc,sizehints); //XSetWMProperties(hw->d,hw->w,NULL,NULL,NULL,0,sizehints,NULL,NULL); //XSetWMSizeHints(hw->d,hw->w,sizehints,sizeatom); //setIconXPM(hw->d,hw->w,hw->s,icon_xpm); //setTitle(hw->d,hw->w,title); //XListFonts() 468 | //XSetWindowBackgroundPixmap(hw->d,hw->w,None); //avoid flicker with trick, by setting empty pixmap background and repainting the window in eventloop at expose-events 469 | XSetWindowAttributes xwa; 470 | xwa.bit_gravity=StaticGravity; 471 | xwa.override_redirect=(options&NOWINMAN)?True:False; //override-redirect causes window to be a 'splash-creen' with no titlebar (but black border?) on top of all windows, also _NET_WM_WINDOW_TYPE property can (& should) be used to set splash 472 | XChangeWindowAttributes(hw->d,hw->w,CWBitGravity|CWOverrideRedirect,&xwa); //bit_gravity=StaticGravity to avoid flickering made by repainting background by X automatically when resizing window 473 | if(options) setWinTypeToOptions(hw,options); //this is not needed if I find a way to tell WM which particular buttons to include in titlebar or not to display window-decoration at all 474 | if(options) setWindowStates(hw); //initialize window-state based on 'options' 475 | //#ifdef USE_XFT xftdraw=XftDrawCreate(hw->d,hw->w,DefaultVisual(hw->d,hw->s),DefaultColorMap(hw->d,hw->s)); 476 | XMapWindow(hw->d,hw->w); 477 | XClearWindow(hw->d,hw->w); 478 | XFlush(hw->d); 479 | XSelectInput(hw->d,hw->w,ExposureMask|StructureNotifyMask|KeyPressMask|ButtonPressMask|Button1MotionMask|Button3MotionMask); //XCopyGC(hw->d,XDefaultGC(hw->d,hw->s),hw->gc,GCFont); 480 | xfont=NULL;//=loadFont(XBUILTINFONT); //Font *font=XLoadFont(hw->d,"6x13"); XFontStruct *fs=XLoadQueryFont(hw->d,"6x13"); //XGCValues gcval; XGetGCValues(hw->d,DefaultGC(hw->d,hw->s),GCFont,&gcval); 481 | SETDRAWCOL(FGCOLOR); //XSetFont(hw->d,hw->gc,defont->fid); //mkfontscale,mkfontdir->/usr/share/fonts.dir //Font fontx=gcval.font; xfont=XQueryFont(hw->d,fontx); 482 | hw->wm_protocols=XInternAtom(hw->d,"WM_PROTOCOLS",False); 483 | hw->delete_window=XInternAtom(hw->d,"WM_DELETE_WINDOW",False); 484 | XSetWMProtocols(hw->d,hw->w,&hw->delete_window,1); //Set WM protocols (for proper close-button hangling throug ClientMessage event-type) 485 | if(parenthw!=NULL) { 486 | hw->parenthw=parenthw; 487 | parenthw->Child[parenthw->ChildAmount]=hw; 488 | hw->id=parenthw->ChildAmount; 489 | parenthw->ChildAmount++; 490 | } else hw->parenthw=NULL; 491 | hw->title=getTitle(hw); 492 | hw->contrast=CONTRAST; 493 | hw->width=getWinWidth(hw); 494 | hw->height=getWinHeight(hw); 495 | hw->WidgetAmount=0; 496 | hw->AnimAmount=0; 497 | return hw; 498 | } 499 | 500 | hWindow* createWindow (int x, int y, int w, int h, char *title, unsigned long bgcol, unsigned long fgcol, int minwidth, int minheight, short options, char* xpmicon[], void (*exitCallback)() ) 501 | { 502 | //setlocale(LC_CTYPE,"en_EN.UTF-8"); if(XSupportsLocale()!=True){printf("\n %s No Locale Support\n",WarnPfx);} else XSetLocaleModifiers(""); 503 | hWindow *hw=malloc(sizeof(hWindow)); 504 | if(hw==NULL) { 505 | printf("%s %s",ErrPfx,ERRORTXT_OUTOFMEM); 506 | exit(EXIT_OUTOFMEM); 507 | } 508 | hw->d=openDisplay(); 509 | hw->s=DefaultScreen(hw->d); 510 | hw->fd=ConnectionNumber(hw->d); 511 | return createAndSetWindow(hw,NULL,&RootWindow(hw->d,hw->s),x,y,w,h,title,bgcol,fgcol,minwidth,minheight,options,xpmicon,exitCallback,0,NULL); 512 | } 513 | 514 | #ifdef HGUI_CHILDWINDOWS 515 | hWindow* createChildWindow (hWindow *parenthw, int x, int y, int w, int h, char *title, unsigned long bgcol, unsigned long fgcol, int minwidth, int minheight, short options, char* xpmicon[], void (*exitCallback)() ) 516 | { 517 | if(parenthw->ChildAmount>=CHILDWIN_AMOUNT_MAX) { 518 | printf("%s Reached maximum child-window amount (%d). Child-window \"%s\" was not created!\n",ErrPfx,CHILDWIN_AMOUNT_MAX,title); 519 | return NULL; 520 | } 521 | //x+=getWinX(parenthw);y+=getWinY(parenthw); relative location to parent-window (might be an issue if parent-window is not in place / minimized -> better leave it for Window-Manager 522 | hWindow *hw=malloc(sizeof(hWindow)); 523 | if(hw==NULL) { 524 | printf("%s %s",ErrPfx,ERRORTXT_OUTOFMEM); 525 | return NULL; 526 | } 527 | hw->d=parenthw->d; 528 | hw->s=parenthw->s; 529 | createAndSetWindow(hw,parenthw,&RootWindow(hw->d,hw->s),x,y,w,h,title,bgcol,fgcol,minwidth,minheight,options,xpmicon,exitCallback,0,NULL); 530 | return hw; 531 | } 532 | 533 | hWindow* createSubWindow(hWindow *parenthw, int x1, int y1, int x2, int y2, char *title, unsigned long bgcol, unsigned long fgcol) 534 | { 535 | if(parenthw->ChildAmount>=CHILDWIN_AMOUNT_MAX) { 536 | printf("%s Reached maximum child-window amount (%d). Subwindow \"%s\" was not created!\n",ErrPfx,CHILDWIN_AMOUNT_MAX,title); 537 | return NULL; 538 | } 539 | x1=dynCoordX(parenthw,x1); 540 | y1=dynCoordY(parenthw,y1); 541 | x2=dynCoordX(parenthw,x2); 542 | y2=dynCoordY(parenthw,y2); //pos might be relative to right/bottom window-edges (negative coordinate-values) 543 | hWindow *hw=malloc(sizeof(hWindow)); 544 | if(hw==NULL) { 545 | printf("%s",ERRORTXT_OUTOFMEM); 546 | return NULL; 547 | } 548 | hw->d=parenthw->d; 549 | hw->s=parenthw->s; //hw->options=0; 550 | createAndSetWindow(hw,parenthw,&parenthw->w,x1,y1,x2-x1,y2-y1,title,bgcol,fgcol,0,0,0b0000,NULL,NULL,0,NULL); 551 | return hw; 552 | } 553 | #endif //HGUI_CHILDWINDOWS 554 | 555 | void moveWindow (hWindow *hw, int x, int y) 556 | { 557 | if(hw==NULL) return; 558 | XMoveWindow(hw->d,hw->w,x,y); 559 | } 560 | void resizeWindow (hWindow *hw, int w, int h) 561 | { 562 | if(hw==NULL) return; 563 | XResizeWindow(hw->d,hw->w,w,h); 564 | } 565 | void iconifyWindow(hWindow *hw) 566 | { 567 | if(hw==NULL) return; 568 | XIconifyWindow(hw->d,hw->w,hw->s); 569 | } 570 | void hideWindow(hWindow *hw) 571 | { 572 | if(hw==NULL) return; //_NET_WM_STATE_HIDDEN or XWithdrawWindow(hw->d,hw->w,hw->s) does nearly the same (no window and no icon is seen) 573 | XUnmapWindow(hw->d, hw->w); 574 | } 575 | void showWindow(hWindow *hw) 576 | { 577 | if(hw==NULL) return; 578 | XMapWindow(hw->d, hw->w); 579 | } 580 | 581 | void toggleFullscreen(hWindow *hw) 582 | { 583 | if(hw==NULL) return; 584 | hw->options^=FULLSCREEN; 585 | //normally restoring original position and size after fullscreen should be handled by window-manager 586 | //if(hw->options&FULLSCREEN) { hw->norm_width=getWinWidth(hw); hw->norm_height=getWinHeight(hw); hw->norm_x=getWinX(hw); hw->norm_y=getWinY(hw); setWindowStates(hw); } 587 | //else { setWindowStates(hw); resizeWindow(hw,hw->norm_width,hw->norm_height); moveWindow(hw,hw->norm_x,hw->norm_y); } 588 | //XUnpapMapWindow-XMapWindow trickery is not good, use XSendEvent to send _NET_WM_STATE ClientMessage to rootwindow instead: 589 | setWindowStates(hw); 590 | sendStateClientMessage(hw,"FULLSCREEN",hw->options&FULLSCREEN?_NET_WM_STATE_ADD:_NET_WM_STATE_REMOVE); 591 | } //XMapWindow(hw->d,hw->w); XSync(hw->d,True); } 592 | 593 | void hideMouseCursor(hWindow *hw) //{ XUndefineCursor(hw->d,hw->w); } //XDefineCursor(hw->d,hw->w,None); } 594 | { 595 | XColor black; 596 | black.red=black.green=black.blue=0; 597 | static char emptydat[]= {0,0,0,0,0,0,0,0}; 598 | Pixmap emptypix=XCreateBitmapFromData(hw->d,hw->w,emptydat,8,8); 599 | Cursor blankcur=XCreatePixmapCursor(hw->d,emptypix,emptypix,&black,&black,0,0); 600 | XDefineCursor(hw->d,hw->w,blankcur); 601 | XFreeCursor(hw->d,blankcur); 602 | XFreePixmap(hw->d,emptypix); 603 | } 604 | 605 | //void setMouseCursor(hWindow *hw) { XColor fc, bc; Cursor cur=XCreatePixmapCursor(hw->d,icon,icon,&fc,&bc,1,1); XDefineCursor(hw->d,hw->w,cur);} 606 | 607 | hWindow* destroyWindow(hWindow *hw) 608 | { 609 | if(hw==NULL) return NULL; 610 | hWindow *parenthw=hw->parenthw; 611 | //#ifdef USE_XFT XftDrawDestroy(xftdraw); 612 | if(parenthw==NULL)XFreeGC(hw->d,hw->gc); 613 | XDestroyWindow(hw->d,hw->w); 614 | if(parenthw==NULL)XCloseDisplay(hw->d); 615 | else { 616 | parenthw->Child[hw->id]=NULL; 617 | } 618 | free(hw); 619 | return NULL; 620 | } 621 | 622 | void setClass(hWindow *hw, char *class, char *name) 623 | { 624 | if(hw==NULL) return; 625 | XClassHint *ch=XAllocClassHint(); 626 | ch->res_name=name; 627 | ch->res_class=class; 628 | XSetClassHint(hw->d,hw->w,ch); 629 | }; 630 | 631 | void setTitle(hWindow *hw, char *title) 632 | { 633 | if(hw==NULL) return; //XSetWMName(hw->d,hw->w,XTextProperty *text) 634 | XStoreName(hw->d,hw->w,title); 635 | XSetIconName(hw->d,hw->w,title); 636 | hw->title=title; 637 | } 638 | 639 | void setIconXPM(hWindow *hw, char *xpm[]) 640 | { 641 | if(hw==NULL) return; 642 | XPMstruct xpms=XPMtoPixels(xpm,TRANSPCOLOR); 643 | XImage *iconimg = XCreateImage(hw->d,CopyFromParent,DefaultDepth(hw->d,hw->s),ZPixmap,0,xpms.pixdata,xpms.width,xpms.height,XPM_DEPTH,0); //bitmap_pad: how much bits a colour is stored on 644 | XInitImage(iconimg); //pic->byte_order = LSBFirst; pic->bitmap_bit_order = LSBFirst; //The bitmap_bit_order doesn't matter with ZPixmap images. 645 | Pixmap icon=XCreatePixmap(hw->d,hw->w,xpms.width,xpms.height,DefaultDepth(hw->d,hw->s)); 646 | XPutImage(hw->d,icon,hw->gc,iconimg,0,0,0,0,xpms.width,xpms.height); //Pixmap icon=XCreatePixmapFromBitmapData(hw->d,hw->w,icon_pixels,ICON_WIDTH,ICON_HEIGHT,0xffffff,0,XPM_DEPTH); 647 | XWMHints *hints = XAllocWMHints(); 648 | hints->flags=IconPixmapHint; 649 | hints->icon_pixmap=icon; 650 | XSetWMHints(hw->d,hw->w,hints); 651 | XDestroyImage(iconimg); 652 | XUnmapWindow(hw->d,hw->w); 653 | XMapWindow(hw->d,hw->w); 654 | XFree(hints); 655 | XSync(hw->d,False); //XFlush(hw->d); //XUnmapWindow-XMapWindow - a dirty hack for JWM to refresh icon (XSync seems not enough. What about XSendEvent ClientMessage _NET_WM_ICON?) 656 | } 657 | 658 | //to get display-size (monitor-resolution), DisplayWidth(hw->d,hw->s) and DisplayHeight(hw->d,hw->s) can be used, or XGetGeometry() 659 | hWindow* getWin(void *widgetptr) 660 | { 661 | Widget* wp=widgetptr; 662 | return wp->parenthw; 663 | } 664 | int getScreenWidth() 665 | { 666 | Display *d=openDisplay(); 667 | return XDisplayWidth(d,DefaultScreen(d)); 668 | } 669 | int getScreenHeight() 670 | { 671 | Display *d=openDisplay(); 672 | return XDisplayHeight(d,DefaultScreen(d)); 673 | } 674 | int getWinWidth(hWindow *hw) 675 | { 676 | if(hw==NULL) return RET_ERR; 677 | XWindowAttributes xwa; 678 | XGetWindowAttributes(hw->d,hw->w,&xwa); 679 | return xwa.width; 680 | } 681 | int getWinHeight(hWindow *hw) 682 | { 683 | if(hw==NULL) return RET_ERR; 684 | XWindowAttributes xwa; 685 | XGetWindowAttributes(hw->d,hw->w,&xwa); 686 | return xwa.height; 687 | } 688 | int getWinX(hWindow *hw) 689 | { 690 | if(hw==NULL) return RET_ERR; 691 | XWindowAttributes xwa; 692 | int x,y; 693 | Window child; 694 | XTranslateCoordinates(hw->d,hw->w,RootWindow(hw->d,hw->s),0,0,&x,&y,&child); 695 | XGetWindowAttributes(hw->d,hw->w,&xwa); 696 | return x-xwa.x; 697 | } 698 | int getWinY(hWindow *hw) 699 | { 700 | if(hw==NULL) return RET_ERR; 701 | XWindowAttributes xwa; 702 | int x,y; 703 | Window child; 704 | XTranslateCoordinates(hw->d,hw->w,RootWindow(hw->d,hw->s),0,0,&x,&y,&child); 705 | XGetWindowAttributes(hw->d,hw->w,&xwa); 706 | return y-xwa.y; 707 | } 708 | int getWidgetCount(hWindow *hw) 709 | { 710 | if(hw==NULL) return RET_ERR; 711 | return hw->WidgetAmount; 712 | } 713 | 714 | char* getTitle (hWindow *hw) 715 | { 716 | if (hw==NULL) return (char*)EmptyString; 717 | char* charptr; 718 | XFetchName(hw->d,hw->w,&charptr); 719 | return charptr; 720 | } 721 | 722 | float getContrast (hWindow *hw) 723 | { 724 | if(hw==NULL) return RET_ERR; 725 | return hw->contrast; 726 | } 727 | void setContrast(hWindow *hw, float contrast) 728 | { 729 | if(hw==NULL) return; 730 | correctRange(&contrast); 731 | hw->contrast=contrast; 732 | refreshWindow(hw); 733 | } 734 | 735 | void setWinCallback (hWindow *hw, void (*callback)() ) 736 | { 737 | if(hw==NULL) return; 738 | hw->exitCallback=callback; 739 | } 740 | 741 | char eventButton (hWindow *hw) 742 | { 743 | if(hw==NULL) return RET_ERR; 744 | return hw->eventbutton; 745 | } 746 | int eventX (hWindow *hw) 747 | { 748 | if(hw==NULL) return RET_ERR; 749 | return hw->eventx; 750 | } 751 | int eventY (hWindow *hw) 752 | { 753 | if(hw==NULL) return RET_ERR; 754 | return hw->eventy; 755 | } 756 | 757 | unsigned long fadeCol(unsigned int col, float bri) //positive bri values cause brightening, negative values cause darkening 758 | { 759 | int r,g,b; 760 | if (bri==0.0) return col; 761 | if (bri<-1.0) bri=-1.0; 762 | if(bri>1.0) bri=1.0; //saturation logic for input 763 | else { 764 | r=(int)(((col&0xFF0000)/65536)*(1.0+bri)); 765 | g=(int)(((col&0xFF00)/256)*(1.0+bri)); 766 | b=(int)((col&0xFF)*(1.0+bri)); 767 | } 768 | if (r>255) r=255; 769 | if(g>255) g=255; 770 | if(b>255) b=255; 771 | if(r<0) r=0; 772 | if(g<0) g=0; 773 | if(b<0) b=0; //saturation logic for output 774 | return r*65536+g*256+b; 775 | } 776 | 777 | int roundfl (float num) 778 | { 779 | if (num>=0 && num-(int)num>=0.5) return ((int)num+1); 780 | else if (num<0 && num-(int)num<-0.5) return ((int)num)-1; 781 | else return (int)num; 782 | } 783 | 784 | int dynCoordX(hWindow *hw, int x) //turn negative X coordinate into dynamic coordinate (counted from right-edge of the window) 785 | { 786 | if(hw->options&ZOOMABLE) x=roundfl(x*((float)hw->width/(float)hw->orig_width)); 787 | if(x<0) return hw->width+x; 788 | else return x; 789 | } 790 | //these 2 functions also provide zooming if set for the window. 791 | int dynCoordY(hWindow *hw, int y) //turn negative Y coordinate into dynamic coordinate (counted from bottom-edge of the window) 792 | { 793 | if(hw->options&ZOOMABLE) y=roundfl(y*((float)hw->height/(float)hw->orig_height)); 794 | if(y<0) return hw->height+y; 795 | else return y; 796 | } 797 | //this sets the region where the widget is sensitive for mouse-click/scroll events 798 | int setActiveRegion(hWindow *hw, int id, int x1, int y1, int x2, int y2, char margin, int knobxy1, int knobxy2) 799 | { 800 | hw->W[id].actx1=x1; 801 | hw->W[id].acty1=y1; 802 | hw->W[id].actx2=x2; 803 | hw->W[id].acty2=y2; 804 | hw->W[id].margin=margin; 805 | hw->W[id].knobx1=knobxy1; 806 | hw->W[id].knobx2=knobxy2; 807 | } 808 | 809 | #if defined(HGUI_TEXTFIELDS) || defined(HGUI_TEXTBUTTONS) 810 | XFontStruct* loadFont(hWindow *hw, char *fontname) 811 | { 812 | //#ifdef USE_XFT return XftFontOpenName(hw->d,hw->s,"Arial-17"); 813 | if (fontname==NULL) return NULL; 814 | XFontStruct* fs = XLoadQueryFont(hw->d,fontname); 815 | if(fs==NULL) printf("%s Font %s not found! Using Xorg built-in 6x13 fixed font in place of it.\n",WarnPfx,fontname); //XLoadQueryFont returns NULL ('xfont' fallback) of font not found 816 | return fs; 817 | } 818 | 819 | XFontStruct* getFontStruct(hWindow *hw, char *fontname) 820 | { 821 | if(hw==NULL) return EmptyFontStruct; //should prevent redundand loading of fonts; also: only creating FontStruct for a new size of the same type 822 | return loadFont(hw,fontname); 823 | } 824 | 825 | GC setFontGC (hWindow *hw, unsigned long bgcol, unsigned long fgcol, XFontStruct *font) 826 | { 827 | if (font==NULL) { 828 | XSetBackground (hw->d,hw->defgc,bgcol); 829 | XSetForeground(hw->d,hw->defgc,fgcol); 830 | return hw->defgc; 831 | } else { 832 | XSetBackground (hw->d,hw->gc,bgcol); 833 | SETDRAWCOL(fgcol); 834 | XSetFont(hw->d,hw->gc,font->fid); 835 | } 836 | return hw->gc; 837 | } 838 | 839 | int getTextWidth(char *text, XFontStruct *font,int charcount) 840 | { 841 | if (font!=NULL) return XTextWidth(font,text,charcount); 842 | else return XBUILTINFONT_WIDTH*charcount; 843 | } 844 | 845 | TextDim getTextDimN (char *text, XFontStruct *font, int len) 846 | { 847 | TextDim dim; 848 | int dir,ascent,descent; 849 | XCharStruct overall; //XChar2b widetxt[]; // font->max_bounds.ascent; font->max_bounds.width ? 850 | //#ifdef USE_XFT XGlyphInfo extents; XftTextExtents8(hw->d,font,(XftChar8*)text,len,&extents); -> extents.width; extents.height; 851 | if (font!=NULL) { 852 | XTextExtents(font,text,len,&dir,&ascent,&descent,&overall); //printf("\n%d,%d,%s",overall.width,height,text); 853 | dim.h=ascent+descent; 854 | dim.w=overall.width; 855 | dim.ascent=ascent; 856 | dim.descent=descent; 857 | } else { 858 | dim.w=XBUILTINFONT_WIDTH*len; 859 | dim.h=XBUILTINFONT_HEIGHT; 860 | dim.ascent=XBUILTINFONT_ASCENT; 861 | dim.descent=XBUILTINFONT_DESCENT; 862 | } 863 | return dim; 864 | } 865 | 866 | TextDim getTextDim (char *text, XFontStruct *font) 867 | { 868 | return getTextDimN(text,font,strlen(text)); 869 | } 870 | #endif //textfields/buttons 871 | 872 | #ifdef HGUI_TEXTBLOCKS 873 | long findSpaceBack(char *text, long pos) 874 | { 875 | for(; pos>0; pos--) { 876 | if(text[pos]==' '||text[pos]=='\t') break; 877 | } 878 | return pos; 879 | } 880 | //long findNonSpaceBack(char *text, long pos) { for(;pos>0;pos--) {if(text[pos]!=' '&&text[pos]!='\t') break;} return pos; } 881 | #endif 882 | 883 | void setClipRegion(hWindow *hw, int x1, int y1, int x2, int y2) 884 | { 885 | XRectangle rectangle[1]; 886 | rectangle[0].x=x1, rectangle[0].y=y1, rectangle[0].width=x2-x1, rectangle[0].height=y2-y1; 887 | XSetClipRectangles(hw->d,hw->gc,0,0,rectangle,1,Unsorted); 888 | XSetClipRectangles(hw->d,hw->defgc,0,0,rectangle,1,Unsorted); 889 | } 890 | 891 | void removeClipRegion(hWindow *hw) 892 | { 893 | XGCValues gcval; //XGetGCValues(hw->d,gcontext,GCClipXOrigin|GCClipYOrigin|GCClipMask,&gcval); 894 | gcval.clip_x_origin=0; 895 | gcval.clip_y_origin=0; 896 | gcval.clip_mask=None; 897 | XChangeGC(hw->d,hw->gc,GCClipXOrigin|GCClipYOrigin|GCClipMask,&gcval); 898 | XChangeGC(hw->d,hw->defgc,GCClipXOrigin|GCClipYOrigin|GCClipMask,&gcval); 899 | } 900 | 901 | 902 | //-------------------------- Graphic Primitives ------------------------ 903 | #ifdef HGUI_PRIMITIVES 904 | void drawPoint(hWindow *hw, int x, int y, unsigned long col) 905 | { 906 | if(hw==NULL) return; 907 | DRAWPOINT(x,y,col); 908 | } 909 | 910 | void drawLine(hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col) 911 | { 912 | if(hw==NULL) return; 913 | SETDRAWCOL(col); 914 | DRAWLINE(x1,y1,x2,y2); 915 | } 916 | 917 | 918 | void drawArc(hWindow *hw, int x1, int y1, int x2, int y2, int startdeg, int degree, unsigned long col) 919 | { 920 | if(hw==NULL) return; 921 | SETDRAWCOL(col); 922 | DRAWARC(x1,y1,x2-x1,y2-y1,startdeg,degree); 923 | } 924 | 925 | void drawArcFill(hWindow *hw, int x1, int y1, int x2, int y2, int startdeg, int degree, unsigned long col) 926 | { 927 | if(hw==NULL) return; 928 | SETDRAWCOL(col); 929 | DRAWARCFILL(x1,y1,x2-x1,y2-y1,startdeg,degree); 930 | } 931 | 932 | void drawRect(hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col) 933 | { 934 | if(hw==NULL) return; 935 | SETDRAWCOL(col); 936 | DRAWRECT(x1,y1,x2-x1,y2-y1); 937 | } 938 | 939 | void drawRectFill(hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col) 940 | { 941 | if(hw==NULL) return; 942 | SETDRAWCOL(col); 943 | DRAWRECTFILL(x1,y1,x2-x1,y2-y1); 944 | } 945 | 946 | void drawCircle(hWindow *hw, int x, int y, int r, unsigned long col) 947 | { 948 | if(hw==NULL) return; 949 | SETDRAWCOL(col); 950 | DRAWARC(x-r,y-r,r*2,r*2,0,360); 951 | } 952 | void drawCircleFill(hWindow *hw, int x, int y, int r, unsigned long col) 953 | { 954 | if(hw==NULL) return; 955 | SETDRAWCOL(col); 956 | DRAWARCFILL(x-r,y-r,r*2,r*2,0,360); 957 | } 958 | 959 | void drawEllipse(hWindow *hw, int x, int y, int rx, int ry, unsigned long col) 960 | { 961 | if(hw==NULL) return; 962 | SETDRAWCOL(col); 963 | DRAWARC(x-rx,y-ry,rx*2,ry*2,0,360); 964 | } 965 | void drawEllipseFill(hWindow *hw, int x, int y, int rx, int ry, unsigned long col) 966 | { 967 | if(hw==NULL) return; 968 | SETDRAWCOL(col); 969 | DRAWARCFILL(x-rx,y-ry,rx*2,ry*2,0,360); 970 | } 971 | 972 | void drawPolygon(hWindow *hw, unsigned long col, char count, ...) //variadic function with ellipsis (...) as last parameter, taking 'count' number of parameters 973 | { 974 | if(hw==NULL) return; 975 | va_list arg; 976 | int i,x,y; 977 | va_start (arg, count); 978 | XPoint *points=malloc(count*sizeof(XPoint)); 979 | for (i=0; id,hw->w,hw->gc,points,count,Complex,CoordModeOrigin); 985 | free(points); 986 | } 987 | #endif //HGUI_PRIMITIVES 988 | 989 | 990 | //-------------------------- Basic widget drawing routines ----------------------------- 991 | #ifdef HGUI_PICTURES 992 | XImage* putPicture(hWindow *hw, int x, int y, char* pixeldata, int width, int height, int depth, int id) 993 | { 994 | //no scaling or colour conversion, the image-data must be prepared; transparency could be handled for images that have alpha channel 995 | XImage *pic = XCreateImage(hw->d,CopyFromParent,DefaultDepth(hw->d,hw->s),ZPixmap,0,pixeldata,width,height,(depth>=24)?32:16,0); //bitmap_pad: how much bits a colour is stored on, 32 for 24/32bit, 16 for 15/16bit 996 | XInitImage(pic); //pic->byte_order = LSBFirst; //pic->bitmap_bit_order = LSBFirst; //The bitmap_bit_order doesn't matter with ZPixmap images. 997 | XPutImage(hw->d,hw->w,hw->gc,pic,0,0,x,y,width,height); 998 | return pic; //XDestroyImage(pic); 999 | } 1000 | 1001 | //XImage* putScaledPicture(int x1, int y1, int x2, int y2, char* pixeldata, int orig_width, int orig_height, int orig_depth) 1002 | //{} //conversion between image-depth and visual-depth should happen here (also scaling-support can be done here) 1003 | 1004 | XPMstruct putXPM(hWindow *hw, int x, int y, char* xpm[], unsigned long bgcol, int id) 1005 | { 1006 | XPMstruct xpms=XPMtoPixels(xpm,bgcol); 1007 | XImage *img=putPicture(hw,x,y,xpms.pixdata,xpms.width,xpms.height,XPM_DEPTH,id); 1008 | XDestroyImage(img); 1009 | return xpms; //depth is always 32bit for XPM 1010 | } 1011 | #endif //HGUI_PICTURES 1012 | 1013 | #ifdef HGUI_TEXTLINES 1014 | TextDim drawCenText(hWindow *hw, int x, int y, int w, int h, char *text, unsigned long fgcol, XFontStruct *font) //draw text centered into x,y,w,h rectangle 1015 | { 1016 | //get dimensions of string to pos then shift text by needed amount to be aligned to center of bounding box given as parameters 1017 | TextDim dim = { 0 }; 1018 | if(text==NULL) return dim; 1019 | dim=getTextDim(text,font); 1020 | dim.x=x+(w-dim.w)/2; 1021 | dim.y=y+(h-dim.ascent)/2; 1022 | setClipRegion(hw,x,y,x+w,y+h); 1023 | DRAWSTRING(dim.x, dim.y+dim.ascent, text, fgcol, font); 1024 | removeClipRegion(hw); 1025 | //XCreateFontset(w->d,"fixed", 1026 | //XwcDrawString(hw->d,hw->w,font,setFontGC(hw,fgcol,font), x+(w-dim.w)/2, y+(h+dim.ascent)/2, text, strlen(text)); 1027 | return dim; 1028 | } //used for onerow-buttons //DRAWRECT(x+(w-overall.width)/2,y+(h-height)/2,overall.width,ascent-descent); 1029 | 1030 | void drawCaption(hWindow *hw, int x, int y, int w, char *caption, unsigned long captcol, XFontStruct *font, int id) 1031 | { 1032 | //y will be bottom of caption 1033 | if(caption==NULL || font==NULL) return; 1034 | TextDim dim=getTextDim(caption,font); 1035 | XDrawImageString(hw->d,hw->w,setFontGC(hw,hw->bgcol,captcol,font), x+(w-dim.w)/2, y-dim.descent-2, caption, strlen(caption)); 1036 | } 1037 | 1038 | void clearCaptionTrails(hWindow *hw, int x, int y, int w, char *caption, XFontStruct *font, int id, Bool FullClear) 1039 | { 1040 | int x1,y1,x1o,y1o,wo; 1041 | if(caption==NULL || font==NULL) return; 1042 | TextDim dim=getTextDim(caption,font); 1043 | x1=x+(w-dim.w)/2; 1044 | y1=y-dim.h-2; 1045 | wo=hw->W[id].actx2-hw->W[id].actx1; 1046 | x1o = hw->W[id].actx1+(wo-dim.w)/2; 1047 | y1o=hw->W[id].acty1-dim.h-2; 1048 | if(!FullClear) cleanUpRect(hw, x1o, y1o, x1o+dim.w, y1o+dim.h, x1, y1, x1+dim.w, y1+dim.h); 1049 | else XClearArea(hw->d,hw->w,x1,y1,dim.w,dim.h,False); //SETDRAWCOL(0x000000); DRAWRECT(x1o,y1o,dim.w,dim.h); SETDRAWCOL(0xff0000); DRAWRECT(x1,y1,dim.w,dim.h); 1050 | } 1051 | 1052 | void drawTextCent(hWindow *hw, int x1, int y1, int x2, int y2, char *text, unsigned long fgcol, XFontStruct *font, int id) 1053 | { 1054 | TextDim dim=drawCenText(hw,x1,y1,x2-x1,y2-y1,text,fgcol,font); 1055 | setActiveRegion(hw,id,dim.x,dim.y,dim.x+dim.w,dim.y+dim.h,0,0,0); 1056 | } 1057 | 1058 | TextDim drawTextLine(hWindow *hw, int x, int y, int h, char *text, unsigned long fgcol, XFontStruct *font) //if doesn't fit into h, not drawing 1059 | { 1060 | //XTextItem *xp,xtext; xp=&xtext; xtext.font=defont->fid; xtext.chars="apadanyad\naniad"; xtext.nchars=strlen(xtext.chars); XDrawText(hw->d,hw->w,hw->gc,x1+4,y1+16,xp,1); 1061 | //#ifdef USE_XFT XftColorAllocValue(hw->d,DefaultVisual(hw->d,hw->s),DefaultColormap(hw->d,hw->s),&xrcolor,&xftcolor); XftDrawString8(xftdraw,&xftcolor,xftfont,x,y,(XftChar8*)text,strlen(text)); 1062 | TextDim dim=getTextDim(text,font); //XDrawText (allows more strings with more fonts & encodings), 1063 | if (h>0) { 1064 | DRAWSTRING(x,y+dim.ascent,text,fgcol,font); //if (dim.h<=h && 1065 | } 1066 | return dim; //info to know where to place next row,etc. ,XDrawImageString, XmbDrawText, XwcDrawText (wide-char), XmbDrawString (multibyte), XTextProperty, Xutf8DrawString (utf-8) 1067 | } 1068 | #endif //HGUI_TEXTLINES 1069 | 1070 | #ifdef HGUI_TEXTBLOCKS 1071 | TextBoxDim drawTextBlock(hWindow *hw, int x1, int y1, int x2, int y2, char *text, unsigned long fgcol, char wrap, int hpos, long vpos, XFontStruct *font, char countallrows, char checkfullwidth) 1072 | { 1073 | if (wrap) { 1074 | checkfullwidth=0; 1075 | hpos=0; 1076 | } 1077 | long ptr,i,pixrow; 1078 | char textstart,textend; 1079 | int j,txtwidth,linestart,xoffset,croppos,fullrowsize=0,w,h; 1080 | static char linebuf[LINESIZE_MAX]; 1081 | TextDim linedim; 1082 | TextBoxDim dim; 1083 | w=x2-x1; 1084 | h=y2-y1; 1085 | ptr=0; 1086 | i=xoffset=linestart=0; 1087 | dim.rowcount=0; 1088 | dim.w=0; 1089 | dim.h=0; 1090 | pixrow=0; 1091 | croppos=LINESIZE_MAX; 1092 | textstart=0; 1093 | textend=0; 1094 | linebuf[0]='\0'; 1095 | setClipRegion(hw,x1,y1,x2,y2); 1096 | while(ptrd,hw->gc,x,y,rectangle,1,Unsorted); 1097 | if (textstart==0) { 1098 | if (dim.rowcount>=vpos) textstart=1; //check when reached vertical pos inside the text to display 1099 | dim.vpixpos=dim.h; 1100 | } 1101 | if (textend==0 && pixrow>=h) { 1102 | if(countallrows) textend=1; //check vertical overflow 1103 | else break; 1104 | } 1105 | txtwidth=getTextWidth(linebuf,font,i); 1106 | if(txtwidth0 && linebuf[wrap?i-1:i]!=' ' && croppos==LINESIZE_MAX && txtwidth>=w+hpos) { 1111 | if(i<2)break; //check horizontal overflow, handle wrapping or tell 'croppos' 1112 | else croppos=wrap?i-1:i; 1113 | } 1114 | if (text[ptr]=='\0' || text[ptr]=='\n' || text[ptr]=='\r' || (wrap && croppos!=LINESIZE_MAX) ) { //check end of text and newlines 1115 | if(!wrap && checkfullwidth) { 1116 | fullrowsize=getTextWidth(linebuf,font,i); //check for longest row 1117 | if (dim.w < fullrowsize) dim.w=fullrowsize; 1118 | } 1119 | if (croppos==LINESIZE_MAX) linebuf[i]='\0'; 1120 | else { 1121 | linebuf[croppos]='\0'; 1122 | if(wrap) if (i=findSpaceBack(linebuf,croppos)) { 1123 | linebuf[i]='\0'; 1124 | ptr=findSpaceBack(text,ptr-2)+1; 1125 | } else ptr-=1; 1126 | } 1127 | linedim=drawTextLine(hw,x1+xoffset,y1+pixrow,(textstart&&!textend)?h-pixrow:0,linebuf+linestart,fgcol,font); 1128 | dim.h+=linedim.h; 1129 | dim.rowcount++; 1130 | if(textstart) pixrow+=linedim.h; 1131 | if(!checkfullwidth) { 1132 | if (dim.w < linedim.w) dim.w = linedim.w; //check for longest visible row 1133 | } 1134 | if (text[ptr]=='\0') break; 1135 | else if (text[ptr]=='\n' && text[ptr+1]=='\r' || text[ptr]=='\r' && text[ptr+1]=='\n') ptr++; //check CR+LF combined newlines 1136 | if (!wrap || croppos==LINESIZE_MAX) ptr++; 1137 | i=xoffset=linestart=0; 1138 | croppos=LINESIZE_MAX; 1139 | } else if (text[ptr]=='\t') { //check TAB whitespace 1140 | for(j=0; jbgcol,-hw->contrast*1.6),bordercol2=bordercol1, statey=(state&&bevel>1)?1:0; 1157 | if (state) { 1158 | shinecol=fadeCol(bgcol,-hw->contrast*0.01); 1159 | shadowcol=fadeCol(bgcol,-hw->contrast-BUTTFADE); 1160 | bodycol=fadeCol(bgcol,-BUTTFADE); 1161 | textcol=fadeCol(fgcol,-BUTTFADE); 1162 | } else { 1163 | shinecol=fadeCol(bgcol,hw->contrast); 1164 | shadowcol=fadeCol(bgcol,-hw->contrast); 1165 | bodycol=bgcol; 1166 | textcol=fgcol; 1167 | bordercol2=fadeCol(hw->bgcol,-hw->contrast*2); 1168 | } 1169 | SETDRAWCOL(bodycol); 1170 | DRAWRECTFILL(x+bevel,y+bevel+statey,w-bevel*2+1,h-bevel*2+1); 1171 | SETDRAWCOL(shinecol); 1172 | for(i=0; icontrast*0.5)); 1183 | DRAWLINE(x,y,x+w,y); 1184 | DRAWLINE(x,y,x,y+h); 1185 | } 1186 | for(i=0; i1)?1:0); //printf("\n%d,%d,%d,%d,%d\n",y,h,xpms.height,picx,picy); 1204 | setClipRegion(hw,x,y,x+w,y+h); 1205 | XImage *img=putPicture(hw,picx,picy,xpms.pixdata,xpms.width,xpms.height,XPM_DEPTH,id); 1206 | removeClipRegion(hw); 1207 | XDestroyImage(img); //depth is always 32bit for XPM 1208 | } 1209 | #endif //HGUI_PICBUTTONS 1210 | #endif //HGUI_BUTTONS 1211 | 1212 | #ifdef HGUI_SLIDERS 1213 | void drawVSlider(hWindow *hw, int x, int y, int w, int y2, char knobsize, char scalewidth, char *caption, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, unsigned long captcol, float pos, float scale , XFontStruct *font, int id) 1214 | { 1215 | float i; 1216 | int h=y2-y, sy, middle=x+w/2, knobsizey=knobsize*0.65, vmargin=knobsizey/2+4, range=h-vmargin*2; 1217 | int knobx=middle-knobsize/2, knobmiddley=y+vmargin+(1-pos)*range, knoby=knobmiddley-knobsizey/2, sx=middle-scalewidth/2; 1218 | if (knobsize>w) XClearArea(hw->d,hw->w,knobx,y,knobsize,y2-y,False); 1219 | if(bgcol!=hw->bgcol) { 1220 | SETDRAWCOL(bgcol); 1221 | DRAWRECTFILL(x,y,w,h); 1222 | } 1223 | if(h>2*vmargin) { 1224 | if (scale>0) { 1225 | SETDRAWCOL(fgcol); 1226 | for(i=0; i<1.0; i+=scale) { 1227 | sy=y+range+vmargin-range*i-1; 1228 | DRAWLINE(sx,sy,sx+scalewidth,sy); 1229 | } 1230 | } 1231 | SETDRAWCOL(fadeCol(bgcol,-hw->contrast*1.8)); 1232 | DRAWRECTFILL(middle-SLIDERHOLE/2,y+vmargin,SLIDERHOLE,range); 1233 | } 1234 | SETDRAWCOL(knobcol); 1235 | DRAWRECTFILL(knobx,knoby,knobsize,knobsizey); 1236 | SETDRAWCOL(fadeCol(knobcol,hw->contrast)); 1237 | DRAWRECTFILL(knobx+2,knobmiddley-1,knobsize-4,2); 1238 | SETDRAWCOL(fadeCol(knobcol,hw->contrast)); 1239 | DRAWLINE(knobx,knoby-1,knobx+knobsize-1,knoby-1); 1240 | DRAWLINE(knobx-1,knoby,knobx-1,knoby+knobsizey-1); 1241 | SETDRAWCOL(fadeCol(knobcol,-hw->contrast)); 1242 | DRAWLINE(knobx,knoby+knobsizey,knobx+knobsize-1,knoby+knobsizey); 1243 | DRAWLINE(knobx+knobsize,knoby,knobx+knobsize,knoby+knobsizey-1); 1244 | setActiveRegion(hw,id, knobsize>w?knobx:x, y, knobsize>w?knobx+knobsize:x+w, y2, vmargin,knoby,knoby+knobsize); 1245 | drawCaption(hw,x,y,w,caption,captcol,font,id); 1246 | } 1247 | 1248 | void drawHSlider(hWindow *hw, int x, int y, int x2, int h, char knobsize, char scalewidth, char *caption, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, unsigned long captcol, float pos, float scale , XFontStruct *font, int id) 1249 | { 1250 | float i; 1251 | int w=x2-x, sx, middle=y+h/2, knobsizex=knobsize*0.65, hmargin=knobsizex/2+4, range=w-hmargin*2; 1252 | int knoby=middle-knobsize/2, knobmiddlex=x+hmargin+(1-pos)*range, knobx=knobmiddlex-knobsizex/2, sy=middle-scalewidth/2; 1253 | if (knobsize>h) XClearArea(hw->d,hw->w,x,knoby,x2-x,knobsize,False); 1254 | if(bgcol!=hw->bgcol) { 1255 | SETDRAWCOL(bgcol); 1256 | DRAWRECTFILL(x,y,w,h); 1257 | } 1258 | if(w>2*hmargin) { 1259 | if (scale>0) { 1260 | SETDRAWCOL(fgcol); 1261 | for(i=0; i<1.0; i+=scale) { 1262 | sx=x+range+hmargin-range*i-1; 1263 | DRAWLINE(sx,sy,sx,sy+scalewidth); 1264 | } 1265 | } 1266 | SETDRAWCOL(fadeCol(bgcol,-hw->contrast*1.8)); 1267 | DRAWRECTFILL(x+hmargin,middle-SLIDERHOLE/2,range,SLIDERHOLE); 1268 | } 1269 | SETDRAWCOL(knobcol); 1270 | DRAWRECTFILL(knobx,knoby,knobsizex,knobsize); 1271 | SETDRAWCOL(fadeCol(knobcol,hw->contrast)); 1272 | DRAWRECTFILL(knobmiddlex-1,knoby+2,2,knobsize-4); 1273 | SETDRAWCOL(fadeCol(knobcol,hw->contrast)); 1274 | DRAWLINE(knobx-1,knoby,knobx-1,knoby+knobsize-1); 1275 | DRAWLINE(knobx,knoby-1,knobx+knobsizex-1,knoby-1); 1276 | SETDRAWCOL(fadeCol(knobcol,-hw->contrast)); 1277 | DRAWLINE(knobx+knobsizex,knoby,knobx+knobsizex,knoby+knobsize-1); 1278 | DRAWLINE(knobx,knoby+knobsize,knobx+knobsizex-1,knoby+knobsize); 1279 | setActiveRegion(hw,id, x, knobsize>h?knoby:y, x2, knobsize>h?knoby+knobsize:y+h, hmargin,knobx,knobx+knobsize); 1280 | drawCaption(hw,x,y,w,caption,captcol,font,id); 1281 | } 1282 | #endif //HGUI_SLIDERS 1283 | 1284 | #ifdef HGUI_PROGBARS 1285 | void drawHProgBar(hWindow *hw, int x, int y, int x2, int y2, char bevel, char *caption, unsigned long bgcol, unsigned long fgcol, unsigned long textcol, unsigned long captcol, float pos, float scale, XFontStruct *font, int id) 1286 | { 1287 | int w=x2-x,h=y2-y, i, length=(w-bevel*2)*pos; 1288 | char percent[16]; 1289 | TextDim dim; 1290 | if (scale==0 || w<=(int)(2.0/scale)) { 1291 | SETDRAWCOL(bgcol); 1292 | DRAWRECTFILL(x+bevel+length,y+bevel,w-length-bevel*2+1,h-bevel*2+1); 1293 | SETDRAWCOL(fgcol); 1294 | DRAWRECTFILL(x+bevel,y+bevel,length,h-bevel*2+1); 1295 | } else { 1296 | SETDRAWCOL(bgcol); 1297 | DRAWRECTFILL(x+bevel,y+bevel,w-bevel*2+1,h-bevel*2+1); 1298 | SETDRAWCOL(fgcol); 1299 | for(i=0; i<=length-w*scale+1; i+=w*scale) DRAWRECTFILL(x+i+2,y+bevel+1,w*scale-1,h-bevel*2-1); 1300 | } 1301 | SETDRAWCOL(fadeCol(bgcol,-hw->contrast)); 1302 | for(i=0; icontrast)); 1307 | for(i=0; icontrast)); 1336 | for(i=0; icontrast)); 1341 | for(i=0; ix2)?dim.x+dim.w:x2, y2, 0,0,0); 1350 | drawCaption(hw,x,y,w,caption,captcol,font,id); 1351 | } 1352 | #endif //HGUI_PROGBARS 1353 | 1354 | #ifdef HGUI_BLOCKS 1355 | void drawBlock(hWindow *hw, int x1, int y1, int x2, int y2) 1356 | { 1357 | SETDRAWCOL(fadeCol(hw->bgcol,hw->contrast)); 1358 | DRAWLINE(x1,y1+1,x2,y1+1); 1359 | DRAWLINE(x1+1,y2+1,x2,y2+1); 1360 | DRAWLINE(x1+1,y1,x1+1,y2); 1361 | DRAWLINE(x2+1,y1+1,x2+1,y2+1); 1362 | SETDRAWCOL(fadeCol(hw->bgcol,-hw->contrast)); 1363 | DRAWLINE(x1,y1,x2-1,y1); 1364 | DRAWLINE(x1,y2,x2,y2); 1365 | DRAWLINE(x1,y1,x1,y2); 1366 | DRAWLINE(x2,y1,x2,y2); 1367 | } 1368 | 1369 | void drawBlockFill(hWindow *hw, int x1, int y1, int x2, int y2, unsigned long color) 1370 | { 1371 | drawBlock(hw,x1-1,y1-1,x2,y2); 1372 | SETDRAWCOL(color); 1373 | DRAWRECTFILL(x1,y1,x2-x1,y2-y1); 1374 | } 1375 | #endif //HGUI_BLOCKS 1376 | 1377 | #ifdef HGUI_SCROLLBARS 1378 | void drawVScroll(hWindow *hw, int x, int y, int w, int y2, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, float pos, float ratio, char press, int id) 1379 | { 1380 | if (ratio>=1.0) ratio=1.0; 1381 | if (pos<0||pos>=1.0) pos=0; 1382 | int i, h=y2-y, knobarea=h-SCROLLBUTTSIZE*2, knobsize=knobarea*ratio, knoby=y+SCROLLBUTTSIZE+pos*knobarea, butt2y=y2-SCROLLBUTTSIZE; 1383 | XPoint downarrow[3],uparrow[3]; 1384 | drawBlockFill(hw,x,y,x+w,y+h,bgcol); 1385 | SETDRAWCOL(fadeCol(knobcol,press&1?-BUTTFADE:0)); 1386 | DRAWRECTFILL(x+1,y+1,w-2,SCROLLBUTTSIZE-1); 1387 | SETDRAWCOL(fadeCol(knobcol,press&2?-BUTTFADE:0)); 1388 | DRAWRECTFILL(x+1,butt2y-1,w-2,SCROLLBUTTSIZE); //XSetFillStyle(hw->d,hw->gc,FillStippled); 1389 | if(knoby+knobsize>butt2y) knobsize=butt2y-knoby; 1390 | if(knobsize<3)knobsize=3; 1391 | if(knobarea>2) { 1392 | SETDRAWCOL(knobcol); 1393 | DRAWRECTFILL(x+1,knoby,w-2,knobsize-2); 1394 | } 1395 | SETDRAWCOL(fadeCol(knobcol,hw->contrast)); 1396 | if(knobarea>2) DRAWLINE(x+1,knoby+1,x+w-2,knoby+1); 1397 | if((press&2)==0)DRAWLINE(x+1,butt2y,x+w-2,butt2y); 1398 | if((press&1)==0)DRAWLINE(x+2,y+1,x+w-3,y+1); 1399 | SETDRAWCOL(fadeCol(knobcol,-hw->contrast)); 1400 | if(knobarea>2) DRAWLINE(x+1,knoby+knobsize-1,x+w-1,knoby+knobsize-1); 1401 | if((press&1)==0) DRAWLINE(x+1,y+SCROLLBUTTSIZE+1,x+w-1,y+SCROLLBUTTSIZE+1); 1402 | for (i=0; i<3; i++) { 1403 | uparrow[i].x=x+w/2+UpArrowPoints[i*2]; 1404 | uparrow[i].y=y+UpArrowPoints[i*2+1]; 1405 | downarrow[i].x=x+w/2+DownArrowPoints[i*2]; 1406 | downarrow[i].y=butt2y+DownArrowPoints[i*2+1]; 1407 | } 1408 | SETDRAWCOL(pos+ratio<1.0?fgcol:fadeCol(knobcol,-0.2)); 1409 | XFillPolygon(hw->d,hw->w,hw->gc,downarrow,3,Convex,CoordModeOrigin); 1410 | SETDRAWCOL(pos>0?fgcol:fadeCol(knobcol,-0.2)); 1411 | XFillPolygon(hw->d,hw->w,hw->gc,uparrow,3,Convex,CoordModeOrigin); 1412 | setActiveRegion(hw,id,x,y,x+w,y2,0,knoby,knoby+knobsize); //printf("%f,%f\n",pos,ratio); 1413 | } 1414 | 1415 | void drawHScroll(hWindow *hw, int x, int y, int x2, int h, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, float pos, float ratio, char press, int id) 1416 | { 1417 | if (ratio>=1.0) ratio=1.0; 1418 | if (pos<0||pos>=1.0) pos=0; 1419 | int i, w=x2-x, knobarea=w-SCROLLBUTTSIZE*2, knobsize=knobarea*ratio, knobx=x+SCROLLBUTTSIZE+pos*knobarea, butt2x=x2-SCROLLBUTTSIZE; 1420 | XPoint rightarrow[3], leftarrow[3]; 1421 | drawBlockFill(hw,x,y,x+w,y+h,bgcol); 1422 | SETDRAWCOL(fadeCol(knobcol,press&1?-BUTTFADE:0)); 1423 | DRAWRECTFILL(x+1,y+1,SCROLLBUTTSIZE-1,h-2); 1424 | SETDRAWCOL(fadeCol(knobcol,press&2?-BUTTFADE:0)); 1425 | DRAWRECTFILL(butt2x-1,y+1,SCROLLBUTTSIZE,h-2); 1426 | if(knobx+knobsize>butt2x) knobsize=butt2x-knobx; 1427 | if(knobsize<3)knobsize=3; 1428 | if(knobarea>2) { 1429 | SETDRAWCOL(knobcol); 1430 | DRAWRECTFILL(knobx,y+1,knobsize-2,h-2); 1431 | } 1432 | SETDRAWCOL(fadeCol(knobcol,hw->contrast)); 1433 | if(knobarea>2) DRAWLINE(knobx+1,y+1,knobx+1,y+h-2); 1434 | if((press&2)==0)DRAWLINE(butt2x,y+1,butt2x,y+h-2); 1435 | if((press&1)==0)DRAWLINE(x+1,y+2,x+1,y+h-3); 1436 | SETDRAWCOL(fadeCol(knobcol,-hw->contrast)); 1437 | if(knobarea>2) DRAWLINE(knobx+knobsize-1,y+1,knobx+knobsize-1,y+h-1); 1438 | if((press&1)==0) DRAWLINE(x+SCROLLBUTTSIZE+1,y+1,x+SCROLLBUTTSIZE+1,y+h-1); 1439 | for (i=0; i<3; i++) { 1440 | leftarrow[i].x=x+LeftArrowPoints[i*2]; 1441 | leftarrow[i].y=y+h/2+LeftArrowPoints[i*2+1]; 1442 | rightarrow[i].x=butt2x+RightArrowPoints[i*2]; 1443 | rightarrow[i].y=y+h/2+RightArrowPoints[i*2+1]; 1444 | } 1445 | SETDRAWCOL(pos+ratio<1.0?fgcol:fadeCol(knobcol,-0.2)); 1446 | XFillPolygon(hw->d,hw->w,hw->gc,rightarrow,3,Convex,CoordModeOrigin); 1447 | SETDRAWCOL(pos>0?fgcol:fadeCol(knobcol,-0.2)); 1448 | XFillPolygon(hw->d,hw->w,hw->gc,leftarrow,3,Convex,CoordModeOrigin); 1449 | setActiveRegion(hw,id,x,y,x2,y+h,0,knobx,knobx+knobsize); //printf("%f,%f\n",pos,ratio); 1450 | } 1451 | #endif //HGUI_SCROLLBARS 1452 | 1453 | 1454 | 1455 | //------------- composite widgets made from other widgets -------------- 1456 | #ifdef HGUI_TEXTBOXES 1457 | void drawTextBox(hWindow *hw, int x1, int y1, int x2, int y2, char *content, unsigned long bgcol, unsigned long fgcol, char wrap, char scrollbars, long vpos, int hpos, XFontStruct *font, int id, Widget *vscroll, Widget *hscroll) 1458 | { 1459 | //composite widget (textblock + scrollbars if requested) 1460 | long pixrows; 1461 | int w,h; 1462 | TextBoxDim dim; 1463 | if(wrap) hpos=0; 1464 | w=x2-x1; 1465 | h=y2-y1; 1466 | drawBlockFill(hw,x1,y1,x2,y2,bgcol); 1467 | dim=drawTextBlock(hw,x1+1,y1+1,x2-1,y2-1,content,fgcol,wrap,hpos,vpos,font,scrollbars&1,scrollbars&2); //printf("\n---%d-%d-%d---%s\n",dim.w,dim.h,dim.rowcount,content); 1468 | setActiveRegion(hw,id,x1,y1,x2,y2,0,0,0); 1469 | hw->W[id].vpixpos=dim.vpixpos; 1470 | hw->W[id].vpixsize=dim.h; 1471 | hw->W[id].hpixsize=dim.w; 1472 | if(scrollbars&1) { 1473 | vscroll->pos=(float)dim.vpixpos/(float)dim.h; 1474 | vscroll->ratio=h/(float)dim.h ; 1475 | refreshWidget(vscroll); 1476 | } 1477 | if(scrollbars&2) { 1478 | hscroll->pos=(float)hpos/(float)dim.w; //printf("%d,%d\n",dim.vpixpos,dim.h); 1479 | hscroll->ratio=w/(float)dim.w ; 1480 | refreshWidget(hscroll); 1481 | } 1482 | } 1483 | //void drawTextBox(int x1, int y1, int x2, int y2, char *content, int pos) {drawTextBox(x1,y1,x2,y2,content,BGCOLOR,FGCOLOR,1,1,pos,DEFAULTFONT) } 1484 | #endif //HGUI_TEXTBOXES 1485 | 1486 | //inputfield,list,radiobutton/checkbutton,tab,menu/pulldown-menu,colorchooser,filedialog... 1487 | 1488 | #ifdef HGUI_FILEBROWSER 1489 | void filedialog() //composite widget (made from textboxes,scrollbar,buttons,etc.) 1490 | { 1491 | 1492 | } 1493 | #endif //HGUI_FILEBROWSER 1494 | 1495 | 1496 | 1497 | 1498 | //-------------------------- widget adder routines --------------------- 1499 | void emptyCallback() {} //NULL can be used if safely handled in safeCallback() 1500 | 1501 | Widget* denyWidget(char type, char* text) 1502 | { 1503 | char name[16]; 1504 | int i,j=0; 1505 | if(text!=NULL) { 1506 | for(i=j=0; i<16; i++) if(text[i]!='\n' && text[i]!='\r') { 1507 | name[j]=text[i]; //strncpy(name,text,16); 1508 | j++; 1509 | } 1510 | } 1511 | name[j]='\0'; 1512 | printf("%s Window doesn't exist. Not adding widget of type %d with text/content: \"%s...\"\n",ErrPfx,type,name); 1513 | return EmptyWidget; 1514 | } 1515 | 1516 | void* addWidget(hWindow *hw, char type, int x, int y, int x2w, int y2h, int zh, long zv, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, unsigned long captcol, 1517 | void *data, float pos, float ratio, char state, char opt1, char opt2, char opt3, XFontStruct *fsp, void (*callback)(), void* argptr ) 1518 | { 1519 | if(hw==NULL) return denyWidget(type,data); 1520 | int L=hw->WidgetAmount; 1521 | if(L>=WIDGET_AMOUNT_MAX) { 1522 | printf("%s Cannot add more widgets, reached the maximum %d. (Check WIDGET_AMOUNT_MAX in hgui.c)\n",ErrPfx,WIDGET_AMOUNT_MAX); 1523 | return NULL; 1524 | } 1525 | hw->W[L].type=type; 1526 | hw->W[L].x=x; 1527 | hw->W[L].y=y; 1528 | hw->W[L].x2w=x2w; 1529 | hw->W[L].y2h=y2h; 1530 | hw->W[L].zh=zh; 1531 | hw->W[L].zv=zv; 1532 | hw->W[L].bgcol=bgcol; 1533 | hw->W[L].fgcol=fgcol; 1534 | hw->W[L].knobcol=knobcol; 1535 | hw->W[L].captcol=captcol; 1536 | hw->W[L].data=data; 1537 | hw->W[L].pos=pos; 1538 | hw->W[L].ratio=ratio; 1539 | hw->W[L].state=state; 1540 | hw->W[L].opt1=opt1; 1541 | hw->W[L].opt2=opt2; 1542 | hw->W[L].opt3=opt3; 1543 | hw->W[L].fsp=fsp; 1544 | hw->W[L].callback=callback; 1545 | hw->W[L].actx1=hw->W[L].acty1=hw->W[L].actx2=hw->W[L].acty2=hw->W[L].hpixsize=hw->W[L].knobx1=hw->W[L].knobx2=0; 1546 | hw->W[L].id=L; 1547 | hw->W[L].parenthw=hw; 1548 | hw->W[L].argptr=argptr; 1549 | hw->W[L].parentbox=NULL; 1550 | return &hw->W[hw->WidgetAmount++]; 1551 | } //init actx1,acty1,actx2,acty2 to 0, drawAllWidgets() widget-routines will init/refresh them 1552 | 1553 | #ifdef HGUI_BUTTONS 1554 | #ifdef HGUI_TEXTBUTTONS 1555 | Button* addButton(hWindow *hw, int x, int y, int w, int h, char *title, unsigned long bgcol, unsigned long fgcol, char state, char bevel, char border, char *font, void (*callback)(), void* argptr ) 1556 | { 1557 | return addWidget(hw,BUTTON,x,y,w,h,border,bevel,bgcol,fgcol,0,0, title,0,0,state,0,0,0,getFontStruct(hw,font),callback,argptr); 1558 | } 1559 | ButtonDyn* addButtonDyn(hWindow *hw, int x1, int y1, int x2, int y2, char *title, unsigned long bgcol, unsigned long fgcol, char state, char bevel, char border, char *font, void (*callback)(), void* argptr ) 1560 | { 1561 | return addWidget(hw,BUTTONDYN,x1,y1,x2,y2,border,bevel,bgcol,fgcol,0,0, title,0,0,state,0,0,0,getFontStruct(hw,font),callback,argptr); 1562 | } 1563 | #endif //HGUI_TEXTBUTTONS 1564 | #ifdef HGUI_PICBUTTONS 1565 | ButtonXPM* addButtonXPM(hWindow *hw, int x, int y, int w, int h, char *xpm[], unsigned long bgcol, char state, char bevel, char border, void (*callback)(), void* argptr ) 1566 | { 1567 | return addWidget(hw,BUTTONXPM,x,y,w,h,border,bevel,bgcol,0,0,0, (char*)xpm,0,0,state,0,0,0,NULL,callback,argptr); 1568 | } 1569 | #endif //HGUI_PICBUTTONS 1570 | #endif //HGUI_BUTTONS 1571 | #ifdef HGUI_SLIDERS 1572 | VSlider* addVSlider(hWindow *hw, int x, int y1, int w, int y2, char knobsize, char scalewidth, char *caption, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, unsigned long captcol, float pos, float scale, char *font, void (*callback)(), void* argptr ) 1573 | { 1574 | return addWidget(hw,VSLIDER,x,y1,w,y2,knobsize,scalewidth,bgcol,fgcol,knobcol,captcol, caption,pos,scale,0,0,0,0,getFontStruct(hw,font),callback,argptr); 1575 | } 1576 | HSlider* addHSlider(hWindow *hw, int x1, int y, int x2, int h, char knobsize, char scalewidth, char *caption, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, unsigned long captcol, float pos, float scale, char *font, void (*callback)(), void* argptr ) 1577 | { 1578 | return addWidget(hw,HSLIDER,x1,y,x2,h,knobsize,scalewidth,bgcol,fgcol,knobcol,captcol, caption,pos,scale,0,0,0,0,getFontStruct(hw,font),callback,argptr); 1579 | } 1580 | #endif //HGUI_SLIDERS 1581 | #ifdef HGUI_TEXTFIELDS 1582 | #ifdef HGUI_TEXTLINES 1583 | TextLine* addTextLine(hWindow *hw, int x, int y, char *text, unsigned long color, char *font) 1584 | { 1585 | return addWidget(hw,TEXTLINE,x,y,0,0,0,0,0x000000,color,0,0, text,0,0,0,0,0,0,getFontStruct(hw,font),emptyCallback,NULL); 1586 | } 1587 | TextCentered* addTextCentered(hWindow *hw, int x1, int y1, int x2, int y2, char *text, unsigned long color, char *font) 1588 | { 1589 | return addWidget(hw,TEXTCENTER,x1,y1,x2,y2,0,0,0x000000,color,0,0, text,0,0,0,0,0,0,getFontStruct(hw,font),emptyCallback,NULL); 1590 | } 1591 | #endif //HGUI_TEXTLINES 1592 | #ifdef HGUI_TEXTBLOCKS 1593 | TextBlock* addTextBlock(hWindow *hw, int x1, int y1, int x2, int y2, char *text, unsigned long color, char wrap, char *font) 1594 | { 1595 | return addWidget(hw,TEXTBLOCK,x1,y1,x2,y2,0,0,0x000000,color,0,0, text,0,0,0,wrap,0,0,getFontStruct(hw,font),emptyCallback,NULL); 1596 | } 1597 | #ifdef HGUI_TEXTBOXES 1598 | TextBox* addTextBox(hWindow *hw, int x1, int y1, int x2, int y2, char *content, unsigned long bgcol, unsigned long fgcol, char wrap, char scrollbars, char autofit, long vpos, int hpos, char *font) 1599 | { 1600 | if(hw==NULL) return denyWidget(TEXTBOX,content); 1601 | TextBox* wp=addWidget(hw,TEXTBOX,x1,y1,(scrollbars&1)?x2-SCROLLBUTTSIZE-3:x2,(scrollbars&2)?y2-SCROLLBUTTSIZE-3:y2,hpos,vpos,bgcol,fgcol,0,0, content,0,0,0,wrap,scrollbars,autofit,getFontStruct(hw,font),emptyCallback,NULL); 1602 | if (scrollbars&2) { 1603 | Widget *hs=addWidget(hw,HSCROLL,x1,y2-SCROLLBUTTSIZE,x2-SCROLLBUTTSIZE-3,SCROLLBUTTSIZE,0,0,SCROLLBGCOL,SCROLLFGCOL,SCROLLKNOBCOL,0, NULL,0.0,0.0,0+0,0,0,0,NULL,emptyCallback,NULL); 1604 | wp->hscroll=hs; 1605 | hs->parentbox=wp; 1606 | } 1607 | if (scrollbars&1) { 1608 | Widget *vs=addWidget(hw,VSCROLL,x2-SCROLLBUTTSIZE,y1,SCROLLBUTTSIZE,y2,0,0,SCROLLBGCOL,SCROLLFGCOL,SCROLLKNOBCOL,0, NULL,0.0,0.0,0+0,0,0,0,NULL,emptyCallback,NULL); 1609 | wp->vscroll=vs; 1610 | vs->parentbox=wp; 1611 | } 1612 | return wp; 1613 | } 1614 | #endif //HGUI_TEXTBOXES 1615 | #endif //HGUI_TEXTBLOCKS 1616 | #endif //HGUI_TEXTFIELDS 1617 | #ifdef HGUI_PROGBARS 1618 | HProgBar* addHProgBar(hWindow *hw, int x1, int y1, int x2, int y2, char bevel, char *caption, unsigned long bgcol, unsigned long fgcol, unsigned long textcol, unsigned long captcol, float pos, float scale, char* font, void (*callback)(), void* argptr ) 1619 | { 1620 | return addWidget(hw,HPROGBAR,x1,y1,x2,y2,0,bevel,bgcol,fgcol,textcol,captcol, caption,pos,scale,0,0,0,0,getFontStruct(hw,font),callback,argptr); 1621 | } 1622 | VProgBar* addVProgBar(hWindow *hw, int x1, int y1, int x2, int y2, char bevel, char *caption, unsigned long bgcol, unsigned long fgcol, unsigned long textcol, unsigned long captcol, float pos, float scale, char* font, void (*callback)(), void* argptr ) 1623 | { 1624 | return addWidget(hw,VPROGBAR,x1,y1,x2,y2,0,bevel,bgcol,fgcol,textcol,captcol, caption,pos,scale,0,0,0,0,getFontStruct(hw,font),callback,argptr); 1625 | } 1626 | #endif //HGUI_PROGBARS 1627 | #ifdef HGUI_SCROLLBARS 1628 | VScroll* addVScroll(hWindow *hw, int x, int y1, int w, int y2, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, float pos, float ratio, void (*callback)(), void* argptr ) 1629 | { 1630 | return addWidget(hw,VSCROLL,x,y1,w,y2,0,0,bgcol,fgcol,knobcol,0, NULL,pos,ratio,0+0,0,0,0,NULL,callback,argptr); 1631 | } 1632 | HScroll* addHScroll(hWindow *hw, int x1, int y, int x2, int h, unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, float pos, float ratio, void (*callback)(), void* argptr ) 1633 | { 1634 | return addWidget(hw,HSCROLL,x1,y,x2,h,0,0,bgcol,fgcol,knobcol,0, NULL,pos,ratio,0+0,0,0,0,NULL,callback,argptr); 1635 | } 1636 | #endif //HGUI_SCROLLBARS 1637 | #ifdef HGUI_BLOCKS 1638 | Block* addBlock(hWindow *hw, int x1, int y1, int x2, int y2) 1639 | { 1640 | return addWidget(hw,BLOCK,x1,y1,x2,y2,0,0,0,0,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1641 | } 1642 | BlockFill* addBlockFill(hWindow *hw, int x1, int y1, int x2, int y2, unsigned int color) 1643 | { 1644 | return addWidget(hw,BLOCKFILL,x1,y1,x2,y2,0,0,color,0,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1645 | } 1646 | #endif //HGUI_BLOCKS 1647 | #ifdef HGUI_PICTURES 1648 | Picture* addPicture(hWindow *hw, int x, int y, int width, int height, int depth, char* pixeldata, void (*callback)(), void* argptr ) 1649 | { 1650 | return addWidget(hw,PICTURE,x,y,width,height,depth,0,0,0,0,0, pixeldata,0,0,0,0,0,0,NULL,callback,argptr); 1651 | } 1652 | PictureXPM* addXPM(hWindow *hw, int x, int y, char *xpm[], unsigned long bgcol, void (*callback)(), void* argptr ) 1653 | { 1654 | return addWidget(hw,XPM,x,y,0,0,0,0,bgcol,0,0,0, (void*)xpm,0,0,0,0,0,0,NULL,callback,argptr); 1655 | } 1656 | #endif //HGUI_PICTURES 1657 | #ifdef HGUI_ANIMATIONS 1658 | int addAnimation(hWindow *hw) 1659 | { 1660 | if(hw==NULL || hw->AnimAmount>=ANIM_AMOUNT_MAX) { 1661 | printf("%s Cannot add more animations, reached the maximum %d. (Check ANIM_AMOUNT_MAX in hgui.c)\n",ErrPfx,ANIM_AMOUNT_MAX); 1662 | return RET_ERR; 1663 | } 1664 | hw->AnimID[hw->AnimAmount] = hw->WidgetAmount ; 1665 | hw->AnimAmount++; 1666 | return hw->AnimAmount; 1667 | } 1668 | #ifdef HGUI_PICANIMS 1669 | AnimXPM* addAnimXPM(hWindow *hw, int x, int y, void* xpmlist[], unsigned long bgcol, char framedelay, void (*callback)(), void* argptr ) 1670 | { 1671 | if(hw==NULL) return denyWidget(ANIMXPM,""); 1672 | if(addAnimation(hw)==RET_ERR) return NULL; 1673 | else return addWidget(hw,ANIMXPM,x,y,0,0,0,0,bgcol,0,0,0, (void*)xpmlist, 0,0,0,framedelay,0,0,NULL,callback,argptr); 1674 | } 1675 | #endif //HGUI_PICANIMS 1676 | #ifdef HGUI_TEXTANIMS 1677 | TextScroll* addTextScroll(hWindow *hw, int x1, int y1, int x2, int y2, char *text, unsigned long bgcol, unsigned long fgcol, char framedelay, char pixstep, char *font) 1678 | { 1679 | if(hw==NULL) return denyWidget(TEXTSCROLL,NULL); 1680 | if(addAnimation(hw)==RET_ERR) return NULL; 1681 | else return addWidget(hw,TEXTSCROLL,x1,y1,x2,y2,0,0,bgcol,fgcol,1,0, text,0,0,0,framedelay,0,pixstep,getFontStruct(hw,font), emptyCallback,NULL); 1682 | } 1683 | #endif //HGUI_TEXTANIMS 1684 | #endif //HGUI_ANIMATIONS 1685 | #ifdef HGUI_PRIMITIVES 1686 | Primitive* addPoint (hWindow *hw, int x, int y, unsigned long col) 1687 | { 1688 | return addWidget(hw,POINT,x,y,0,0,0,0,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1689 | } 1690 | Primitive* addLine (hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col) 1691 | { 1692 | return addWidget(hw,LINE,x1,y1,x2,y2,0,0,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1693 | } 1694 | Primitive* addRect (hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col) 1695 | { 1696 | return addWidget(hw,RECT,x1,y1,x2,y2,0,0,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1697 | } 1698 | Primitive* addRectFill (hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col) 1699 | { 1700 | return addWidget(hw,RECTFILL,x1,y1,x2,y2,0,0,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1701 | } 1702 | Primitive* addArc (hWindow *hw, int x1, int y1, int x2, int y2, int startdeg, int degree, unsigned long col) 1703 | { 1704 | return addWidget(hw,ARC,x1,y1,x2,y2,startdeg,degree,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1705 | } 1706 | Primitive* addArcFill (hWindow *hw, int x1, int y1, int x2, int y2, int startdeg, int degree, unsigned long col) 1707 | { 1708 | return addWidget(hw,ARCFILL,x1,y1,x2,y2,startdeg,degree,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1709 | } 1710 | Primitive* addCircle (hWindow *hw, int x, int y, int r, unsigned long col) 1711 | { 1712 | return addWidget(hw,CIRCLE,x,y,r,0,0,0,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1713 | } 1714 | Primitive* addCircleFill (hWindow *hw, int x, int y, int r, unsigned long col) 1715 | { 1716 | return addWidget(hw,CIRCLEFILL,x,y,r,0,0,0,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1717 | } 1718 | Primitive* addEllipse (hWindow *hw, int x, int y, int rx, int ry, unsigned long col) 1719 | { 1720 | return addWidget(hw,ELLIPSE,x,y,rx,ry,0,0,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1721 | } 1722 | Primitive* addEllipseFill (hWindow *hw, int x, int y, int rx, int ry, unsigned long col) 1723 | { 1724 | return addWidget(hw,ELLIPSEFILL,x,y,rx,ry,0,0,0,col,0,0, NULL,0,0,0,0,0,0,NULL,emptyCallback,NULL); 1725 | } 1726 | #endif //HGUI_PRIMITIVES 1727 | 1728 | //widget short (and automatic width/height/font/etc.) forms of add-routines: 1729 | //void addButton(char *title){} 1730 | //void addButton(int x, int y, char *title){} 1731 | 1732 | 1733 | 1734 | 1735 | //----------------------- Window/Widget redraw/refresh-routines ----------------------- 1736 | void correctRange(float *input) 1737 | { 1738 | if (*input>1.0) *input=1.0; 1739 | else if (*input<0.0) *input=0.0; 1740 | } 1741 | 1742 | void cleanUpRect(hWindow *hw, int x1o, int y1o, int x2o, int y2o, int x1, int y1, int x2, int y2) 1743 | { 1744 | //clears (with window-background-color) the non-intersecting area of two rectangles: the old bouncing box and the new one 1745 | //XClearArea(hw->d,hw->w,x1o,y1o,x2o-x1o,y2o-y1o,False); 1746 | if(x1od,hw->w,x1o,y1o,x1-x1o,y2o-y1o,False); 1747 | if(y1od,hw->w,x1o,y1o,x2o-x1o,y1-y1o,False); 1748 | if(x2o>x2) XClearArea(hw->d,hw->w,x2,y1o,x2o-x2,y2o-y1o,False); 1749 | if(y2o>y2) XClearArea(hw->d,hw->w,x1o,y2,x2o-x1o,y2o-y2,False); 1750 | } 1751 | 1752 | #ifdef HGUI_PRIMITIVES 1753 | void drawPrimitive(hWindow *hw, Widget *wp, int x1, int y1, int x2, int y2, unsigned long color) 1754 | { 1755 | int *x=&x1, *y=&y1; 1756 | switch (wp->type) { 1757 | case POINT: 1758 | drawPoint(hw,*x,*y,color); 1759 | break; 1760 | case LINE: 1761 | drawLine(hw,x1,y1,x2,y2,color); 1762 | break; 1763 | case RECT: 1764 | drawRect(hw,x1,y1,x2,y2,color); 1765 | break; 1766 | case RECTFILL: 1767 | drawRectFill(hw,x1,y1,x2,y2,color); 1768 | break; 1769 | case ARC: 1770 | drawArc(hw,x1,y1,x2,y2,wp->startdeg,wp->degree,color); 1771 | break; 1772 | case ARCFILL: 1773 | drawArcFill(hw,x1,y1,x2,y2,wp->startdeg,wp->degree,color); 1774 | break; 1775 | case CIRCLE: 1776 | drawCircle(hw,*x,*y,wp->r,color); 1777 | break; 1778 | case CIRCLEFILL: 1779 | drawCircleFill(hw,*x,*y,wp->r,color); 1780 | break; 1781 | case ELLIPSE: 1782 | drawEllipse(hw,*x,*y,wp->rx,wp->ry,color); 1783 | break; 1784 | case ELLIPSEFILL: 1785 | drawEllipseFill(hw,*x,*y,wp->rx,wp->ry,color); 1786 | break; 1787 | } 1788 | } 1789 | #endif //HGUI_PRIMITIVES 1790 | 1791 | void clearWidgetTrails(hWindow *hw, int i, Bool TextChange) 1792 | { 1793 | if(hw==NULL) return; 1794 | Widget *wp=&hw->W[i]; 1795 | int x1,y1,x2,y2,x1o,y1o,x2o,y2o,brd, *x=&x1,*y=&y1; 1796 | x1o=wp->actx1; 1797 | y1o=wp->acty1; 1798 | x2o=wp->actx2; 1799 | y2o=wp->acty2; 1800 | brd=wp->border; 1801 | x1=dynCoordX(hw,wp->x1); 1802 | y1=dynCoordY(hw,wp->y1); 1803 | x2=dynCoordX(hw,wp->x2); 1804 | y2=dynCoordY(hw,wp->y2); 1805 | //if(x1==x1o && y1==y1o && x2==x2o && y2==y2o) return; //if no moving/resizing of widget, no trail to clear //printf("%d,%d,%d,%d, %d,%d,%d,%d\n",x1,y1,x2,y2, x1o,y1o,x2o,y2o); 1806 | if(x1o<=0 || x2o<=0 || x2o<=x1o || y2o<=y1o) return; //invalid rectangle returns 1807 | switch (wp->type) { 1808 | #ifdef HGUI_BUTTONS 1809 | case BUTTON: 1810 | case BUTTONXPM: 1811 | cleanUpRect(hw, x1o-brd, y1o-brd, x2o+brd+1, y2o+brd+1, *x-brd,*y-brd,*x+wp->w+brd+1,*y+wp->h+brd+1); 1812 | XClearArea(hw->d,hw->w,*x-brd,*y-brd,1,1,False); 1813 | XClearArea(hw->d,hw->w,*x-brd,*y+wp->h+brd,1,1,False); 1814 | XClearArea(hw->d,hw->w,*x+wp->w+brd,*y-brd,1,1,False); 1815 | XClearArea(hw->d,hw->w,*x+wp->w+brd,*y+wp->h+brd,1,1,False); 1816 | break; 1817 | case BUTTONDYN: 1818 | cleanUpRect(hw, x1o-brd, y1o-brd, x2o+brd+1, y2o+brd+1, x1-brd,y1-brd,x2+brd+1,y2+brd+1); 1819 | XClearArea(hw->d,hw->w,x1-brd,y1-brd,1,1,False); 1820 | XClearArea(hw->d,hw->w,x1-brd,y2+brd,1,1,False); 1821 | XClearArea(hw->d,hw->w,x2+brd,y1-brd,1,1,False); 1822 | XClearArea(hw->d,hw->w,x2+brd,y2+brd,1,1,False); 1823 | break; 1824 | #endif //HGUI_BUTTONS 1825 | #ifdef HGUI_SLIDERS 1826 | case VSLIDER: 1827 | cleanUpRect(hw, x1o, y1o, x2o, y2o, *x,*y,*x+wp->w,y2); 1828 | clearCaptionTrails(hw,*x,y1,wp->w,wp->caption,wp->font,i,TextChange); 1829 | break; 1830 | case HSLIDER: 1831 | cleanUpRect(hw, x1o, y1o, x2o, y2o, *x,*y,x2,*y+wp->h); 1832 | clearCaptionTrails(hw,x1,*y,x2-x1,wp->caption,wp->font,i,TextChange); 1833 | break; 1834 | #endif //HGUI_SLIDERS 1835 | #ifdef HGUI_PROGBARS 1836 | case HPROGBAR: 1837 | case VPROGBAR: 1838 | cleanUpRect(hw, x1o, y1o, x2o+1, y2o+1, x1,y1,x2+1,y2+1); 1839 | clearCaptionTrails(hw,x1,y1,x2-x1,wp->caption,wp->font,i,TextChange); 1840 | break; 1841 | #endif //HGUI_PROGBARS 1842 | #ifdef HGUI_TEXTFIELDS 1843 | #if defined(HGUI_TEXTLINES) || defined(HGUI_TEXTBLOCKS) 1844 | case TEXTLINE: 1845 | case TEXTCENTER: 1846 | case TEXTBLOCK: 1847 | XClearArea(hw->d,hw->w,x1o,y1o,x2o-x1o,y2o-y1o,False); 1848 | break; 1849 | #endif 1850 | #ifdef HGUI_TEXTBOXES 1851 | case TEXTBOX: 1852 | cleanUpRect(hw, x1o-1, y1o-1, x2o+2, y2o+2, x1-1,y1-1,x2+2,y2+2); 1853 | break; 1854 | #endif //HGUI_TEXTBOXES 1855 | #endif //HGUI_TEXTFIELDS 1856 | #ifdef HGUI_SCROLLBARS 1857 | case VSCROLL: 1858 | cleanUpRect(hw, x1o-1, y1o-1, x2o+2, y2o+2, *x-1,y1-1,*x+wp->w+1,y2+1); 1859 | break; 1860 | case HSCROLL: 1861 | cleanUpRect(hw, x1o-1, y1o-1, x2o+2, y2o+2, x1-1,*y-1,x2+1,*y+wp->h+1); 1862 | break; 1863 | #endif //HGUI_SCROLLBARS 1864 | #ifdef HGUI_BLOCKS 1865 | case BLOCK: 1866 | cleanUpRect(hw,x1o,y1o,x1o+2,y2o+1, x1,y1,x1+2,y2+1); 1867 | cleanUpRect(hw,x1o,y1o,x2o+1,y1o+2, x1,y1,x2+1,y1+2); 1868 | cleanUpRect(hw,x2o,y1o,x2o+2,y2o+1, x2,y1,x2+2,y2+1); 1869 | cleanUpRect(hw,x1o,y2o,x2o+2,y2o+2, x1,y2,x2+2,y2+2); 1870 | break; 1871 | case BLOCKFILL: 1872 | cleanUpRect(hw, x1o-1, y1o-1, x2o+2, y2o+2, x1-1,y1-1,x2+2,y2+2); 1873 | break; 1874 | #endif //HGUI_BLOCKS 1875 | #ifdef HGUI_PICTURES 1876 | case PICTURE: 1877 | case XPM: 1878 | cleanUpRect(hw, x1o,y1o,x2o,y2o, *x,*y,*x+wp->w,*y+wp->h); 1879 | break; 1880 | #endif //HGUI_PICTURES 1881 | #ifdef HGUI_PICANIMS 1882 | case ANIMXPM: 1883 | XClearArea(hw->d,hw->w,x1o,y1o,x2o-x1o,y2o-y1o,False); 1884 | break; 1885 | #endif //HGUI_PICANIMS 1886 | #if defined(HGUI_PRIMITIVES) || defined (HGUI_TEXTANIMS) 1887 | case RECTFILL: 1888 | case TEXTSCROLL: 1889 | cleanUpRect(hw,x1o,y1o,x2o,y2o, x1,y1,x2,y2); 1890 | break; 1891 | #endif //HGUI_PRIMITIVES || HGUI_TEXTANIMS 1892 | #ifdef HGUI_PRIMITIVES 1893 | case CIRCLE: 1894 | case CIRCLEFILL: 1895 | case ELLIPSE: 1896 | case ELLIPSEFILL: 1897 | if(x1==x1o && y1==y1o) return; 1898 | default: 1899 | drawPrimitive(hw,wp,x1o,y1o,x2o,y2o,hw->bgcol); //GXxor graphic context could be used here to avoid flickering when moving primitives? 1900 | #endif //HGUI_PRIMITIVES 1901 | } 1902 | } 1903 | 1904 | void drawOnlyWidget(hWindow *hw, int i) 1905 | { 1906 | if(hw==NULL) return; 1907 | char cvpos=2,chpos=2; 1908 | Widget *wp=&hw->W[i]; 1909 | int x1,y1,x2,y2, *x=&x1,*y=&y1; 1910 | XPMstruct xpms; 1911 | TextDim dim; //cvpos/chpos and other position/value corrections are made inside this function where it makes sense 1912 | x1=dynCoordX(hw,wp->x1); 1913 | y1=dynCoordY(hw,wp->y1); 1914 | x2=dynCoordX(hw,wp->x2); 1915 | y2=dynCoordY(hw,wp->y2); //pos might be zoomed or relative to right/bottom window-edges (negative coordinate-values) 1916 | if(x2type) { 1920 | #ifdef HGUI_BUTTONS 1921 | #ifdef HGUI_TEXTBUTTONS 1922 | case BUTTON: 1923 | drawButton(hw,*x,*y,wp->w,wp->h,wp->data,wp->bgcol,wp->fgcol,wp->state,wp->bevel,wp->border,wp->fsp,i); 1924 | break; 1925 | case BUTTONDYN: 1926 | drawButton(hw,x1,y1,x2-x1,y2-y1,wp->data,wp->bgcol,wp->fgcol,wp->state,wp->bevel,wp->border,wp->fsp,i); 1927 | break; 1928 | #endif //HGUI_TEXTBUTTONS 1929 | #ifdef HGUI_PICBUTTONS 1930 | case BUTTONXPM: 1931 | drawButtonXPM(hw,*x,*y,wp->w,wp->h,(void*)wp->pixdata,wp->bgcol,wp->state,wp->bevel,wp->border,i); 1932 | break; 1933 | #endif //HGUI_PICBUTTONS 1934 | #endif //HGUI_BUTTONS 1935 | #ifdef HGUI_SLIDERS 1936 | case VSLIDER: 1937 | correctRange(&wp->pos); 1938 | correctRange(&wp->ratio); //push these between 0.0 and 1.0 1939 | drawVSlider(hw,*x,y1,wp->w,y2,wp->knobsize,wp->scalewidth,wp->caption,wp->bgcol,wp->fgcol,wp->knobcol,wp->captcol,wp->pos,wp->scale,wp->fsp,i); 1940 | break; 1941 | case HSLIDER: 1942 | correctRange(&wp->pos); 1943 | correctRange(&wp->ratio); //push these between 0.0 and 1.0 1944 | drawHSlider(hw,x1,*y,x2,wp->h,wp->knobsize,wp->scalewidth,wp->caption,wp->bgcol,wp->fgcol,wp->knobcol,wp->captcol,wp->pos,wp->scale,wp->fsp,i); 1945 | break; 1946 | #endif //HGUI_SLIDERS 1947 | #ifdef HGUI_TEXTFIELDS 1948 | #ifdef HGUI_TEXTLINES 1949 | case TEXTLINE: 1950 | dim=drawTextLine(hw,*x,*y,255,wp->text,wp->textcol,wp->fsp); 1951 | setActiveRegion(hw,i,*x,*y,*x+dim.w,*y+dim.h,0,0,0); 1952 | break; 1953 | case TEXTCENTER: 1954 | drawTextCent(hw,x1,y1,x2,y2,wp->text,wp->textcol,wp->fsp, i); 1955 | break; 1956 | #endif //HGUI_TEXTLINES 1957 | #ifdef HGUI_TEXTBLOCKS 1958 | case TEXTBLOCK: 1959 | drawTextBlock(hw,x1,y1,x2,y2,wp->text,wp->textcol,wp->wrap,0,0,wp->fsp,0,0); 1960 | break; 1961 | #endif //HGUI_TEXTBLOCKS 1962 | #ifdef HGUI_TEXTBOXES 1963 | case TEXTBOX: 1964 | while(cvpos>0||chpos>0) { 1965 | drawTextBox(hw,x1,y1,x2,y2,wp->text,wp->bgcol,wp->fgcol,wp->wrap,wp->scrollbars,wp->vpos,wp->hpos,wp->fsp,i,wp->vscroll,wp->hscroll); 1966 | if(wp->autofit && wp->vpixsize<=wp->acty2-wp->acty1) { 1967 | wp->vpos=0; 1968 | cvpos--; 1969 | } else cvpos=0; 1970 | if(wp->autofit && wp->hpixsize<=wp->actx2-wp->actx1) { 1971 | wp->hpos=0; 1972 | chpos--; 1973 | } else chpos=0; 1974 | } 1975 | break; 1976 | #endif //HGUI_TEXTBOXES 1977 | #endif //HGUI_TEXTFIELDS 1978 | #ifdef HGUI_PROGBARS 1979 | case HPROGBAR: 1980 | correctRange(&wp->pos); 1981 | correctRange(&wp->ratio); //push these between 0.0 and 1.0 1982 | drawHProgBar(hw,x1,y1,x2,y2,wp->bevel,wp->caption,wp->bgcol,wp->fgcol,wp->progtextcol,wp->captcol,wp->pos,wp->scale,wp->fsp,i); 1983 | break; 1984 | case VPROGBAR: 1985 | correctRange(&wp->pos); 1986 | correctRange(&wp->ratio); //push these between 0.0 and 1.0 1987 | drawVProgBar(hw,x1,y1,x2,y2,wp->bevel,wp->caption,wp->bgcol,wp->fgcol,wp->progtextcol,wp->captcol,wp->pos,wp->scale,wp->fsp,i); 1988 | break; 1989 | #endif //HGUI_PROGBARS 1990 | #ifdef HGUI_SCROLLBARS 1991 | case VSCROLL: 1992 | correctRange(&wp->pos); 1993 | correctRange(&wp->ratio); //push these between 0.0 and 1.0 1994 | drawVScroll(hw,*x,y1,wp->w,y2,wp->bgcol,wp->fgcol,wp->knobcol,wp->pos,wp->ratio,wp->buttonstate,i); 1995 | break; 1996 | case HSCROLL: 1997 | correctRange(&wp->pos); 1998 | correctRange(&wp->ratio); //push these between 0.0 and 1.0 1999 | drawHScroll(hw,x1,*y,x2,wp->h,wp->bgcol,wp->fgcol,wp->knobcol,wp->pos,wp->ratio,wp->buttonstate,i); 2000 | break; 2001 | #endif //HGUI_SCROLLBARS 2002 | #ifdef HGUI_BLOCKS 2003 | case BLOCK: 2004 | drawBlock(hw,x1,y1,x2,y2); 2005 | break; 2006 | case BLOCKFILL: 2007 | drawBlockFill(hw,x1,y1,x2,y2,wp->color); 2008 | break; 2009 | #endif //HGUI_BLOCKS 2010 | #ifdef HGUI_PICTURES 2011 | case PICTURE: 2012 | putPicture(hw,*x,*y,wp->pixdata,wp->w,wp->h,wp->depth,i); 2013 | setActiveRegion(hw,i,*x,*y,*x+wp->w,*y+wp->h,0,0,0); 2014 | break; 2015 | case XPM: 2016 | xpms=putXPM(hw,*x,*y,(void*)wp->xpm,wp->transpcol,i); 2017 | wp->w=xpms.width; 2018 | wp->h=xpms.height; 2019 | setActiveRegion(hw,i,*x,*y,*x+xpms.width,*y+xpms.height,0,0,0); 2020 | break; 2021 | #endif //HGUI_PICTURES 2022 | #ifdef HGUI_ANIMATIONS 2023 | #ifdef HGUI_TEXTANIMS 2024 | case TEXTSCROLL: 2025 | drawTextScrollFrame(hw,wp, x1,y1,x2,y2, wp->text); 2026 | if(wp->scrolloffset>=x2-x1) wp->scrolloffset=x2-x1; 2027 | break; 2028 | #endif //HGUI_TEXTANIMS 2029 | #ifdef HGUI_PICANIMS 2030 | case ANIMXPM: 2031 | putAnimXPMframe(hw,wp->id,*x,*y,wp->bgcol,wp->xpmlist,wp->framecount); 2032 | break; 2033 | #endif //HGUI_PICANIMS 2034 | #endif //HGUI_ANIMATIONS 2035 | } 2036 | #ifdef HGUI_PRIMITIVES 2037 | drawPrimitive(hw,wp,x1,y1,x2,y2,wp->fgcol); 2038 | #endif //HGUI_PRIMITIVES 2039 | switch(wp->type) { 2040 | //bouncing boxes might be needed for callback even for primitives 2041 | #ifdef HGUI_PRIMITIVES 2042 | case POINT: 2043 | case CIRCLE: 2044 | case CIRCLEFILL: //setActiveRegion(hw,i,*x-wp->r,*y-wp->r,*x+wp->r,*y+wp->r,0,0,0); break; 2045 | case ELLIPSE: 2046 | case ELLIPSEFILL: 2047 | x2=x1+1; 2048 | y2=y1+1; //setActiveRegion(hw,i,*x-wp->rx,*y-wp->ry,*x+wp->rx,*y+wp->ry,0,0,0); break; 2049 | case LINE: 2050 | case RECT: 2051 | case ARC: 2052 | case ARCFILL: 2053 | #endif //HGUI_PRIMITIVES 2054 | case TEXTBLOCK: 2055 | case BLOCK: 2056 | case BLOCKFILL: 2057 | case TEXTSCROLL: 2058 | case RECTFILL: 2059 | setActiveRegion(hw,i,x1,y1,x2,y2,0,0,0); 2060 | break; 2061 | } 2062 | //#ifdef DEBUG 2063 | //SETDRAWCOL(0xffffff); DRAWRECT(wp->actx1,wp->acty1,wp->actx2-wp->actx1,wp->acty2-wp->acty1); 2064 | //#endif 2065 | } 2066 | 2067 | void refreshWidget(Widget *wp) 2068 | { 2069 | hWindow *hw=wp->parenthw; 2070 | if(hw==NULL) return; 2071 | drawOnlyWidget(hw,wp->id); 2072 | XFlush(hw->d); 2073 | } 2074 | 2075 | void redrawWidget(void *widgetptr) 2076 | { 2077 | Widget *wp=widgetptr; 2078 | hWindow *hw=wp->parenthw; 2079 | if(hw==NULL) return; 2080 | hw->width=getWinWidth(hw); 2081 | hw->height=getWinHeight(hw); 2082 | clearWidgetTrails(hw,wp->id,False); 2083 | drawOnlyWidget(hw,wp->id); 2084 | XFlush(hw->d); 2085 | } 2086 | 2087 | void changeTextPtr(void *widgetptr, char *textptr) 2088 | { 2089 | Widget *wp=widgetptr; 2090 | hWindow *hw=wp->parenthw; 2091 | if(hw==NULL) return; 2092 | switch (wp->type) { 2093 | #if defined(HGUI_SLIDERS) || defined(HGUI_PROGBARS) 2094 | case VSLIDER: 2095 | case HSLIDER: 2096 | case HPROGBAR: 2097 | case VPROGBAR: 2098 | clearWidgetTrails(hw,wp->id,True); 2099 | break; //true ensures full clear of previous caption 2100 | #endif 2101 | } 2102 | wp->text=textptr; //caption/text/content, all the same mem.location, but under different names depending on widget-type 2103 | drawOnlyWidget(hw,wp->id); 2104 | } 2105 | 2106 | /*void drawWidgets(hWindow *hw, XExposeEvent *exp) 2107 | { 2108 | printf("%d,%d,%d,%d\n",exp->x,exp->y,exp->width,exp->height); 2109 | }*/ 2110 | 2111 | //redrawing background is not a good way, it causes flickering. delete/draw only the background between the widgets or send the whole window as PixMap to server 2112 | void drawBackground(hWindow *hw) 2113 | { 2114 | if(hw==NULL) return; 2115 | XClearWindow(hw->d,hw->w); 2116 | } //or XClearArea(hw->d,hw->w,0,0,0,0,False)//SETDRAWCOL(BGCOLOR); DRAWRECTFILL(0,0,getWinWidth(hw),getWinHeight(hw)); } 2117 | //XClearWindow ad XClearArea doesn't work if background-pixmap is 'None' 2118 | 2119 | void redrawBackground(hWindow *hw) 2120 | { 2121 | if(hw==NULL) return; //XExposeEvent *exp) XClearArea(hw->d,hw->w,exp->x,exp->y,exp->width,exp->height,False); 2122 | int i; 2123 | for(i=0; iWidgetAmount; i++) clearWidgetTrails(hw,i,False); 2124 | } 2125 | 2126 | void clearWindow (hWindow *hw) 2127 | { 2128 | XClearWindow(hw->d,hw->w); 2129 | XFlush(hw->d); 2130 | }; 2131 | 2132 | void drawAllWidgets(hWindow *hw) 2133 | { 2134 | if(hw==NULL) return; 2135 | int i=0; 2136 | for(i=0; iWidgetAmount; i++) drawOnlyWidget(hw,i); //iterate through widgets in widget-array hw->W[] till last widget 2137 | XFlush(hw->d); 2138 | } 2139 | 2140 | void refreshWindow(hWindow *hw) 2141 | { 2142 | if(hw==NULL) return; 2143 | hw->width=getWinWidth(hw); 2144 | hw->height=getWinHeight(hw); 2145 | drawAllWidgets(hw); 2146 | } 2147 | 2148 | void redrawWindow(hWindow *hw) 2149 | { 2150 | if(hw==NULL) return; 2151 | XClearWindow(hw->d,hw->w); 2152 | refreshWindow(hw); 2153 | } 2154 | 2155 | 2156 | #ifdef HGUI_ANIMATIONS 2157 | #ifdef HGUI_PICANIMS 2158 | Bool putAnimXPMframe(hWindow *hw, int id, int x, int y, unsigned long transpcol, void* xpmlist[], int framenumber ) 2159 | { 2160 | XPMstruct xpms=putXPM(hw,x,y,xpmlist[framenumber],transpcol,id); 2161 | XFlush(hw->d); 2162 | setActiveRegion(hw,id,x,y,x+xpms.width,y+xpms.height,0,0,0); //hw->W[id].w=xpms.width; hw->W[id].h=xpms.height; 2163 | if(xpmlist[framenumber]==NULL || xpmlist[framenumber+1]==NULL) return False; 2164 | else return True; 2165 | } 2166 | #endif //HGUI_PICANIMS 2167 | #ifdef HGUI_TEXTANIMS 2168 | TextDim drawTextScrollFrame(hWindow *hw, Widget *wp, int x1, int y1, int x2, int y2, char *text) 2169 | { 2170 | int i; 2171 | int w=x2-x1, h=y2-y1; 2172 | SETDRAWCOL(wp->bgcol); 2173 | DRAWRECTFILL(x1,y1,w,h); //debug: SETDRAWCOL(0x107050); DRAWRECTFILL(x1+w,y1,80,h); DRAWRECTFILL(x1-80,y1,80,h); 2174 | setClipRegion(hw,x1,y1,x2,y2); 2175 | TextDim dim=getTextDimN(text+wp->scrollindex,wp->font,wp->scrolldisplen); 2176 | DRAWSTRINGN(x1+wp->scrollpixcnt+(w-wp->scrolloffset), y1+(h+dim.ascent)/2, text+wp->scrollindex, wp->fgcol, wp->font, wp->scrolldisplen); 2177 | removeClipRegion(hw); 2178 | return dim; 2179 | } 2180 | 2181 | void doTextScroll(hWindow *hw, Widget *wp, int x1, int y1, int x2, int y2, char *text) 2182 | { 2183 | int i; 2184 | int w=x2-x1, h=y2-y1; 2185 | TextDim dim=drawTextScrollFrame(hw,wp,x1,y1,x2,y2,text); 2186 | if (text[wp->scrollindex]=='\0') { 2187 | wp->scrollindex=wp->scrollpixcnt=wp->scrolloffset=wp->state=0; 2188 | wp->scrolldisplen=1; 2189 | } else { 2190 | if(wp->scrolloffsetscrollpixcnt <= 0) { 2192 | wp->scrollpixcnt=getTextWidth(text+wp->scrolldisplen-1,wp->font,1); 2193 | wp->scrolloffset+=wp->scrollpixcnt; 2194 | if(text[wp->scrollindex+wp->scrolldisplen]=='\0') wp->state=1; 2195 | if(!wp->state) wp->scrolldisplen++; 2196 | } 2197 | if(!wp->state) wp->scrollpixcnt-=wp->pixstep; 2198 | else wp->scrolloffset++; //pull scrolltext toward the field's beginning 2199 | } else { 2200 | if( -wp->scrollpixcnt >= getTextWidth(text+wp->scrollindex,wp->font,1) ) { //check if a character passed 2201 | for(i=0; iscrollindex+i]=='\0' ) { 2203 | wp->scrolldisplen=i-1; //if scrolltext is over, shorten its display 2204 | break; 2205 | } else if( getTextWidth(text+wp->scrollindex,wp->font,i) > w+dim.h*4 ) { 2206 | wp->scrolldisplen=i; //otherwise exceed the end of field to cover from right 2207 | break; 2208 | } 2209 | } 2210 | wp->scrollpixcnt=0; 2211 | wp->scrollindex++; //advance in scroll-string 2212 | } 2213 | wp->scrollpixcnt-=wp->pixstep; //advance a pixel inside current character 2214 | } 2215 | } 2216 | XFlush(hw->d); 2217 | } 2218 | #endif 2219 | 2220 | void playAnimations(hWindow *hw) 2221 | { 2222 | if(hw==NULL) return; 2223 | int h,i,x1,y1,x2,y2, *x=&x1,*y=&y1; 2224 | Widget *aniw; 2225 | for(i=0; iAnimAmount; i++) { 2226 | aniw=&hw->W[hw->AnimID[i]]; 2227 | if (aniw->spdcnt) { 2228 | aniw->spdcnt--; 2229 | continue; 2230 | } else { 2231 | aniw->spdcnt=aniw->framedelay; 2232 | x1=dynCoordX(hw,aniw->x1); 2233 | y1=dynCoordY(hw,aniw->y1); 2234 | x2=dynCoordX(hw,aniw->x2); 2235 | y2=dynCoordY(hw,aniw->y2); 2236 | if(x2W[hw->AnimID[i]].type) { 2239 | #ifdef HGUI_PICANIMS 2240 | case ANIMXPM: { 2241 | if ( putAnimXPMframe(hw,aniw->id,*x,*y,aniw->bgcol,aniw->xpmlist,aniw->framecount) ) aniw->framecount++; 2242 | else aniw->framecount=0; 2243 | } 2244 | break; 2245 | #endif 2246 | #ifdef HGUI_TEXTANIMS 2247 | case TEXTSCROLL: 2248 | doTextScroll(hw,aniw,x1,y1,x2,y2,aniw->text); 2249 | break; //DRAWSTRING(aniw->x1, aniw->y1, aniw->text, aniw->fgcol, aniw->font); 2250 | #endif 2251 | } 2252 | } 2253 | } 2254 | } 2255 | #endif //HGUI_ANIMATIONS 2256 | 2257 | 2258 | 2259 | //----------------------- Event handling routines ---------------------- 2260 | Bool alwaysTrue() 2261 | { 2262 | return True; //needed fo XCheckIfEvent, as XCheckWindowEvent / XCheckMaskEvent doesn't handle ClientMessage event-type 2263 | } 2264 | 2265 | Bool inActRange (hWindow *hw, int i, int x, int y) 2266 | { 2267 | if (hw->W[i].actx1<=x && x<=hw->W[i].actx2 && hw->W[i].acty1<=y && y<=hw->W[i].acty2) return True; 2268 | else return False; 2269 | } 2270 | 2271 | void safeCallback(Widget *w, void* argptr) 2272 | { 2273 | if (w->callback!=NULL) (w->callback)(w,argptr); 2274 | } 2275 | 2276 | void setCallback(void *widgetptr, void (*callback)(), void* argptr) 2277 | { 2278 | Widget *wp=widgetptr; 2279 | wp->callback=callback; 2280 | wp->argptr=argptr; 2281 | } 2282 | 2283 | scrollTextDown(hWindow *hw, Widget *w, int rows) 2284 | { 2285 | if (w->vpixpos+(w->acty2-w->acty1) <= w->vpixsize) w->vpos+=rows; 2286 | refreshWidget(w); 2287 | } 2288 | 2289 | scrollTextUp(hWindow *hw, Widget *w, int rows) 2290 | { 2291 | if(w->vpos>=0) { 2292 | w->vpos-=rows; 2293 | refreshWidget(w); 2294 | } 2295 | } 2296 | 2297 | scrollTextRight(hWindow *hw, Widget *w, int pixrows) 2298 | { 2299 | if(w->hpos+(w->actx2-w->actx1) <= w->hpixsize) { 2300 | w->hpos+=pixrows; 2301 | refreshWidget(w); 2302 | } 2303 | } 2304 | 2305 | scrollTextLeft(hWindow *hw, Widget *w, int pixrows) 2306 | { 2307 | if(w->hpos>=0) { 2308 | w->hpos-=pixrows; 2309 | refreshWidget(w); 2310 | } 2311 | } 2312 | 2313 | Bool leftButtonAction(hWindow *hw, Widget *w, int x, int y) 2314 | { 2315 | int width=w->actx2-w->actx1, height=w->acty2-w->acty1; 2316 | Widget *par; //parent widget pointer for some widgets 2317 | switch (w->type) { 2318 | #ifdef HGUI_BUTTONS 2319 | case BUTTON: 2320 | case BUTTONDYN: 2321 | case BUTTONXPM: 2322 | if(hw->dragging)break; 2323 | w->state^=1; 2324 | refreshWidget(w); 2325 | safeCallback(w,w->argptr); 2326 | break; 2327 | #endif 2328 | #ifdef HGUI_SLIDERS 2329 | case VSLIDER: 2330 | w->pos = 1.0 - (float)(y-(w->acty1+w->margin)) / (float)(height-w->margin*2); 2331 | correctRange(&w->pos); 2332 | refreshWidget(w); 2333 | safeCallback(w,w->argptr); 2334 | break; 2335 | case HSLIDER: 2336 | w->pos = 1.0 - (float)(x-(w->actx1+w->margin)) / (float)(width-w->margin*2); 2337 | correctRange(&w->pos); 2338 | refreshWidget(w); 2339 | safeCallback(w,w->argptr); 2340 | break; 2341 | #endif 2342 | #ifdef HGUI_PROGBARS 2343 | case HPROGBAR: 2344 | case VPROGBAR: 2345 | safeCallback(w,w->argptr); 2346 | break; 2347 | #endif 2348 | #ifdef HGUI_SCROLLBARS 2349 | case VSCROLL: 2350 | par=w->parentbox; 2351 | if(par!=NULL) { 2352 | if(y > w->knoby2) { 2353 | w->state=2; 2354 | scrollTextDown(hw,par,1); 2355 | } else if (y < w->knoby1) { 2356 | w->state=1; 2357 | scrollTextUp(hw,par,1); 2358 | } 2359 | } else { 2360 | { 2361 | if (y >= w->knoby2) { 2362 | w->pos+=0.02; 2363 | w->state=2; 2364 | } else if (y < w->knoby1) { 2365 | w->pos-=0.02; 2366 | w->state=1; 2367 | } 2368 | } //else if(hw->dragging) {w->pos=(float)(y-w->y1)/(float)height;w->state=0;} } 2369 | refreshWidget(w); 2370 | safeCallback(w,w->argptr); 2371 | } 2372 | break; 2373 | case HSCROLL: 2374 | par=w->parentbox; 2375 | if(par!=NULL) { 2376 | if(x > w->knobx2) { 2377 | w->state=2; 2378 | scrollTextRight(hw,par,SCROLLSPEEDX); 2379 | } else if (xknobx1) { 2380 | w->state=1; 2381 | scrollTextLeft(hw,par,SCROLLSPEEDX); 2382 | } 2383 | } else { 2384 | { 2385 | if (x >= w->knobx2) { 2386 | if(w->pos+w->ratio<1.0) { 2387 | w->pos+=0.02; 2388 | w->state=2; 2389 | } 2390 | } else if(x < w->knobx1) { 2391 | if(w->pos>0) { 2392 | w->pos-=0.02; 2393 | w->state=1; 2394 | } 2395 | } 2396 | } 2397 | refreshWidget(w); 2398 | safeCallback(w,w->argptr); 2399 | } 2400 | break; 2401 | #endif 2402 | #ifdef HGUI_PICTURES 2403 | case PICTURE: 2404 | if(hw->dragging)break; 2405 | refreshWidget(w); 2406 | safeCallback(w,w->argptr); 2407 | break; 2408 | case XPM: 2409 | if(hw->dragging)break; 2410 | refreshWidget(w); 2411 | safeCallback(w,w->argptr); 2412 | break; 2413 | #endif 2414 | default: 2415 | return False; 2416 | } 2417 | return True; 2418 | } 2419 | 2420 | Bool midButtonAction(hWindow *hw, Widget *w) 2421 | { 2422 | switch (w->type) { 2423 | #ifdef HGUI_BUTTONS 2424 | case BUTTON: 2425 | w->state^=1; 2426 | refreshWidget(w); 2427 | safeCallback(w,w->argptr); 2428 | break; 2429 | case BUTTONXPM: 2430 | w->state^=1; 2431 | refreshWidget(w); 2432 | safeCallback(w,w->argptr); 2433 | break; 2434 | #endif 2435 | #ifdef HGUI_PICTURES 2436 | case PICTURE: 2437 | safeCallback(w,w->argptr); 2438 | break; 2439 | case XPM: 2440 | refreshWidget(w); 2441 | safeCallback(w,w->argptr); 2442 | break; 2443 | #endif 2444 | default: 2445 | return False; 2446 | } 2447 | return True; 2448 | } 2449 | 2450 | Bool rightButtonAction(hWindow *hw, Widget *w, int x, int y) 2451 | { 2452 | int width=w->actx2-w->actx1, height=w->acty2-w->acty1; 2453 | switch (w->type) { 2454 | #ifdef HGUI_BUTTONS 2455 | case BUTTON: 2456 | if(hw->dragging)break; 2457 | w->state^=1; 2458 | refreshWidget(w); 2459 | safeCallback(w,w->argptr); 2460 | break; 2461 | case BUTTONXPM: 2462 | if(hw->dragging)break; 2463 | w->state^=1; 2464 | refreshWidget(w); 2465 | safeCallback(w,w->argptr); 2466 | break; 2467 | #endif 2468 | #ifdef HGUI_SLIDERS 2469 | case VSLIDER: 2470 | w->pos = 1.0 - (float)(y-(w->acty1+w->margin)) / (float)(height-w->margin*2); 2471 | correctRange(&w->pos); 2472 | refreshWidget(w); 2473 | safeCallback(w,w->argptr); 2474 | break; 2475 | case HSLIDER: 2476 | w->pos = 1.0 - (float)(x-(w->actx1+w->margin)) / (float)(width-w->margin*2); 2477 | correctRange(&w->pos); 2478 | refreshWidget(w); 2479 | safeCallback(w,w->argptr); 2480 | break; 2481 | #endif 2482 | #ifdef HGUI_PICTURES 2483 | case PICTURE: 2484 | if(hw->dragging)break; 2485 | safeCallback(w,w->argptr); 2486 | break; 2487 | case XPM: 2488 | if(hw->dragging)break; 2489 | refreshWidget(w); 2490 | safeCallback(w,w->argptr); 2491 | break; 2492 | #endif 2493 | default: 2494 | return False; 2495 | } 2496 | return True; 2497 | } 2498 | 2499 | Bool wheelUpAction(hWindow *hw, Widget *w) 2500 | { 2501 | Widget *par; //parent widget pointer for some widgets 2502 | switch (w->type) { 2503 | #ifdef HGUI_SLIDERS 2504 | case VSLIDER: 2505 | w->pos+=w->ratio; 2506 | correctRange(&w->pos); 2507 | refreshWidget(w); 2508 | safeCallback(w,w->argptr); 2509 | break; 2510 | case HSLIDER: 2511 | w->pos+=w->ratio; 2512 | correctRange(&w->pos); 2513 | refreshWidget(w); 2514 | safeCallback(w,w->argptr); 2515 | break; 2516 | #endif 2517 | #ifdef HGUI_TEXTBOXES 2518 | case TEXTBOX: 2519 | scrollTextUp(hw,w,SCROLLSPEEDY); 2520 | break; 2521 | #endif 2522 | #ifdef HGUI_PROGBARS 2523 | case HPROGBAR: 2524 | case VPROGBAR: 2525 | safeCallback(w,w->argptr); 2526 | break; 2527 | #endif 2528 | #ifdef HGUI_SCROLLBARS 2529 | case VSCROLL: 2530 | w->state=0; 2531 | par=w->parentbox; 2532 | if (par!=NULL) scrollTextUp(hw,par,SCROLLSPEEDY); 2533 | else { 2534 | w->pos-=0.02; 2535 | if(w->pos<0.0)w->pos=0.0; 2536 | refreshWidget(w); 2537 | safeCallback(w,w->argptr); 2538 | } 2539 | break; 2540 | case HSCROLL: 2541 | w->state=0; 2542 | par=w->parentbox; 2543 | if (par!=NULL) scrollTextLeft(hw,par,SCROLLSPEEDX); 2544 | else { 2545 | w->pos-=0.02; 2546 | if(w->pos<0.0)w->pos=0.0; 2547 | refreshWidget(w); 2548 | safeCallback(w,w->argptr); 2549 | } 2550 | break; 2551 | #endif 2552 | default: 2553 | return False; 2554 | } 2555 | return True; 2556 | } 2557 | 2558 | Bool wheelDnAction(hWindow *hw, Widget *w) 2559 | { 2560 | Widget *par; //parent widget pointer for some widgets 2561 | switch (w->type) { 2562 | #ifdef HGUI_SLIDERS 2563 | case VSLIDER: 2564 | w->pos-=w->ratio; 2565 | correctRange(&w->pos); 2566 | refreshWidget(w); 2567 | safeCallback(w,w->argptr); 2568 | break; 2569 | case HSLIDER: 2570 | w->pos-=w->ratio; 2571 | correctRange(&w->pos); 2572 | refreshWidget(w); 2573 | safeCallback(w,w->argptr); 2574 | break; 2575 | #endif 2576 | #ifdef HGUI_TEXTBOXES 2577 | case TEXTBOX: 2578 | scrollTextDown(hw,w,SCROLLSPEEDY); 2579 | break; 2580 | #endif 2581 | #ifdef HGUI_PROGBARS 2582 | case HPROGBAR: 2583 | case VPROGBAR: 2584 | safeCallback(w,w->argptr); 2585 | break; 2586 | #endif 2587 | #ifdef HGUI_SCROLLBARS 2588 | case VSCROLL: 2589 | w->state=0; 2590 | par=w->parentbox; 2591 | if (par!=NULL) scrollTextDown(hw,par,SCROLLSPEEDY); 2592 | else { 2593 | w->pos+=0.02; 2594 | if(w->pos>1.0-w->ratio)w->pos=1.0-w->ratio; 2595 | refreshWidget(w); 2596 | safeCallback(w,w->argptr); 2597 | } 2598 | break; 2599 | case HSCROLL: 2600 | w->state=0; 2601 | par=w->parentbox; 2602 | if (par!=NULL) scrollTextRight(hw,par,SCROLLSPEEDX); 2603 | else { 2604 | w->pos+=0.02; 2605 | if(w->pos>1.0-w->ratio)w->pos=1.0-w->ratio; 2606 | refreshWidget(w); 2607 | safeCallback(w,w->argptr); 2608 | } 2609 | break; 2610 | #endif 2611 | default: 2612 | return False; 2613 | } 2614 | return True; 2615 | } 2616 | 2617 | void eventLoop (hWindow *hw, void (*callback)(), void* argptr ) //a custom function can be injected into event loop. if NULL, nothing is run 2618 | { 2619 | hWindow *ewin,*cwin; 2620 | XEvent event; 2621 | int i,x,y,x2,y2; //struct timeval timeout; fd_set rset; int selRes; 2622 | hw->exitsig=0; 2623 | drawAllWidgets(hw); 2624 | #ifdef HGUI_CHILDWINDOWS 2625 | for(i=0; iChildAmount; i++) { 2626 | cwin=hw->Child[i]; //XFlush(hw->d); //XSync(hw->d,False); 2627 | if(cwin==NULL) continue; 2628 | cwin->exitsig=0; 2629 | drawAllWidgets(cwin); 2630 | } 2631 | #endif 2632 | 2633 | while(hw->exitsig==0) { 2634 | //FD_ZERO(&rset); FD_SET(hw->fd,&rset); timeout.tv_sec=REFRESHDELAY/1000000; timeout.tv_usec=REFRESHDELAY; 2635 | //selRes=select(hw->fd+1,&rset,0,0,&timeout); //memset(&timeout.tv_usec,0,sizeof(timeout)); 2636 | //if ( XPending(hw->d) || FD_ISSET( ConnectionNumber(hw->d), &rset ) ) 2637 | { 2638 | //if(XPending(hw->d) || selRes>0) 2639 | { 2640 | hw->exposecnt=hw->resizecnt=0; 2641 | #ifdef HGUI_CHILDWINDOWS 2642 | for(i=0; iChildAmount; i++) { 2643 | cwin=hw->Child[i]; 2644 | if(cwin==NULL) continue; 2645 | cwin->exposecnt=cwin->resizecnt=0; 2646 | } 2647 | #endif 2648 | while( XPending(hw->d) ) { // XEventsQueued(hw->d,QueuedAfterFlush) ) 2649 | XNextEvent(hw->d,&event); 2650 | ewin=hw; //while (XCheckIfEvent(hw->d,&event,alwaysTrue,0)) //( XCheckWindowEvent(hw->d,hw->w,ExposureMask|KeyPressMask|ButtonPressMask,&event) ) //XNextEvent(hw->d,&event); 2651 | #ifdef HGUI_CHILDWINDOWS 2652 | if (event.xany.window==hw->w) ewin=hw; 2653 | else { 2654 | ewin=NULL; 2655 | for(i=0; iChildAmount; i++) { 2656 | cwin=hw->Child[i]; 2657 | if(cwin==NULL) continue; //find if childwindow matches the currently processedevent 2658 | if (event.xany.window==cwin->w) { 2659 | ewin=cwin; 2660 | break; 2661 | } 2662 | } 2663 | if (ewin==NULL) continue; 2664 | } 2665 | #endif 2666 | 2667 | switch (event.type) { 2668 | case ButtonPress: 2669 | case MotionNotify: 2670 | ewin->eventbutton=event.xbutton.button; 2671 | ewin->dragging=0; 2672 | ewin->eventx=x=event.xbutton.x; 2673 | ewin->eventy=y=event.xbutton.y; 2674 | if(event.type=MotionNotify) { 2675 | if (event.xmotion.state&Button1Mask) { 2676 | ewin->eventbutton=LEFTBUTTON; 2677 | ewin->dragging=1; 2678 | } else if(event.xmotion.state&Button3Mask) { 2679 | ewin->eventbutton=RIGHTBUTTON; //dragging for sliders/scrollbars/etc. 2680 | ewin->dragging=1; 2681 | } 2682 | } 2683 | switch (ewin->eventbutton) { 2684 | case LEFTBUTTON: 2685 | for(i=ewin->WidgetAmount-1; i>=0; i--) { 2686 | if(inActRange(ewin,i,x,y)) { 2687 | if(leftButtonAction(ewin,&ewin->W[i],x,y))break; 2688 | } 2689 | } 2690 | break; 2691 | case MIDBUTTON: 2692 | for(i=ewin->WidgetAmount-1; i>=0; i--) { 2693 | if(inActRange(ewin,i,x,y)) { 2694 | if(midButtonAction(ewin,&ewin->W[i]))break; 2695 | } 2696 | } 2697 | break; 2698 | case RIGHTBUTTON: 2699 | for(i=ewin->WidgetAmount-1; i>=0; i--) { 2700 | if(inActRange(ewin,i,x,y)) { 2701 | if(rightButtonAction(ewin,&ewin->W[i],x,y))break; 2702 | } 2703 | } 2704 | break; 2705 | case SCROLLUP: 2706 | for(i=ewin->WidgetAmount-1; i>=0; i--) { 2707 | if(inActRange(ewin,i,x,y)) { 2708 | if(wheelUpAction(ewin,&ewin->W[i]))break; 2709 | } 2710 | } 2711 | break; 2712 | case SCROLLDOWN: 2713 | for(i=ewin->WidgetAmount-1; i>=0; i--) { 2714 | if(inActRange(ewin,i,x,y)) { 2715 | if(wheelDnAction(ewin,&ewin->W[i]))break; 2716 | } 2717 | } 2718 | break; 2719 | } 2720 | break; 2721 | case Expose: 2722 | ewin->exposecnt++; 2723 | break; //if (event.xexpose.count==0) //full/partial refresh might be needed when moving this / other windows above 2724 | case ConfigureNotify: 2725 | if(event.xconfigure.width!=ewin->width || event.xconfigure.height!=ewin->height) { //if ((event.xconfigure.x!=ewin->x || event.xconfigure.y!=ewin->y)) break; 2726 | ewin->resizecnt++; //ewin->x=event.xconfigure.x; ewin->y=event.xconfigure.y; 2727 | ewin->width=event.xconfigure.width; 2728 | ewin->height=event.xconfigure.height; 2729 | } 2730 | break; //resizing //printf ("%d,%d, %d,%d \n",event.xconfigure.width,event.xconfigure.height,ewin->width,ewin->height); 2731 | case KeyPress: 2732 | switch (XLookupKeysym(&event.xkey,0)) { 2733 | case XK_Escape: 2734 | ewin->exitsig=1; 2735 | break; 2736 | //case XK_space: setIconXPM(ewin->d,ewin->w,ewin->s,icon_xpm); setTitle(ewin->d,ewin->w,"space nmély-szőrke pressed"); break; 2737 | } 2738 | break; 2739 | case ClientMessage: 2740 | if (event.xclient.message_type==ewin->wm_protocols && event.xclient.data.l[0]==ewin->delete_window) ewin->exitsig=1; 2741 | break; 2742 | default: 2743 | break; //keeping convention 2744 | } 2745 | 2746 | } 2747 | 2748 | if (hw->exitsig) { 2749 | if (hw->exitCallback!=NULL) { 2750 | (hw->exitCallback)(hw); 2751 | hw->exitsig=0; 2752 | } 2753 | } 2754 | #ifdef HGUI_CHILDWINDOWS 2755 | for(i=0; iChildAmount; i++) { 2756 | cwin=hw->Child[i]; 2757 | if(cwin==NULL) continue; //check if window is destroyed/uninitialized - array-size (ChildAmout) might change dynamically in the future 2758 | if(cwin->exitsig) { 2759 | if(cwin->exitCallback!=NULL) (cwin->exitCallback)(cwin); 2760 | else hideWindow(cwin); 2761 | } 2762 | } //destroyWindow(cwin); } } 2763 | #endif 2764 | 2765 | if (hw->resizecnt) { 2766 | redrawBackground(hw); //hw->width=getWinWidth(hw); hw->height=getWinHeight(hw); //redrawBackground(ewin,&event.xexpose); //drawBackground(ewin); // XFlush(ewin->d); //redrawing the whole background makes flickering. better if window is sent to X all-at-once as a pixmap 2767 | } 2768 | if (hw->exposecnt || hw->resizecnt) drawAllWidgets(hw); 2769 | #ifdef HGUI_ANIMATIONS 2770 | playAnimations(hw); //if(!hw->exposecnt) //if (selRes==0) 2771 | #endif //HGUI ANIMATIONS 2772 | 2773 | #ifdef HGUI_CHILDWINDOWS 2774 | for(i=0; iChildAmount; i++) { 2775 | cwin=hw->Child[i]; 2776 | if(cwin==NULL) continue; //check if window is destroyed/uninitialized 2777 | if (cwin->resizecnt) { 2778 | redrawBackground(cwin); //cwin->width=getWinWidth(cwin); cwin->height=getWinHeight(cwin); 2779 | } 2780 | if (cwin->exposecnt || cwin->resizecnt) drawAllWidgets(cwin); //drawWidgets(ewin,&event.xexpose); 2781 | #ifdef HGUI_ANIMATIONS 2782 | playAnimations(hw->Child[i]); 2783 | #endif //HGUI_ANIMATIONS 2784 | } 2785 | #endif //HGUI_CHILDWINDOWS 2786 | 2787 | if((void(*)())callback!=NULL) callback(hw,argptr); //custom loop-callback for main program. if NULL, nothing happens here 2788 | 2789 | usleep(REFRESHDELAY); 2790 | } 2791 | //else if(selRes==-1 && errno!=EINTR){printf("%s select error\n",ErrPfx);exit(EXIT_ERROR);} 2792 | } 2793 | } 2794 | } 2795 | 2796 | 2797 | 2798 | 2799 | //---------------------------------------------------------------------- 2800 | #if defined(__cplusplus) 2801 | } 2802 | #endif 2803 | //===================================================================================================== 2804 | -------------------------------------------------------------------------------- /hgui.h: -------------------------------------------------------------------------------- 1 | 2 | //====================================================================== 3 | //HermitGUI header-file to include in programs (or use as documentation) 4 | //====================================================================== 5 | #ifndef HGUI_HEADER 6 | #define HGUI_HEADER //used to prevent double inclusion of this header-file 7 | #if defined(__cplusplus) 8 | extern "C" 9 | { 10 | #endif 11 | 12 | 13 | //------------------------ defines and enumerations -------------------- 14 | #ifndef NULL 15 | #define NULL 0 //in case main program doesn't want to include stdlib 16 | #endif 17 | 18 | //define which widgets to include (reduce code size even more): (unfortunately enum can't be used for this, as it contains 'signed int' constants ) 19 | #ifndef HGUI_SELECTWIDGETS //if this is defined for gcc (-D option), the separate needed widgets can be added one-by-one in gcc-commandlin / makefile 20 | #define HGUI_PRIMITIVES //plot/line/rectangle/circle/etc. 21 | #define HGUI_BUTTONS //common group of all buttons 22 | #define HGUI_BLOCKS //rectangle-decorations to group widgets together 23 | #define HGUI_SLIDERS //adjustable sliders with knobs 24 | #define HGUI_SCROLLBARS //(depends on HGUI_BLOCKS) 25 | #define HGUI_PROGBARS //progress bars 26 | #define HGUI_TEXTFIELDS //common group of all widgets to display/edit text 27 | #define HGUI_PICTURES //adding pictures (plain pixdata or XPM-image) to the GUI 28 | #define HGUI_ANIMATIONS //common group for animations 29 | #define HGUI_CHILDWINDOWS //child- and subwindow support 30 | //#define HGUI_FILEBROWSER //composite widget 31 | //#define HGUI_COLORCHOOSER //composite widget 32 | #endif //HGUI_SELECTWIDGETS (#elif defined()...) 33 | //handle common groups - the groupnames define the internal names all at once 34 | #ifdef HGUI_BUTTONS //involve group-members automatically for BUTTONS 35 | #define HGUI_TEXTBUTTONS //push-buttons with text in the middle 36 | #define HGUI_PICBUTTONS //buttons with pictures in the middle (depends on HGUI_BUTTONS and HGUI_PICTURES) 37 | #endif 38 | #ifdef HGUI_TEXTFIELDS //involve group-members automatically for TEXTFIELDS 39 | #define HGUI_TEXTLINES //simple/centered one-line texts 40 | #define HGUI_TEXTBLOCKS //multiline text with wrapping capabilities 41 | #define HGUI_TEXTBOXES //multiline text(block) with scrolling, selection & editing capabilities 42 | //#define HGUI_TEXTEDITORS //TEXTBOXES with line(inputfield) / block editing capability 43 | //#define HGUI_LISTS //TEXTBOXES without wrapping, with row-selection capability 44 | //#define HGUI_MENUS //BUTTON+TEXTBOX with temporary pulldown 45 | //#define HGUI_TABS //BUTTON + widget-array start/end positions 46 | #endif 47 | #ifdef HGUI_ANIMATIONS //involve group-members automatically for ANIMATIONS 48 | #define HGUI_PICANIMS //playing successive (XPM) pictures repeatedly by a given speed 49 | #define HGUI_TEXTANIMS //scrolling text, etc. 50 | #endif 51 | 52 | //window options for createWindow() / createChildWindow() functions (they can be OR-ed if it makes sense) 53 | #define NORESIZE 1 //window can't be maximized or resized by grabbing its endges (and maximize button shouldn't appear in titlebar) 54 | #define NOTASKBAR 2 //window icon & title shouldn't appear in taskbar, window shouldn't be minimized/iconified to taskbar anytime (and minimize button shouldn't appear in titlebar) 55 | #define ALWAYSONTOP 4 //should be above all other windows until closed/hidden 56 | #define NODECOR 8 //no titlebar and border - window-moving/resizing/etc. should be handled from the main program (_WM_MOTIF_HINTS) 57 | #define MODALWIN 16 //for dialog-boxes, appears in front of parent-window and blocks access to parent window until modal window is closed 58 | #define TRAYAPP 32 //window should go into the system-tray/dock 59 | #define FULLSCREEN 64 //occupy tho whole screen including taskbar (useful for e.g. screensaver, maybe combined with NOWINMAN & ALWAYSONTOP to have screen-locking?) 60 | #define ZOOMABLE 128 //tells createWindow() if widgets should change size automatically to fit window-size. This clashes with NORESIZE option. 61 | #define NOWINMAN 256 //can be an option for window ignored by Window-manager: no titlebar/border, no taksbar-icon, stays on top of other windows (splash screen behaviour) 62 | 63 | 64 | enum MouseButtons { NOBUTTON,LEFTBUTTON,MIDBUTTON,RIGHTBUTTON,SCROLLUP,SCROLLDOWN } MouseButtons; 65 | 66 | 67 | 68 | 69 | //---- Screen & Window & Widget Structures and function-prototypes ----- 70 | int getScreenWidth (); //in pixels 71 | int getScreenHeight (); //in pixels 72 | 73 | 74 | typedef struct hWindow hWindow; //forward declaration, defined later in hgui.c 75 | 76 | hWindow* createWindow( int x, int y, int w, int h, char *title, unsigned long bgcol, unsigned long fgcol, 77 | int minwidth, int minheight, short options, char* xpmicon[], void (*exitCallback)() ); 78 | #ifdef HGUI_CHILDWINDOWS 79 | hWindow* createChildWindow( hWindow *root, int x, int y, int w, int h, char *title, unsigned long bgcol, unsigned long fgcol, 80 | int minwidth, int minheight, short options, char* xpmicon[], void (*exitCallback)() ); 81 | hWindow* createSubWindow( hWindow *parenthw, int x1, int y1, int x2, int y2, char *title, unsigned long bgcol, unsigned long fgcol); 82 | #endif 83 | //(subwindow is inner window, its coordinates can be negative and those are counted from parent-window's right/bottom-edge at creation/startup) 84 | 85 | hWindow* destroyWindow (hWindow *hw); 86 | 87 | void eventLoop (hWindow *hw, void (*callback)(), void* argptr ); 88 | //void loopCallback (hWindow *hw, void* argptr) {} //the format for main-loop callback function (both parameters can be omitted if not needed) 89 | //void exitCallback (hWindow *hw) {} //the format fo exit-callback function 90 | 91 | char eventButton (hWindow *hw); //(mouse) button of latest event, see MouseButtons enumeration for values 92 | int eventX (hWindow *hw); //mouse X coordinate of latest mouse click/scroll event (relative to window) 93 | int eventY (hWindow *hw); //mouse Y coordinate of latest mouse click/scroll event (relative to window) 94 | 95 | int getWinWidth (hWindow *hw); //in pixels, not including window-decoration 96 | int getWinHeight (hWindow *hw); //in pixels, not including window-decoration 97 | int getWinX (hWindow *hw); //in pixels from screen origin 98 | int getWinY (hWindow *hw); //in pixels from screen origin 99 | int getWidgetCount (hWindow *hw); //current number of added widgets in the window 100 | float getContrast (hWindow *hw); 101 | char* getTitle (hWindow *hw); //return window-title 102 | 103 | void setContrast (hWindow *hw, float contrast); //acceptable values between: 0.0..1.0 (if value is outside range, gets truncated) 104 | void setTitle (hWindow *hw, char *title); 105 | void setIconXPM (hWindow *hw, char *xpm[]); //only XPM with max. 64 colours is supported 106 | void setClass (hWindow *hw, char *cls, char *name); //'name' here is not titlebar (WM_NAME) but identification for the X-server 107 | void setWinCallback (hWindow *hw, void (*callback)() ); //set window-callback afterwards 108 | 109 | void iconifyWindow (hWindow *hw); 110 | void hideWindow (hWindow *hw); 111 | void showWindow (hWindow *hw); 112 | void refreshWindow (hWindow *hw); 113 | void redrawWindow (hWindow *hw); 114 | void clearWindow (hWindow *hw); 115 | void moveWindow (hWindow *hw, int x, int y); 116 | void resizeWindow (hWindow *hw, int w, int h); 117 | void toggleFullscreen(hWindow *hw); 118 | void hideMouseCursor (hWindow *hw); 119 | 120 | typedef struct hWidget { //universal widget structure - full version is defined later in hgui.c, their structure should match exactly to the specific widgets below 121 | union { 122 | int x,x1; 123 | } ; 124 | union { 125 | int y,y1; 126 | } ; 127 | union { 128 | int x2,w,r,rx; 129 | } ; 130 | union { 131 | int y2,h,ry; 132 | } ; 133 | union { 134 | int hpos,border,knobsize,depth,startdeg; 135 | } ; 136 | union { 137 | long vpos,bevel,scalewidth,degree; 138 | } ; 139 | union { 140 | unsigned long bgcol,color,transpcol; 141 | } ; 142 | union { 143 | unsigned long fgcol,textcol; 144 | } ; 145 | union { 146 | unsigned long knobcol,progtextcol; 147 | } ; 148 | unsigned long captcol; 149 | union { 150 | void *data,*text,*content,*title,*caption,*pixdata,*xpm,*xpmlist; 151 | } ; 152 | float pos ; 153 | union { 154 | float ratio,scale; 155 | } ; 156 | union { 157 | char wrap,framedelay; 158 | } ; 159 | char scrollbars ; 160 | union { 161 | char pixstep,autofit; 162 | } ; 163 | char state; 164 | int actx1,acty1,actx2,acty2; //read-only (writing could fuck up the GUI 165 | } hWidget; 166 | 167 | hWindow* getWin (void *widgetptr); //find hgui-window for the given widget 168 | void redrawWidget (void *widgetptr); //involves dynamic coordinates & zooming according to current window-size and clearing movement-trails, and flushing to X-server 169 | void changeTextPtr (void *widgetptr,char* textptr); //caption/text-content POINTER change.. be careful not to give literal strings in functions as they will be destroyed eventually 170 | void setCallback (void *widgetptr, void (*callback)(), void* argptr); //set the callback function an arg/parameter afterwards (e.g. when cross-linking widgets or when widget-adding order requires it) 171 | //void callback (hWidget *widgetptr, void* argptr) {} //the full format for widget-callback-functions (both parameters can be omitted if not needed) 172 | 173 | //these distinct widget-structures are not totally necessary (but strongly advised), the universal 'hWidget' structure can be used in their place: 174 | // Widgetname //signatures and members/fields to read/set for complex operations: 175 | #ifdef HGUI_TEXTBUTTONS 176 | typedef struct Button { 177 | int x,y,w,h; 178 | int border; 179 | long bevel; 180 | unsigned long color,textcol,nop1,nop2; 181 | char* title; 182 | float nop3,nop4; 183 | char state; 184 | } Button; // if bevel>1: 3D-effect 185 | Button* addButton ( hWindow *hw, int x, int y, int w, int h, char *title, unsigned long bgcol, unsigned long fgcol, 186 | char state, char bevel, char border, char *font, void (*callback)(), void* argptr ); 187 | 188 | typedef struct ButtonDyn { 189 | int x1,y1,x2,y2; 190 | int border; 191 | long bevel; 192 | unsigned long color,textcol,nop1,nop2; 193 | char* title; 194 | float nop3,nop4; 195 | char state; 196 | } ButtonDyn; // if bevel>1: 3D-effect 197 | ButtonDyn* addButtonDyn ( hWindow *hw, int x1, int y1, int x2, int y2, char *title, unsigned long bgcol, unsigned long fgcol, 198 | char state, char bevel, char border, char *font, void (*callback)(), void* argptr ); 199 | #endif 200 | 201 | #ifdef HGUI_PICBUTTONS 202 | typedef struct Widget ButtonXPM; // x,y,w,h, *pixdata, bgcol, state (0/1), bevel(if>1:3D-effect),border, *callback, (readonly: actx1,acty1,acty1,acty2, id) 203 | ButtonXPM* addButtonXPM ( hWindow *hw, int x, int y, int w, int h, char *xpm[], unsigned long bgcol, 204 | char state, char bevel, char border, void (*callback)(), void* argptr ); 205 | #endif 206 | 207 | #ifdef HGUI_SLIDERS 208 | typedef struct Widget VSlider; // x,y1,w,y2, knobsize,scalewidth, *caption, bgcol,fgcol,knobcol,captcol, pos(0.0..1.0),scale(0.0..1.0), *font, *callback, (readonly: actx1,acty1,acty1,acty2,margin, id) 209 | VSlider* addVSlider ( hWindow *hw, int x, int y1, int w, int y2, char knobsize, char scalewidth, char *caption, 210 | unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, unsigned long captcol, 211 | float pos, float scale, char *font, void (*callback)(), void* argptr ); 212 | typedef struct Widget HSlider; // x1,y,x2,h, knobsize,scalewidth, *caption, bgcol,fgcol,knobcol,captcol, pos(0.0..1.0),scale(0.0..1.0), *font, *callback, (readonly: actx1,acty1,acty1,acty2,margin, id) 213 | HSlider* addHSlider ( hWindow *hw, int x1, int y, int x2, int h, char knobsize, char scalewidth, char *caption, 214 | unsigned long bgcol, unsigned long fgcol, unsigned long knobcol, 215 | unsigned long captcol, float pos, float scale, char *font, void (*callback)(), void* argptr ); 216 | #endif 217 | 218 | #ifdef HGUI_TEXTLINES 219 | typedef struct Widget TextLine; // x, y, *text, textcol, *font, (readonly: id) 220 | TextLine* addTextLine ( hWindow *hw, int x, int y, char *text, unsigned long color, char *font); 221 | typedef struct Widget TextCentered;// x1,y1,x2,y2, *text, textcol, *font, (readonly: id) 222 | TextCentered* addTextCentered ( hWindow *hw, int x1, int y1, int x2, int y2, char *text, unsigned long color, char *font ); 223 | #endif 224 | #ifdef HGUI_TEXTBLOCKS 225 | typedef struct Widget TextBlock; // x1,y1,x2,y2, *text, textcol, *font, wrap(0/1), (readonly: id) 226 | TextBlock* addTextBlock ( hWindow *hw, int x1, int y1, int x2, int y2, char *text, unsigned long color, char wrap, char *font ); 227 | #endif 228 | #ifdef HGUI_TEXTBOXES 229 | typedef struct Widget TextBox; // x1,y1,x2,y2, *text, bgcol,fgcol, wrap(0/1), scrollbars(1/2/1+2), autofit(0/1), vpos,hpos,vpixpos,vpixsize, *font, actx1,acty1,acty1,acty2,hpixsize, id, (readonly: *vscroll,*hscroll (widget-pointers to children-scrollbars of textbox)) 230 | TextBox* addTextBox ( hWindow *hw, int x1, int y1, int x2, int y2, char *content, unsigned long bgcol, unsigned long fgcol, 231 | char wrap, char scrollbars, char autofit, long vpos, int hpos, char *font ); 232 | #endif 233 | 234 | #ifdef HGUI_PROGBARS 235 | typedef struct Widget HProgBar; // x1,y1,x2,y2, bevel, *caption, bgcol,fgcol,progtextcol,captcol, pos(0.0..1.0),scale(0.0..1.0), *font, *callback, (readonly: actx1,acty1,acty1,acty2, id) 236 | HProgBar* addHProgBar ( hWindow *hw, int x1, int y1, int x2, int y2, char bevel, char *caption, unsigned long bgcol, unsigned long fgcol, 237 | unsigned long textcol, unsigned long captcol, float pos, float scale, char* font, void (*callback)(), void* argptr ); 238 | typedef struct Widget VProgBar; // x1,y1,x2,y2, bevel, *caption, bgcol,fgcol,progtextcol,captcol, pos(0.0..1.0),scale(0.0..1.0), *font, *callback, (readonly: actx1,acty1,acty1,acty2, id) 239 | VProgBar* addVProgBar ( hWindow *hw, int x1, int y1, int x2, int y2, char bevel, char *caption, unsigned long bgcol, unsigned long fgcol, 240 | unsigned long textcol, unsigned long captcol, float pos, float scale, char* font, void (*callback)(), void* argptr ); 241 | #endif 242 | 243 | #ifdef HGUI_SCROLLBARS 244 | typedef struct Widget VScroll; // x,y1,w,y2, bgcol,fgcol,knobcol, pos(0.0..1.0),ratio(0.0..1.0), *callback, (readonly: actx1,acty1,acty1,acty2,margin, id, *parentbox) 245 | VScroll* addVScroll ( hWindow *hw, int x, int y1, int w, int y2, unsigned long bgcol, unsigned long fgcol, 246 | unsigned long knobcol, float pos, float ratio, void (*callback)(), void* argptr ); 247 | typedef struct Widget HScroll; // x1,y,x2,h, bgcol,fgcol,knobcol, pos(0.0..1.0),ratio(0.0..1.0), *callback, (readonly: actx1,acty1,acty1,acty2,margin, id, *parentbox) 248 | HScroll* addHScroll ( hWindow *hw, int x1, int y, int x2, int h, unsigned long bgcol, unsigned long fgcol, 249 | unsigned long knobcol, float pos, float ratio, void (*callback)(), void* argptr ); 250 | #endif 251 | 252 | #ifdef HGUI_BLOCKS 253 | typedef struct Widget Block; // x1, y1, x2, y2, (readonly: id) 254 | Block* addBlock ( hWindow *hw, int x1, int y1, int x2, int y2 ); 255 | typedef struct Widget BlockFill; // x1, y1, x2, y2, color, (readonly: id) 256 | BlockFill* addBlockFill ( hWindow *hw, int x1, int y1, int x2, int y2, unsigned int color ); 257 | #endif 258 | 259 | #ifdef HGUI_PICTURES 260 | typedef struct Widget Picture; // x,y, *pixdata, width,height,depth, *callback, (readonly: actx1,acty1,acty1,acty2, id) 261 | Picture* addPicture ( hWindow *hw, int x, int y, int width, int height, int depth, char* pixeldata, void (*callback)(), void* argptr ); 262 | typedef struct Widget PictureXPM; // x, y, *xpm, transpcol, *callback, (readonly: actx1,acty1,acty1,acty2, id) 263 | PictureXPM* addXPM ( hWindow *hw, int x, int y, char *xpm[], unsigned long bgcol, void (*callback)(), void* argptr ); 264 | #endif // XPM:max 64 colours! 265 | 266 | #ifdef HGUI_PICANIMS 267 | //typedef struct Widget Animation; 268 | typedef struct Widget AnimXPM; // x,y, *xpmlist, transpcol, framedelay, framecnt,spdcnt, *callback, (readonly:actx1,acty1,acty1,acty2, id) 269 | AnimXPM* addAnimXPM ( hWindow *hw, int x, int y, void* xpmlist[], unsigned long bgcol, char framedelay, void (*callback)(), void* argptr ); 270 | #endif 271 | 272 | #ifdef HGUI_TEXTANIMS 273 | typedef struct Widget TextScroll; // x1,y1,x2,y2, *text, bgcol, fgcol, framedelay,pixstep *font, framecnt,spdcnt (readonly:actx1,acty1,acty1,acty2, id) 274 | TextScroll* addTextScroll ( hWindow *hw, int x1, int y1, int x2, int y2, char *text, unsigned long bgcol, unsigned long fgcol, 275 | char framedelay, char pixstep, char *font ); 276 | #endif //HGUI_TEXTANIMS 277 | 278 | #ifdef HGUI_PRIMITIVES 279 | typedef struct Widget Primitive; 280 | Primitive* addPoint (hWindow *hw, int x, int y, unsigned long col); 281 | Primitive* addLine (hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col); 282 | Primitive* addRect (hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col); 283 | Primitive* addRectFill (hWindow *hw, int x1, int y1, int x2, int y2, unsigned long col); 284 | Primitive* addArc (hWindow *hw, int x1, int y1, int x2, int y2, int startdeg, int degree, unsigned long col); 285 | Primitive* addArcFill (hWindow *hw, int x1, int y1, int x2, int y2, int startdeg, int degree, unsigned long col); 286 | Primitive* addCircle (hWindow *hw, int x, int y, int r, unsigned long col); 287 | Primitive* addCircleFill (hWindow *hw, int x, int y, int r, unsigned long col); 288 | Primitive* addEllipse (hWindow *hw, int x, int y, int rx, int ry, unsigned long col); 289 | Primitive* addEllipseFill (hWindow *hw, int x, int y, int rx, int ry, unsigned long col); 290 | 291 | typedef struct hWindow hDrawable; //should be able to assign pixmap as drawable destination instead of bare X-window 292 | //primitive drawing routines (if put on window directly they get destructed when window gets resized / etc. -> better drawing into a picture/pixmap widget): 293 | void drawPoint (hDrawable *hw, int x, int y, unsigned long col); 294 | void drawLine (hDrawable *hw, int x1, int y1, int x2, int y2, unsigned long col); 295 | void drawRect (hDrawable *hw, int x1, int y1, int x2, int y2, unsigned long col); 296 | void drawRectFill (hDrawable *hw, int x1, int y1, int x2, int y2, unsigned long col); 297 | void drawArc (hDrawable *hw, int x1, int y1, int x2, int y2, int startdeg, int degree, unsigned long col); 298 | void drawArcFill (hDrawable *hw, int x1, int y1, int x2, int y2, int startdeg, int degree, unsigned long col); 299 | void drawCircle (hDrawable *hw, int x, int y, int r, unsigned long col); 300 | void drawCircleFill (hDrawable *hw, int x, int y, int r, unsigned long col); 301 | void drawEllipse (hDrawable *hw, int x, int y, int rx, int ry, unsigned long col); 302 | void drawEllipseFill (hDrawable *hw, int x, int y, int rx, int ry, unsigned long col); 303 | void drawPolygon (hDrawable *hw, unsigned long col, char count, ...); //count:number of points, parameters following 'count' are X and Y coordinates alternating 304 | #endif 305 | 306 | 307 | 308 | 309 | //--------------------- Miscellaneous helper routines ------------------ 310 | typedef struct XPMstruct { 311 | char *pixdata; 312 | int width, height; 313 | } XPMstruct; 314 | 315 | XPMstruct XPMtoPixels(char* source[], unsigned long bgcol); //max. 64-colour XPMs are supported! (one base64 char/colour) 316 | 317 | unsigned long fadeCol(unsigned int col, float bri); // 0.0 < bri <= 1.0 enlightens ; -1.0 <= bri < 0.0 darkens color 318 | 319 | void correctRange(float *input); //sets input between 0.0 and 1.0 320 | 321 | 322 | 323 | 324 | //---------------------------------------------------------------------- 325 | #if defined(__cplusplus) 326 | } 327 | #endif 328 | #endif //HGUI_HEADER 329 | //====================================================================== 330 | -------------------------------------------------------------------------------- /hguidemo/diagram.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //#include 4 | #include 5 | 6 | #define SBHEIGHT 30 7 | #define MAX_DATA_LEN 32768 8 | #define DATA_HEIGHT 256 9 | 10 | int data[MAX_DATA_LEN]; 11 | int datalen=0; 12 | 13 | 14 | void drawData(hWindow *hw, long int pos, int* data, int width) 15 | { 16 | int i,x=0; 17 | for (i=0; i<256; i+=16) drawLine(hw,0,DATA_HEIGHT-i,width-1,DATA_HEIGHT-i,i%0x40?0x000080:0x0000FF); 18 | for (i=0; ipos*(datalen), data, getWinWidth(hw) ); 33 | } 34 | 35 | void sbCallback(hWidget *w) 36 | { 37 | drawRectFill(getWin(w),0,0,getWinWidth(getWin(w)),DATA_HEIGHT,0); //clearWindow(getWin(w)); 38 | drawData( getWin(w), w->pos*(datalen), data, getWinWidth(getWin(w)) ); 39 | } 40 | 41 | int main (int argc, char **argv) 42 | { 43 | hWindow *hw; 44 | int i, width, readata=0; 45 | FILE *InputFile; 46 | 47 | if (argc<2) { 48 | printf("Usage: diagram \n"); 49 | return 1; 50 | } 51 | 52 | InputFile = fopen(argv[1],"rb"); 53 | printf("\n"); 54 | datalen=0; 55 | do { 56 | readata=fgetc(InputFile); 57 | data[datalen++]=readata; 58 | if(readata!=EOF) printf("%2.2X ",readata); 59 | } while (readata!=EOF && datalen //C standard library 10 | #include //printf,sprintf,fprintf,etc. 11 | //#include //operations like strlen() 12 | 13 | #include //subcomponents can be selected with -D options for gcc (see hgui.h for info) 14 | 15 | //defining some defaults to use as 'theme', but you can have custom mechanism for styling of course 16 | #define BGCOLOR 0xCEC8CA 17 | #define FGCOLOR 0x001000 18 | #define HOLECOLOR 0x001100 19 | #define BUTTBGCOL 0x10D428 20 | #define BUTTFGCOL 0x202020 21 | #define BUTTBEVEL 2 22 | #define BUTTBORDER 1 23 | #define BUTTBORDCOL HOLECOLOR 24 | #define TEXTBGCOL 0xE0F0E0 25 | #define TEXTFGCOL 0x203010 26 | #define PROGBGCOL 0x80E0C0 27 | #define PROGFGCOL 0x1020E0 28 | #define PROGBEVEL BUTTBEVEL 29 | #define PROGTEXTCOL 0xFFFFFF 30 | #define SLIDERHOLE 2 31 | #define SLIDSCALEW 20 32 | #define SLIDKNOBSIZE 16 33 | #define SLIDBGCOL 0xC0E0D0 34 | #define SLIDFGCOL 0x20C080 35 | #define SLIDKNOBCOL 0xC020E0 36 | #define SCROLLBGCOL 0xC0A080 37 | #define SCROLLFGCOL 0x624050 38 | #define SCROLLKNOBCOL 0xD8D0D4 39 | #define SCROLLBUTTSIZE 14 40 | #define ANIMDELAY 10 //in frames (check hgui.c for REFRESHRATE definition ) 41 | 42 | #include "icon.xpm" 43 | 44 | static char *questionmark_xpm[] = { "16 16 8 1"," c None","1 c #DB0000","2 c #FF0000","3 c #B60000","4 c #6D0000","5 c #FFB400","6 c #FF7A00","7 c #920000", 45 | " 12234 "," 155566234 "," 25622226234 "," 662 26234 "," 22 2234 "," 2334 "," 2234 "," 22344 ", 46 | " 2634 "," 637 "," 234 "," 424 "," "," 22 "," 2624 "," 24 " 47 | }; 48 | 49 | static char *mouse_xpm[] = {"20 20 3 1 0 0","0 c #000000","1 c #FFFFFF"," c None", 50 | "00 ","010 ","01100 ","011100 ","0111100 ","01110100 ","010111100 ", 51 | "0111111100 ","01111111100 ","01111111100 ","01111111100 ","01111111000 ","0011111000 "," 00000100 ", 52 | " 000010 "," 010 "," 010 "," 01 "," 1 "," ", 53 | }; 54 | 55 | #include "robodance.anim" 56 | 57 | typedef struct twoWidgets { 58 | hWidget *w1,*w2; 59 | } twoWidgets; 60 | 61 | char blabla[]="Bla Bla global"; //this global text doesn't get destructed when function exits 62 | 63 | void b1callback(hWidget *w, ButtonDyn *butt2) 64 | { 65 | setTitle(getWin(w),"Button 1 pressed!"); 66 | butt2->state=0; 67 | butt2->title="b1press"; 68 | butt2->x1+=1; 69 | butt2->x2+=1; 70 | redrawWidget(butt2); 71 | } 72 | 73 | void b2callback(ButtonDyn *butt2) 74 | { 75 | setTitle(getWin(butt2),"Button 2 pressed!"); 76 | butt2->title="Na?"; 77 | redrawWidget(butt2); 78 | } 79 | 80 | void b3callback(hWidget *w, hWidget *scr1) 81 | { 82 | setTitle(getWin(w),"Button 3 pressed!"); 83 | scr1->pos=0.2; 84 | redrawWidget(scr1); 85 | toggleFullscreen(getWin(w)); 86 | } 87 | 88 | void sl1callback(hWidget *slider1, char* constr) 89 | { 90 | hWindow *win=getWin(slider1); 91 | setTitle(win,"Slider1"); 92 | setContrast(win,slider1->pos); 93 | sprintf(constr,"c.:%1.1f",getContrast(win)); 94 | changeTextPtr(slider1,constr); 95 | } //slider1->caption=constr; redrawWidget(slider1); } 96 | 97 | void hslid1callback(hWidget *sl1, hWidget* prog3) 98 | { 99 | hWindow *win=getWin(sl1); 100 | setTitle(win,"horizontal Slider callback"); 101 | changeTextPtr(sl1,blabla); //remember, this is only a POINTER to a text! Don't use literals for changeTextPtr as they could be destroyed after this function exits 102 | if (eventButton(win)==SCROLLDOWN) { 103 | prog3->pos-=0.01; 104 | if(prog3->pos<=0.0) prog3->pos=0.0; 105 | redrawWidget(prog3); 106 | } else if (eventButton(win)==SCROLLUP) { 107 | prog3->pos+=0.1; 108 | redrawWidget(prog3); 109 | } 110 | }; 111 | 112 | void scrcallback(hWidget *w, hWindow *win) 113 | { 114 | setTitle(win,"Scrolling ás, ő maga "); 115 | } 116 | 117 | void piccallback(hWidget *pic, twoWidgets *tw) 118 | { 119 | hWidget *prog1=tw->w1; 120 | hWidget *xpb1=tw->w2; 121 | setTitle(getWin(pic),"Pictureclick"); 122 | prog1->pos+=0.01; 123 | if(prog1->pos>1.0) prog1->pos=0.05; 124 | redrawWidget(prog1); 125 | xpb1->data=mouse_xpm; 126 | redrawWidget(xpb1); 127 | } 128 | 129 | void xpmcallback(PictureXPM *xpm, twoWidgets *t) 130 | { 131 | hWidget *prog1=t->w1; 132 | hWidget *xpb1=t->w2; 133 | prog1->pos-=0.02; 134 | if(prog1->pos<0) prog1->pos=0.9; 135 | redrawWidget(prog1); 136 | xpb1->data=icon_xpm; 137 | redrawWidget(xpb1); 138 | } 139 | 140 | void butxpmcallback(hWidget *w, char* toggle) 141 | { 142 | setIconXPM(getWin(w),*toggle?questionmark_xpm:mouse_xpm); 143 | *toggle^=1; 144 | setTitle(getWin(w),"ProgramIcon changed"); 145 | } 146 | 147 | void prog2callback(hWidget *pr2, hWindow *win) 148 | { 149 | if(eventButton(win)==SCROLLUP) pr2->pos+=0.1; 150 | if(eventButton(win)==SCROLLDOWN) pr2->pos-=0.2; 151 | if(eventButton(win)==LEFTBUTTON) pr2->pos=(float)(eventX(win)-pr2->actx1)/(float)(pr2->actx2-pr2->actx1); 152 | correctRange(&pr2->pos); 153 | redrawWidget(pr2); 154 | } 155 | 156 | void prog3callback(hWidget *prog3, hWindow *win) 157 | { 158 | if(eventButton(win)==SCROLLUP) prog3->pos+=prog3->ratio; 159 | if(eventButton(win)==SCROLLDOWN) prog3->pos-=prog3->ratio; 160 | redrawWidget(prog3); 161 | } 162 | 163 | void subwbcallback() 164 | { 165 | printf("Subwindow button pressed\n"); 166 | } 167 | 168 | void loopcallback(hWindow *hw, char* fullscrswitch) 169 | { 170 | if(*fullscrswitch==0 && getWinWidth(hw)>720) { 171 | setTitle(hw,"Bigger than 720p!"); 172 | *fullscrswitch=1; 173 | } 174 | } 175 | 176 | void exitcallback(hWindow *hw) 177 | { 178 | printf("Exit button on main window pressed: Exiting by this custom callback-function...\n"); 179 | destroyWindow(hw); 180 | exit(0); 181 | } 182 | void childExit(hWindow *hw) 183 | { 184 | printf("Exit button on child-window pressed. Killing child-window \"%s\" by custom callback.\n",getTitle(hw)); 185 | destroyWindow(hw); 186 | } 187 | 188 | 189 | //====================== Main program & entry-point ================================================ 190 | 191 | int main (int argc, char **argv) //note: literals (buttun-names,progressbar-captions,etc.) get destroyed when main exits. 192 | { 193 | int i, GUIwidth=600, GUIheight=400, ChildWidth=300, ChildHeight=200; 194 | 195 | char textample[]="Addig nyújtózkodj, ameddig a takaród ér! \n Aki másnak vermet ás, ő maga esik bele!"; 196 | char scrolltext[]="ő á I wonder why the grass is green, and why the wind is never seen. Who taught the birds to build a nest, and told the trees to take a rest? " \ 197 | "O, when the Moon is not quite round, where can the missing bit be found? Who lights the stars when they blow out, and makes the lightning flash about? " \ 198 | "Who paints the rainbow in the sky, and hangs the fluffy clouds so high? Why is it now, do you suppose, that Dad won't tell me if he knows? (Connie Amarel)"; 199 | char constr[16]="contr:xx"; //note: this string doesn't get destroyed when the callback functions using it exits, but it IS destroyed upon exiting this main() function 200 | char defont[]="-*-*vera sans-bold-r-*-*-14-*-*-*-p-*-*-*"; 201 | 202 | hWindow *hwin, *childwin=NULL, *subwin; 203 | ButtonDyn *butt2; 204 | HProgBar *prog2; 205 | ButtonXPM *xpb1; 206 | hWidget *text1,*slider1,*prog1,*prog3,*scr1; 207 | PictureXPM *xpmw; 208 | char fullscrswitch=0,toggle; 209 | 210 | printf("\nScreen Resolution: %d x %d\n",getScreenWidth(),getScreenHeight()); 211 | hwin=createWindow( (getScreenWidth()-GUIwidth)/2, (getScreenHeight()-GUIwidth)/2, GUIwidth, GUIheight, 212 | "HermitGUI!", BGCOLOR, FGCOLOR, 512, 384, ZOOMABLE, icon_xpm, exitcallback); 213 | //resizeWindow(hwin,GUIwidth-10,GUIheight-5); 214 | 215 | butt2=addButtonDyn(hwin,90,30,140,56,"adgButton",BUTTBGCOL,BUTTFGCOL,1,2,2,"6x13",b2callback,NULL); 216 | addButton(hwin,20,30,50,26,"addButt",BUTTBGCOL,BUTTFGCOL,0,4,2,"6x13",b1callback,butt2); 217 | scr1=(hWidget*)addVScroll(hwin,366,20,16,-20,SCROLLBGCOL,SCROLLFGCOL,SCROLLKNOBCOL,0.1,0.3,scrcallback,hwin); 218 | addButton(hwin,-90,-60,70,26,"ődgBétt2",BGCOLOR,FGCOLOR,0,1,1,"6x13",b3callback,scr1); 219 | addTextLine(hwin,210,-20,"TextLine\nNoLinefeedSupport",0x305015,defont); 220 | addTextBlock(hwin,160,30,270,155,textample,0x001000,1,defont); 221 | addTextBlock(hwin,400,10,-20,-360,textample,0x001000,0,"-*-*vera sans-medium-r-*-*-12-*-*-*-p-*-*-*"); 222 | addBlock(hwin,160-10,30-10,270+10,150+10); //addBlock(400-2,20-2,-20,80); 223 | addTextBox(hwin,400,100,-20,200,"blaab\noaiaos ő maga ao\nse hiao \n se tohe\naisoa ith ioód ér! he hae\nsteho a",TEXTBGCOL,TEXTFGCOL,1,0,1,0,0,"fixed"); 224 | addTextBox(hwin,400,210,-20,-70,"gipszjakab oea\niieo aooi ouiola\nmély\nszőr aoe\noei a a\noei u keo eoae iio \na\noabsol\noiaoeioiu",0x506020,0xc0e0a0,0,1+2,1,1,4,defont); 225 | slider1=(hWidget*)addVSlider(hwin,20,100,50,200,SLIDKNOBSIZE,SLIDSCALEW,"Contrast",SLIDBGCOL,SLIDFGCOL,SLIDKNOBCOL,0x0000ff,getContrast(hwin),0.05,defont,sl1callback,constr); 226 | addVSlider(hwin,90,100,56,-200,48,SLIDSCALEW,"Speaker",0x303030,0x504050,0xC0C0C0,0x003000,0.2,0.04,"fixed",NULL,NULL); 227 | prog3=(hWidget*)addVProgBar(hwin,65,232,82,-80,PROGBEVEL,"Vert.pr",0x00C040,0xd0F050,0xFFFFFF,0x00c000,0.76,0.05,NULL,prog3callback,hwin); 228 | addHSlider(hwin,160,179,272,20,10,4,"horizontal slider",fadeCol(BGCOLOR,0.1),0x101010,0xc0c0c0,0x101010,0.3,0.1,"fixed",hslid1callback,prog3); 229 | prog1=(hWidget*)addHProgBar(hwin,80,-60,200,-20,PROGBEVEL,"Process...",PROGBGCOL,PROGFGCOL,PROGTEXTCOL,0xFF0000,0.63,0.0,"fixed",NULL,NULL); 230 | addBlock(hwin,5,5,-6,-6); //separator decoration lines between blocks of widgets 231 | prog2=addHProgBar(hwin,10,-40,72,-20,1,NULL,0x000000,0x00c030,PROGTEXTCOL,0xFF0000,0.83,0.1,"fixed",prog2callback,hwin); 232 | addVProgBar(hwin,30,232,55,290,PROGBEVEL,"Vert.pr",PROGBGCOL,PROGFGCOL,PROGTEXTCOL,0x00c000,0.76,0.0,defont,NULL,NULL); 233 | addBlockFill(hwin,250,270,330,-50,0x251506); 234 | addTextCentered(hwin,250,270,330,-50,"CenText ógé",0xf0e0a0,"fixed"); 235 | addHScroll(hwin,440,-25,-12,16,0x3a6302,0x002000,0x40c020,0.18,0.74,scrcallback,hwin); 236 | int w=124,h=98; 237 | char pixeldata[w*h*32/8]; 238 | for(i=0; i c #FF6363", 16 | ", c #FFCE9C", 17 | "' c #FFFFCE", 18 | ") c #101010", 19 | " ", 20 | " ", 21 | " ", 22 | " ", 23 | " ", 24 | " ", 25 | " ", 26 | " ", 27 | " ", 28 | " ", 29 | " ", 30 | " ", 31 | " ", 32 | " ", 33 | " '''''' ", 34 | " ''',,,,' ", 35 | " '',,,,,,,' ", 36 | " ' %)$,,$)$,*= ", 37 | " ''))),,)))**$ ", 38 | " ',$)$,,$)#*$# ", 39 | " ',,,,,,,**$#$ ", 40 | " ,,,*****$##= ", 41 | " ',***$$#+#% ", 42 | " =*#+##%- ", 43 | " #% ", 44 | " - ,>@@>, ", 45 | " =%#)+$;;;;$+ ", 46 | " &++##$;;;;;;+# ", 47 | " &+& >;;;;;;$+$ ", 48 | " ) >;;;;;@$-)& ", 49 | " +% ;;;;;;@@'=) ", 50 | " ## >;;;;;@+'++ ", 51 | " ## >;;;;@@#)# ", 52 | " -% *;;;;@@)% ", 53 | " ->;;@@)% ", 54 | " &)>$$$% ", 55 | " %)- +% ", 56 | " #) %)% ", 57 | " %+ -)+ ", 58 | " =# %) ", 59 | " &+ &+ ", 60 | " %+- - - - -) ", 61 | " %+)+%-====%+)#% ", 62 | " )))))&&&%&+)))+- ", 63 | " -%+)+#%%%%%#+)+$=- ", 64 | " -==&&&%%%%%%&&&==- ", 65 | " -===&%&&&&&&===- ", 66 | " -----====----- ", 67 | " ", 68 | " ", 69 | " ", 70 | " ", 71 | " ", 72 | " ", 73 | " ", 74 | " ", 75 | " ", 76 | " ", 77 | " ", 78 | " "}; 79 | 80 | 81 | static char * a1_xpm[] = { 82 | "60 60 16 1", 83 | " c None", 84 | ". c #101010", 85 | "+ c #424242", 86 | "@ c #630000", 87 | "# c #636331", 88 | "$ c #9C4A4A", 89 | "% c #ADADAD", 90 | "& c #BDBDBD", 91 | "* c #CE9C63", 92 | "= c #CECECE", 93 | "- c #DEDEDE", 94 | "; c #FF0000", 95 | "> c #FF6363", 96 | ", c #FFCE9C", 97 | "' c #FFFFCE", 98 | ") c #101010", 99 | " ", 100 | " ", 101 | " ", 102 | " ", 103 | " ", 104 | " ", 105 | " ", 106 | " ", 107 | " ", 108 | " ", 109 | " ", 110 | " ", 111 | " ", 112 | " '''''' ", 113 | " ''',,,,' ", 114 | " '',,,,,,,' ", 115 | " ' %)$,,$)$,*= ", 116 | " ''))),,)))**$ ", 117 | " ',$)$,,$)#*$# ", 118 | " ',,,,,,,**$#$ ", 119 | " ,,,*****$##= ", 120 | " ',***$$#+#% ", 121 | " =*#+##%- ", 122 | " #% ", 123 | " -===,>@@>, - ", 124 | " -##+)+$;;;;$)%+%# ", 125 | " -+#%$$;;;;;@$+#=)- ", 126 | " )- >;;;;;;$ +& ", 127 | " -+- >;;;;;@$ +% ", 128 | " =+% ;;;;;;@@ +% ", 129 | " &+% >;;;;;@$ %# ", 130 | " -%= >;;;;@@$ &+ ", 131 | " *;;;;@@% -& ", 132 | " >;;@@$ ", 133 | " #$$$+ ", 134 | " #% =) ", 135 | " += ) ", 136 | " ) )- ", 137 | " %+)+= += ", 138 | " ))))) +% ", 139 | " %+)+% #% ", 140 | " %# ", 141 | " -----====&+)$- ", 142 | " -===&&&&&&+)))+- ", 143 | " -==&&&%%%%%%+)+%=- ", 144 | " -==&%&%%%%%%&&&==- ", 145 | " -===&&&&&%&&===- ", 146 | " -----====----- ", 147 | " ", 148 | " ", 149 | " ", 150 | " ", 151 | " ", 152 | " ", 153 | " ", 154 | " ", 155 | " ", 156 | " ", 157 | " ", 158 | " "}; 159 | 160 | 161 | static char * a2_xpm[] = { 162 | "60 60 16 1", 163 | " c None", 164 | ". c #101010", 165 | "+ c #424242", 166 | "@ c #630000", 167 | "# c #636331", 168 | "$ c #9C4A4A", 169 | "% c #ADADAD", 170 | "& c #BDBDBD", 171 | "* c #CE9C63", 172 | "= c #CECECE", 173 | "- c #DEDEDE", 174 | "; c #FF0000", 175 | "> c #FF6363", 176 | ", c #FFCE9C", 177 | "' c #FFFFCE", 178 | ") c #101010", 179 | " ", 180 | " ", 181 | " ", 182 | " ", 183 | " ", 184 | " ", 185 | " ", 186 | " ", 187 | " ", 188 | " ", 189 | " ", 190 | " ", 191 | " ", 192 | " ", 193 | " ", 194 | " ", 195 | " '''''' ", 196 | " ''',,,,' ", 197 | " '',,,,,,,' ", 198 | " ' %)$,,$)$,*= ", 199 | " ''))),,)))**$ ", 200 | " ',$)$,,$)#*$# ", 201 | " ',,,,,,,**$#$ ", 202 | " ,,,*****$##= ", 203 | " ',***$$#+#% ", 204 | " =*#+##%- ", 205 | " #% ", 206 | " ,>@@>, ", 207 | " -)#$;;;;$)%= ", 208 | " %#++;;;;;@)#$% ", 209 | " %+#%$;;;;;;$'#) ", 210 | " #+='>;;;;;@$'$# ", 211 | " %+'';;;;;;@@'+# ", 212 | " +%->;;;;;@+-#% ", 213 | " %+=>;;;;@@$=#& ", 214 | " &+%*;;;;@@%=#& ", 215 | " %& >;;@@$ &- ", 216 | " #$$$)= ", 217 | " %# += ", 218 | " ## +% ", 219 | " +% #% ", 220 | " #% -%# ", 221 | " --%+)+%&+)#=-- ", 222 | " -==)))))+)))+==- ", 223 | " -==&#)))#%+)+%&==- ", 224 | " -==&&&%%%%%%&&&==- ", 225 | " -===&%&&&%&&===- ", 226 | " -----==&=----- ", 227 | " ", 228 | " ", 229 | " ", 230 | " ", 231 | " ", 232 | " ", 233 | " ", 234 | " ", 235 | " ", 236 | " ", 237 | " ", 238 | " "}; 239 | 240 | 241 | static char * a3_xpm[] = { 242 | "60 60 16 1", 243 | " c None", 244 | ". c #101010", 245 | "+ c #424242", 246 | "@ c #630000", 247 | "# c #636331", 248 | "$ c #9C4A4A", 249 | "% c #ADADAD", 250 | "& c #BDBDBD", 251 | "* c #CE9C63", 252 | "= c #CECECE", 253 | "- c #DEDEDE", 254 | "; c #FF0000", 255 | "> c #FF6363", 256 | ", c #FFCE9C", 257 | "' c #FFFFCE", 258 | ") c #101010", 259 | " ", 260 | " ", 261 | " ", 262 | " ", 263 | " ", 264 | " ", 265 | " ", 266 | " ", 267 | " ", 268 | " ", 269 | " ", 270 | " ", 271 | " ", 272 | " '''''' ", 273 | " ''',,,,' ", 274 | " '',,,,,,,' ", 275 | " ' %)$,,$)$,*= ", 276 | " ''))),,)))**$ ", 277 | " ',$)$,,$)#*$# ", 278 | " ',,,,,,,**$#$ ", 279 | " ,,,*****$##= ", 280 | " ',***$$#+#% ", 281 | " =*#+##%- ", 282 | " #% ", 283 | " -===,>@@>, - ", 284 | " -##+)+$;;;;$)%+%# ", 285 | " -+#%$$;;;;;@$+#=)- ", 286 | " )- >;;;;;;$ +& ", 287 | " -+- >;;;;;@$ +% ", 288 | " =+% ;;;;;;@@ +% ", 289 | " &+% >;;;;;@$ %# ", 290 | " -%= >;;;;@@$ &+ ", 291 | " *;;;;@@% -& ", 292 | " >;;@@$ ", 293 | " #$$$+ ", 294 | " #% =) ", 295 | " += ) ", 296 | " ) )- ", 297 | " %+)+= += ", 298 | " ))))) +% ", 299 | " %+)+% #% ", 300 | " %# ", 301 | " -----====&+)$- ", 302 | " -===&&&&&&+)))+- ", 303 | " -==&&&%%%%%%+)+%=- ", 304 | " -==&%&%%%%%%&&&==- ", 305 | " -===&&&&&%&&===- ", 306 | " -----====----- ", 307 | " ", 308 | " ", 309 | " ", 310 | " ", 311 | " ", 312 | " ", 313 | " ", 314 | " ", 315 | " ", 316 | " ", 317 | " ", 318 | " "}; 319 | 320 | 321 | static char * a4_xpm[] = { 322 | "60 60 16 1", 323 | " c None", 324 | ". c #101010", 325 | "+ c #424242", 326 | "@ c #630000", 327 | "# c #636331", 328 | "$ c #9C4A4A", 329 | "% c #ADADAD", 330 | "& c #BDBDBD", 331 | "* c #CE9C63", 332 | "= c #CECECE", 333 | "- c #DEDEDE", 334 | "; c #FF0000", 335 | "> c #FF6363", 336 | ", c #FFCE9C", 337 | "' c #FFFFCE", 338 | ") c #101010", 339 | " ", 340 | " ", 341 | " ", 342 | " ", 343 | " ", 344 | " ", 345 | " ", 346 | " ", 347 | " ", 348 | " ", 349 | " ", 350 | " ", 351 | " ", 352 | " ", 353 | " '''''' ", 354 | " ''',,,,' ", 355 | " '',,,,,,,' ", 356 | " ' %)$,,$)$,*= ", 357 | " ''))),,)))**$ ", 358 | " ',$)$,,$)#*$# ", 359 | " ',,,,,,,**$#$ ", 360 | " ,,,*****$##= ", 361 | " ',***$$#+#% ", 362 | " =*#+##%- ", 363 | " #% ", 364 | " - ,>@@>, ", 365 | " =%#)+$;;;;$+ ", 366 | " &++##$;;;;;;+# ", 367 | " &+& >;;;;;;$+$ ", 368 | " ) >;;;;;@$-)& ", 369 | " +% ;;;;;;@@'=) ", 370 | " ## >;;;;;@+'++ ", 371 | " ## >;;;;@@#)# ", 372 | " -% *;;;;@@)% ", 373 | " ->;;@@)% ", 374 | " &)>$$$% ", 375 | " %)- +% ", 376 | " #) %)% ", 377 | " %+ -)+ ", 378 | " =# %) ", 379 | " &+ &+ ", 380 | " %+- - - - -) ", 381 | " %+)+%-====%+)#% ", 382 | " )))))&&&%&+)))+- ", 383 | " -%+)+#%%%%%#+)+$=- ", 384 | " -==&&&%%%%%%&&&==- ", 385 | " -===&%&&&&&&===- ", 386 | " -----====----- ", 387 | " ", 388 | " ", 389 | " ", 390 | " ", 391 | " ", 392 | " ", 393 | " ", 394 | " ", 395 | " ", 396 | " ", 397 | " ", 398 | " "}; 399 | 400 | 401 | static char * a5_xpm[] = { 402 | "60 60 16 1", 403 | " c None", 404 | ". c #101010", 405 | "+ c #424242", 406 | "@ c #630000", 407 | "# c #636331", 408 | "$ c #9C4A4A", 409 | "% c #ADADAD", 410 | "& c #BDBDBD", 411 | "* c #CE9C63", 412 | "= c #CECECE", 413 | "- c #DEDEDE", 414 | "; c #FF0000", 415 | "> c #FF6363", 416 | ", c #FFCE9C", 417 | "' c #FFFFCE", 418 | ") c #101010", 419 | " ", 420 | " ", 421 | " ", 422 | " ", 423 | " ", 424 | " ", 425 | " ", 426 | " ", 427 | " ", 428 | " ", 429 | " ", 430 | " ", 431 | " '''' ", 432 | " ''',,,,' ", 433 | " '',,,,,,,' ", 434 | " %)$,,$)$,*= ", 435 | " ''))),,)))**$ ", 436 | " ',$)$,,$)#*$# ", 437 | " ',,,,,,,**$#$ ", 438 | " ,,,*****$##= ", 439 | " ',***$$#+#% ", 440 | " =*#+##%- ", 441 | " #& ", 442 | " -==& >@@>, - ", 443 | " -##+)+$;;;;$)%+%# ", 444 | " -+#%%$;;;;;;+##=)- ", 445 | " )- >;;;;;;$ +& ", 446 | " -+- ,>;;;;;@$ +% ", 447 | " =+% ;;;;;;@@ +% ", 448 | " &+% ,>;;;;;@+ %# ", 449 | " -%= >;;;;@@$ &+ ", 450 | " *;;;;@@% -& ", 451 | " >;;@@$ ", 452 | " -%*$$* ", 453 | " += %& ", 454 | " )- %# ", 455 | " ) =+ ", 456 | " -) ) ", 457 | " =+ =+)+% ", 458 | " %+ ))))) ", 459 | " %# %+)+% ", 460 | " #$ ", 461 | " -%)+&-====----- ", 462 | " +)))+&&&&&&&===- ", 463 | " -&+)+%%%%%%%&&&==- ", 464 | " -==&&&%%%%%%&&%==- ", 465 | " -===&%&&&%&&===- ", 466 | " -----====----- ", 467 | " ", 468 | " ", 469 | " ", 470 | " ", 471 | " ", 472 | " ", 473 | " ", 474 | " ", 475 | " ", 476 | " ", 477 | " ", 478 | " "}; 479 | 480 | 481 | static char * a6_xpm[] = { 482 | "60 60 16 1", 483 | " c None", 484 | ". c #101010", 485 | "+ c #424242", 486 | "@ c #630000", 487 | "# c #636331", 488 | "$ c #9C4A4A", 489 | "% c #ADADAD", 490 | "& c #BDBDBD", 491 | "* c #CE9C63", 492 | "= c #CECECE", 493 | "- c #DEDEDE", 494 | "; c #FF0000", 495 | "> c #FF6363", 496 | ", c #FFCE9C", 497 | "' c #FFFFCE", 498 | ") c #101010", 499 | " ", 500 | " ", 501 | " ", 502 | " ", 503 | " ", 504 | " ", 505 | " ", 506 | " ", 507 | " ", 508 | " ", 509 | " ", 510 | " ", 511 | " ", 512 | " ", 513 | " ", 514 | " ", 515 | " '''''' ", 516 | " ''',,,,' ", 517 | " '',,,,,,,' ", 518 | " ' %)$,,$)$,*= ", 519 | " ''))),,)))**$ ", 520 | " ',$)$,,$)#*$# ", 521 | " ',,,,,,,**$#$ ", 522 | " ,,,*****$##= ", 523 | " ',***$$#+#% ", 524 | " =*#+##%- ", 525 | " #% ", 526 | " ,>@@>, ", 527 | " -)#$;;;;$)%= ", 528 | " %#++;;;;;@)#$% ", 529 | " %+#%$;;;;;;$'#) ", 530 | " #+='>;;;;;@$'$# ", 531 | " %+'';;;;;;@@'+# ", 532 | " +%->;;;;;@+-#% ", 533 | " %+=>;;;;@@$=#& ", 534 | " &+%*;;;;@@%=#& ", 535 | " %& >;;@@$ &- ", 536 | " #$$$)= ", 537 | " %+ +& ", 538 | " ## +% ", 539 | " +%- #% ", 540 | " ---+%==#+----- ", 541 | " -=%+)+$%+)#&===- ", 542 | " -==)))))+)))+&&==- ", 543 | " -==#+))#%+)+%&&==- ", 544 | " -===&&&&&&&&===- ", 545 | " -----====----- ", 546 | " - ", 547 | " ", 548 | " ", 549 | " ", 550 | " ", 551 | " ", 552 | " ", 553 | " ", 554 | " ", 555 | " ", 556 | " ", 557 | " ", 558 | " "}; 559 | 560 | 561 | static char * a7_xpm[] = { 562 | "60 60 16 1", 563 | " c None", 564 | ". c #101010", 565 | "+ c #424242", 566 | "@ c #630000", 567 | "# c #636331", 568 | "$ c #9C4A4A", 569 | "% c #ADADAD", 570 | "& c #BDBDBD", 571 | "* c #CE9C63", 572 | "= c #CECECE", 573 | "- c #DEDEDE", 574 | "; c #FF0000", 575 | "> c #FF6363", 576 | ", c #FFCE9C", 577 | "' c #FFFFCE", 578 | ") c #101010", 579 | " ", 580 | " ", 581 | " ", 582 | " ", 583 | " ", 584 | " ", 585 | " ", 586 | " ", 587 | " ", 588 | " ", 589 | " ", 590 | " ", 591 | " '''' ", 592 | " ''',,,,' ", 593 | " '',,,,,,,' ", 594 | " %)$,,$)$,*= ", 595 | " ''))),,)))**$ ", 596 | " ',$)$,,$)#*$# ", 597 | " ',,,,,,,**$#$ ", 598 | " ,,,*****$##= ", 599 | " ',***$$#+#% ", 600 | " =*#+##%- ", 601 | " #& ", 602 | " -==& >@@>, - ", 603 | " -##+)+$;;;;$)%+%# ", 604 | " -+#%%$;;;;;;+##=)- ", 605 | " )- >;;;;;;$ +& ", 606 | " -+- ,>;;;;;@$ +% ", 607 | " =+% ;;;;;;@@ +% ", 608 | " &+% ,>;;;;;@+ %# ", 609 | " -%= >;;;;@@$ &+ ", 610 | " *;;;;@@% -& ", 611 | " >;;@@$ ", 612 | " -%*$$* ", 613 | " += %& ", 614 | " )- %# ", 615 | " ) =+ ", 616 | " -) ) ", 617 | " =+ =+)+% ", 618 | " %+ ))))) ", 619 | " %# %+)+% ", 620 | " #$ ", 621 | " -%)+&-====----- ", 622 | " +)))+&&&&&&&===- ", 623 | " -&+)+%%%%%%%&&&==- ", 624 | " -==&&&%%%%%%&&%==- ", 625 | " -===&%&&&%&&===- ", 626 | " -----====----- ", 627 | " ", 628 | " ", 629 | " ", 630 | " ", 631 | " ", 632 | " ", 633 | " ", 634 | " ", 635 | " ", 636 | " ", 637 | " ", 638 | " "}; 639 | -------------------------------------------------------------------------------- /hguidemo/screensav.c: -------------------------------------------------------------------------------- 1 | //====================================================================== 2 | //simple hgui screensaver demonstration 3 | //===================================== 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | const char* hacknames[] = { "blank","ellipsoid","lissajous","cube","starfield" , NULL }; 11 | 12 | hWindow *hw; //hacks' global variables can be found in their section (sorry,fast&dirty) 13 | int width,height; 14 | #define REFRESHRATE 100 15 | #define TIMEOUT 1280; //60*REFRESHRATE //hgui refresh-rate is 100Hz -> 1 minute equals to 100*60=6000 frames 16 | int changecnt=TIMEOUT; 17 | 18 | void callhack (hWindow *hw, unsigned char *hacknum); //function-prototype of handler loop-callback 19 | 20 | // ============================ MAIN ROUTINE =========================== 21 | int main (int argc, char **argv) 22 | { 23 | unsigned char hacknum=0; 24 | int i; //default is blanking 25 | if (argc==2) { 26 | if (!strcmp(argv[1],"-help")) { 27 | printf("\nHermitGUI screensaver example. Usage: screensav [hackname]\n" 28 | "If hackname is not given, it's selected randomly, and\n" 29 | "hacks are randomly changed automatically in every minutes.\nhacknames: "); 30 | for(i=0; hacknames[i]!=NULL; i++) printf("%s ",hacknames[i]); 31 | printf("\n\n"); 32 | exit(0); 33 | } else { 34 | for(i=0; hacknames[i]!=NULL; i++) if (!strcmp(argv[1],hacknames[i])) { 35 | hacknum=i; 36 | break; 37 | } 38 | } 39 | } else hacknum=1; //rand()*16; 40 | printf("Hgui screensaver-example. (Type 'screensav -help' for info.)\n"); 41 | printf("Running hack %d: '%s'\n",hacknum,hacknames[hacknum]); 42 | 43 | width=getScreenWidth(); 44 | height=getScreenHeight(); 45 | hw=createWindow(0,0,width,height,"hgui screensaver example",0,0x000000,0,0,FULLSCREEN,NULL,NULL); 46 | setClass(hw,"screensaver","hguiscreensav"); 47 | hideMouseCursor(hw); 48 | eventLoop(hw,callhack,&hacknum); 49 | destroyWindow(hw); 50 | return 0; 51 | } 52 | 53 | // ============================= HACKS ================================= 54 | #define PI 3.14 55 | int movcnt=0,stripcnt=0; 56 | float poscnt=0.0; 57 | unsigned long anicol=0x405070; 58 | char phase=0; 59 | float angle=0.0,anglecnt=0.0; 60 | float rad=PI/180.0; 61 | 62 | void blank() { } 63 | 64 | void ellipsoid() 65 | { 66 | //if (!changecnt) anicol=0xffffff; 67 | drawEllipse(hw,width/2,height/2,movcnt,height/2-movcnt/2,phase?0:anicol); 68 | if(movcnt 4 | 5 | int main (int argc, char **argv) 6 | { 7 | #include "icon.xpm" 8 | hWindow *hw=createWindow(50,50,300,200,"Simplest HermitGUI window",0xc0c0c0,0x000000,200,100,0,icon_xpm,NULL); 9 | addTextCentered(hw,0,0,-1,-1,"Hello World!",0x000000,"-*-*vera sans*-bold-r-*-*-24-*-*-*-p-*-*-*"); 10 | eventLoop(hw,NULL,NULL); 11 | destroyWindow(hw); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | #======================================================================= 2 | #HermuitGUI makefile 3 | #=================== 4 | VERSION=1 5 | 6 | AR=ar rcs 7 | 8 | CD=cd 9 | CP=cp -a 10 | LN=ln -sfn 11 | MD=mkdir -p 12 | MV=mv 13 | RM=rm -rf 14 | STRIP=strip 15 | CHMOD=chmod 16 | 17 | 18 | all: libhgui.so libhgui.a hguidemo/hguidemo 19 | 20 | libhgui.so: hgui.c hgui.h 21 | $(CC) -c hgui.c -fpic -o hgui.so.o -lX11 # -DHGUI_SELECTWIDGETS -DHGUI_BUTTONS # -DDEBUG # -DUSE_XFT -lXft 22 | $(CC) hgui.so.o -shared -o libhgui.so -lX11 #-lm 23 | 24 | libhgui.a: hgui.c hgui.h 25 | $(CC) -c hgui.c -o hgui.a.o -lX11 #-lm 26 | $(AR) libhgui.a hgui.a.o 27 | 28 | hguidemo/hguidemo: hguidemo/hguidemo.c hgui.c hgui.h hguidemo/robodance.anim 29 | make -C hguidemo 30 | 31 | 32 | install: /usr/lib/libhgui.so /usr/lib/libhgui.a /usr/include/hgui.h 33 | 34 | /usr/lib/libhgui.so: ./libhgui.so 35 | $(CP) libhgui.so /usr/lib/libhgui.so.$(VERSION) 36 | $(STRIP) /usr/lib/libhgui.so.$(VERSION) #not a standard thing for GNU but it's a bit smaller this way 37 | $(CHMOD) 0755 /usr/lib/libhgui.so.$(VERSION) 38 | $(CD) /usr/lib/ ; $(LN) libhgui.so.$(VERSION) libhgui.so 39 | 40 | /usr/lib/libhgui.a: ./libhgui.a 41 | $(CP) libhgui.a /usr/lib/ 42 | 43 | /usr/include/hgui.h: ./hgui.h 44 | $(CP) hgui.h /usr/include/hgui.h 45 | 46 | 47 | clean: 48 | $(RM) hgui.so.o libhgui.so hgui.a.o libhgui.a hgui.o 49 | make -C hguidemo clean 50 | 51 | uninstall: 52 | $(RM) /usr/lib/libhgui.so /usr/lib/libhgui.so.$(VERSION) /usr/lib/libhgui.a 53 | $(RM) /usr/include/hgui.h 54 | 55 | purge: clean uninstall 56 | 57 | 58 | #======================================================================= 59 | --------------------------------------------------------------------------------