├── doc ├── Makefile └── stk.txt ├── Makefile ├── roadmap ├── .gitignore ├── src ├── Makefile ├── stk_menu.h ├── stk_window.h ├── stk_button.h ├── stk_text.h ├── stk_progress_bar.h ├── stk_canvas.h ├── stk_menu.c ├── stk_widget.h ├── stk_window.c ├── test.c ├── stk_button.c ├── stk_progress_bar.c ├── stk_canvas.c ├── stk_widget.c └── stk_text.c └── README.md /doc/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | asciidoc -b html5 -a toc2 -a theme=flask stk.txt 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | @make -C src 3 | # @make -C test 4 | 5 | clean: 6 | @make -C src clean 7 | # @make -C test clean 8 | -------------------------------------------------------------------------------- /roadmap: -------------------------------------------------------------------------------- 1 | 0.8 2 | - Set stk_text to be text output as well - DONE 3 | - Finish Canvas with basic geometric primitives - DONE 4 | - Write a listbox with single and multiple selection 5 | - Do a code review - DONE 6 | - Write the widget's hierarchy for event propagation 7 | - Write binds to Lua 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | 4 | # Libraries 5 | *.lib 6 | *.a 7 | 8 | # Shared objects (inc. Windows DLLs) 9 | *.dll 10 | *.so 11 | *.so.* 12 | *.dylib 13 | 14 | # Executables 15 | *.exe 16 | *.out 17 | *.app 18 | test 19 | 20 | #folders 21 | test.dSYM 22 | 23 | #others 24 | *.html 25 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-c -g -I. -pedantic -Wall 3 | LDFLAGS=-L/usr/X11R6/lib -lX11 4 | SOURCES=$(wildcard *.c) 5 | 6 | OBJECTS=$(SOURCES:.c=.o) 7 | 8 | 9 | all: $(OBJECTS) 10 | gcc *.o -o test -lX11 11 | 12 | %.o: %.c 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | clean: 16 | rm -rf $(OBJECTS) test 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | STK - Small Graphical toolkit based on Xlib; 2 | 3 | STK is a small Graphical toolkit for desktop applications. 4 | 5 | To compile, type ''make'' (without the quotes) on your terminal and voilà! 6 | 7 | Widget list: 8 | 9 | * Window 10 | * Button 11 | * Text Input/Output - still need some changes/improvements 12 | * Plotter - under development/test 13 | * ProgressBar 14 | 15 | Take a look at test.c to see the basics of STK; 16 | 17 | -------------------------------------------------------------------------------- /src/stk_menu.h: -------------------------------------------------------------------------------- 1 | #ifndef STK_MENU_H 2 | #define STK_MENU_H 3 | 4 | #include 5 | 6 | stk_widget *stk_menu_new(stk_widget *, int, int, uint, uint, char*); 7 | void stk_menu_show(stk_widget *); 8 | void stk_menu_handle(STKEvent *, void *); 9 | void stk_menu_set_size(stk_widget *); 10 | void stk_menu_set_pos(stk_widget *, uint, uint); 11 | void stk_menu_set_color(stk_widget *, int color); 12 | 13 | #endif /* STK_MENU_H */ 14 | -------------------------------------------------------------------------------- /src/stk_window.h: -------------------------------------------------------------------------------- 1 | #ifndef STK_WINDOW_H 2 | #define STK_WINDOW_H 3 | 4 | #include 5 | 6 | stk_widget *stk_window_new(int, int, uint, uint, const char *); 7 | void stk_window_show(stk_widget *); 8 | void stk_window_set_title(stk_widget *, const char *); 9 | void stk_window_handle(STKEvent *, void *); 10 | void stk_window_set_size(stk_widget *); 11 | void stk_window_set_pos(stk_widget *, uint, uint); 12 | void stk_window_set_color(stk_widget *, int color); 13 | 14 | #endif /* STK_WINDOW_H */ 15 | -------------------------------------------------------------------------------- /src/stk_button.h: -------------------------------------------------------------------------------- 1 | #ifndef STK_BUTTON_H 2 | #define STK_BUTTON_H 3 | 4 | #include 5 | 6 | /* STKButton Events */ 7 | #define STK_BUTTON_EXPOSE 0x10 8 | #define STK_BUTTON_PRESS 0x20 9 | #define STK_BUTTON_RELEASE 0x30 10 | #define STK_BUTTON_ENTER 0x40 11 | #define STK_BUTTON_LEAVE 0x50 12 | 13 | stk_widget *stk_button_new(stk_widget *, int, int, uint, uint, char *, 14 | void (*)(void*), void *); 15 | void stk_button_handle(STKEvent *, void *); 16 | 17 | #endif /* STK_BUTTON_H */ 18 | -------------------------------------------------------------------------------- /src/stk_text.h: -------------------------------------------------------------------------------- 1 | #ifndef STK_TEXT_H 2 | #define STK_TEXT_H 3 | 4 | #include 5 | 6 | /* STKText Events */ 7 | #define STK_TEXT_EXPOSE 0x10 8 | #define STK_TEXT_PRESS 0x20 9 | #define STK_TEXT_RELEASE 0x30 10 | #define STK_TEXT_ENTER 0x40 11 | #define STK_TEXT_LEAVE 0x50 12 | #define STK_TEXT_KEYPRESS 0x60 13 | #define STK_TEXT_KEYRELEASE 0x70 14 | #define STK_TEXT_BUFFER_SIZE 4096 15 | 16 | 17 | 18 | /* STKText Properties */ 19 | enum { 20 | STK_TEXT_INPUT = 0, 21 | STK_TEXT_OUTPUT = 1 22 | }; 23 | 24 | 25 | 26 | typedef struct 27 | { 28 | char text[STK_TEXT_BUFFER_SIZE]; 29 | } stk_text; 30 | 31 | stk_widget *stk_text_new(stk_widget *, int, int, uint, uint, char *, int); 32 | void stk_text_handle(STKEvent *, void *); 33 | void stk_text_redraw(int, stk_widget *, void *); 34 | char *stk_text_get_text(stk_widget *); 35 | void stk_text_set_text(stk_widget *, char *); 36 | 37 | #endif /* STK_TEXT_H */ 38 | -------------------------------------------------------------------------------- /src/stk_progress_bar.h: -------------------------------------------------------------------------------- 1 | #ifndef STK_PROGRESS_BAR_H 2 | #define STK_PROGRESS_BAR_H 3 | 4 | #include 5 | 6 | /* STKButton Events */ 7 | #define STK_PROGRESS_BAR_EXPOSE 0x10 8 | #define STK_PROGRESS_BAR_PRESS 0x20 9 | #define STK_PROGRESS_BAR_RELEASE 0x30 10 | #define STK_PROGRESS_BAR_ENTER 0x40 11 | #define STK_PROGRESS_BAR_LEAVE 0x50 12 | 13 | #define STK_PROGRESS_BAR_LABEL_SIZE (1 << 6) 14 | 15 | 16 | typedef struct 17 | { 18 | Colormap cmap; 19 | XColor color, colorrgb; 20 | uint pct; 21 | char label[STK_PROGRESS_BAR_LABEL_SIZE]; 22 | } stk_progress_bar; 23 | 24 | 25 | stk_widget *stk_progress_bar_new(stk_widget *, int, int, uint, uint, char *); 26 | void stk_progress_bar_handle(STKEvent *, void *); 27 | void stk_progress_bar_set(stk_widget *, uint); 28 | void stk_progress_bar_set_value(stk_widget *, uint); 29 | void stk_progress_bar_set_label(stk_widget *, char *); 30 | uint stk_progress_bar_get_value(stk_widget *); 31 | 32 | #endif /* STK_PROGRESS_BAR_H */ 33 | -------------------------------------------------------------------------------- /src/stk_canvas.h: -------------------------------------------------------------------------------- 1 | #ifndef STK_CANVAS_H 2 | #define STK_CANVAS_H 3 | 4 | #include 5 | 6 | /* STKCanvas Events */ 7 | #define STK_CANVAS_EXPOSE 0x10 8 | #define STK_CANVAS_PRESS 0x20 9 | #define STK_CANVAS_RELEASE 0x30 10 | #define STK_CANVAS_ENTER 0x40 11 | #define STK_CANVAS_LEAVE 0x50 12 | #define STK_CANVAS_MOVE 0x60 13 | 14 | 15 | typedef struct 16 | { 17 | Pixmap pmap; 18 | } stk_canvas; 19 | 20 | 21 | 22 | stk_widget *stk_canvas_new(stk_widget *, int, int, uint, uint); 23 | void stk_canvas_draw_line(stk_widget *, uint, uint, uint, uint); 24 | void stk_canvas_draw_point(stk_widget *, uint, uint); 25 | void stk_canvas_draw_arc(stk_widget *, uint, uint, uint, uint, uint, uint); 26 | void stk_canvas_draw_rectangle(stk_widget *, int, int); 27 | void stk_canvas_draw_string(stk_widget *pl, uint x, uint y, char *str); 28 | void stk_canvas_set_string_font_size(stk_widget *, char *); 29 | void stk_canvas_set_string_font(stk_widget *, char *); 30 | void stk_canvas_handle(STKEvent *, void *); 31 | 32 | 33 | /* TODO */ 34 | void stk_canvas_area_rotate(stk_widget *pl, uint x0, uint y0, uint x1, uint y1, uint angle); 35 | void stk_canvas_area_move(stk_widget *pl, uint x0, uint y0, uint x1, uint y1, uint x, uint y); 36 | void stk_canvas_line_color(stk_widget *pl, int color); 37 | 38 | 39 | #endif /* STK_CANVAS_H */ 40 | -------------------------------------------------------------------------------- /doc/stk.txt: -------------------------------------------------------------------------------- 1 | STK - Small Graphic Toolkit 2 | =========================== 3 | Gabriel Duarte 4 | v0.5, 2013-03 5 | 6 | 7 | STK - Small toolkit based on Xlib for GUI applications. 8 | 9 | .Widget Set 10 | * Window 11 | * Button 12 | * Text Area - still need some changes/improvements 13 | * Canvas - under development/test 14 | * ProgressBar - under test 15 | * Listbox - planned 16 | 17 | 18 | STK Functions 19 | -------------- 20 | 21 | stk_widget 22 | ~~~~~~~~~~ 23 | The stk_widget functions are the base of STK. They are responsible for initializing 24 | the widget list, connect to display, set widget's size, etc. 25 | 26 | [source, c] 27 | void stk_init() 28 | 29 | Starts the widget list and connects to the display. 30 | 31 | +return *void*+ 32 | 33 | CAUTION: This function MUST be called before any other stk function. 34 | 35 | 36 | 37 | 38 | [source, c] 39 | int stk_widget_insert(void *widget) 40 | 41 | Alloc and insert a widget in the widget list. 42 | Every widget must call it to be registered and have its events handled. 43 | 44 | +return *0 if success, -1 if not*+ + 45 | 46 | 47 | 48 | [source, c] 49 | void stk_run() 50 | 51 | Search for a widget in the widget list. It's the event loop that handles the all the event callings of the widgets. 52 | Must be the last stk called. 53 | 54 | +return *void*+ 55 | 56 | 57 | 58 | 59 | [source, c] 60 | stk_widget *stk_widget_root() 61 | 62 | Returns the pointer to first widget added the list. 63 | 64 | +return *stk_widget**+ 65 | 66 | 67 | 68 | 69 | [source, c] 70 | stk_widget *stk_widget_search(void *widget) 71 | 72 | Searchs for a widget in the widget list. 73 | 74 | +return *stk_widget** if found or *NULL*+ 75 | 76 | 77 | 78 | 79 | [source, c] 80 | void stk_widget_set_pos(stk_widget *win, uint x, uint y) 81 | 82 | Set widget position on the screen. 83 | 84 | +return *void*+ 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/stk_menu.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | stk_widget *stk_menu_new(stk_widget *parent_win, int x, int y, uint w, uint h, 6 | char *title) 7 | { 8 | stk_widget *new_menu = (stk_widget*) malloc(sizeof(stk_widget)); 9 | 10 | memset(new_menu, 0, sizeof(stk_widget)); 11 | 12 | new_menu->dsp = display; 13 | 14 | if(new_menu->dsp) 15 | { 16 | new_menu->win = XCreateSimpleWindow(new_menu->dsp, parent_win->win, 17 | x, y, w, h, 1, 0, 0); 18 | 19 | new_menu->mask = ExposureMask | ButtonPressMask | ButtonReleaseMask | 20 | PointerMotionMask | KeyPressMask | StructureNotifyMask | 21 | EnterWindowMask | LeaveWindowMask; 22 | 23 | XSelectInput(new_menu->dsp, new_menu->win, new_menu->mask); 24 | XSetWindowBackground(new_menu->dsp, new_menu->win, 0xd3d3d3); 25 | stk_menu_show(new_menu); 26 | 27 | new_menu->handler = &stk_menu_handle; 28 | 29 | new_menu->x = x; 30 | new_menu->y = y; 31 | new_menu->w = w; 32 | new_menu->h = h; 33 | 34 | 35 | 36 | new_menu->gc = XCreateGC(display, new_menu->win, 0, 0); 37 | 38 | stk_widget_insert((void*)new_menu); 39 | 40 | return new_menu; 41 | } 42 | else 43 | return NULL; 44 | } 45 | 46 | /* 47 | void stk_menu_set_pos(stk_widget *menu, uint x, uint y) 48 | { 49 | stk_widget_set_pos(win, x, y); 50 | } 51 | 52 | void stk_menu_set_color(stk_widget *menu, int color) 53 | { 54 | stk_widget_set_color(win, color); 55 | } 56 | */ 57 | 58 | void stk_menu_handle(STKEvent *event, void *warg) 59 | { 60 | stk_widget *wg = (stk_widget*)warg; 61 | 62 | switch(event->type) 63 | { 64 | case Expose: 65 | break; 66 | 67 | case ButtonPress: 68 | XResizeWindow(wg->dsp, wg->win, wg->w, wg->h+100); 69 | break; 70 | 71 | case ButtonRelease: 72 | break; 73 | 74 | case EnterNotify: 75 | break; 76 | 77 | case LeaveNotify: 78 | XResizeWindow(wg->dsp, wg->win, wg->w, 20); 79 | break; 80 | } 81 | } 82 | 83 | void stk_menu_show(stk_widget *menu) 84 | { 85 | XMapWindow(menu->dsp, menu->win); 86 | XFlush(menu->dsp); 87 | } 88 | 89 | -------------------------------------------------------------------------------- /src/stk_widget.h: -------------------------------------------------------------------------------- 1 | #ifndef STK_WIDGET_H 2 | #define STK_WIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | 17 | /* STK_WIDGET Events */ 18 | #define STK_WIDGET_EXPOSE 0x10 19 | #define STK_WIDGET_PRESS 0x20 20 | #define STK_WIDGET_RELEASE 0x30 21 | #define STK_WIDGET_ENTER 0x40 22 | #define STK_WIDGET_LEAVE 0x50 23 | #define STK_WIDGET_MOVE 0x60 24 | #define STK_WIDGET_KEYPRESS 0x70 25 | #define STK_WIDGET_KEYRELEASE 0x80 26 | 27 | 28 | typedef XEvent STKEvent; 29 | 30 | Display *display; 31 | 32 | 33 | typedef struct widget_ptr 34 | { 35 | void *this; 36 | struct widget_ptr *prev, *next; 37 | } widget_list; 38 | 39 | 40 | typedef struct 41 | { 42 | uint w, h; 43 | int x, y; 44 | Window win; 45 | Display *dsp; 46 | void (*handler)(STKEvent *, void *); 47 | int mask; 48 | GC gc, gc2; 49 | XFontStruct *font_info; 50 | STKEvent *ev; 51 | widget_list *child_list; 52 | char *fontname; 53 | char *label; 54 | void *ext_struct; /* if need a place to store a reference to other struct, if it's not a basic widget, etc. */ 55 | void (*movefunc)(void *), *margs; /* move event */ 56 | void (*pressfunc)(void *), *pargs; /* press event */ 57 | void (*enterfunc)(void *), *eargs; /* enter event */ 58 | void (*leavefunc)(void *), *largs; /* leave event */ 59 | void (*exposefunc)(void *), *exargs; /* expose event */ 60 | void (*releasefunc)(void *), *rargs; /* realse event */ 61 | void (*kpressfunc)(void *), *kpxargs;/* keypress event */ 62 | void (*kreleasefunc)(void *), *krargs; /* keyrelease event */ 63 | } stk_widget; 64 | 65 | /* Font Sizes */ 66 | #define STK_FONT_SIZE_6x9 "6x9" 67 | #define STK_FONT_SIZE_7x13 "7x13" 68 | #define STK_FONT_SIZE_9x15 "9x15" 69 | 70 | stk_widget *stk_widget_search(void *); 71 | int stk_widget_insert(void *); 72 | int stk_widget_delete(void *); 73 | void stk_init(); 74 | void stk_run(); 75 | void stk_widget_set_size(stk_widget *, uint, uint); 76 | void stk_widget_set_pos(stk_widget *, uint, uint); 77 | void stk_widget_set_color(stk_widget *, int color); 78 | void stk_widget_set_font_size(stk_widget *, char *); 79 | stk_widget *stk_widget_root(); 80 | void stk_widget_event_listen_add(stk_widget *, int, 81 | void (*)(void*),void *); 82 | void stk_widget_event_listen_remove(stk_widget *, int); 83 | 84 | #endif /* STK_WIDGET_H */ 85 | -------------------------------------------------------------------------------- /src/stk_window.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | stk_widget *stk_window_new(int x, int y, uint w, uint h, const char *title) 4 | { 5 | stk_widget *new_win = (stk_widget*) malloc(sizeof(stk_widget)); 6 | Atom del_win; 7 | 8 | memset(new_win, 0, sizeof(stk_widget)); 9 | 10 | new_win->dsp = display; 11 | 12 | if(new_win->dsp) 13 | { 14 | new_win->win = XCreateWindow(new_win->dsp, DefaultRootWindow(new_win->dsp), 15 | x, y, w, h, 0, CopyFromParent, CopyFromParent, 16 | CopyFromParent, 0, 0); 17 | 18 | new_win->mask = ExposureMask | ButtonPressMask | ButtonReleaseMask | 19 | PointerMotionMask | KeyPressMask | StructureNotifyMask; 20 | 21 | XSelectInput(new_win->dsp, new_win->win, new_win->mask); 22 | XSetWindowBackground(new_win->dsp, new_win->win, 0xd3d3d3); 23 | del_win = XInternAtom(new_win->dsp, "WM_DELETE_WINDOW", 0); 24 | XSetWMProtocols(new_win->dsp, new_win->win, &del_win, 1); 25 | 26 | 27 | 28 | 29 | new_win->x = x; 30 | new_win->y = y; 31 | new_win->w = w; 32 | new_win->h = h; 33 | 34 | 35 | new_win->handler = &stk_window_handle; 36 | 37 | if(title) 38 | stk_window_set_title(new_win, title); 39 | 40 | new_win->gc = XCreateGC(display, new_win->win, 0, 0); 41 | 42 | stk_widget_insert((void*)new_win); 43 | 44 | return new_win; 45 | } 46 | else 47 | return NULL; 48 | } 49 | 50 | 51 | void stk_window_set_pos(stk_widget *win, uint x, uint y) 52 | { 53 | stk_widget_set_pos(win, x, y); 54 | } 55 | 56 | void stk_window_set_color(stk_widget *win, int color) 57 | { 58 | stk_widget_set_color(win, color); 59 | } 60 | 61 | void stk_window_handle(STKEvent *event, void *warg) 62 | { 63 | stk_widget *wg = (stk_widget*)warg; 64 | stk_widget *wroot = stk_widget_root(); 65 | 66 | switch(event->type) 67 | { 68 | case Expose: 69 | break; 70 | 71 | case ButtonPress: 72 | XSetInputFocus(wg->dsp, wg->win, RevertToNone, CurrentTime); 73 | break; 74 | 75 | case ButtonRelease: 76 | /*if(wg->func) 77 | wg->func(wg->args);*/ 78 | break; 79 | 80 | case ClientMessage: 81 | if(wg == wroot) 82 | { 83 | XDestroyWindow(wg->dsp, wg->win); 84 | /* close connection to server */ 85 | XCloseDisplay(wg->dsp); 86 | exit(0); 87 | } 88 | else 89 | { 90 | XUnmapWindow(wg->dsp, wg->win); 91 | XFlush(wg->dsp); 92 | } 93 | 94 | break; 95 | } 96 | } 97 | 98 | void stk_window_show(stk_widget *win) 99 | { 100 | XMapWindow(win->dsp, win->win); 101 | XFlush(win->dsp); 102 | } 103 | 104 | 105 | void stk_window_set_title(stk_widget *win, const char *title) 106 | { 107 | /* This variable will store the newly created property. */ 108 | XTextProperty window_title_property; 109 | 110 | /* translate the given string into an X property. */ 111 | XStringListToTextProperty((char**)&title, 112 | 1, 113 | &window_title_property); 114 | XSetWMName(win->dsp, win->win, &window_title_property); 115 | } 116 | -------------------------------------------------------------------------------- /src/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | typedef struct 9 | { 10 | void *d1; 11 | int c, x, y; 12 | } ptr; 13 | 14 | 15 | void draw(void *c) 16 | { 17 | int i = 0; 18 | 19 | stk_widget *p = (stk_widget*)c; 20 | stk_canvas_draw_arc(p, 80, 70, 300, 100, 100, 360*64); 21 | stk_canvas_draw_line(p, 10, 10, 100, 100); 22 | /*stk_canvas_set_string_font_size(p, STK_FONT_SIZE_9x15);*/ 23 | stk_canvas_draw_string(p, 50, 50, "50x50"); 24 | 25 | for(i = 350; i > 200; i--) 26 | stk_canvas_draw_point(p, 100+i, i-150); 27 | } 28 | 29 | void hello(void *string) 30 | { 31 | char *str = (char*)string; 32 | printf("Hello %s\n", str); 33 | } 34 | 35 | 36 | void color(void *c) 37 | { 38 | ptr *w = (ptr*)c; 39 | 40 | printf("Win = %p, Color %x\n", w->d1, w->c); 41 | stk_window_set_color((stk_widget*)w->d1, w->c); 42 | } 43 | 44 | 45 | void move(void *c) 46 | { 47 | ptr *w = (ptr*)c; 48 | 49 | printf("Win = %p, pos %dx%d\n", w->d1, w->x, w->y); 50 | stk_widget_set_pos((stk_widget*)w->d1, w->x, w->y); 51 | } 52 | 53 | void add(void *c) 54 | { 55 | int val = 0; 56 | char buffer[10] = {0}; 57 | stk_widget *p = (stk_widget*)c; 58 | 59 | val = stk_progress_bar_get_value(p); 60 | 61 | if(val < 100) 62 | { 63 | val += 1; 64 | sprintf(buffer, "%d%%", val); 65 | stk_progress_bar_set_value(p, val); 66 | stk_progress_bar_set_label(p, buffer); 67 | } 68 | } 69 | 70 | void listen(void *c) 71 | { 72 | stk_widget *p = (stk_widget*)c; 73 | char coords[10] = {0}; 74 | sprintf(coords, "%dx%d", p->ev->xbutton.x, p->ev->xbutton.y); 75 | printf("%dx%d\n", p->ev->xbutton.x, p->ev->xbutton.y); 76 | stk_canvas_draw_string(p, p->ev->xbutton.x, p->ev->xbutton.y, coords); 77 | } 78 | 79 | void sub(void *c) 80 | { 81 | int val; 82 | char buffer[10]; 83 | stk_widget *p = (stk_widget*)c; 84 | 85 | val = stk_progress_bar_get_value(p); 86 | 87 | if(val > 0) 88 | { 89 | val -= 1; 90 | sprintf(buffer, "%d%%", val); 91 | stk_progress_bar_set_value(p, val); 92 | stk_progress_bar_set_label(p, buffer); 93 | } 94 | } 95 | 96 | 97 | int main() 98 | { 99 | stk_widget *bt, *bt1, *bt2, *bt3, 100 | *bt4, *bt5, *bt6, *cv, 101 | *bt7, *txt, *pb, *win, 102 | *mn; 103 | 104 | ptr wc, wc1, wc2, wc3; 105 | 106 | stk_init(); 107 | 108 | win = stk_window_new(500, 500, 800, 600, "STK Demo"); 109 | mn = stk_menu_new(win, 600, 70, 60, 20, NULL); 110 | bt = stk_button_new(win, 100, 100, 60, 20, "Hello", &hello, "to STKButton"); 111 | bt1 = stk_button_new(win, 200, 100, 60, 20, "MoveWin", &move, (void*)&wc2); 112 | bt2 = stk_button_new(win, 300, 100, 60, 20, "Color1", &color, (void*)&wc1); 113 | bt3 = stk_button_new(win, 400, 100, 60, 20, "Color2", &color, (void*)&wc); 114 | bt4 = stk_button_new(win, 400, 150, 60, 20, "MoveBt1", &move, (void*)&wc3); 115 | txt = stk_text_new(win, 100, 150, 200, 20, "TxtArea", STK_TEXT_INPUT); 116 | pb = stk_progress_bar_new(win, 100, 200, 200, 20, "0%"); 117 | bt5 = stk_button_new(win, 300, 200, 20, 20, "+", &add, (void*)pb); 118 | bt6 = stk_button_new(win, 80, 200, 20, 20, "-", &sub, (void*)pb); 119 | cv = stk_canvas_new(win, 80, 230, 700, 350); 120 | bt7 = stk_button_new(win, 400, 200, 60, 20, "CanvasBt", &draw, (void*)cv); 121 | 122 | stk_widget_event_listen_add(cv, STK_WIDGET_MOVE, listen, (void*)cv); 123 | stk_widget_event_listen_add(cv, STK_WIDGET_PRESS, listen, (void*)cv); 124 | 125 | stk_text_set_text(txt, "Oba!!!"); 126 | stk_canvas_draw_arc(cv, 50, 70, 150, 150, 10, 360*64); 127 | 128 | wc.d1 = win; 129 | wc.c = 0xd3d3d3; 130 | 131 | wc1.d1 = win; 132 | wc1.c = 0xdda0dd; 133 | 134 | wc2.d1 = win; 135 | wc2.x = 600; 136 | wc2.y = 200; 137 | 138 | wc3.d1 = bt4; 139 | wc3.x = 10; 140 | wc3.y = 10; 141 | 142 | stk_window_show(win); 143 | 144 | stk_run(); 145 | 146 | return 0; 147 | } 148 | -------------------------------------------------------------------------------- /src/stk_button.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | stk_widget *stk_button_new(stk_widget *parent_win, int x, int y, uint w, uint h, 5 | char *label, void (*func)(void*), void *args) 6 | { 7 | stk_widget *new_bt = (stk_widget*) malloc(sizeof(stk_widget)); 8 | int screen; 9 | 10 | XGCValues gcval; 11 | long fg, bg; 12 | XSetWindowAttributes setwinattr; 13 | 14 | memset(new_bt, 0, sizeof(stk_widget)); 15 | 16 | 17 | new_bt->dsp = display; 18 | new_bt->fontname = STK_FONT_SIZE_7x13; 19 | 20 | screen = DefaultScreen(new_bt->dsp); 21 | fg = BlackPixel(new_bt->dsp, screen); 22 | bg = WhitePixel(new_bt->dsp, screen); 23 | 24 | gcval.foreground = fg; 25 | gcval.background = bg; 26 | new_bt->gc2 = XCreateGC(new_bt->dsp, parent_win->win, GCForeground | 27 | GCBackground, &gcval); 28 | 29 | setwinattr.backing_store = Always; 30 | 31 | new_bt->font_info = XLoadQueryFont(new_bt->dsp, new_bt->fontname); 32 | 33 | if(new_bt->fontname != NULL) 34 | XSetFont(display, new_bt->gc2, new_bt->font_info->fid); 35 | else 36 | perror("XLoadQueryFont"); 37 | 38 | if(new_bt->dsp) 39 | { 40 | new_bt->win = XCreateSimpleWindow(new_bt->dsp, parent_win->win, x, y, w, 41 | h, 1, fg, bg); 42 | new_bt->mask = ExposureMask | EnterWindowMask | LeaveWindowMask | 43 | ButtonPressMask | ButtonReleaseMask; 44 | 45 | XChangeWindowAttributes(new_bt->dsp, new_bt->win, CWBackingStore, 46 | &setwinattr); 47 | XSetWindowBackground(new_bt->dsp, new_bt->win, 0xF2E6EB); 48 | XSelectInput( new_bt->dsp, new_bt->win, new_bt->mask); 49 | XMapWindow(new_bt->dsp, new_bt->win); 50 | 51 | 52 | new_bt->x = x; 53 | new_bt->y = y; 54 | new_bt->w = w; 55 | new_bt->h = h; 56 | 57 | new_bt->handler = &stk_button_handle; 58 | 59 | if(func) 60 | new_bt->pressfunc = func; 61 | 62 | if(args) 63 | new_bt->pargs = args; 64 | 65 | if(label) 66 | new_bt->label = label; 67 | 68 | stk_widget_insert((void*)new_bt); 69 | 70 | return new_bt; 71 | } 72 | else 73 | return NULL; 74 | } 75 | 76 | 77 | void stk_button_expose(stk_widget *bt) 78 | { 79 | int width, wcenter, hcenter; 80 | XClearWindow(bt->dsp, bt->win); 81 | 82 | if(bt->label) 83 | { 84 | 85 | width = XTextWidth(bt->font_info, bt->label, strlen(bt->label)); 86 | wcenter = (bt->w - width) / 2; 87 | hcenter = ((bt->font_info->descent + bt->font_info->ascent)/2) + (bt->h / 2); 88 | 89 | XDrawString(bt->dsp, bt->win, bt->gc2, wcenter, hcenter, 90 | bt->label, strlen(bt->label)); 91 | } 92 | XFlush(bt->dsp); 93 | } 94 | 95 | 96 | void stk_button_redraw(int dtype, stk_widget *bt) 97 | { 98 | 99 | switch(dtype) 100 | { 101 | case STK_BUTTON_EXPOSE: 102 | stk_button_expose(bt); 103 | break; 104 | 105 | case STK_BUTTON_PRESS: 106 | XSetInputFocus(bt->dsp, bt->win, RevertToNone, CurrentTime); 107 | XDrawRectangle(bt->dsp, bt->win, bt->gc2, 0, 0, bt->w - 1, 108 | bt->h - 1); 109 | break; 110 | 111 | case STK_BUTTON_RELEASE: 112 | stk_button_expose(bt); 113 | break; 114 | 115 | case STK_BUTTON_ENTER: 116 | case STK_BUTTON_LEAVE: 117 | default: 118 | break; 119 | } 120 | } 121 | 122 | 123 | 124 | void stk_button_handle(STKEvent *event, void *warg) 125 | { 126 | stk_widget *wg = (stk_widget*)warg; 127 | 128 | wg->ev = event; 129 | 130 | switch(event->type) 131 | { 132 | case Expose: 133 | if(wg->exposefunc) 134 | wg->exposefunc(wg->exargs); 135 | stk_button_redraw(STK_BUTTON_EXPOSE, wg); 136 | break; 137 | 138 | case EnterNotify: 139 | if(wg->enterfunc) 140 | wg->enterfunc(wg->eargs); 141 | break; 142 | 143 | case LeaveNotify: 144 | if(wg->leavefunc) 145 | wg->leavefunc(wg->largs); 146 | break; 147 | 148 | case ButtonPress: 149 | if(event->xbutton.button == Button1) 150 | stk_button_redraw(STK_BUTTON_PRESS, wg); 151 | break; 152 | 153 | case ButtonRelease: 154 | if(event->xbutton.button == Button1) 155 | { 156 | if(wg->pressfunc) 157 | wg->pressfunc(wg->pargs); 158 | } 159 | stk_button_redraw(STK_BUTTON_RELEASE, wg); 160 | 161 | break; 162 | 163 | case MotionNotify: 164 | if(wg->movefunc) 165 | wg->movefunc(wg->margs); 166 | break; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/stk_progress_bar.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | stk_widget *stk_progress_bar_new(stk_widget *parent_win, int x, int y, uint w, uint h, char *label) 5 | { 6 | stk_widget *new_pb = (stk_widget*) malloc(sizeof(stk_widget)); 7 | stk_progress_bar *pb = (stk_progress_bar*) malloc(sizeof(stk_progress_bar)); 8 | int screen; 9 | 10 | XGCValues gcval; 11 | long fg, bg; 12 | 13 | memset(new_pb, 0, sizeof(stk_widget)); 14 | 15 | new_pb->dsp = display; 16 | new_pb->fontname = "7x13"; 17 | 18 | screen = DefaultScreen(new_pb->dsp); 19 | fg = BlackPixel(new_pb->dsp, screen); 20 | bg = WhitePixel(new_pb->dsp, screen); 21 | 22 | gcval.foreground = fg; 23 | gcval.background = bg; 24 | 25 | new_pb->gc2 = XCreateGC(new_pb->dsp, parent_win->win, GCForeground | 26 | GCBackground, &gcval); 27 | 28 | if(new_pb->dsp) 29 | { 30 | new_pb->win = XCreateSimpleWindow(new_pb->dsp, parent_win->win, x, y, w, 31 | h, 1, fg, bg); 32 | new_pb->gc = XCreateGC(new_pb->dsp, new_pb->win, 0, 0); 33 | new_pb->font_info = XLoadQueryFont(new_pb->dsp, new_pb->fontname); 34 | 35 | if(new_pb->fontname != NULL) 36 | XSetFont(display, new_pb->gc2, new_pb->font_info->fid); 37 | else 38 | perror("XLoadQueryFont"); 39 | 40 | new_pb->mask = ExposureMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask; 41 | 42 | XSelectInput(new_pb->dsp, new_pb->win, new_pb->mask); 43 | 44 | 45 | 46 | if(DisplayPlanes(new_pb->dsp, screen) != 1) 47 | { 48 | pb->cmap = DefaultColormap(new_pb->dsp, screen); 49 | if(XAllocNamedColor(new_pb->dsp, pb->cmap, "red", &pb->color, &pb->colorrgb)) 50 | XSetForeground(new_pb->dsp, new_pb->gc, pb->color.pixel); 51 | } 52 | 53 | XMapWindow(new_pb->dsp, new_pb->win); 54 | 55 | memset(pb, 0, sizeof(stk_progress_bar)); 56 | 57 | new_pb->x = x; 58 | new_pb->y = y; 59 | new_pb->w = w; 60 | new_pb->h = h; 61 | 62 | new_pb->handler = &stk_progress_bar_handle; 63 | pb->pct = 0; 64 | new_pb->ext_struct = (void*)pb; 65 | 66 | 67 | if(label) 68 | strcpy(pb->label, label); 69 | else 70 | new_pb->label = NULL; 71 | 72 | stk_widget_insert((void*)new_pb); 73 | 74 | return new_pb; 75 | } 76 | else 77 | return NULL; 78 | } 79 | 80 | 81 | void stk_progress_bar_expose(stk_widget *pb) 82 | { 83 | int width, wcenter, hcenter, 84 | len; 85 | stk_progress_bar *spb = (stk_progress_bar*)pb->ext_struct; 86 | 87 | XClearWindow(pb->dsp, pb->win); 88 | XFillRectangle(pb->dsp, pb->win, pb->gc, 0, 0, (pb->w * spb->pct)/100, pb->h); 89 | 90 | len = strlen(spb->label); 91 | 92 | 93 | if(len > 0) 94 | { 95 | width = XTextWidth(pb->font_info, spb->label, strlen(spb->label)); 96 | wcenter = (pb->w - width) / 2; 97 | hcenter = ((pb->font_info->descent + pb->font_info->ascent)/2) + (pb->h / 2); 98 | 99 | XDrawString(pb->dsp, pb->win, pb->gc2, wcenter, hcenter, 100 | spb->label, strlen(spb->label)); 101 | } 102 | XFlush(pb->dsp); 103 | } 104 | 105 | 106 | void stk_progress_bar_set_label(stk_widget *pb, char *new_label) 107 | { 108 | stk_progress_bar *spb = (stk_progress_bar*)pb->ext_struct; 109 | 110 | memset(spb->label, 0, strlen(spb->label)); 111 | strcpy(spb->label, new_label); 112 | stk_progress_bar_expose(pb); 113 | } 114 | 115 | 116 | uint stk_progress_bar_get_value(stk_widget *pb) 117 | { 118 | stk_progress_bar *spb = (stk_progress_bar*)pb->ext_struct; 119 | return spb->pct; 120 | } 121 | 122 | 123 | void stk_progress_bar_set_value(stk_widget *pb, uint pct) 124 | { 125 | stk_progress_bar *spb = (stk_progress_bar*)pb->ext_struct; 126 | spb->pct = pct; 127 | stk_progress_bar_expose(pb); 128 | } 129 | 130 | 131 | void stk_progress_bar_redraw(int dtype, stk_widget *pb) 132 | { 133 | 134 | switch(dtype) 135 | { 136 | case STK_PROGRESS_BAR_EXPOSE: 137 | stk_progress_bar_expose(pb); 138 | break; 139 | 140 | case STK_PROGRESS_BAR_PRESS: 141 | break; 142 | 143 | case STK_PROGRESS_BAR_RELEASE: 144 | break; 145 | 146 | case STK_PROGRESS_BAR_ENTER: 147 | case STK_PROGRESS_BAR_LEAVE: 148 | default: 149 | break; 150 | } 151 | } 152 | 153 | 154 | void stk_progress_bar_handle(STKEvent *event, void *warg) 155 | { 156 | stk_widget *wg = (stk_widget*)warg; 157 | 158 | wg->ev = event; 159 | 160 | switch(event->type) 161 | { 162 | case Expose: 163 | if(wg->exposefunc) 164 | wg->exposefunc(wg->exargs); 165 | stk_progress_bar_redraw(STK_PROGRESS_BAR_EXPOSE, wg); 166 | break; 167 | 168 | case EnterNotify: 169 | if(wg->enterfunc) 170 | wg->enterfunc(wg->eargs); 171 | break; 172 | 173 | case LeaveNotify: 174 | if(wg->leavefunc) 175 | wg->leavefunc(wg->largs); 176 | break; 177 | 178 | case ButtonPress: 179 | if(wg->pressfunc) 180 | wg->pressfunc(wg->pargs); 181 | break; 182 | 183 | case ButtonRelease: 184 | if(wg->releasefunc) 185 | wg->releasefunc(wg->rargs); 186 | break; 187 | 188 | case MotionNotify: 189 | if(wg->movefunc) 190 | wg->movefunc(wg->margs); 191 | break; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/stk_canvas.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | stk_widget *stk_canvas_new(stk_widget *parent_win, int x, int y, uint w, uint h) 5 | { 6 | stk_widget *new_pl = (stk_widget*) malloc(sizeof(stk_widget)); 7 | stk_canvas *pl = (stk_canvas*) malloc(sizeof(stk_canvas)); 8 | int screen, depth; 9 | 10 | XGCValues gplal; 11 | long fg, bg; 12 | XSetWindowAttributes setwinattr; 13 | memset(new_pl, 0, sizeof(stk_widget)); 14 | 15 | 16 | new_pl->dsp = display; 17 | new_pl->fontname = STK_FONT_SIZE_6x9; 18 | 19 | screen = DefaultScreen(new_pl->dsp); 20 | depth = DefaultDepth(new_pl->dsp, screen); 21 | fg = BlackPixel(new_pl->dsp, screen); 22 | bg = WhitePixel(new_pl->dsp, screen); 23 | 24 | gplal.foreground = fg; 25 | gplal.background = bg; 26 | gplal.line_width = 1; 27 | gplal.line_style = LineSolid; 28 | 29 | 30 | new_pl->gc2 = XCreateGC(new_pl->dsp, parent_win->win, GCForeground | 31 | GCBackground|GCLineWidth|GCLineStyle, &gplal); 32 | 33 | 34 | gplal.foreground = bg; 35 | gplal.background = fg; 36 | 37 | new_pl->gc = XCreateGC(new_pl->dsp, parent_win->win, GCForeground | 38 | GCBackground|GCLineWidth|GCLineStyle, &gplal); 39 | 40 | setwinattr.backing_store = Always; 41 | 42 | if(new_pl->dsp) 43 | { 44 | new_pl->win = XCreateSimpleWindow(new_pl->dsp, parent_win->win, x, y, w, 45 | h, 1, fg, bg); 46 | new_pl->mask = ExposureMask | EnterWindowMask | LeaveWindowMask | 47 | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; 48 | 49 | XChangeWindowAttributes(new_pl->dsp, new_pl->win, CWBackingStore, 50 | &setwinattr); 51 | XSelectInput(new_pl->dsp, new_pl->win, new_pl->mask); 52 | XMapWindow(new_pl->dsp, new_pl->win); 53 | 54 | pl->pmap = XCreatePixmap(new_pl->dsp, new_pl->win, w, h, depth); 55 | XSetForeground(new_pl->dsp, new_pl->gc, 56 | WhitePixelOfScreen(DefaultScreenOfDisplay(new_pl->dsp))); 57 | XFillRectangle(new_pl->dsp, pl->pmap, new_pl->gc, 0, 0, w, h); 58 | 59 | stk_canvas_set_string_font(new_pl, new_pl->fontname); 60 | 61 | new_pl->x = x; 62 | new_pl->y = y; 63 | new_pl->w = w; 64 | new_pl->h = h; 65 | 66 | new_pl->handler = &stk_canvas_handle; 67 | new_pl->ext_struct = (void*)pl; 68 | 69 | stk_widget_insert((void*)new_pl); 70 | 71 | return new_pl; 72 | } 73 | else 74 | return NULL; 75 | } 76 | 77 | 78 | void stk_canvas_expose(stk_widget *pl) 79 | { 80 | stk_canvas *spl = (stk_canvas*)pl->ext_struct; 81 | 82 | XCopyArea(pl->dsp, spl->pmap, pl->win, pl->gc2, 0, 0, pl->w, pl->h, 0, 0); 83 | XFlush(pl->dsp); 84 | } 85 | 86 | 87 | void stk_canvas_draw_arc(stk_widget *pl, uint x, uint y, uint w, uint h, 88 | uint angle0, uint angle1) 89 | { 90 | stk_canvas *spl = (stk_canvas*)pl->ext_struct; 91 | XDrawArc(pl->dsp, spl->pmap, pl->gc2, x, y, w, h, angle0, angle1); 92 | stk_canvas_expose(pl); 93 | } 94 | 95 | 96 | void stk_canvas_draw_string(stk_widget *pl, uint x, uint y, char *str) 97 | { 98 | stk_canvas *spl = (stk_canvas*)pl->ext_struct; 99 | XDrawString(pl->dsp, spl->pmap, pl->gc2, x, y, str, strlen(str)); 100 | stk_canvas_expose(pl); 101 | } 102 | 103 | 104 | void stk_canvas_draw_line(stk_widget *pl, uint x0, uint y0, uint x1, uint y1) 105 | { 106 | stk_canvas *spl = (stk_canvas*)pl->ext_struct; 107 | XDrawLine(pl->dsp, spl->pmap, pl->gc2, x0, y0, x1, y1); 108 | stk_canvas_expose(pl); 109 | } 110 | 111 | 112 | void stk_canvas_draw_point(stk_widget *pl, uint x, uint y) 113 | { 114 | stk_canvas *spl = (stk_canvas*)pl->ext_struct; 115 | XDrawPoint(pl->dsp, spl->pmap, pl->gc2, x, y); 116 | stk_canvas_expose(pl); 117 | } 118 | 119 | 120 | void stk_canvas_area_rotate(stk_widget *pl, uint x0 , uint y0, uint x1, uint y1, 121 | uint angle) 122 | { 123 | } 124 | 125 | 126 | void stk_canvas_set_string_font_size(stk_widget *pl, char *size) 127 | { 128 | stk_widget_set_font_size(pl, size); 129 | } 130 | 131 | 132 | void stk_canvas_set_string_font(stk_widget *pl, char *font) 133 | { 134 | stk_widget_set_font_size(pl, font); 135 | } 136 | 137 | 138 | void stk_canvas_redraw(int dtype, stk_widget *pl) 139 | { 140 | switch(dtype) 141 | { 142 | case STK_CANVAS_EXPOSE: 143 | stk_canvas_expose(pl); 144 | break; 145 | 146 | case STK_CANVAS_PRESS: 147 | break; 148 | 149 | case STK_CANVAS_RELEASE: 150 | break; 151 | 152 | case STK_CANVAS_ENTER: 153 | case STK_CANVAS_LEAVE: 154 | case STK_CANVAS_MOVE: 155 | default: 156 | break; 157 | } 158 | } 159 | 160 | 161 | 162 | void stk_canvas_handle(STKEvent *event, void *warg) 163 | { 164 | stk_widget *wg = (stk_widget*)warg; 165 | 166 | wg->ev = event; 167 | 168 | switch(event->type) 169 | { 170 | case Expose: 171 | if(wg->exposefunc) 172 | wg->exposefunc(wg->exargs); 173 | stk_canvas_redraw(STK_CANVAS_EXPOSE, wg); 174 | break; 175 | 176 | case EnterNotify: 177 | if(wg->enterfunc) 178 | wg->enterfunc(wg->eargs); 179 | break; 180 | 181 | case LeaveNotify: 182 | if(wg->leavefunc) 183 | wg->leavefunc(wg->largs); 184 | break; 185 | 186 | case ButtonPress: 187 | if(wg->pressfunc) 188 | wg->pressfunc(wg->pargs); 189 | break; 190 | 191 | case ButtonRelease: 192 | if(wg->releasefunc) 193 | wg->releasefunc(wg->rargs); 194 | break; 195 | 196 | case MotionNotify: 197 | if(wg->movefunc) 198 | wg->movefunc(wg->margs); 199 | break; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/stk_widget.c: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | */ 4 | #include 5 | 6 | widget_list *list; 7 | 8 | /*! 9 | @brief 10 | Initialize the Display connection to X and the widget list 11 | 12 | Must be called before any STK functions 13 | */ 14 | void stk_init() 15 | { 16 | list = NULL; 17 | display = XOpenDisplay(0); 18 | } 19 | 20 | 21 | /** 22 | @brief Alloc and insert a widget in the widget list. 23 | @param widget The pointer to the widget to be inserted on the list 24 | @return 0 if success or -1 if unsuccessful. 25 | @discussion Every widget must call it to be 26 | registered and have its events 27 | handled 28 | */ 29 | int stk_widget_insert(void *widget) 30 | { 31 | widget_list *new_widget = (widget_list *)malloc(sizeof(widget_list)); 32 | 33 | if(new_widget) 34 | { 35 | new_widget->this = widget; 36 | new_widget->prev = NULL; 37 | new_widget->next = list; 38 | 39 | if(list != NULL) 40 | list->prev = new_widget; 41 | 42 | list = new_widget; 43 | 44 | return 0; 45 | } 46 | return -1; 47 | } 48 | 49 | 50 | int stk_widget_delete(void *widget) 51 | { 52 | return 0; 53 | } 54 | 55 | 56 | /*! 57 | @brief Searchs for a widget in the widget list. 58 | @param widget The widget to be located on the list. 59 | @return Returns a pointer to stk_widget or NULL 60 | */ 61 | stk_widget *stk_widget_search(void *widget) 62 | { 63 | widget_list *node = list; 64 | stk_widget *wnode = NULL; 65 | 66 | 67 | if(node == NULL) 68 | printf("Empty widget list\n"); 69 | else 70 | { 71 | while(node) 72 | { 73 | wnode = (stk_widget*)node->this; 74 | if(wnode->win == (Window)widget) 75 | return wnode; 76 | else 77 | node = node->next; 78 | } 79 | } 80 | 81 | printf("Widget %p not found :(\n", widget); 82 | return NULL; 83 | } 84 | 85 | 86 | /*! 87 | @brief Search for a widget in the widget list. 88 | @return Must be called after all STK functions. 89 | It's the event loop that handles the all 90 | the event callings of the widgets. 91 | */ 92 | void stk_run() 93 | { 94 | STKEvent event; 95 | widget_list *node = list; 96 | stk_widget *wnode = NULL; 97 | 98 | if(node == NULL) 99 | printf("Empty list\n"); 100 | else 101 | { 102 | while(1) 103 | { 104 | XNextEvent(display, &event); 105 | wnode = stk_widget_search((void*)event.xany.window); 106 | 107 | if(wnode != NULL) 108 | wnode->handler(&event, wnode); 109 | } 110 | } 111 | } 112 | 113 | 114 | 115 | void stk_widget_event_listen_add(stk_widget *win, int event_type, 116 | void (*func)(void*), void *args) 117 | { 118 | switch(event_type) 119 | { 120 | case STK_WIDGET_MOVE: 121 | win->movefunc = func; 122 | win->margs = args; 123 | break; 124 | 125 | case STK_WIDGET_PRESS: 126 | win->pressfunc = func; 127 | win->pargs = args; 128 | break; 129 | 130 | case STK_WIDGET_EXPOSE: 131 | win->exposefunc = func; 132 | win->exargs = args; 133 | break; 134 | 135 | case STK_WIDGET_LEAVE: 136 | win->leavefunc = func; 137 | win->largs = args; 138 | break; 139 | 140 | case STK_WIDGET_ENTER: 141 | win->enterfunc = func; 142 | win->eargs = args; 143 | break; 144 | 145 | case STK_WIDGET_RELEASE: 146 | win->releasefunc = func; 147 | win->rargs = args; 148 | break; 149 | } 150 | } 151 | 152 | 153 | 154 | void stk_widget_event_listen_remove(stk_widget *win, int event_type) 155 | { 156 | switch(event_type) 157 | { 158 | case STK_WIDGET_MOVE: 159 | win->movefunc = NULL; 160 | win->margs = NULL; 161 | break; 162 | 163 | case STK_WIDGET_PRESS: 164 | win->pressfunc = NULL; 165 | win->pargs = NULL; 166 | break; 167 | 168 | case STK_WIDGET_EXPOSE: 169 | win->exposefunc = NULL; 170 | win->exargs = NULL; 171 | break; 172 | 173 | case STK_WIDGET_LEAVE: 174 | win->leavefunc = NULL; 175 | win->largs = NULL; 176 | break; 177 | 178 | case STK_WIDGET_ENTER: 179 | win->enterfunc = NULL; 180 | win->eargs = NULL; 181 | break; 182 | 183 | case STK_WIDGET_RELEASE: 184 | win->releasefunc = NULL; 185 | win->rargs = NULL; 186 | break; 187 | } 188 | } 189 | 190 | void stk_widget_set_size(stk_widget *win, uint w, uint h) 191 | { 192 | XResizeWindow(win->dsp, win->win, w, h); 193 | } 194 | 195 | /*! 196 | @brief returns the first widget created 197 | @return The pointer to the first widget added on the list 198 | */ 199 | stk_widget *stk_widget_root() 200 | { 201 | widget_list *node = list; 202 | stk_widget *wnode = NULL; 203 | 204 | while(node) 205 | { 206 | 207 | wnode = (stk_widget*)node->this; 208 | node = node->next; 209 | } 210 | return wnode; 211 | } 212 | 213 | /*! 214 | @brief set widget position on the screen 215 | */ 216 | void stk_widget_set_pos(stk_widget *win, uint x, uint y) 217 | { 218 | XMoveWindow(win->dsp, win->win, x, y); 219 | } 220 | 221 | /*! 222 | @brief set widget color 223 | */ 224 | void stk_widget_set_color(stk_widget *win, int color) 225 | { 226 | XSetWindowBackground(win->dsp, win->win, color); 227 | XClearWindow(win->dsp, win->win); 228 | XFlush(win->dsp); 229 | } 230 | 231 | 232 | void stk_widget_set_font_size(stk_widget *win, char *str_size) 233 | { 234 | win->font_info = XLoadQueryFont(win->dsp, str_size); 235 | 236 | if(win->fontname != NULL) 237 | XSetFont(win->dsp, win->gc2, win->font_info->fid); 238 | else 239 | perror("XLoadQueryFont"); 240 | } 241 | 242 | 243 | -------------------------------------------------------------------------------- /src/stk_text.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | stk_widget *stk_text_new(stk_widget *parent_win, int x, int y, uint w, uint h, 5 | char *label, int type) 6 | { 7 | stk_widget *new_txt = (stk_widget*) malloc(sizeof(stk_widget)); 8 | stk_text *txt = (stk_text*) malloc(sizeof(stk_text)); 9 | int screen; 10 | 11 | XGCValues gcval; 12 | long fg, bg; 13 | XSetWindowAttributes setwinattr; 14 | 15 | memset(new_txt, 0, sizeof(stk_widget)); 16 | memset(txt->text, 0, sizeof(stk_text)); 17 | 18 | new_txt->dsp = display; 19 | new_txt->fontname = STK_FONT_SIZE_7x13; 20 | 21 | screen = DefaultScreen(new_txt->dsp); 22 | fg = BlackPixel(new_txt->dsp, screen); 23 | bg = WhitePixel(new_txt->dsp, screen); 24 | 25 | gcval.foreground = fg; 26 | gcval.background = bg; 27 | new_txt->gc2 = XCreateGC(new_txt->dsp, parent_win->win, GCForeground | 28 | GCBackground, &gcval); 29 | 30 | setwinattr.backing_store = Always; 31 | 32 | new_txt->font_info = XLoadQueryFont(new_txt->dsp, new_txt->fontname); 33 | 34 | if(new_txt->fontname != NULL) 35 | XSetFont(display, new_txt->gc2, new_txt->font_info->fid); 36 | else 37 | perror("XLoadQueryFont"); 38 | 39 | if(new_txt->dsp) 40 | { 41 | new_txt->win = XCreateSimpleWindow(new_txt->dsp, parent_win->win, x, y, w, 42 | h, 1, fg, bg); 43 | 44 | if(type == STK_TEXT_INPUT) 45 | { 46 | new_txt->mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | 47 | EnterWindowMask | LeaveWindowMask | 48 | FocusChangeMask | StructureNotifyMask | PropertyChangeMask | VisibilityChangeMask; 49 | } 50 | else 51 | { 52 | new_txt->mask = ExposureMask| EnterWindowMask | LeaveWindowMask | 53 | FocusChangeMask | StructureNotifyMask | PropertyChangeMask | VisibilityChangeMask; 54 | } 55 | 56 | XChangeWindowAttributes(new_txt->dsp, new_txt->win, CWBackingStore, 57 | &setwinattr); 58 | 59 | XSelectInput(new_txt->dsp, new_txt->win, new_txt->mask); 60 | XMapWindow(new_txt->dsp, new_txt->win); 61 | 62 | 63 | new_txt->x = x; 64 | new_txt->y = y; 65 | new_txt->w = w; 66 | new_txt->h = h; 67 | new_txt->handler = &stk_text_handle; 68 | new_txt->ext_struct = (void*)txt; 69 | 70 | if(label) 71 | strcpy(txt->text, label); 72 | 73 | 74 | stk_widget_insert((void*)new_txt); 75 | 76 | return new_txt; 77 | } 78 | else 79 | return NULL; 80 | } 81 | 82 | 83 | 84 | void stk_text_append(stk_widget *txt, char c) 85 | { 86 | int len = 0; 87 | 88 | stk_text *string = (stk_text*)txt->ext_struct; 89 | 90 | len = strlen(string->text); 91 | 92 | if(len == 0) 93 | string->text[0] = c; 94 | else 95 | string->text[len] = c; 96 | } 97 | 98 | 99 | 100 | void stk_text_delete(stk_widget *txt) 101 | { 102 | int len = 0; 103 | stk_text *string = (stk_text*)txt->ext_struct; 104 | 105 | len = strlen(string->text); 106 | 107 | if(len == 0) 108 | return; 109 | else 110 | string->text[len - 1] = 0; 111 | } 112 | 113 | 114 | 115 | void stk_text_expose(stk_widget *txt, void *arg) 116 | { 117 | stk_text *string = (stk_text*)txt->ext_struct; 118 | int hcenter = ((txt->font_info->descent + txt->font_info->ascent )/2) + (txt->h / 2); 119 | int sw, begin; 120 | 121 | XClearWindow(txt->dsp, txt->win); 122 | 123 | if(string->text) 124 | { 125 | sw = XTextWidth(txt->font_info, string->text, strlen(string->text)); 126 | if(sw > txt->w) 127 | begin = txt->w - sw; 128 | else 129 | begin = 2; 130 | 131 | XDrawString(txt->dsp, txt->win, txt->gc2, begin, hcenter, 132 | string->text, strlen(string->text)); 133 | } 134 | XFlush(txt->dsp); 135 | } 136 | 137 | 138 | 139 | void stk_text_set_text(stk_widget *txt, char *string) 140 | { 141 | int i, len; 142 | stk_text *extstr = (stk_text*)txt->ext_struct; 143 | 144 | len = strlen(string); 145 | memset(extstr->text, '\0', STK_TEXT_BUFFER_SIZE); 146 | 147 | for(i = 0; i < len; i++) 148 | stk_text_append(txt, *string++); 149 | 150 | stk_text_expose(txt, NULL); 151 | } 152 | 153 | 154 | 155 | void stk_text_keys(stk_widget *txt, XKeyEvent *event, KeySym *key) 156 | { 157 | KeySym keysym = (KeySym)&key; 158 | char c; 159 | 160 | XLookupString(event, &c, sizeof(char), &keysym, NULL); 161 | 162 | if((keysym == XK_BackSpace) || (keysym == XK_Delete)) 163 | { 164 | stk_text_delete(txt); 165 | stk_text_redraw(STK_TEXT_EXPOSE, txt, NULL); 166 | } 167 | 168 | if((keysym >= XK_Left) && (keysym <= XK_Down)) 169 | { 170 | printf("Arrow Key:-"); 171 | switch(keysym){ 172 | case XK_Left: printf("Left\n"); break; 173 | case XK_Up: printf("Up\n"); break; 174 | case XK_Right: printf("Right\n"); break; 175 | case XK_Down: printf("Down\n"); break; 176 | } 177 | } 178 | if((keysym >= XK_space) && (keysym <= XK_asciitilde)) 179 | { 180 | stk_text_append(txt, c); 181 | } 182 | 183 | } 184 | 185 | 186 | char *stk_text_get_text(stk_widget *txt) 187 | { 188 | stk_text *string = (stk_text*)txt->ext_struct; 189 | return string->text; 190 | } 191 | 192 | 193 | void stk_text_redraw(int dtype, stk_widget *txt, void *args) 194 | { 195 | 196 | STKEvent *ev; 197 | 198 | if(args) 199 | ev = (STKEvent*)args; 200 | 201 | switch(dtype) 202 | { 203 | case STK_TEXT_EXPOSE: 204 | stk_text_expose(txt, NULL); 205 | break; 206 | 207 | case STK_TEXT_PRESS: 208 | XSetInputFocus(txt->dsp, txt->win, RevertToNone, CurrentTime); 209 | break; 210 | 211 | case STK_TEXT_RELEASE: 212 | break; 213 | 214 | case STK_TEXT_KEYPRESS: 215 | { 216 | KeySym keysym; 217 | stk_text_keys(txt, &ev->xkey, &keysym); 218 | stk_text_expose(txt, NULL); 219 | } 220 | break; 221 | 222 | case STK_TEXT_KEYRELEASE: 223 | break; 224 | 225 | 226 | case STK_TEXT_ENTER: 227 | XDefineCursor(txt->dsp, txt->win, XCreateFontCursor(txt->dsp, XC_xterm)); 228 | break; 229 | case STK_TEXT_LEAVE: 230 | default: 231 | break; 232 | } 233 | } 234 | 235 | 236 | 237 | void stk_text_handle(STKEvent *event, void *warg) 238 | { 239 | stk_widget *wg = (stk_widget*)warg; 240 | 241 | switch(event->type) 242 | { 243 | case Expose: 244 | if(wg->exposefunc) 245 | wg->exposefunc(wg->exargs); 246 | 247 | stk_text_redraw(STK_TEXT_EXPOSE, wg, NULL); 248 | break; 249 | 250 | case ButtonPress: 251 | if(wg->pressfunc) 252 | wg->pressfunc(wg->pargs); 253 | 254 | stk_text_redraw(STK_TEXT_PRESS, wg, NULL); 255 | break; 256 | 257 | case ButtonRelease: 258 | if(wg->releasefunc) 259 | wg->releasefunc(wg->rargs); 260 | 261 | stk_text_redraw(STK_TEXT_RELEASE, wg, NULL); 262 | break; 263 | 264 | case KeyPress: 265 | /*MISSING STK_WIDGET_KEYPRESS */ 266 | stk_text_redraw(STK_TEXT_KEYPRESS, wg, event); 267 | break; 268 | 269 | case KeyRelease: 270 | 271 | /*MISSING STK_WIDGET_KEYRELEASE */ 272 | stk_text_redraw(STK_TEXT_KEYRELEASE, wg, NULL); 273 | break; 274 | 275 | case EnterNotify: 276 | if(wg->enterfunc) 277 | wg->enterfunc(wg->eargs); 278 | stk_text_redraw(STK_TEXT_ENTER, wg, NULL); 279 | break; 280 | 281 | case LeaveNotify: 282 | if(wg->leavefunc) 283 | wg->leavefunc(wg->largs); 284 | break; 285 | } 286 | } 287 | --------------------------------------------------------------------------------