From cc4eceba1549c8f7bce981f4d75367da298d1af9 Mon Sep 17 00:00:00 2001 From: Mike Lowis Date: Thu, 6 Oct 2016 11:37:43 -0400 Subject: [PATCH] Moved keyboard controls to a separate C file to abstract from the UI handling code --- Makefile | 2 +- buf.c | 4 ++++ edit.h | 32 +++++++++++++++-------------- keyboard.c | 45 +++++++++++++++++++++++++++++++++++++++++ xedit.c | 59 ++++-------------------------------------------------- 5 files changed, 71 insertions(+), 71 deletions(-) create mode 100644 keyboard.c diff --git a/Makefile b/Makefile index a02d568..3245475 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ LDFLAGS = -L/opt/X11/lib -lX11 -lXft CFLAGS = --std=c99 -Wall -Wextra -I. -I/opt/X11/include -I/opt/local/include/freetype2 -I/usr/include/freetype2 -SRCS = xedit.c buf.c screen.c utf8.c +SRCS = xedit.c buf.c screen.c utf8.c keyboard.c OBJS = $(SRCS:.c=.o) TESTSRCS = tests/tests.c tests/buf.c tests/utf8.c TESTOBJS = $(TESTSRCS:.c=.o) diff --git a/buf.c b/buf.c index b3c8fc2..f8b8743 100644 --- a/buf.c +++ b/buf.c @@ -9,6 +9,7 @@ int fpeekc(FILE* fin) { void buf_load(Buf* buf, char* path) { + buf->insert_mode = true; unsigned i = 0; FILE* in = (!strcmp(path,"-") ? stdin : fopen(path, "rb")); while (EOF != fpeekc(in)) { @@ -18,6 +19,7 @@ void buf_load(Buf* buf, char* path) buf_ins(buf, i++, r); } fclose(in); + buf->insert_mode = false; } void buf_initsz(Buf* buf, size_t sz) @@ -71,12 +73,14 @@ void buf_clr(Buf* buf) void buf_del(Buf* buf, unsigned off) { + if (!buf->insert_mode) return; syncgap(buf, off); buf->gapend++; } void buf_ins(Buf* buf, unsigned off, Rune rune) { + if (!buf->insert_mode) return; syncgap(buf, off); *(buf->gapstart++) = rune; } diff --git a/edit.h b/edit.h index 0388397..1319072 100644 --- a/edit.h +++ b/edit.h @@ -4,6 +4,22 @@ #include #include +/* UTF-8 Handling + *****************************************************************************/ +enum { + UTF_MAX = 6u, /* maximum number of bytes that make up a rune */ + RUNE_SELF = 0x80, /* byte values larger than this are *not* ascii */ + RUNE_ERR = 0xFFFD, /* rune value representing an error */ + RUNE_MAX = 0x10FFFF, /* Maximum decodable rune value */ + RUNE_EOF = EOF /* ruen value representing end of file */ +}; + +/* Represents a unicode code point */ +typedef uint32_t Rune; + +size_t utf8encode(char str[UTF_MAX], Rune rune); +bool utf8decode(Rune* rune, size_t* length, int byte); + /* Input Handling *****************************************************************************/ /* key definitions */ @@ -87,21 +103,7 @@ enum MouseBtn { MOUSE_WHEELDOWN }; -/* UTF-8 Handling - *****************************************************************************/ -enum { - UTF_MAX = 6u, /* maximum number of bytes that make up a rune */ - RUNE_SELF = 0x80, /* byte values larger than this are *not* ascii */ - RUNE_ERR = 0xFFFD, /* rune value representing an error */ - RUNE_MAX = 0x10FFFF, /* Maximum decodable rune value */ - RUNE_EOF = EOF /* ruen value representing end of file */ -}; - -/* Represents a unicode code point */ -typedef uint32_t Rune; - -size_t utf8encode(char str[UTF_MAX], Rune rune); -bool utf8decode(Rune* rune, size_t* length, int byte); +void handle_key(Rune key); /* Buffer management functions *****************************************************************************/ diff --git a/keyboard.c b/keyboard.c new file mode 100644 index 0000000..3a49a36 --- /dev/null +++ b/keyboard.c @@ -0,0 +1,45 @@ +#include "edit.h" + +extern Buf Buffer; +extern unsigned CursorPos; + +static void special_keys(Rune key); +static void control_keys(Rune key); + +void handle_key(Rune key) { + /* ignore invalid keys */ + if (key == RUNE_ERR) return; + /* handle the special keys */ + if (0xE000 <= key && key <= 0xF8FF) + special_keys(key); + /* Handle regular key */ + else if (key < 0x20) + control_keys(key); + else if (Buffer.insert_mode) + buf_ins(&Buffer, CursorPos++, key); + +} + +static void special_keys(Rune key) { + switch (key) { + case KEY_F1: Buffer.insert_mode = !Buffer.insert_mode; break; + case KEY_F6: ColorBase = !ColorBase; break; + case KEY_LEFT: CursorPos = buf_byrune(&Buffer, CursorPos, -1); break; + case KEY_RIGHT: CursorPos = buf_byrune(&Buffer, CursorPos, 1); break; + case KEY_DOWN: CursorPos = buf_byline(&Buffer, CursorPos, 1); break; + case KEY_UP: CursorPos = buf_byline(&Buffer, CursorPos, -1); break; + case KEY_DELETE: + if (Buffer.insert_mode) + buf_del(&Buffer, CursorPos); + break; + + } +} + +static void control_keys(Rune key) { + switch (key) { + case KEY_ESCAPE: Buffer.insert_mode = false; break; + case KEY_BACKSPACE: buf_del(&Buffer, --CursorPos); break; + default: buf_ins(&Buffer, CursorPos++, key); break; + } +} diff --git a/xedit.c b/xedit.c index 27f21f4..eb642f8 100644 --- a/xedit.c +++ b/xedit.c @@ -6,6 +6,9 @@ #include "edit.h" +Buf Buffer; +unsigned CursorPos = 0; +enum ColorScheme ColorBase = DEFAULT_COLORSCHEME; struct { Display* display; Visual* visual; @@ -24,9 +27,6 @@ struct { XIC xic; XIM xim; } X; -Buf Buffer; -unsigned CursorPos = 0; -enum ColorScheme ColorBase = DEFAULT_COLORSCHEME; void die(char* m) { fprintf(stderr, "dying, %s\n", m); @@ -120,7 +120,6 @@ static Rune getkey(XEvent* e) { if (buf[0] == '\r') buf[0] = '\n'; for(int i = 0; i < 8 && !utf8decode(&rune, &len, buf[i]); i++); } - printf("key: %#x\n", rune); /* translate the key code into a unicode codepoint */ switch (key) { case XK_F1: return KEY_F1; @@ -149,56 +148,6 @@ static Rune getkey(XEvent* e) { } } -static void handle_key(XEvent* e) { - Rune key = getkey(e); - /* Handle the key */ - switch (key) { - case RUNE_ERR: break; - case KEY_F1: - Buffer.insert_mode = !Buffer.insert_mode; - break; - - case KEY_F6: - ColorBase = !ColorBase; - break; - - case KEY_LEFT: - CursorPos = buf_byrune(&Buffer, CursorPos, -1); - break; - - case KEY_RIGHT: - CursorPos = buf_byrune(&Buffer, CursorPos, 1); - break; - - case KEY_DOWN: - CursorPos = buf_byline(&Buffer, CursorPos, 1); - break; - - case KEY_UP: - CursorPos = buf_byline(&Buffer, CursorPos, -1); - break; - - case KEY_ESCAPE: - Buffer.insert_mode = false; - break; - - case KEY_BACKSPACE: - if (Buffer.insert_mode) - buf_del(&Buffer, --CursorPos); - break; - - case KEY_DELETE: - if (Buffer.insert_mode) - buf_del(&Buffer, CursorPos); - break; - - default: - if (Buffer.insert_mode) - buf_ins(&Buffer, CursorPos++, key); - break; - } -} - static void handle_mousebtn(XEvent* e) { switch (e->xbutton.button) { case Button1: /* Left Button */ @@ -224,7 +173,7 @@ static void handle_event(XEvent* e) { case FocusIn: if (X.xic) XSetICFocus(X.xic); break; case FocusOut: if (X.xic) XUnsetICFocus(X.xic); break; case ButtonPress: handle_mousebtn(e); break; - case KeyPress: handle_key(e); break; + case KeyPress: handle_key(getkey(e)); break; case ConfigureNotify: // Resize the window if (e->xconfigure.width != X.width || e->xconfigure.height != X.height) { X.width = e->xconfigure.width; -- 2.49.0