From 75ef9f9f18d3e2a144a9d9d207b0c812e464dbc4 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 30 Oct 2018 23:07:03 -0400 Subject: [PATCH] added multi window approach for opening files --- src/edit.c | 188 ++++++++---------------------------------------- src/registrar.c | 31 +++++--- 2 files changed, 50 insertions(+), 169 deletions(-) diff --git a/src/edit.c b/src/edit.c index a4ed0c1..5d11930 100644 --- a/src/edit.c +++ b/src/edit.c @@ -2,7 +2,7 @@ #include #include -Atom XA_REGISTRAR, XA_OPEN; +Atom XA_REGISTRAR, XA_OPEN, XA_DONE; int spawn(char* cmd) { int pid = fork(); @@ -20,28 +20,41 @@ Window start_registrar(XConf* x) { return XGetSelectionOwner(x->display, XA_REGISTRAR); } -void edit_file(XConf* x, Window registrar, char* path, size_t lnnum) { - char number[32] = {0}; - snprintf(number, 32, ":%lu", lnnum); - char* rpath = realpath(path, NULL); - if (rpath) - path = strmcat(rpath, number, 0); - else - path = strmcat(path, number, 0); +void prop_set(XConf* x, Window win, char* prop, char* value) { + Atom xa_prop = XInternAtom(x->display, prop, False); XChangeProperty( - x->display, registrar, XA_OPEN, XA_STRING, 8, PropModeAppend, - (const unsigned char *)path, strlen(path)+1); - free(path); + x->display, win, xa_prop, XA_STRING, 8, PropModeReplace, + (const unsigned char *)value, strlen(value)+1); +} + +Window edit_file(XConf* x, Window registrar, char* path, char* addr) { + static char wdirbuf[32768] = {0}; + char* wdir = getcwd(wdirbuf, sizeof(wdirbuf)); + if (!wdir) return None; + Window win = XCreateSimpleWindow(x->display, x->self, 0, 0, 1, 1, 0, 0, 0); + prop_set(x, win, "WDIR", wdir); + prop_set(x, win, "FILE", path); + prop_set(x, win, "ADDR", addr); + XChangeProperty( + x->display, registrar, XA_OPEN, XA_WINDOW, 32, PropModeAppend, + (const unsigned char *)&win, 1); + XSelectInput(x->display, win, 0); + return win; +} + +void xclientmsg(XConf* x, XEvent* e) { + puts("clientmsg"); } int main(int argc, char** argv) { XConf x = {0}; x11_init(&x); x11_mkwin(&x, 1, 1, 0); + x.eventfns[ClientMessage] = xclientmsg; XA_REGISTRAR = XInternAtom(x.display, "TIDE_REGISTRAR", PropertyChangeMask); XA_OPEN = XInternAtom(x.display, "OPEN", 0); + XA_DONE = XInternAtom(x.display, "DONE", 0); Window registrar = start_registrar(&x); - if (argc == 1) { spawn("tide"); } else { @@ -49,155 +62,10 @@ int main(int argc, char** argv) { for (int i = 1; i < argc; i++) { char* addr = strrchr(argv[i], ':'); if (addr) *addr = '\0', addr++; - edit_file(&x, registrar, argv[i], strtoul((addr ? addr : ""), NULL, 0)); + edit_file(&x, registrar, argv[i], (addr ? addr : "0")); } } - XSync(x.display, False); + x11_event_loop(&x); return 0; } - - - - - - - - -#if 0 -struct { - Display* display; - Window root; - Window self; - int error; -} X; - -size_t WinCount; -Window* Windows; -char** WinFiles; - -static void get_windows(Window** wins, char*** files, size_t* nwins); -static int error_handler(Display* disp, XErrorEvent* ev); -static void* prop_get(Window win, char* propname, Atom type, unsigned long* nitems); -static void prop_set(Window win, char* propname, Atom type, int format, void* items, unsigned long nitems); -static void edit(char* path); -static Window win_byfile(char* path); -static void focus_window(Window w, char* addr); -static void get_abspath(char* path, char** abspath, char** addr); - -/* Main Routine - ******************************************************************************/ -int main(int argc, char** argv) { - if (!(X.display = XOpenDisplay(0))) - die("could not open display"); - X.root = DefaultRootWindow(X.display); - X.self = XCreateSimpleWindow(X.display, X.root, 0, 0, 1, 1, 0, 0, 0); - XSetErrorHandler(error_handler); - get_windows(&Windows, &WinFiles, &WinCount); - - for (int i = 1; i < argc; i++) { - bool last = (i == argc-1); - char *orig = argv[i], *path = NULL, *addr = NULL; - get_abspath(orig, &path, &addr); - - Window win = win_byfile(path); - if (!win) { - fprintf(stderr, "edit(%s)\n", argv[i]); - edit(argv[i]); - } else if (last) { - fprintf(stderr, "focus(%#x,%s)\n", (int)win, addr); - focus_window(win, addr); - } - free(path); - } - - XFlush(X.display); - return 0; -} - -static void get_windows(Window** wins, char*** files, size_t* nwins) { - XGrabServer(X.display); - unsigned long nwindows = 0, nactive = 0, nstrings = 0; - Window *windows = prop_get(X.root, "TIDE_WINDOWS", XA_WINDOW, &nwindows); - Window *active = calloc(nwindows, sizeof(Window)); - char **wfiles = calloc(nwindows, sizeof(char*)); - Atom xa_comm = XInternAtom(X.display, "TIDE_COMM", False); - for (int i = 0; i < nwindows; i++) { - X.error = 0; - int nprops; - Atom* props = XListProperties(X.display, windows[i], &nprops); - if (!props || X.error) continue; - for (int x = 0; x < nprops; x++) { - if (props[x] == xa_comm) { - active[nactive] = windows[i]; - wfiles[nactive] = prop_get(windows[i], "TIDE_FILE", XA_STRING, &nstrings); - nactive++; - break; - } - } - XFree(props); - } - prop_set(X.root, "TIDE_WINDOWS", XA_WINDOW, 32, active, nactive); - XSync(X.display, False); - XUngrabServer(X.display); - XFree(windows); - *wins = active, *files = wfiles, *nwins = nactive; -} - -static int error_handler(Display* disp, XErrorEvent* ev) { - X.error = ev->error_code; - return 0; -} - -static void* prop_get(Window win, char* propname, Atom type, unsigned long* nitems) { - Atom rtype, prop = XInternAtom(X.display, propname, False); - unsigned long rformat = 0, nleft = 0; - unsigned char* data = NULL; - XGetWindowProperty(X.display, win, prop, 0, -1, False, type, &rtype, - (int*)&rformat, nitems, &nleft, &data); - if (rtype != type) - data = NULL, *nitems = 0; - return data; -} - -static void prop_set(Window win, char* propname, Atom type, int format, void* items, unsigned long nitems) { - Atom prop = XInternAtom(X.display, propname, False); - XChangeProperty(X.display, win, prop, type, format, PropModeReplace, items, (int)nitems); -} - -static void edit(char* path) { - if (fork() == 0) - exit(execvp("tide", (char*[]){ "tide", path, NULL })); -} - -static Window win_byfile(char* path) { - for (int i = 0; i < WinCount; i++) - if (WinFiles[i] && !strcmp(path, WinFiles[i])) - return Windows[i]; - return (Window)0; -} - -static void focus_window(Window w, char* addr) { - XEvent ev = {0}; - ev.xclient.type = ClientMessage; - ev.xclient.send_event = True; - ev.xclient.message_type = XInternAtom(X.display, "_NET_ACTIVE_WINDOW", False); - ev.xclient.window = w; - ev.xclient.format = 32; - long mask = SubstructureRedirectMask | SubstructureNotifyMask; - XSendEvent(X.display, X.root, False, mask, &ev); - XMapRaised(X.display, w); - if (addr && *addr) - prop_set(w, "TIDE_COMM", XA_STRING, 8, addr, strlen(addr)); - XFlush(X.display); -} - -void get_abspath(char* path, char** abspath, char** addr) { - path = stringdup(path); - char* faddr = strrchr(path, ':'); - if (faddr) *(faddr++) = '\0'; - char* rpath = realpath(path, NULL); - if (!rpath) rpath = path; - *abspath = rpath, *addr = faddr; -} -#endif diff --git a/src/registrar.c b/src/registrar.c index a8e9834..a4d82c4 100644 --- a/src/registrar.c +++ b/src/registrar.c @@ -7,7 +7,7 @@ typedef struct TWindow { char* path; } TWindow; -Atom XA_REGISTRAR, XA_ADD, XA_DEL, XA_OPEN, XA_FILE; +Atom XA_REGISTRAR, XA_ADD, XA_DEL, XA_OPEN, XA_DONE, XA_FILE; TWindow* Windows = NULL; char* readprop(XConf* x, Window win, Atom prop, size_t* length) { @@ -94,15 +94,27 @@ void clientmsg(XConf* x, XEvent* e) { } void propnotify(XConf* x, XEvent* e) { - size_t length; - char* paths = readprop(x, x->self, XA_OPEN, &length); - char* path = paths; - while (length && *path) { - size_t sz = strlen((char*)path)+1; - win_open(x, (char*)path); - path += sz, length -= sz; + Atom type; + int format; + unsigned long datalen, nleft; + unsigned char* data = NULL; + XGetWindowProperty( + x->display, x->self, XA_OPEN, 0, -1, True, XA_WINDOW, + &type, &format, &datalen, &nleft, &data); + for (Window* win = (Window*)data; datalen && win && *win; win++, datalen--) { + printf("%#lx\n", *win); + win_send(x, x->self, *win, 0, "DONE", 0); } - XFree(paths); + +// size_t length; +// char* paths = readprop(x, x->self, XA_OPEN, &length); +// char* path = paths; +// while (length && *path) { +// size_t sz = strlen((char*)path)+1; +// win_open(x, (char*)path); +// path += sz, length -= sz; +// } +// XFree(paths); } int main(int argc, char** argv) { @@ -113,6 +125,7 @@ int main(int argc, char** argv) { XA_ADD = XInternAtom(x.display, "ADD", 0); XA_DEL = XInternAtom(x.display, "DEL", 0); XA_OPEN = XInternAtom(x.display, "OPEN", 0); + XA_DONE = XInternAtom(x.display, "DONE", 0); XA_FILE = XInternAtom(x.display, "FILE", 0); x.eventfns[SelectionClear] = selclear; x.eventfns[ClientMessage] = clientmsg; -- 2.51.0