From e1c0b83c2f5fb4707931d6a29c260d9704130cd1 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 6 May 2019 21:58:12 -0400 Subject: [PATCH] added prototype of tframe --- .gitignore | 1 + Makefile | 2 +- src/tframe.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/tide.c | 11 ++- src/tsed.c | 12 +--- 5 files changed, 202 insertions(+), 14 deletions(-) create mode 100644 src/tframe.c diff --git a/.gitignore b/.gitignore index 08a7f57..07bd245 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ registrar fetch tests/test_tide bin/tsed +bin/tframe diff --git a/Makefile b/Makefile index 756b79e..8886a89 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = ./acc INCS = -Iinc/ -BINS = bin/tide bin/registrar bin/edit bin/fetch bin/pick bin/tsed +BINS = bin/tide bin/registrar bin/edit bin/fetch bin/pick bin/tsed bin/tframe TEST_BINS = tests/libedit MAN1 = docs/tide.1 diff --git a/src/tframe.c b/src/tframe.c new file mode 100644 index 0000000..90917c9 --- /dev/null +++ b/src/tframe.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define INCLUDE_DEFS +#include "config.h" + +static struct XConf X; +static View Tags; +static int Divider; +static int FontSel; + +/* X11 Window Code + ******************************************************************************/ +static void font_load(char* name) { + XftFont* font = x11_font_load(&X, name); + X.font = (font ? font : X.font); // Update if we found a new font +} + +size_t glyph_width(View* view, int c) { + (void)view; + FcChar32 rune = (FcChar32)c; + XGlyphInfo extents; + XftTextExtents32(X.display, X.font, &rune, 1, &extents); + if (c == '\t') + return (TabWidth * extents.xOff); + else + return extents.xOff; +} + +Window child_window = 0; + +static void xmaprequest(XConf* x, XEvent* e) { + (void)x; + XMapWindow(e->xmaprequest.display, e->xmaprequest.window); + child_window = e->xmaprequest.window; +} + +static void xconfigure(XConf* x, XEvent* e) { + if (e->xconfigure.width != x->width || e->xconfigure.height != x->height) { + x->width = e->xconfigure.width; + x->height = e->xconfigure.height; + x->pixmap = XCreatePixmap(x->display, x->self, x->width, x->height, x->depth); + x->xft = XftDrawCreate(x->display, x->pixmap, x->visual, x->colormap); + } + + if (child_window) { + // Get container window attributes + XWindowAttributes attrs; + XGetWindowAttributes(x->display, x->self, &attrs); + + // Move and resize child + XMoveResizeWindow(x->display, + child_window, + 0, Divider+2, attrs.width, attrs.height - Divider - 2); + } +} + +static void xdestroy(XConf* x, XEvent* e) { + (void)x, (void)e; +} + +static void xclientmsg(XConf* x, XEvent* e) { + if ((Atom)(e->xclient.data.l[0]) == XInternAtom(x->display, "WM_DELETE_WINDOW", False)) + win_quit(); +} + +static void xupdate(Job* job) { + int nqueued, nevents; + do { + nqueued = XEventsQueued(X.display, QueuedAfterFlush); + XGetMotionEvents(X.display, X.self, CurrentTime, CurrentTime, &nevents); + for (XEvent e; XPending(X.display);) { + XNextEvent(X.display, &e); + if (!XFilterEvent(&e, None) && X.eventfns[e.type]) + (X.eventfns[e.type])(&X, &e); + for (int status; waitpid(-1, &status, WNOHANG) > 0;); + } + if (nqueued || !job) { + /* determine the size of the regions */ + size_t maxtagrows = ((X.height/4) / X.font->height); + size_t tagrows = view_limitrows(&Tags, maxtagrows); + /* draw the regions to the window */ + drawcsr csr = { .w = X.width, .h = X.height }; + csr.x += ScrollWidth + 1; + draw_statbox(&X, Tags.buffer.status); + draw_view(&X, &Tags, X.font, tagrows, &csr, TagsBg, TagsFg, TagsSel, false); + Divider = draw_hrule(&X, &csr); + draw_rect(&X, EditBg, 0, Divider+2, csr.w, csr.h); + XCopyArea(X.display, X.pixmap, X.self, X.gc, 0, 0, X.width, X.height, 0, 0); + XFlush(X.display); + } + } while ((nqueued = XEventsQueued(X.display, QueuedAfterFlush)) > 0); +} + +void win_init(KeyBinding* bindings) { + (void)bindings; + signal(SIGPIPE, SIG_IGN); // Ignore the SIGPIPE signal + setlocale(LC_CTYPE, ""); + XSetLocaleModifiers(""); + + /* open the X display and get basic attributes */ + x11_init(&X); + font_load(Fonts[FontSel = 0]); + if (!X.font) { + perror("unable to load base font"); + exit(EXIT_FAILURE); + } + x11_mkwin(&X, 640, 480, 0 +// | FocusChangeMask +// | KeyPressMask +// | ButtonPressMask +// | ButtonReleaseMask +// | ButtonMotionMask +// | PropertyChangeMask +// | VisibilityChangeMask + | SubstructureRedirectMask + | SubstructureNotifyMask + | StructureNotifyMask + | ExposureMask + ); + + x11_init_gc(&X); + x11_sel_init(&X); + x11_show(&X); + + /* register event handlers */ +// X.eventfns[KeyPress] = xkeypress; +// X.eventfns[ButtonPress] = xbtnpress; +// X.eventfns[ButtonRelease] = xbtnrelease; +// X.eventfns[MotionNotify] = xbtnmotion; + + X.eventfns[MapRequest] = xmaprequest; + X.eventfns[ConfigureNotify] = xconfigure; + X.eventfns[DestroyNotify] = xdestroy; + X.eventfns[ClientMessage] = xclientmsg; +} + +void win_loop(void) { + job_spawn(ConnectionNumber(X.display), xupdate, 0, 0); + XSync(X.display, False); + while (X.running) { + if (job_poll(Timeout)) + xupdate(NULL); + } +} + +void win_quit(void) { + X.eventfns[SelectionClear] = x11_sel_quit; + XUnmapWindow(X.display, X.self); + if (!x11_sel_ready(&X)) { + X.running = False; + } else { + if (fork()) exit(0); /* fork into background if we still have selection */ + } +} + +/* Main Routine + ******************************************************************************/ +int main(void) { + /* create the window */ + win_init(NULL); + + /* Initialize the views */ + view_init(&Tags, NULL); + view_putstr(&Tags, "Newcol Kill Putall Dump Exit"); + view_resize(&Tags, 640, 1); + buf_logclear(&(Tags.buffer)); + + char window_id[64]; + sprintf(window_id, "%lu", X.self); + setenv("TIDE_PARENT", window_id, 1); + + if (fork() == 0) { + char* tidecmd[] = { "tide", 0 }; + execvp(tidecmd[0], tidecmd); + fprintf(stderr, "error: can't execute child process!\n"); + exit(1); + } + + /* now create the window and start the event loop */ + xupdate(NULL); + win_loop(); + return 0; +} diff --git a/src/tide.c b/src/tide.c index 7a05bc3..92e1177 100644 --- a/src/tide.c +++ b/src/tide.c @@ -33,7 +33,7 @@ typedef struct { } Tag; char* ARGV0; -static Tag Builtins[18]; +static Tag Builtins[]; static Time Now; static struct XConf X; static int KeyBtnState; @@ -810,7 +810,7 @@ static void tag_line(char* cmd) { /* Main Routine ******************************************************************************/ -static Tag Builtins[18] = { +static Tag Builtins[] = { { .tag = "Cut", .action = cut }, { .tag = "Copy", .action = copy }, { .tag = "Del", .action = quit }, @@ -947,6 +947,13 @@ int main(int argc, char** argv) { if (!gethostname(host, sizeof(host))) win_prop_set("HOST", "host", host); + /* check if we should embede in a parent */ + char* winid = getenv("TIDE_PARENT"); + if (winid) { + XReparentWindow(X.display, X.self, strtoul(winid, 0, 0), 0, 0); + XFlush(X.display); + } + /* now create the window and start the event loop */ xupdate(NULL); win_loop(); diff --git a/src/tsed.c b/src/tsed.c index 20d20c9..16302c9 100644 --- a/src/tsed.c +++ b/src/tsed.c @@ -58,18 +58,8 @@ static void lbputc(LineBuf* lbuf, int c) { } static void lbputsn(LineBuf* lbuf, char* s, ssize_t l) { -#if 1 for (ssize_t i = 0; i < l; i++) lbputc(lbuf, *(s+i)); -#else - if ((lbuf->length + l + 1) >= lbuf->capacity) { - lbuf->capacity += (l + 1); - lbuf->buffer = realloc(lbuf->buffer, lbuf->capacity); - } - memcpy((lbuf->buffer + lbuf->length), s, l); - lbuf->length += l; - lbuf->buffer[lbuf->length] = '\0'; -#endif } static void cmd_d(Cmd* cmd, LineBuf* lbuf) { @@ -258,7 +248,7 @@ void prog_exec(Prog* prog, LineBuf* lbuf) { prog->line++; for (size_t i = 0; i < prog->ncmds; i++) { Cmd* cmd = &(prog->cmds[i]); - if ((cmd->flags & IN_RANGE) ||match_addr(prog, &(cmd->addr[0]), lbuf)) { + if ((cmd->flags & IN_RANGE) || match_addr(prog, &(cmd->addr[0]), lbuf)) { if (cmd->addr[1].type != NONE) { cmd->flags |= IN_RANGE; if (match_addr(prog, &(cmd->addr[1]), lbuf)) -- 2.52.0