--- /dev/null
+#include <stdc.h>
+#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;
+}
--- /dev/null
+AUTOLIB(X11)
+AUTOLIB(Xinerama)
+AUTOLIB(Xft)
+AUTOLIB(fontconfig)
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xft/Xft.h>
+
+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*));
--- /dev/null
+#include <stdc.h>
+#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)
+//{
+//}
--- /dev/null
+#include <stdc.h>
+#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);
+}