+++ /dev/null
-/* (The MIT License)
- *
- * Copyright (c) 2014 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the 'Software'), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/*
- * Link with libusb >= 1.0.0 (which uses the newer style api)
- *
- * gcc -Wall button.c -lusb-1.0.0 -I /usr/include/libusb-1.0/
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
-#include <unistd.h>
-#include <signal.h>
-
-#include <libusb.h>
-
-static bool debug = false;
-
-#define DEBUG(_fmt, ...) if (debug) fprintf(stdout, "brb: " _fmt "\n", ## __VA_ARGS__)
-#define INFO(_fmt, ...) fprintf(stdout, "brb: "_fmt "\n", ## __VA_ARGS__)
-#define ERROR(_fmt, ...) fprintf(stderr, "brb: " _fmt "\n", ## __VA_ARGS__)
-
-typedef enum button_state {
- BUTTON_STATE_ERROR = -1, //!< Error occurred getting button state
- BUTTON_STATE_UNKNOWN = 0,
- BUTTON_STATE_LID_CLOSED = 0x15, //!< Button lid is closed
- BUTTON_STATE_PRESSED = 0x16, //!< Button is currently depressed (and lid is open)
- BUTTON_STATE_LID_OPEN = 0x17 //!< Button lid is open
-} button_states_t;
-
-#define BRB_VID 0x1d34 //!< Big Red Button Vendor ID
-#define BRB_PID 0x0008 //!< Big Red Button Product ID
-#define BRB_POLL_INTERVAL 20000 //!< How long we wait in between polling the button
-
-static char const *progname; //!< What the binary's called
-static bool should_exit = false; //!< If true, break out of the poll loop.
-
-static bool kernel_was_attached;
-
-/** Find the device, and detach the kernel driver
- *
- */
-static struct libusb_device_handle *get_button_handle(void){
- struct libusb_device_handle *handle = NULL;
- int ret;
-
- DEBUG("Attempting to open device (vendor 0x%04x, device 0x%04x)", BRB_VID, BRB_PID);
- handle = libusb_open_device_with_vid_pid(NULL, BRB_VID, BRB_PID);
- if (!handle) {
- ERROR("Failed opening device descriptor (you may need to be root)...");
- return NULL;
- }
-
- /* If the kernel driver is active, we need to detach it */
- if (libusb_kernel_driver_active(handle, 0)) {
- DEBUG("Kernel driver active, attempting to detach...");
- ret = libusb_detach_kernel_driver(handle, 0);
- if (ret < 0 ){
- ERROR("Can't detach kernel driver");
- return NULL;
- }
-
- kernel_was_attached = true;
- }
-
- return handle;
-}
-
-
-static int set_button_control(struct libusb_device_handle *handle)
-{
- int ret;
- uint8_t state[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 };
-
- ret = libusb_control_transfer(handle, 0x21, 0x09, 0x00, 0x00, state, 8, 0);
- if (ret < 0) {
- ERROR("Error reading response %i", ret);
- return -1;
- }
- if (ret == 0) {
- ERROR("Device didn't send enough data");
- return -1;
- }
-
- return 0;
-}
-
-/** Returns the current button state
- *
- */
-static button_states_t read_button_state(struct libusb_device_handle *handle) {
-
- uint8_t data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- int dev[8];
- int ret;
-
- ret = set_button_control(handle);
- if (ret < 0) {
- return -1;
- }
-
- /* Send 0x81 to the EP to retrieve the state */
- ret = libusb_interrupt_transfer(handle, 0x81, data, 8, dev, 200);
- if (ret < 0) {
- ERROR("Error getting interrupt data");
- return -1;
- }
-
-// printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-// data[0],
-// data[1],
-// data[2],
-// data[3],
-// data[4],
-// data[5],
-// data[6],
-// data[7]
-// );
-
- return (data[0] == 0x1A ? BUTTON_STATE_PRESSED : BUTTON_STATE_UNKNOWN);
-}
-
-void run_command(char const *cmd) {
- int ret;
-
- DEBUG("Running command: %s", cmd);
- ret = system(cmd);
- DEBUG("Command returned %i", ret);
-}
-
-/** Cleanup gracefully
- *
- */
-void exit_handler(int sig_num); /* Prototype for signal */
-void exit_handler(int sig_num)
-{
- signal(SIGINT, exit_handler);
- should_exit = true;
-}
-
-static void usage(int status)
-{
- FILE *output = status ? stderr : stdout;
-
- fprintf(output, "Usage: %s [options]\n", progname);
- fprintf(output, " -P <microsends> Polling interval\n");
- fprintf(output, " -o <command> Command to execute when button lid is open.\n");
- fprintf(output, " -c <command> Command to execute when button lid is closed.\n");
- fprintf(output, " -p <command> Command to execute when button is pressed.\n");
- fprintf(output, " -r <command> Command to execute when button is released.\n");
- fprintf(output, " -h This help text.\n");
- fprintf(output, " -v Turn on verbose output.\n");
-
- exit(status);
-}
-
-/** Main program
- *
- */
-int main (int argc, char *argv[]) {
- char c;
-
- char const *cmd_lid_open = NULL;
- char const *cmd_lid_closed = NULL;
- char const *cmd_pressed = NULL;
- char const *cmd_released = NULL;
-
- int interval = BRB_POLL_INTERVAL;
-
- struct libusb_device_handle *handle = NULL;
- button_states_t then = BUTTON_STATE_UNKNOWN, now;
-
- progname = argv[0];
-
- while ((c = getopt(argc, argv, "P:o:c:p:r:hv")) != EOF) {
- switch (c) {
- case 'P':
- interval = atoi(optarg);
- break;
-
- case 'o':
- cmd_lid_open = optarg;
- break;
-
- case 'c':
- cmd_lid_closed = optarg;
- break;
-
- case 'p':
- cmd_released = optarg;
- break;
-
- case 'r':
- cmd_pressed = optarg;
- break;
-
- case 'h':
- usage(0);
- break;
-
- case 'v':
- debug = true;
- break;
- }
- }
-
- /* Setup a signal handler, so we can cleanup gracefully */
- signal(SIGINT, exit_handler);
-
- /* Initialise libusb (with the default context) */
- libusb_init(NULL);
-
-#if defined(LIBUSB_LOG_LEVEL_DEBUG) && defined(LIBUSB_LOG_LEVEL_ERROR)
- /* All the debugging messages !*/
- if (debug) {
- libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_DEBUG);
- /* We still want to know about errors (helps with debugging) */
- } else {
- libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_ERROR);
- }
-#endif
-
- /* If we can't get the handle, exit... */
- handle = get_button_handle();
- if (!handle) exit(1);
-
- if (read_button_state(handle) == BUTTON_STATE_ERROR) goto finish;
-
- /* Loop, polling the device to get it's status */
- while (should_exit != true) {
- now = read_button_state(handle);
- if (now == BUTTON_STATE_ERROR) goto skip;
- if (then == now) goto skip;
-
- if (then == BUTTON_STATE_PRESSED) {
- /* Run the released action */
- INFO("RELEASED");
- if (cmd_released) run_command(cmd_released);
-
- /* Weird but I guess it could happen... */
- if (now == BUTTON_STATE_LID_CLOSED) goto closed;
- goto next;
- }
-
- switch (now) {
- case BUTTON_STATE_PRESSED:
- /* Run the pressed action */
- INFO("PRESSED");
- if (cmd_pressed) run_command(cmd_pressed);
- break;
-
- case BUTTON_STATE_LID_OPEN:
- /* Run the lid open action */
- INFO("LID_OPEN");
- if (cmd_lid_open) run_command(cmd_lid_open);
- break;
-
- case BUTTON_STATE_LID_CLOSED:
- closed:
- /* Run the closed action */
- INFO("LID_CLOSED");
- if (cmd_lid_closed) run_command(cmd_lid_closed);
- break;
-
- default:
- goto skip;
- }
-
- next:
- then = now;
- skip:
- usleep(interval);
- }
-
-finish:
- DEBUG("Exiting...");
-
- fflush(stdout);
- fflush(stderr);
-
-// if (kernel_was_attached) {
-// libusb_attach_kernel_handle(ghandle, 0);
-// }
-
- libusb_close(handle);
-
- exit(0);
-}
+++ /dev/null
-diff --git a/TODO.md b/TODO.md
-index fcfe8a5..475e3bb 100644
---- a/TODO.md
-+++ b/TODO.md
-@@ -37,3 +37,14 @@ Maybe think about addressing these later:
- * Find shortcut should select previous word if current char is newline
- * implement command diffing logic to optimize the undo/redo log
- * right click negative numbers should jump to that many lines from the end of file
-+
-+
-+1P Move the cursor
-+1P 1R 1P Select clicked on word
-+1P 1R 1P 1R 1P Select whole non whitespace thing
-+2P 2R Execute clicked word
-+2P 1P 2R Execute clicked word with argument
-+3P 3R Fetch clicked word
-+3P 1P 3R ?? Go to definition ??
-+1P 2P 2R Cut the selected text
-+1P 3P 3R Paste the selection
-diff --git a/inc/edit.h b/inc/edit.h
-index b9e2881..01fdcee 100644
---- a/inc/edit.h
-+++ b/inc/edit.h
-@@ -127,7 +127,8 @@ Row* view_getrow(View* view, size_t row);
- void view_byrune(View* view, int move, bool extsel);
- void view_byword(View* view, int move, bool extsel);
- void view_byline(View* view, int move, bool extsel);
--char* view_fetch(View* view, size_t row, size_t col, bool (*isword)(Rune));
-+size_t view_getoffset(View* view, size_t row, size_t col);
-+char* view_fetch(View* view, size_t off, bool (*isword)(Rune));
- bool view_findstr(View* view, int dir, char* str);
- void view_insert(View* view, Rune rune);
- void view_delete(View* view, int dir, bool byword);
-@@ -149,10 +150,10 @@ void view_scrollpage(View* view, int move);
- void view_setln(View* view, size_t line);
- size_t view_selsize(View* view);
- void view_selprev(View* view);
--void view_setcursor(View* view, size_t row, size_t col, bool extsel);
-+void view_setcursor(View* view, size_t off, bool extsel);
- void view_selextend(View* view, size_t row, size_t col);
--void view_selword(View* view, size_t row, size_t col);
--void view_select(View* view, size_t row, size_t col);
-+void view_selword(View* view, size_t off);
-+void view_select(View* view, size_t off);
- void view_jumpto(View* view, bool extsel, size_t off);
- void view_scrollto(View* view, size_t csr);
- Rune view_getrune(View* view);
-diff --git a/src/lib/view.c b/src/lib/view.c
-index 40d2865..e6f6a62 100644
---- a/src/lib/view.c
-+++ b/src/lib/view.c
-@@ -204,7 +204,7 @@ void view_byline(View* view, int move, bool extsel) {
- move_selection(view, extsel, move, buf_byline);
- }
-
--static size_t getoffset(View* view, size_t row, size_t col) {
-+size_t view_getoffset(View* view, size_t row, size_t col) {
- size_t i = 0, y = 0, idx = view->index + row;
- if (idx >= view->nrows) return 0;
- Row* selrow = view->rows[idx];
-@@ -215,16 +215,15 @@ static size_t getoffset(View* view, size_t row, size_t col) {
- return selrow->cols[i].off;
- }
-
--void view_setcursor(View* view, size_t row, size_t col, bool extsel) {
-- getsel(view)->end = getoffset(view, row, col);
-+void view_setcursor(View* view, size_t off, bool extsel) {
-+ getsel(view)->end = off;
- if (!extsel)
- getsel(view)->beg = getsel(view)->end;
- buf_getcol(BUF);
- }
-
--void view_selword(View* view, size_t row, size_t col) {
-- if (row != SIZE_MAX && col != SIZE_MAX)
-- view_setcursor(view, row, col, false);
-+void view_selword(View* view, size_t off) {
-+ view_setcursor(view, off, false);
- buf_selword(BUF, risbigword);
- }
-
-@@ -235,8 +234,8 @@ void view_selprev(View* view) {
- buf_selclr(BUF, RIGHT);
- }
-
--void view_select(View* view, size_t row, size_t col) {
-- view_setcursor(view, row, col, false);
-+void view_select(View* view, size_t off) {
-+ view_setcursor(view, off, false);
- buf_selctx(BUF, risword);
- }
-
-@@ -244,12 +243,8 @@ size_t view_selsize(View* view) {
- return buf_selsz(BUF);
- }
-
--char* view_fetch(View* view, size_t row, size_t col, bool (*isword)(Rune)) {
-- char* str = NULL;
-- size_t off = getoffset(view, row, col);
-- if (off != SIZE_MAX)
-- str = buf_fetch(BUF, isword, off);
-- return str;
-+char* view_fetch(View* view, size_t off, bool (*isword)(Rune)) {
-+ return buf_fetch(BUF, isword, off);
- }
-
- bool view_findstr(View* view, int dir, char* str) {
-diff --git a/src/pick.c b/src/pick.c
-index 9c525cd..503b49d 100644
---- a/src/pick.c
-+++ b/src/pick.c
-@@ -59,7 +59,7 @@ static int by_score(const void* a, const void* b) {
- else if (ca->score > cb->score)
- return -1;
- else
-- return 0;
-+ return strcmp(ca->string, cb->string);
- }
-
- static void load_choices(XConf* x) {
-diff --git a/src/tide.c b/src/tide.c
-index 7a05bc3..28ad559 100644
---- a/src/tide.c
-+++ b/src/tide.c
-@@ -115,7 +115,7 @@ static uint32_t getkey(XConf* x, XEvent* e) {
- return special_keys(key);
- }
-
--static void mouse_left(WinRegion id, bool pressed, size_t row, size_t col) {
-+static void mouse_left(WinRegion id, bool pressed, size_t off) {
- static int count = 0;
- static Time before = 0;
- if (!pressed) return;
-@@ -128,42 +128,42 @@ static void mouse_left(WinRegion id, bool pressed, size_t row, size_t col) {
- char* arg = NULL;
- if (!arg || !*arg) arg = view_getstr(win_view(EDIT));
- if (!arg || !*arg) arg = view_getstr(win_view(TAGS));
-- char* str = view_fetch(win_view(id), row, col, riscmd);
-+ char* str = view_fetch(win_view(id), off, riscmd);
- if (str) exec(str, arg);
- free(str);
- free(arg);
- ExecRequest = 0;
- } else {
- if (count == 1)
-- view_setcursor(win_view(id), row, col, win_keymodsset(ModShift));
-+ view_setcursor(win_view(id), off, win_keymodsset(ModShift));
- else if (count == 2)
-- view_select(win_view(id), row, col);
-+ view_select(win_view(id), off);
- else if (count == 3)
-- view_selword(win_view(id), row, col);
-+ view_selword(win_view(id), off);
- }
- }
-
--static void mouse_middle(WinRegion id, bool pressed, size_t row, size_t col) {
-+static void mouse_middle(WinRegion id, bool pressed, size_t off) {
- if (pressed) { ExecRequest = 1; return; }
- if (PRESSED(MouseLeft)) {
- cut(NULL);
- } else if (ExecRequest) {
-- char* str = view_fetch(win_view(id), row, col, riscmd);
-+ char* str = view_fetch(win_view(id), off, riscmd);
- if (str) exec(str, NULL);
- free(str);
- }
- }
-
--static void mouse_right(WinRegion id, bool pressed, size_t row, size_t col) {
-+static void mouse_right(WinRegion id, bool pressed, size_t off) {
- if (pressed) return;
- if (PRESSED(MouseLeft)) {
- paste(NULL);
- } else {
-- FetchCmd[2] = view_fetch(win_view(id), row, col, risfile);
-+ FetchCmd[2] = view_fetch(win_view(id), off, risfile);
- if (job_run(FetchCmd) != 0) {
- SearchDir *= (win_keymodsset(ModShift) ? -1 : +1);
- free(SearchTerm);
-- SearchTerm = view_fetch(win_view(id), row, col, risfile);
-+ SearchTerm = view_fetch(win_view(id), off, risfile);
- view_findstr(win_view(EDIT), SearchDir, SearchTerm);
- SyncMouse = true;
- }
-@@ -180,10 +180,12 @@ static void mouse_click(int btn, bool pressed, int x, int y) {
- size_t row, col;
- Focused = (y <= Divider ? TAGS : EDIT);
- get_position(Focused, x, y, &row, &col);
-+ size_t off = view_getoffset(win_view(Focused), row, col);
-+// printf("B%d %d %lu\n", btn, pressed, off);
- switch(btn) {
-- case MouseLeft: mouse_left(Focused, pressed, row, col); break;
-- case MouseMiddle: mouse_middle(Focused, pressed, row, col); break;
-- case MouseRight: mouse_right(Focused, pressed, row, col); break;
-+ case MouseLeft: mouse_left(Focused, pressed, off); break;
-+ case MouseMiddle: mouse_middle(Focused, pressed, off); break;
-+ case MouseRight: mouse_right(Focused, pressed, off); break;
- case MouseWheelUp: mouse_scroll(Focused, pressed, -ScrollBy); break;
- case MouseWheelDn: mouse_scroll(Focused, pressed, +ScrollBy); break;
- }
-@@ -225,18 +227,46 @@ static void xkeypress(XConf* x, XEvent* e) {
- view_insert(win_view(FOCUSED), key);
- }
-
-+static void xbtnhandle(XConf* x, XEvent* e) {
-+ (void)x;
-+ bool press = (e->type == ButtonPress);
-+ switch (e->xbutton.button) {
-+ case Button1:
-+ printf("left\n");
-+ break;
-+
-+ case Button2:
-+ if (e->xbutton.state & (1 << (Button1 + 7)))
-+ printf("left+middle\n");
-+ else
-+ printf("middle\n");
-+ break;
-+
-+ case Button3:
-+ if (e->xbutton.state & (1 << (Button1 + 7)))
-+ printf("left+right\n");
-+ else
-+ printf("right\n");
-+ break;
-+ }
-+ (void)press;
-+}
-+
- static void xbtnpress(XConf* x, XEvent* e) {
- (void)x;
- Now = e->xbutton.time;
- KeyBtnState = (e->xbutton.state | (1 << (e->xbutton.button + 7)));
-- mouse_click(e->xbutton.button, true, e->xbutton.x, e->xbutton.y);
-+(void)mouse_click;
-+// mouse_click(e->xbutton.button, true, e->xbutton.x, e->xbutton.y);
-+ xbtnhandle(x,e);
- }
-
- static void xbtnrelease(XConf* x, XEvent* e) {
- (void)x;
- Now = e->xbutton.time;
- KeyBtnState = (KeyBtnState & ~(1 << (e->xbutton.button + 7)));
-- mouse_click(e->xbutton.button, false, e->xbutton.x, e->xbutton.y);
-+// mouse_click(e->xbutton.button, false, e->xbutton.x, e->xbutton.y);
-+ xbtnhandle(x,e);
- }
-
- static void xbtnmotion(XConf* x, XEvent* e) {
-@@ -246,8 +276,9 @@ static void xbtnmotion(XConf* x, XEvent* e) {
- KeyBtnState = e->xbutton.state;
- int xpos = e->xbutton.x, ypos = e->xbutton.y;
- get_position(Focused, xpos, ypos, &row, &col);
-+ size_t off = view_getoffset(win_view(Focused), row, col);
- if (PRESSED(MouseLeft))
-- view_setcursor(win_view(Focused), row, col, true);
-+ view_setcursor(win_view(Focused), off, true);
- }
-
- static void xclientmsg(XConf* x, XEvent* e) {
-@@ -947,6 +978,16 @@ int main(int argc, char** argv) {
- if (!gethostname(host, sizeof(host)))
- win_prop_set("HOST", "host", host);
-
-+ /* check if we should embede in a parent */
-+ char* winid = getenv("TIDE_PARENT");
-+ if (winid)
-+ {
-+ Window parent = strtoul(winid, 0, 0);
-+ XReparentWindow(X.display, X.self, parent, 0, 0);
-+ XFlush(X.display);
-+ }
-+
-+
- /* now create the window and start the event loop */
- xupdate(NULL);
- win_loop();