]> git.mdlowis.com Git - projs/tide.git/commitdiff
added multi window approach for opening files
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 31 Oct 2018 03:07:03 +0000 (23:07 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 31 Oct 2018 03:07:03 +0000 (23:07 -0400)
src/edit.c
src/registrar.c

index a4ed0c18c4b39add47251871c1d66bd8f4071a55..5d11930c0e2747ae3ae341bd8bfb1d4cbbbf34b3 100644 (file)
@@ -2,7 +2,7 @@
 #include <unistd.h>
 #include <stdc.h>
 
-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
index a8e9834753cffd72929b94580e9bf939ab1515f3..a4d82c4ce2b1ea259958dfc6b4bbeddbf85df2f1 100644 (file)
@@ -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;