lib/x11.o \
lib/win.o \
lib/colors.o \
- lib/config.o
+ lib/config.o \
+ lib/event.o
TEST_BINS = \
tests/tide \
bool file_exists(char* path);
char* strmcat(char* first, ...);
+
+enum { INPUT, OUTPUT, NOTIFY };
+
+typedef void (*event_cbfn_t)(int fd, void* data);
+
+bool event_poll(int ms);
+void event_watchfd(int fd, int iodir, event_cbfn_t fn, void* data);
+
+
/* Buffer management functions
*****************************************************************************/
/* undo/redo list item */
void x11_init(XConfig* cfg);
void x11_deinit(void);
+int x11_connfd(void);
char* x11_cfg_get(char* opt);
int x11_keybtnstate(void);
bool x11_keymodsset(int mask);
--- /dev/null
+#define _XOPEN_SOURCE 700
+#include <stdc.h>
+#include <utf.h>
+#include <edit.h>
+#include <unistd.h>
+#include <poll.h>
+
+struct event_data {
+ int iodir;
+ void* data;
+ event_cbfn_t fn;
+};
+
+static size_t NumDescriptors = 0;
+static struct pollfd* Descriptors = NULL;
+static struct event_data* EventData = NULL;
+
+bool event_poll(int ms) {
+ /* poll for new events */
+ long n = poll(Descriptors, NumDescriptors, ms);
+ if (n < 0) die("poll() :");
+
+ /* Handle any events that occurred */
+ for (int i = 0; i < NumDescriptors; i++) {
+ /* skip any eventless entries */
+ if (!Descriptors[i].revents) continue;
+
+ /* if a requested event occurred, handle it */
+ if (Descriptors[i].revents & Descriptors[i].events) {
+ EventData[i].fn(Descriptors[i].fd, EventData[i].data);
+ Descriptors[i].revents = 0;
+ }
+
+ /* if the desriptor is done or errored, throw it out */
+ if (Descriptors[i].revents & (POLLERR|POLLHUP)) {
+ close(Descriptors[i].fd);
+ for (int x = i+1; x < NumDescriptors; x++) {
+ Descriptors[x-1] = Descriptors[x];
+ EventData[x-1] = EventData[x];
+ }
+ NumDescriptors--;
+ }
+ }
+
+ return (n > 0);
+}
+
+void event_watchfd(int fd, int iodir, event_cbfn_t fn, void* data) {
+ int idx = NumDescriptors++;
+ Descriptors = realloc(Descriptors, NumDescriptors * sizeof(struct pollfd));
+ EventData = realloc(EventData, NumDescriptors * sizeof(struct event_data));
+ if (!Descriptors || !EventData)
+ die("event_Watchfd() : out of memory\n");
+ Descriptors[idx].fd = fd;
+ EventData[idx].data = data;
+ EventData[idx].fn = fn;
+ switch (iodir) {
+ case INPUT: Descriptors[idx].events = POLLIN; break;
+ case OUTPUT: Descriptors[idx].events = POLLOUT; break;
+ case NOTIFY: Descriptors[idx].events = (POLLIN|POLLOUT); break;
+ }
+}
x11_dialog(name, config_get_int(WinWidth), config_get_int(WinHeight));
}
+static void win_update(int xfd, void* data) {
+ if (x11_events_queued())
+ x11_events_take();
+ x11_flush();
+}
+
void win_loop(void) {
x11_show();
x11_flip();
+ int ms = config_get_int(EventTimeout);
+ event_watchfd(x11_connfd(), INPUT, win_update, NULL);
while (x11_running()) {
- bool pending = x11_events_await(config_get_int(EventTimeout));
- int nevents = x11_events_queued();
- if (update_focus() || pending || nevents || update_needed()) {
- x11_events_take();
- if (x11_running())
- x11_flip();
- }
- x11_flush();
+ if (event_poll(ms) || update_focus() || x11_running())
+ x11_flip();
}
x11_finish();
}
config_init(X.display);
}
+int x11_connfd(void) {
+ return ConnectionNumber(X.display);
+}
+
int x11_keybtnstate(void) {
return KeyBtnState;
}
#include <ctype.h>
#include <unistd.h>
#include <sys/select.h>
-//#include <termios.h>
-//#include <sys/types.h>
#ifdef __MACH__
#include <util.h>
#else
strncat(status, path, remlen);
win_settext(STATUS, status_bytes);
win_view(STATUS)->selection = (Sel){0,0,0};
-
- /* Read from command if we have one */
- long n = 0, r = 0, i = 0;
- static char cmdbuf[8192];
- if (!update_needed()) return;
- if ((n = read(CmdFD, cmdbuf, sizeof(cmdbuf))) < 0)
- CmdFD = -1;
- while (i < n) {
- Rune rune = 0;
- size_t length = 0;
- while (!utf8decode(&rune, &length, cmdbuf[i++]));
- view_insert(win_view(EDIT), false, rune);
- }
- win_buf(EDIT)->outpoint = win_view(EDIT)->selection.end;
}
void onlayout(void) {
}
bool update_needed(void) {
- if (CmdFD < 0) return false;
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(CmdFD, &fds);
- struct timeval tv = { .tv_usec = 0 };
- return (select(CmdFD+1, &fds, NULL, NULL, &tv) > 0);
+ return false;
}
static void oninput(Rune rune) {
return fd;
}
+void pty_update(int fd, void* data) {
+ /* Read from command if we have one */
+ long n = 0, r = 0, i = 0;
+ static char cmdbuf[8192];
+ if ((n = read(CmdFD, cmdbuf, sizeof(cmdbuf))) < 0)
+ CmdFD = -1;
+ while (i < n) {
+ Rune rune = 0;
+ size_t length = 0;
+ while (!utf8decode(&rune, &length, cmdbuf[i++]));
+ view_insert(win_view(EDIT), false, rune);
+ }
+ win_buf(EDIT)->outpoint = win_view(EDIT)->selection.end;
+}
+
void edit_relative(char* path) {
char *currdir = NULL, *currpath = NULL, *relpath = NULL;
char* origdir = getcurrdir();
win_setlinenums(false);
win_setruler(0);
CmdFD = pty_spawn(*cmd ? cmd : shellcmd);
+ event_watchfd(CmdFD, INPUT, pty_update, NULL);
+
}
#ifndef TEST