]> git.mdlowis.com Git - projs/tide.git/commitdiff
Added tctl.c first pass for controlling a session. Added property handling to x11...
authorMichael D. Lowis <mike.lowis@gentex.com>
Thu, 10 Aug 2017 18:36:43 +0000 (14:36 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Thu, 10 Aug 2017 18:36:43 +0000 (14:36 -0400)
.gitignore
Makefile
TODO.md
inc/x11.h
lib/x11.c
tctl.c [new file with mode: 0644]
tide.c

index 604d147ed06acb8d8a6b4de4888cf0f45b848b02..e924b78af19ad50f4f23acf934684442f6ec5c54 100644 (file)
@@ -54,3 +54,4 @@ tests/pick
 hl-cpp
 pty
 tfetch
+tserve
index 48c7681a22e12a67b0dc68a1237c4807a27cddcb..b40135c3f3fa05d7547cc88580f5ed88e35a8646 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 INCS = -Iinc/
 
-BINS = tide pick xcpd hl-cpp tfetch
+BINS = tide tfetch tctl pick xcpd hl-cpp
 MAN1 = docs/tide.1 docs/pick.1 docs/picktag.1 docs/pickfile.1
 
 LIBEDIT_OBJS =     \
@@ -34,8 +34,7 @@ docs:
 clean:
        find . -name '*.[oad]' -delete
        find . \( -name '*.gcno' -o -name '*.gcda' \) -delete
-       $(RM) pick tide xcpd term tests/libedit hl-cpp
-       $(RM) $(TEST_BINS)
+       $(RM) $(BINS) $(TEST_BINS)
 
 install: all
        mkdir -p $(PREFIX)/bin
@@ -43,6 +42,7 @@ install: all
        cp -f tfetch $(PREFIX)/bin
        cp -f tide $(PREFIX)/bin
        cp -f tide-hl.rb $(PREFIX)/bin
+       cp -f tctl $(PREFIX)/bin
        cp -f pick $(PREFIX)/bin
        cp -f xcpd $(PREFIX)/bin
        cp -f pickfile $(PREFIX)/bin
@@ -53,6 +53,7 @@ uninstall:
        rm -f $(PREFIX)/bin/tfetch
        rm -f $(PREFIX)/bin/tide
        rm -f $(PREFIX)/bin/tide-hl.rb
+       rm -f $(PREFIX)/bin/tctl
        rm -f $(PREFIX)/bin/pick
        rm -f $(PREFIX)/bin/xcpd
        rm -f $(PREFIX)/bin/pickfile
@@ -69,6 +70,7 @@ pick: pick.o libedit.a
 xcpd: xcpd.o libedit.a
 hl-cpp: hl-cpp.o libedit.a
 tfetch: tfetch.o
+tctl: tctl.o libedit.a
 tests/libedit: tests/libedit.o tests/lib/buf.o tests/lib/utf8.o libedit.a
 tests/tide: tests/tide.o libedit.a
 tests/pick: tests/pick.o libedit.a
diff --git a/TODO.md b/TODO.md
index 0efafa627e05c9b64ba68911e066266d16a8b6c2..cd3ae38560e1e47675676d7c465fbb8f60dc7d07 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -2,6 +2,10 @@
 
 Up Next:
 
+* Implement tab completion
+* Change status to current dir in pty mode.
+* synchronize title with status contents.
+* Implement server daemon for tracking open files
 * B2+B1 click executes command with selection as argument
 * right click to fetch file or line
 * Run commands in the background and don't block the main thread.
index a22224b489590305dc1162ddceb12f66a388c6a3..3279b8c3632c9bb7547b3717958eca51d1ac99a5 100644 (file)
--- a/inc/x11.h
+++ b/inc/x11.h
@@ -147,5 +147,3 @@ void x11_draw_utf8(XFont font, int fg, int bg, int x, int y, char* str);
 
 bool x11_sel_get(int selid, void(*cbfn)(char*));
 bool x11_sel_set(int selid, char* str);
-
-
index bc8950aa59b040e7e32bdd666712ddd56e326959..c089a961d7a150b37e7b4a8341a703fb6418aa1f 100644 (file)
--- a/lib/x11.c
+++ b/lib/x11.c
@@ -15,6 +15,7 @@ static struct XSel* selfetch(Atom atom);
 static void selclear(XEvent* evnt);
 static void selnotify(XEvent* evnt);
 static void selrequest(XEvent* evnt);
+static void propnotify(XEvent* evnt);
 
 struct XFont {
     struct {
@@ -42,7 +43,7 @@ static struct {
     unsigned depth;
     int screen;
     /* assume a single window for now. these are its attributes */
-    Window window;
+    Window self;
     XftDraw* xft;
     Pixmap pixmap;
     int width;
@@ -94,6 +95,7 @@ void x11_init(XConfig* cfg) {
     X.colormap = wa.colormap;
     X.screen   = DefaultScreen(X.display);
     X.depth    = DefaultDepth(X.display, X.screen);
+
     /* initialize selection atoms */
     for (int i = 0; i < (sizeof(Selections) / sizeof(Selections[0])); i++)
         Selections[i].atom = XInternAtom(X.display, Selections[i].name, 0);
@@ -121,7 +123,7 @@ void x11_window(char* name, int width, int height) {
     X.height = height;
     XWindowAttributes wa;
     XGetWindowAttributes(X.display, X.root, &wa);
-    X.window = XCreateSimpleWindow(X.display, X.root,
+    X.self = XCreateSimpleWindow(X.display, X.root,
         (wa.width  - X.width) / 2,
         (wa.height - X.height) /2,
         X.width,
@@ -131,15 +133,16 @@ void x11_window(char* name, int width, int height) {
 
     /* register interest in the delete window message */
     Atom wmDeleteMessage = XInternAtom(X.display, "WM_DELETE_WINDOW", False);
-    XSetWMProtocols(X.display, X.window, &wmDeleteMessage, 1);
+    XSetWMProtocols(X.display, X.self, &wmDeleteMessage, 1);
 
     /* setup window attributes and events */
     XSetWindowAttributes swa;
     swa.backing_store = WhenMapped;
     swa.bit_gravity = NorthWestGravity;
-    XChangeWindowAttributes(X.display, X.window, CWBackingStore|CWBitGravity, &swa);
-    XStoreName(X.display, X.window, name);
-    XSelectInput(X.display, X.window,
+    XChangeWindowAttributes(X.display, X.self, CWBackingStore|CWBitGravity, &swa);
+    XStoreName(X.display, X.self, name);
+    XSelectInput(X.display, X.root, PropertyChangeMask);
+    XSelectInput(X.display, X.self,
           StructureNotifyMask
         | ButtonPressMask
         | ButtonReleaseMask
@@ -150,24 +153,30 @@ void x11_window(char* name, int width, int height) {
 
     /* set input methods */
     if ((X.xim = XOpenIM(X.display, 0, 0, 0)))
-        X.xic = XCreateIC(X.xim, XNInputStyle, XIMPreeditNothing|XIMStatusNothing, XNClientWindow, X.window, XNFocusWindow, X.window, NULL);
+        X.xic = XCreateIC(X.xim, XNInputStyle, XIMPreeditNothing|XIMStatusNothing, XNClientWindow, X.self, XNFocusWindow, X.self, NULL);
 
     /* initialize pixmap and drawing context */
-    X.pixmap = XCreatePixmap(X.display, X.window, width, height, X.depth);
+    X.pixmap = XCreatePixmap(X.display, X.self, width, height, X.depth);
     X.xft    = XftDrawCreate(X.display, X.pixmap, X.visual, X.colormap);
 
     /* initialize the graphics context */
     XGCValues gcv;
     gcv.foreground = WhitePixel(X.display, X.screen);
     gcv.graphics_exposures = False;
-    X.gc = XCreateGC(X.display, X.window, GCForeground|GCGraphicsExposures, &gcv);
+    X.gc = XCreateGC(X.display, X.self, GCForeground|GCGraphicsExposures, &gcv);
+
+    /* Create and updtate tide-specific properties */
+    Atom prop = XInternAtom(X.display, "TIDE_WINDOWS", False);
+    XChangeProperty(X.display, X.root, prop, XA_WINDOW, 32, PropModeAppend, (unsigned char*)&X.self, 1);
+    prop = XInternAtom(X.display, "TIDE_COMM", False);
+    XChangeProperty(X.display, X.self, prop, XA_STRING, 8, PropModeReplace, "", 0);
 }
 
 void x11_dialog(char* name, int height, int width) {
     x11_window(name, height, width);
     Atom WindowType = XInternAtom(X.display, "_NET_WM_WINDOW_TYPE", False);
     Atom DialogType = XInternAtom(X.display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
-    XChangeProperty(X.display, X.window, WindowType, XA_ATOM, 32, PropModeReplace, (unsigned char*)&DialogType, 1);
+    XChangeProperty(X.display, X.self, WindowType, XA_ATOM, 32, PropModeReplace, (unsigned char*)&DialogType, 1);
 }
 
 void x11_show(void) {
@@ -176,8 +185,8 @@ void x11_show(void) {
     ce.type   = ConfigureNotify;
     ce.width  = X.width;
     ce.height = X.height;
-    XSendEvent(X.display, X.window, False, StructureNotifyMask, (XEvent *)&ce);
-    XMapWindow(X.display, X.window);
+    XSendEvent(X.display, X.self, False, StructureNotifyMask, (XEvent *)&ce);
+    XMapWindow(X.display, X.self);
 }
 
 bool x11_running(void) {
@@ -186,7 +195,7 @@ bool x11_running(void) {
 
 void x11_flip(void) {
     Config->redraw(X.width, X.height);
-    XCopyArea(X.display, X.pixmap, X.window, X.gc, 0, 0, X.width, X.height, 0, 0);
+    XCopyArea(X.display, X.pixmap, X.self, X.gc, 0, 0, X.width, X.height, 0, 0);
     x11_flush();
 }
 
@@ -327,6 +336,7 @@ void x11_handle_event(XEvent* e) {
         case SelectionClear:   selclear(e);      break;
         case SelectionNotify:  selnotify(e);     break;
         case SelectionRequest: selrequest(e);    break;
+        case PropertyNotify:   propnotify(e);    break;
         case ClientMessage:
             if (e->xclient.data.l[0] == wmDeleteMessage)
                 Config->shutdown();
@@ -335,7 +345,7 @@ void x11_handle_event(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.window, X.width, X.height, X.depth);
+                X.pixmap = XCreatePixmap(X.display, X.self, X.width, X.height, X.depth);
                 X.xft    = XftDrawCreate(X.display, X.pixmap, X.visual, X.colormap);
             }
             break;
@@ -349,7 +359,7 @@ int x11_events_queued(void) {
 void x11_events_take(void) {
     XEvent e;
     int nevents;
-    XGetMotionEvents(X.display, X.window, CurrentTime, CurrentTime, &nevents);
+    XGetMotionEvents(X.display, X.self, CurrentTime, CurrentTime, &nevents);
     while (XPending(X.display)) {
         XNextEvent(X.display, &e);
         if (!XFilterEvent(&e, None))
@@ -358,12 +368,12 @@ void x11_events_take(void) {
 }
 
 void x11_mouse_set(int x, int y) {
-    XWarpPointer(X.display, X.window, X.window, 0, 0, X.width, X.height, x, y);
+    XWarpPointer(X.display, X.self, X.self, 0, 0, X.width, X.height, x, y);
 }
 
 void x11_mouse_get(int* ptrx, int* ptry) {
     Window xw; int x; unsigned int ux;
-    XQueryPointer(X.display, X.window, &xw, &xw, &x, &x, ptrx, ptry, &ux);
+    XQueryPointer(X.display, X.self, &xw, &xw, &x, &x, ptrx, ptry, &ux);
 }
 
 XFont x11_font_load(char* name) {
@@ -522,7 +532,6 @@ void x11_draw_utf8(XFont fnt, int fg, int bg, int x, int y, char* str) {
 
 /* Selection Handling
  *****************************************************************************/
-
 static char* readprop(Display* disp, Window win, Atom prop) {
     Atom type;
     int format;
@@ -562,7 +571,7 @@ static void selnotify(XEvent* evnt) {
     if (evnt->xselection.property == None)
         return;
     struct XSel* sel = selfetch( evnt->xselection.selection );
-    char* propdata = readprop(X.display, X.window, sel->atom);
+    char* propdata = readprop(X.display, X.self, sel->atom);
     if (evnt->xselection.target == SelTarget) {
         void(*cbfn)(char*) = sel->callback;
         sel->callback = NULL;
@@ -608,11 +617,11 @@ bool x11_sel_get(int selid, void(*cbfn)(char*)) {
     struct XSel* sel = &(Selections[selid]);
     if (sel->callback) return false;
     Window owner = XGetSelectionOwner(X.display, sel->atom);
-    if (owner == X.window) {
+    if (owner == X.self) {
         cbfn(sel->text);
     } else if (owner != None){
         sel->callback = cbfn;
-        XConvertSelection(X.display, sel->atom, SelTarget, sel->atom, X.window, CurrentTime);
+        XConvertSelection(X.display, sel->atom, SelTarget, sel->atom, X.self, CurrentTime);
     }
     return true;
 }
@@ -624,7 +633,12 @@ bool x11_sel_set(int selid, char* str) {
         return false;
     } else {
         sel->text = str;
-        XSetSelectionOwner(X.display, sel->atom, X.window, CurrentTime);
+        XSetSelectionOwner(X.display, sel->atom, X.self, CurrentTime);
         return true;
     }
 }
+
+/* Tide Server Communication
+ *****************************************************************************/
+static void propnotify(XEvent* evnt) {
+}
diff --git a/tctl.c b/tctl.c
new file mode 100644 (file)
index 0000000..00cd196
--- /dev/null
+++ b/tctl.c
@@ -0,0 +1,49 @@
+#include <stdc.h>
+#include <utf.h>
+#include <edit.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xft/Xft.h>
+#include <unistd.h>
+
+struct {
+    Display* display;
+    Window root;
+    Window self;
+} X;
+
+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);
+
+/* 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);
+
+    XGrabServer(X.display);
+    unsigned long nwindows = 0;
+    Window* windows = prop_get(X.root, "TIDE_WINDOWS", XA_WINDOW, &nwindows);
+    printf("Windows: %lu\n", nwindows);
+    XUngrabServer(X.display);
+
+    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);
+}
diff --git a/tide.c b/tide.c
index 0fb1b699188a00de4717bda7aa314a9fefe88fe7..915f5e4e1a1fb0974240ef2dfdac3a5616e9b81a 100644 (file)
--- a/tide.c
+++ b/tide.c
@@ -232,6 +232,7 @@ void onmouseright(WinRegion id, bool pressed, size_t row, size_t col) {
 /* Keyboard Handling
  ******************************************************************************/
 static void saveas(char* arg) {
+    //win_saveas(stringdup(arg));
     if (arg) {
         char* path = win_buf(EDIT)->path;
         win_buf(EDIT)->path = stringdup(arg);
@@ -573,9 +574,11 @@ void edit_relative(char* path) {
         else
             strconcat(currpath, fname, 0);
         chdir(currdir);
+        //win_open(currpath, ondiagmsg);
         view_init(win_view(EDIT), currpath, ondiagmsg);
     } else {
         chdir(origdir);
+        //win_open(path, ondiagmsg);
         view_init(win_view(EDIT), path, ondiagmsg);
     }