From: Michael D. Lowis Date: Tue, 22 Mar 2022 20:53:15 +0000 (-0400) Subject: started writing a new UI lib. just experimenting now. This will be a more traditional... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=a4ac3092e0fddd427b98762dbca0b94c9df4ec34;p=projs%2Ftide.git started writing a new UI lib. just experimenting now. This will be a more traditional widget based approach and allow more than one window per process --- diff --git a/src/uitest/main.c b/src/uitest/main.c new file mode 100644 index 0000000..0e2826a --- /dev/null +++ b/src/uitest/main.c @@ -0,0 +1,98 @@ +#include +#include "ui.h" + +int main(int argc, char** argv) +{ +// /* open the X display and get basic attributes */ +// x11_init(&X); +//// font_load(Fonts[FontSel = 0]); +//// X.tagfont = X.font; +//// if (!X.font) +//// { +//// perror("unable to load base font"); +//// exit(EXIT_FAILURE); +//// } +// x11_mkwin(&X, 640, 480, 0 +// | KeyPressMask +// | ButtonPressMask +// | ButtonReleaseMask +// | ButtonMotionMask +// | PropertyChangeMask +// ); +// x11_init_gc(&X); +// x11_sel_init(&X); +// +//// tide_send("ADD"); +//// job_spawn(ConnectionNumber(X.display), xupdate, 0, 0); +// XSync(X.display, False); +// +// int maxcount = 1000 / Timeout; +// int count = 0; +// while (X.state != QUITTING) +// { +// bool ready = job_poll(Timeout); +// count += (ready ? -count : 1); +// if (count < maxcount) +// { +//// xupdate(NULL); +// } +// } +// +//typedef struct { +// long x, y; +// long state; +// long rune; +//} KeyPress; // or Release +// +//typedef struct { +// long x, y; +// long state; +// long button; +//} ButtonPress; // or Release, or Drag +// +// +// /* register event handlers */ +//// X.eventfns[KeyPress] = xkeypress; +//// X.eventfns[ButtonPress] = xmousebtn; +//// X.eventfns[ButtonRelease] = xmousebtn; +//// X.eventfns[MotionNotify] = xbtnmotion; +// +//// X.eventfns[ClientMessage] = xclientmsg; +//// X.eventfns[ConfigureNotify] = xresize; +// +//// win_init(); +//// view_init(&Regions[TAGS], NULL); +//// view_init(&Regions[EDIT], NULL); +//// view_putstr(win_view(TAGS), TagString); +//// view_resize(win_view(TAGS), 640, 1); +//// buf_logclear(win_buf(TAGS)); +//// win_prop_set("TIDE", "", "tide"); +//// dbc_init(NULL, dumpdata); +//// +//// /* if we still have args left we're going to open it in this instance */ +//// if (*argv) +//// { +//// edit_file(*argv, line_num); +//// } +//// +//// /* set host name property */ +//// char buf[8192]; +//// if (!gethostname(buf, sizeof(buf))) +//// win_prop_set("HOST", "host", buf); +//// +//// /* exit */ +//// if (termcmd) +//// { +//// termcmd = strmcat("&", termcmd, 0); +//// exec_cmd(termcmd); +//// free(termcmd); +//// } +//// +//// /* now create the window and start the event loop */ +////#ifndef TEST +//// x11_show(&X); +////#endif +//// xupdate(NULL); +//// win_loop(); + return 0; +} diff --git a/src/uitest/ui.h b/src/uitest/ui.h new file mode 100644 index 0000000..b482855 --- /dev/null +++ b/src/uitest/ui.h @@ -0,0 +1,212 @@ +AUTOLIB(X11) +AUTOLIB(Xinerama) +AUTOLIB(Xft) +AUTOLIB(fontconfig) + +#include +#include +#include + +enum { + RUNNING, + SERVE_SEL, + QUITTING +}; + +typedef struct XConf { + Bool error; + int state, fd, screen, mods; + Window root; + Display* display; + Visual* visual; + Colormap colormap; + unsigned depth; + +// Window self; +// XftDraw* xft; +// XftFont *tagfont, *font; +// Pixmap pixmap; +// XIC xic; +// XIM xim; +// GC gc; +// void (*eventfns[LASTEvent])(struct XConf*, XEvent*); +// Time now; +} XConf; + +///* Selection identifiers */ +//enum { +// PRIMARY = 0, +// CLIPBOARD = 1 +//}; +// +///* key definitions */ +//enum Keys { +// /* Define some runes in the private use area of unicode to represent +// * special keys */ +// KEY_F1 = (0xE000+0), +// KEY_F2 = (0xE000+1), +// KEY_F3 = (0xE000+2), +// KEY_F4 = (0xE000+3), +// KEY_F5 = (0xE000+4), +// KEY_F6 = (0xE000+5), +// KEY_F7 = (0xE000+6), +// KEY_F8 = (0xE000+7), +// KEY_F9 = (0xE000+8), +// KEY_F10 = (0xE000+9), +// KEY_F11 = (0xE000+10), +// KEY_F12 = (0xE000+11), +// KEY_INSERT = (0xE000+12), +// KEY_DELETE = (0xE000+13), +// KEY_HOME = (0xE000+14), +// KEY_END = (0xE000+15), +// KEY_PGUP = (0xE000+16), +// KEY_PGDN = (0xE000+17), +// KEY_UP = (0xE000+18), +// KEY_DOWN = (0xE000+19), +// KEY_RIGHT = (0xE000+20), +// KEY_LEFT = (0xE000+21), +// +// /* ASCII Control Characters */ +// KEY_CTRL_TILDE = 0x00, +// KEY_CTRL_2 = 0x00, +// KEY_CTRL_A = 0x01, +// KEY_CTRL_B = 0x02, +// KEY_CTRL_C = 0x03, +// KEY_CTRL_D = 0x04, +// KEY_CTRL_E = 0x05, +// KEY_CTRL_F = 0x06, +// KEY_CTRL_G = 0x07, +// KEY_BACKSPACE = 0x08, +// KEY_CTRL_H = 0x08, +// KEY_TAB = 0x09, +// KEY_CTRL_I = 0x09, +// KEY_CTRL_J = 0x0A, +// KEY_CTRL_K = 0x0B, +// KEY_CTRL_L = 0x0C, +// KEY_ENTER = 0x0D, +// KEY_CTRL_M = 0x0D, +// KEY_CTRL_N = 0x0E, +// KEY_CTRL_O = 0x0F, +// KEY_CTRL_P = 0x10, +// KEY_CTRL_Q = 0x11, +// KEY_CTRL_R = 0x12, +// KEY_CTRL_S = 0x13, +// KEY_CTRL_T = 0x14, +// KEY_CTRL_U = 0x15, +// KEY_CTRL_V = 0x16, +// KEY_CTRL_W = 0x17, +// KEY_CTRL_X = 0x18, +// KEY_CTRL_Y = 0x19, +// KEY_CTRL_Z = 0x1A, +// KEY_ESCAPE = 0x1B, +// KEY_CTRL_LSQ_BRACKET = 0x1B, +// KEY_CTRL_3 = 0x1B, +// KEY_CTRL_4 = 0x1C, +// KEY_CTRL_BACKSLASH = 0x1C, +// KEY_CTRL_5 = 0x1D, +// KEY_CTRL_RSQ_BRACKET = 0x1D, +// KEY_CTRL_6 = 0x1E, +// KEY_CTRL_7 = 0x1F, +// KEY_CTRL_SLASH = 0x1F, +// KEY_CTRL_UNDERSCORE = 0x1F, +//}; +// +///* Key modifier masks */ +//enum { +// ModNone = 0, +// ModShift = (1 << 0), +// ModCapsLock = (1 << 1), +// ModCtrl = (1 << 2), +// ModAlt = (1 << 3), +// ModNumLock = (1 << 4), +// ModScrollLock = (1 << 5), +// ModWindows = (1 << 6), +// ModOneOrMore = (ModCtrl|ModAlt), +// ModAny = -1 +//}; +// +//typedef struct { +// int mods; +// uint32_t key; +// void (*fn)(char*); +// char* arg; +//} KeyBinding; + +extern struct XConf X; + +//typedef struct { +// Window winid; +// Pixmap pixmap; +// XIC xic; +// XIM xim; +// GC gc; +//} XWindow; + +int X11_Init(XConf* x); +void X11_ClearError(void); +XErrorEvent* X11_GetError(void); +Window X11_MakeWindow(XConf* x, int width, int height); +Window X11_MakeDialog(XConf* x, int width, int height); +//void UI_ShowWindow(UIWindow* w); +//void UI_HideWindow(UIWindow* w); + +//void x11_resize(XConf* x, XEvent* e); +//void x11_process_events(XConf* x); +//void x11_event_loop(XConf* x, void (*redraw)(XConf* x)); +//int x11_getptr(XConf* x, int* ptrx, int* ptry); +//uint32_t x11_getkey(XConf* x, XEvent* e); +//uint32_t x11_process_key(XConf* x, XEvent* e, KeyBinding* keys); +//int x11_seturgent(XConf* x, int urgent); +// +//void x11_centerwin(XConf* x); +//void x11_init_gc(XConf* x); +//void x11_show(XConf* x); +//XftFont* x11_font_load(XConf* x, char* name); +//void xftcolor(XConf* x, XftColor* xc, unsigned int c); +//void x11_draw_rect(XConf* x, int color, int px, int py, int width, int height); +//void x11_draw_glyphs(XConf* x, int color, XftFont* font, XftGlyphSpec* specs, long nspecs); +//void x11_flip(XConf* x); +//void x11_draw_string(XConf* x, XftFont* font, int posx, int posy, int color, char* str); +// +//void x11_sel_init(XConf* x); +//int x11_sel_get(XConf* x, int selid, void(*cbfn)(char*)); +//int x11_sel_set(XConf* x, int selid, char* str); +//void x11_sel_quit(XConf* x, XEvent* e); +//int x11_sel_ready(XConf* x); +//void x11_sel_serve(XConf* x); + + +typedef struct { + enum { + KeyDn, KeyUp, + MouseDn, MouseUp, MouseDrag, MouseMove, + Resize, + ClientMsg + } type; + long x, y; + long mod_state; + long btn_state; + long key; + long btn; + long extra; +} UIEvent; + +struct UIWidget; + +typedef struct { + void (*resize)(struct UIWidget* widget, long maxw, long maxh); + void (*draw)(struct UIWidget* widget, long maxw, long maxh); + long (*process)(struct UIWidget* widget, UIEvent* ev); +} UIWidgetFuncs; + +typedef struct UIWidget { + UIWidgetFuncs* funcs; + struct UIWidget* next; + struct UIWidget* children; + long x, y; + long w, h; +} UIWidget; + +UIWidget* UI_MakeWindow(long width, long height); +UIWidget* UI_MakeDialog(void); +void UI_StartEventLoop(void (*)(UIWidget*, UIEvent*)); diff --git a/src/uitest/ui_window.c b/src/uitest/ui_window.c new file mode 100644 index 0000000..23c50cc --- /dev/null +++ b/src/uitest/ui_window.c @@ -0,0 +1,37 @@ +#include +#include "ui.h" + +typedef struct UIWindow { + struct UIWindow* next; + UIWidget widget; + Window winid; +} UIWindow; + +UIWindow* WindowList = NULL; + +UIWidget* UI_MakeWindow(long width, long height) +{ + if (!WindowList) { X11_Init(&X); } + UIWindow* win = calloc(1, sizeof(UIWindow)); + win->winid = X11_MakeWindow(&X, width, height); +} + +UIWidget* UI_MakeDialog(void) +{ + if (!WindowList) { X11_Init(&X); } + UIWindow* win = calloc(1, sizeof(UIWindow)); + win->winid = X11_MakeDialog(&X, 640, 480); +} + +//void UI_StartEventLoop(void (*)(UIWidget*, UIEvent*)) +//{ +// /* TODO: implement event loop */ +//} +// +//void UI_ShowWindow(UIWindow* w) +//{ +//} +// +//void UI_HideWindow(UIWindow* w) +//{ +//} diff --git a/src/uitest/x11.c b/src/uitest/x11.c new file mode 100644 index 0000000..f2a739b --- /dev/null +++ b/src/uitest/x11.c @@ -0,0 +1,86 @@ +#include +#include "ui.h" +#include "config.h" + +struct XConf X; +static Bool Has_Error = False; +static XErrorEvent Error = {0}; + +static int onerror(Display* disp, XErrorEvent* ev) +{ + (void)disp; + Has_Error = True, Error = *ev; + return 0; +} + +int X11_Init(XConf* x) +{ + int ret = -1; +// signal(SIGPIPE, SIG_IGN); // Ignore the SIGPIPE signal +// setlocale(LC_CTYPE, ""); +// XSetLocaleModifiers(""); + + /* open the X display and get basic attributes */ + if ( (x->display = XOpenDisplay(0)) ) + { + x->root = DefaultRootWindow(x->display); + XWindowAttributes wa; + XGetWindowAttributes(x->display, x->root, &wa); + x->visual = wa.visual; + x->colormap = wa.colormap; + x->screen = DefaultScreen(x->display); + x->depth = DefaultDepth(x->display, x->screen); + x->state = RUNNING; + XSetErrorHandler(onerror); + ret = 0; + } + return ret; +} + +void X11_ClearError(void) +{ + Has_Error = False; + memset(&Error, 0, sizeof(Error)); +} + +XErrorEvent* X11_GetError(void) +{ + return (Has_Error ? &Error : NULL); +} + +Window X11_MakeWindow(XConf* x, int width, int height) +{ + /* create the main window */ + XSetWindowAttributes attr; + attr.background_pixel = Palette[EditBg]; /* TODO: get this from a widget or a param */ + attr.bit_gravity = NorthWestGravity; + attr.backing_store = WhenMapped; + attr.event_mask = 0 + | KeyPressMask + | ButtonPressMask + | ButtonReleaseMask + | ButtonMotionMask + | PropertyChangeMask + | EnterWindowMask + | ExposureMask + | VisibilityChangeMask + | StructureNotifyMask + ; + Window win = XCreateWindow( + x->display, x->root, 0, 0, width, height, 0, x->depth, InputOutput, x->visual, + CWBackPixel | CWBitGravity | CWBackingStore | CWEventMask, + &attr); + + /* register interest in the delete window message */ + Atom wmDeleteMessage = XInternAtom(x->display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(x->display, win, &wmDeleteMessage, 1); + return win; +} + +Window X11_MakeDialog(XConf* x, int width, int height) +{ + Window win = X11_MakeWindow(x, width, height); + Atom WindowType = XInternAtom(x->display, "_NET_WM_WINDOW_TYPE", False); + Atom DialogType = XInternAtom(x->display, "_NET_WM_WINDOW_TYPE_DIALOG", False); + XChangeProperty(x->display, win, WindowType, XA_ATOM, 32, PropModeReplace, (unsigned char*)&DialogType, 1); +}