#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();
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 {
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
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) {
}
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) {
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;