[hackers] [st] reorganized several stuff

From: Anselm R. Garbe <arg_AT_suckless.org>
Date: Fri, 02 Mar 2007 14:57:19 -0000

changeset: 55:633afd8fecb3
tag: tip
user: Anselm R. Garbe <arg_AT_suckless.org>
date: Fri Mar 02 15:55:30 2007 +0100
summary: reorganized several stuff

diff -r ecbf9d3b38b9 -r 633afd8fecb3 Makefile
--- a/Makefile Fri Mar 02 15:53:26 2007 +0100
+++ b/Makefile Fri Mar 02 15:55:30 2007 +0100
@@ -3,7 +3,7 @@
 
 include config.mk
 
-SRC = events.c main.c process.c screen.c ui.c util.c
+SRC = event.c main.c process.c util.c vt.c
 OBJ = ${SRC:.c=.o}
 
 all: options st
diff -r ecbf9d3b38b9 -r 633afd8fecb3 event.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/event.c Fri Mar 02 15:55:30 2007 +0100
@@ -0,0 +1,435 @@
+/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
+ * See LICENSE file for license details.
+ */
+#include "st.h"
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+#include <X11/Xmd.h>
+
+#define REFRESH_NO 0
+#define REFRESH_FULL 1
+#define REFRESH_PARTIALLY 2
+#define KEYSEQLEN 10
+#define ModMetaMask Mod4Mask
+#define Atom32 CARD32
+
+int refresh_type = 0;
+int saved_cursor_x, saved_cursor_y;
+int application_keypad_mode = 0;
+int insert_mode = 0;
+int decckm_mode = 0;
+int wraparound_mode = 0;
+int cursor_visible = 1;
+int using_alternate_screen = 0;
+
+char *eventnames[] = {
+ "",
+ "",
+ "KeyPress",
+ "KeyRelease",
+ "ButtonPress",
+ "ButtonRelease",
+ "MotionNotify",
+ "EnterNotify",
+ "LeaveNotify",
+ "FocusIn",
+ "FocusOut",
+ "KeymapNotify",
+ "Expose",
+ "GraphicsExpose",
+ "NoExpose",
+ "VisibilityNotify",
+ "CreateNotify",
+ "DestroyNotify",
+ "UnmapNotify",
+ "MapNotify",
+ "MapRequest",
+ "ReparentNotify",
+ "ConfigureNotify",
+ "ConfigureRequest",
+ "GravityNotify",
+ "ResizeRequest",
+ "CirculateNotify",
+ "CirculateRequest",
+ "PropertyNotify",
+ "SelectionClear",
+ "SelectionRequest",
+ "SelectionNotify",
+ "ColormapNotify",
+ "ClientMessage",
+ "MappingNotify"
+};
+
+void
+selection_paste(Time tm) {
+ int nbytes;
+ char *text;
+
+ XConvertSelection(dpy, XA_PRIMARY, XA_CUT_BUFFER0, None, win, tm);
+ text = XFetchBytes(dpy, &nbytes);
+ cmd_write(text, nbytes);
+}
+
+void
+handle_keypress(XEvent *xev) {
+ char kbuf[KEYSEQLEN];
+ KeySym keysym;
+ static XComposeStatus compose = {NULL, 0};
+ int len;
+ int meta;
+ int shift;
+
+ meta = xev->xkey.state & ModMetaMask;
+ shift = xev->xkey.state & ShiftMask;
+ len = XLookupString(&(xev->xkey), &kbuf[0], sizeof(kbuf), &keysym, &compose);
+ if(len > 0) {
+ kbuf[KEYSEQLEN-1] = 0;
+ if(meta && len == 1)
+ cmd_write("\033", 1);
+ cmd_write(kbuf, len);
+ return;
+ }
+ if(keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
+ /* modifiers, these are handled by XLookupString */
+ return;
+ switch(keysym) {
+ default:
+ fprintf(stderr, "Unhandled special key: %d\n", (int)keysym);
+ break;
+ case XK_Up:
+ case XK_Down:
+ case XK_Left:
+ case XK_Right:
+ kbuf[0] = '\033';
+ if(decckm_mode)
+ kbuf[1] = 'O';
+ else
+ kbuf[1] = '[';
+ kbuf[2] = "DACB"[keysym - XK_Left];
+ cmd_write(kbuf, 3);
+ break;
+ case XK_Delete:
+ cmd_write(DELETE_KEY, sizeof(DELETE_KEY)-1);
+ break;
+ case XK_Home:
+ cmd_write(HOME_KEY, sizeof(HOME_KEY)-1);
+ break;
+ case XK_End:
+ cmd_write(END_KEY, sizeof(END_KEY)-1);
+ break;
+ case XK_Prior:
+ cmd_write(PREV_KEY, sizeof(PREV_KEY)-1);
+ break;
+ case XK_Next:
+ cmd_write(NEXT_KEY, sizeof(NEXT_KEY)-1);
+ break;
+ case XK_Insert:
+ if(shift)
+ selection_paste(CurrentTime);
+ break;
+ }
+}
+
+void
+handle_resize(XEvent *xev) {
+ int new_cols, new_rows;
+
+ new_cols = xev->xconfigure.width / dc.font.width;
+ new_rows = xev->xconfigure.height / dc.font.height;
+ if(new_cols != screen_cols || new_rows != screen_rows) {
+ buffer_resize(new_rows, new_cols);
+ screen_cols = new_cols;
+ screen_rows = new_rows;
+ scroll_region_start = 1;
+ scroll_region_end = screen_rows;
+ ww = xev->xconfigure.width;
+ wh = xev->xconfigure.height;
+ /* make sure the cursor is within the window */
+ cursor_rego();
+ /* Finally: pass the info to the application */
+ resize_app();
+ /* and redraw */
+ force_redraw_screen();
+ }
+}
+
+static int selection_start_col, selection_start_row, selection_end_col, selection_end_row;
+static int selection_mode = 0;
+
+static unsigned char *selection_text = NULL;
+
+#define SELECT_NONE 0
+#define SELECT_LETTER 1
+#define SELECT_WORD 2
+#define SELECT_LINE 3
+
+void
+selection_reset(void) {
+ int i, j;
+
+ selection_mode = SELECT_NONE;
+ for(i = 0; i < screen_rows; i++) {
+ for(j = 0; j < screen_cols; j++)
+ text_screen[i].line[j].sel = 0;
+ text_screen[i].needs_update = 1;
+ }
+ if(selection_text) {
+ free(selection_text);
+ selection_text = NULL;
+ }
+}
+
+void
+selection_start(int row, int col, Time tm) {
+ fprintf(stderr, "Selection started, row=%d, col=%d\n", row, col);
+ selection_start_col = col, selection_start_row = row;
+ selection_end_col = col, selection_end_row = row;
+ selection_mode = SELECT_LETTER;
+}
+
+void
+selection_select_word(int row, int col, Time tm) {
+ int i, len;
+
+ if(selection_text)
+ free(selection_text);
+ selection_text = malloc(screen_cols+1);
+ assert(selection_text);
+ fprintf(stderr, "Select word on %d,%d\n", col, row);
+ i = col - 1;
+ while(i >= 0 && isalnum(text_screen[row-1].line[i].letter))
+ i--;
+ i++;
+ len = 0;
+ while((i < screen_cols) && isalnum(text_screen[row-1].line[i].letter)) {
+ selection_text[len++] = text_screen[row-1].line[i].letter;
+ text_screen[row-1].line[i].sel = 1;
+ i++;
+ }
+ fprintf(stderr, "len=%d\n", len);
+ text_screen[row-1].needs_update = 1;
+ XStoreBuffer(dpy, selection_text, len, XA_CUT_BUFFER0);
+ XSetSelectionOwner(dpy, XA_PRIMARY, win, tm);
+}
+
+void
+selection_select_line(int row, int col, Time tm) {
+ int i;
+
+ if(selection_text)
+ free(selection_text);
+ selection_text = malloc(screen_cols+1);
+ assert(selection_text);
+ fprintf(stderr, "select line %d\n", row);
+ for(i = 0; i < screen_cols; i++) {
+ selection_text[i] = text_screen[row-1].line[i].letter;
+ text_screen[row-1].line[i].sel = 1;
+ }
+ while(selection_text[i] == ' ') i--;
+ text_screen[row-1].needs_update=1;
+ XStoreBuffer(dpy, selection_text, screen_cols, XA_CUT_BUFFER0);
+ XSetSelectionOwner(dpy, XA_PRIMARY, win, tm);
+}
+
+void
+handle_buttonpress(XEvent *xev) {
+ static int lastclick_time = 0;
+ static int times_clicked = 0;
+ int click_col, click_row;
+ int button;
+
+ click_col = xev->xbutton.x / dc.font.width + 1;
+ click_row = xev->xbutton.y / dc.font.height + 1;
+ click_col = click_col > screen_cols ? screen_cols : (click_col < 1 ? 1 : click_col);
+ click_row = click_row > screen_rows ? screen_rows : (click_row < 1 ? 1 : click_row);
+ button = xev->xbutton.button;
+ fprintf(stderr, "Mouse button %d pressed on (%d,%d)\n", button, click_col, click_row);
+ switch(button) {
+ case 1:
+ if(xev->xbutton.time <= lastclick_time + 600 &&
+ xev->xbutton.time > lastclick_time)
+ times_clicked = (times_clicked) % 3 + 1;
+ else
+ times_clicked = 0;
+ switch(times_clicked) {
+ case SELECT_NONE:
+ case SELECT_LETTER:
+ selection_reset();
+ selection_start(click_row, click_col, xev->xbutton.time);
+ times_clicked = 1;
+ break;
+ case SELECT_WORD:
+ selection_select_word(click_row, click_col, xev->xbutton.time);
+ break;
+ case SELECT_LINE:
+ selection_select_line(click_row, click_col, xev->xbutton.time);
+ break;
+ }
+ lastclick_time = xev->xbutton.time;
+ break;
+ case 2: /* middle button */
+ selection_paste(xev->xbutton.time);
+ break;
+ case 3: /* right button */
+ break;
+ }
+}
+
+void
+handle_motionnotify(XEvent *xev) {
+ int unused;
+
+ while(XCheckTypedWindowEvent(dpy, win, MotionNotify, xev));
+ XQueryPointer(dpy, win, &unused, &unused,
+ &unused, &unused, &(xev->xbutton.x), &(xev->xbutton.y), &unused);
+}
+
+void
+selection_copy(XEvent *xev) {
+ XEvent ev;
+ XSelectionRequestEvent *rq = (XSelectionRequestEvent*)xev;
+ Atom32 target_list[4];
+ Atom target;
+ static Atom xa_targets = None;
+ static Atom xa_compound_text = None;
+ static Atom xa_text = None;
+ XTextProperty ct;
+ XICCEncodingStyle style;
+ char *cl[4];
+
+ if(!selection_text)
+ return;
+ ev.xselection.type = SelectionNotify;
+ ev.xselection.property = None;
+ ev.xselection.display = rq->display;
+ ev.xselection.requestor = rq->requestor;
+ ev.xselection.selection = rq->selection;
+ ev.xselection.target = rq->target;
+ ev.xselection.time = rq->time;
+ if(rq->target == None) {
+ target_list[0] = (Atom32) xa_targets;
+ target_list[1] = (Atom32) XA_STRING;
+ target_list[2] = (Atom32) xa_text;
+ target_list[3] = (Atom32) xa_compound_text;
+ XChangeProperty(dpy, rq->requestor, rq->property, rq->target,
+ (8 * sizeof(target_list[0])), PropModeReplace,
+ (unsigned char *)target_list,
+ (sizeof(target_list) / sizeof(target_list[0])));
+ ev.xselection.property = rq->property;
+ }
+ else if(rq->target == XA_STRING || rq->target == xa_compound_text || rq->target == xa_text) {
+ if(rq->target == XA_STRING) {
+ style = XStringStyle;
+ target = XA_STRING;
+ }
+ else {
+ target = xa_compound_text;
+ style = (rq->target == xa_compound_text) ? XCompoundTextStyle
+ : XStdICCTextStyle;
+ }
+ cl[0] = selection_text;
+ XmbTextListToTextProperty(dpy, cl, 1, style, &ct);
+ XChangeProperty(dpy, rq->requestor, rq->property,
+ target, 8, PropModeReplace,
+ ct.value, ct.nitems);
+ ev.xselection.property = rq->property;
+ }
+ XSendEvent(dpy, rq->requestor, False, 0, &ev);
+}
+
+int
+handle_x_events(void) {
+ XEvent xev;
+
+ /* Input from the X server */
+ while (XPending(dpy)) {
+ /* process pending X events */
+ XNextEvent(dpy, &xev);
+
+ switch(xev.type) {
+ default:
+ fprintf(stderr, "Got unhandled X event %d (%s)\n", xev.type, eventnames[xev.type]);
+ case ButtonPress:
+ handle_buttonpress(&xev);
+ break;
+ case MotionNotify:
+ handle_motionnotify(&xev);
+ break;
+ case KeyPress:
+ handle_keypress(&xev);
+ break;
+ case ConfigureNotify:
+ handle_resize(&xev);
+ break;
+ case SelectionNotify:
+ /* Ignore this? */
+ break;
+ case GraphicsExpose:
+ case Expose:
+ /* Part of the window needs a redraw */
+ switch(refresh_type) {
+ case REFRESH_FULL:
+ force_redraw_screen();
+ break;
+ case REFRESH_PARTIALLY:
+ {
+ int a,b,c,d;
+ a = xev.xexpose.x / dc.font.width + 1;
+ b = xev.xexpose.y / dc.font.height + 1;
+ c = (xev.xexpose.x + xev.xexpose.width) / dc.font.width + 1;
+ d = (xev.xexpose.y + xev.xexpose.height) / dc.font.height + 1;
+ a = a > screen_cols ? screen_cols : a;
+ b = b > screen_rows ? screen_rows : b;
+ c = c > screen_cols ? screen_cols : c;
+ d = d > screen_rows ? screen_rows : d;
+ redraw_region(a,b,c,d);
+ }
+ break;
+ default:
+ /* No refreshing needs to be done */
+ break;
+ }
+ break;
+ case VisibilityNotify:
+ /* Some part of the screen has to be redrawn */
+ switch(xev.xvisibility.state)
+ {
+ case VisibilityUnobscured:
+ refresh_type = REFRESH_FULL;
+ break;
+ case VisibilityPartiallyObscured:
+ refresh_type = REFRESH_PARTIALLY;
+ break;
+ default:
+ refresh_type = REFRESH_NO;
+ break;
+ }
+ break;
+ case MapNotify:
+ case UnmapNotify:
+ case FocusIn:
+ case FocusOut:
+ case NoExpose:
+ /* Silently unhandled for now */
+ break;
+ case SelectionClear:
+ selection_reset();
+ free(selection_text);
+ selection_text = NULL;
+ break;
+ case SelectionRequest:
+ fprintf(stderr, "SelectionRequest\n");
+ selection_copy(&xev);
+ break;
+ }
+ }
+ return 0;
+}
diff -r ecbf9d3b38b9 -r 633afd8fecb3 events.c
--- a/events.c Fri Mar 02 15:53:26 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,435 +0,0 @@
-/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-#include "st.h"
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#include <X11/cursorfont.h>
-#include <X11/keysym.h>
-#include <X11/Xmd.h>
-
-#define REFRESH_NO 0
-#define REFRESH_FULL 1
-#define REFRESH_PARTIALLY 2
-#define KEYSEQLEN 10
-#define ModMetaMask Mod4Mask
-#define Atom32 CARD32
-
-int refresh_type = 0;
-int saved_cursor_x, saved_cursor_y;
-int application_keypad_mode = 0;
-int insert_mode = 0;
-int decckm_mode = 0;
-int wraparound_mode = 0;
-int cursor_visible = 1;
-int using_alternate_screen = 0;
-
-char *eventnames[] = {
- "",
- "",
- "KeyPress",
- "KeyRelease",
- "ButtonPress",
- "ButtonRelease",
- "MotionNotify",
- "EnterNotify",
- "LeaveNotify",
- "FocusIn",
- "FocusOut",
- "KeymapNotify",
- "Expose",
- "GraphicsExpose",
- "NoExpose",
- "VisibilityNotify",
- "CreateNotify",
- "DestroyNotify",
- "UnmapNotify",
- "MapNotify",
- "MapRequest",
- "ReparentNotify",
- "ConfigureNotify",
- "ConfigureRequest",
- "GravityNotify",
- "ResizeRequest",
- "CirculateNotify",
- "CirculateRequest",
- "PropertyNotify",
- "SelectionClear",
- "SelectionRequest",
- "SelectionNotify",
- "ColormapNotify",
- "ClientMessage",
- "MappingNotify"
-};
-
-void
-selection_paste(Time tm) {
- int nbytes;
- char *text;
-
- XConvertSelection(dpy, XA_PRIMARY, XA_CUT_BUFFER0, None, win, tm);
- text = XFetchBytes(dpy, &nbytes);
- cmd_write(text, nbytes);
-}
-
-void
-handle_keypress(XEvent *xev) {
- char kbuf[KEYSEQLEN];
- KeySym keysym;
- static XComposeStatus compose = {NULL, 0};
- int len;
- int meta;
- int shift;
-
- meta = xev->xkey.state & ModMetaMask;
- shift = xev->xkey.state & ShiftMask;
- len = XLookupString(&(xev->xkey), &kbuf[0], sizeof(kbuf), &keysym, &compose);
- if(len > 0) {
- kbuf[KEYSEQLEN-1] = 0;
- if(meta && len == 1)
- cmd_write("\033", 1);
- cmd_write(kbuf, len);
- return;
- }
- if(keysym >= XK_Shift_L && keysym <= XK_Hyper_R)
- /* modifiers, these are handled by XLookupString */
- return;
- switch(keysym) {
- default:
- fprintf(stderr, "Unhandled special key: %d\n", (int)keysym);
- break;
- case XK_Up:
- case XK_Down:
- case XK_Left:
- case XK_Right:
- kbuf[0] = '\033';
- if(decckm_mode)
- kbuf[1] = 'O';
- else
- kbuf[1] = '[';
- kbuf[2] = "DACB"[keysym - XK_Left];
- cmd_write(kbuf, 3);
- break;
- case XK_Delete:
- cmd_write(DELETE_KEY, sizeof(DELETE_KEY)-1);
- break;
- case XK_Home:
- cmd_write(HOME_KEY, sizeof(HOME_KEY)-1);
- break;
- case XK_End:
- cmd_write(END_KEY, sizeof(END_KEY)-1);
- break;
- case XK_Prior:
- cmd_write(PREV_KEY, sizeof(PREV_KEY)-1);
- break;
- case XK_Next:
- cmd_write(NEXT_KEY, sizeof(NEXT_KEY)-1);
- break;
- case XK_Insert:
- if(shift)
- selection_paste(CurrentTime);
- break;
- }
-}
-
-void
-handle_resize(XEvent *xev) {
- int new_cols, new_rows;
-
- new_cols = xev->xconfigure.width / dc.font.width;
- new_rows = xev->xconfigure.height / dc.font.height;
- if(new_cols != screen_cols || new_rows != screen_rows) {
- buffer_resize(new_rows, new_cols);
- screen_cols = new_cols;
- screen_rows = new_rows;
- scroll_region_start = 1;
- scroll_region_end = screen_rows;
- ww = xev->xconfigure.width;
- wh = xev->xconfigure.height;
- /* make sure the cursor is within the window */
- cursor_rego();
- /* Finally: pass the info to the application */
- resize_app();
- /* and redraw */
- force_redraw_screen();
- }
-}
-
-static int selection_start_col, selection_start_row, selection_end_col, selection_end_row;
-static int selection_mode = 0;
-
-static unsigned char *selection_text = NULL;
-
-#define SELECT_NONE 0
-#define SELECT_LETTER 1
-#define SELECT_WORD 2
-#define SELECT_LINE 3
-
-void
-selection_reset(void) {
- int i, j;
-
- selection_mode = SELECT_NONE;
- for(i = 0; i < screen_rows; i++) {
- for(j = 0; j < screen_cols; j++)
- text_screen[i].line[j].sel = 0;
- text_screen[i].needs_update = 1;
- }
- if(selection_text) {
- free(selection_text);
- selection_text = NULL;
- }
-}
-
-void
-selection_start(int row, int col, Time tm) {
- fprintf(stderr, "Selection started, row=%d, col=%d\n", row, col);
- selection_start_col = col, selection_start_row = row;
- selection_end_col = col, selection_end_row = row;
- selection_mode = SELECT_LETTER;
-}
-
-void
-selection_select_word(int row, int col, Time tm) {
- int i, len;
-
- if(selection_text)
- free(selection_text);
- selection_text = malloc(screen_cols+1);
- assert(selection_text);
- fprintf(stderr, "Select word on %d,%d\n", col, row);
- i = col - 1;
- while(i >= 0 && isalnum(text_screen[row-1].line[i].letter))
- i--;
- i++;
- len = 0;
- while((i < screen_cols) && isalnum(text_screen[row-1].line[i].letter)) {
- selection_text[len++] = text_screen[row-1].line[i].letter;
- text_screen[row-1].line[i].sel = 1;
- i++;
- }
- fprintf(stderr, "len=%d\n", len);
- text_screen[row-1].needs_update = 1;
- XStoreBuffer(dpy, selection_text, len, XA_CUT_BUFFER0);
- XSetSelectionOwner(dpy, XA_PRIMARY, win, tm);
-}
-
-void
-selection_select_line(int row, int col, Time tm) {
- int i;
-
- if(selection_text)
- free(selection_text);
- selection_text = malloc(screen_cols+1);
- assert(selection_text);
- fprintf(stderr, "select line %d\n", row);
- for(i = 0; i < screen_cols; i++) {
- selection_text[i] = text_screen[row-1].line[i].letter;
- text_screen[row-1].line[i].sel = 1;
- }
- while(selection_text[i] == ' ') i--;
- text_screen[row-1].needs_update=1;
- XStoreBuffer(dpy, selection_text, screen_cols, XA_CUT_BUFFER0);
- XSetSelectionOwner(dpy, XA_PRIMARY, win, tm);
-}
-
-void
-handle_buttonpress(XEvent *xev) {
- static int lastclick_time = 0;
- static int times_clicked = 0;
- int click_col, click_row;
- int button;
-
- click_col = xev->xbutton.x / dc.font.width + 1;
- click_row = xev->xbutton.y / dc.font.height + 1;
- click_col = click_col > screen_cols ? screen_cols : (click_col < 1 ? 1 : click_col);
- click_row = click_row > screen_rows ? screen_rows : (click_row < 1 ? 1 : click_row);
- button = xev->xbutton.button;
- fprintf(stderr, "Mouse button %d pressed on (%d,%d)\n", button, click_col, click_row);
- switch(button) {
- case 1:
- if(xev->xbutton.time <= lastclick_time + 600 &&
- xev->xbutton.time > lastclick_time)
- times_clicked = (times_clicked) % 3 + 1;
- else
- times_clicked = 0;
- switch(times_clicked) {
- case SELECT_NONE:
- case SELECT_LETTER:
- selection_reset();
- selection_start(click_row, click_col, xev->xbutton.time);
- times_clicked = 1;
- break;
- case SELECT_WORD:
- selection_select_word(click_row, click_col, xev->xbutton.time);
- break;
- case SELECT_LINE:
- selection_select_line(click_row, click_col, xev->xbutton.time);
- break;
- }
- lastclick_time = xev->xbutton.time;
- break;
- case 2: /* middle button */
- selection_paste(xev->xbutton.time);
- break;
- case 3: /* right button */
- break;
- }
-}
-
-void
-handle_motionnotify(XEvent *xev) {
- int unused;
-
- while(XCheckTypedWindowEvent(dpy, win, MotionNotify, xev));
- XQueryPointer(dpy, win, &unused, &unused,
- &unused, &unused, &(xev->xbutton.x), &(xev->xbutton.y), &unused);
-}
-
-void
-selection_copy(XEvent *xev) {
- XEvent ev;
- XSelectionRequestEvent *rq = (XSelectionRequestEvent*)xev;
- Atom32 target_list[4];
- Atom target;
- static Atom xa_targets = None;
- static Atom xa_compound_text = None;
- static Atom xa_text = None;
- XTextProperty ct;
- XICCEncodingStyle style;
- char *cl[4];
-
- if(!selection_text)
- return;
- ev.xselection.type = SelectionNotify;
- ev.xselection.property = None;
- ev.xselection.display = rq->display;
- ev.xselection.requestor = rq->requestor;
- ev.xselection.selection = rq->selection;
- ev.xselection.target = rq->target;
- ev.xselection.time = rq->time;
- if(rq->target == None) {
- target_list[0] = (Atom32) xa_targets;
- target_list[1] = (Atom32) XA_STRING;
- target_list[2] = (Atom32) xa_text;
- target_list[3] = (Atom32) xa_compound_text;
- XChangeProperty(dpy, rq->requestor, rq->property, rq->target,
- (8 * sizeof(target_list[0])), PropModeReplace,
- (unsigned char *)target_list,
- (sizeof(target_list) / sizeof(target_list[0])));
- ev.xselection.property = rq->property;
- }
- else if(rq->target == XA_STRING || rq->target == xa_compound_text || rq->target == xa_text) {
- if(rq->target == XA_STRING) {
- style = XStringStyle;
- target = XA_STRING;
- }
- else {
- target = xa_compound_text;
- style = (rq->target == xa_compound_text) ? XCompoundTextStyle
- : XStdICCTextStyle;
- }
- cl[0] = selection_text;
- XmbTextListToTextProperty(dpy, cl, 1, style, &ct);
- XChangeProperty(dpy, rq->requestor, rq->property,
- target, 8, PropModeReplace,
- ct.value, ct.nitems);
- ev.xselection.property = rq->property;
- }
- XSendEvent(dpy, rq->requestor, False, 0, &ev);
-}
-
-int
-handle_x_events(void) {
- XEvent xev;
-
- /* Input from the X server */
- while (XPending(dpy)) {
- /* process pending X events */
- XNextEvent(dpy, &xev);
-
- switch(xev.type) {
- default:
- fprintf(stderr, "Got unhandled X event %d (%s)\n", xev.type, eventnames[xev.type]);
- case ButtonPress:
- handle_buttonpress(&xev);
- break;
- case MotionNotify:
- handle_motionnotify(&xev);
- break;
- case KeyPress:
- handle_keypress(&xev);
- break;
- case ConfigureNotify:
- handle_resize(&xev);
- break;
- case SelectionNotify:
- /* Ignore this? */
- break;
- case GraphicsExpose:
- case Expose:
- /* Part of the window needs a redraw */
- switch(refresh_type) {
- case REFRESH_FULL:
- force_redraw_screen();
- break;
- case REFRESH_PARTIALLY:
- {
- int a,b,c,d;
- a = xev.xexpose.x / dc.font.width + 1;
- b = xev.xexpose.y / dc.font.height + 1;
- c = (xev.xexpose.x + xev.xexpose.width) / dc.font.width + 1;
- d = (xev.xexpose.y + xev.xexpose.height) / dc.font.height + 1;
- a = a > screen_cols ? screen_cols : a;
- b = b > screen_rows ? screen_rows : b;
- c = c > screen_cols ? screen_cols : c;
- d = d > screen_rows ? screen_rows : d;
- redraw_region(a,b,c,d);
- }
- break;
- default:
- /* No refreshing needs to be done */
- break;
- }
- break;
- case VisibilityNotify:
- /* Some part of the screen has to be redrawn */
- switch(xev.xvisibility.state)
- {
- case VisibilityUnobscured:
- refresh_type = REFRESH_FULL;
- break;
- case VisibilityPartiallyObscured:
- refresh_type = REFRESH_PARTIALLY;
- break;
- default:
- refresh_type = REFRESH_NO;
- break;
- }
- break;
- case MapNotify:
- case UnmapNotify:
- case FocusIn:
- case FocusOut:
- case NoExpose:
- /* Silently unhandled for now */
- break;
- case SelectionClear:
- selection_reset();
- free(selection_text);
- selection_text = NULL;
- break;
- case SelectionRequest:
- fprintf(stderr, "SelectionRequest\n");
- selection_copy(&xev);
- break;
- }
- }
- return 0;
-}
diff -r ecbf9d3b38b9 -r 633afd8fecb3 screen.c
--- a/screen.c Fri Mar 02 15:53:26 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,627 +0,0 @@
-/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-#include "st.h"
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-
-/* Maximum (numerical) parameters to an escape sequence */
-#define NPAR 16
-
-text_row_t *
-buffer_create(int rows, int cols) {
- int i;
- text_row_t *tr;
-
- tr = emallocz(rows * sizeof(text_row_t));
- for(i = 0; i < rows; i++)
- tr[i].line = emallocz(cols * sizeof(text_letter_t));
- return tr;
-}
-
-/* Cursor movement functions */
-int
-cursor_move_up(int n) {
- curr_row -= n;
- if(curr_row < 1)
- curr_row = 0;
- return curr_row;
-}
-
-int
-cursor_move_down(int n) {
- curr_row += n;
- if(curr_row > screen_rows)
- curr_row = screen_rows;
- return curr_row;
-}
-
-int
-cursor_move_left(int n) {
- curr_col -= n;
- if(curr_col < 1)
- curr_col = 1;
- return curr_col;
-}
-
-int
-cursor_move_right(int n) {
- curr_col += n;
- if(curr_col > screen_cols)
- curr_col = screen_cols;
- return curr_col;
-}
-
-int
-cursor_move_col(int n) {
- curr_col = n;
- if(curr_col < 1)
- curr_col = 1;
- if(curr_col > screen_cols)
- curr_col = screen_cols;
- return curr_col;
-}
-
-int
-cursor_move_row(int n) {
- curr_row = n;
- if(curr_row < 1)
- curr_row = 1;
- if(curr_row > screen_rows)
- curr_row = screen_rows;
- return curr_row;
-}
-
-void
-cursor_goto(int x, int y) {
- curr_col = x;
- curr_row = y;
- if(curr_col < 1)
- curr_col = 1;
- if(curr_col > screen_cols)
- curr_col = screen_cols;
- if(curr_row < 1)
- curr_row = 1;
- if(curr_row > screen_rows)
- curr_row = screen_rows;
-}
-
-void
-cursor_rego(void) {
- cursor_goto(curr_col, curr_row);
-}
-
-void
-delete_rows(text_row_t *screen, int start, int n) {
- int i;
-
- for(i = 0; i < n; i++)
- free(screen[start + i - 1].line);
-}
-
-void
-add_rows(text_row_t *screen, int pos, int n) {
- int i, j;
-
- text_attrs.letter = ' ';
- for(i = 0; i < n; i++) {
- screen[pos + i - 1].line = calloc(screen_cols, sizeof(text_letter_t));
- assert(screen[pos + i - 1].line);
- for(j = 0; j < screen_cols; j++)
- screen[pos + i - 1].line[j] = text_attrs;
- screen[pos + i - 1].needs_update = 1;
- }
-}
-
-void
-buffer_destroy(text_row_t *screen) {
- int i;
-
- for(i = 0; i < screen_rows; i++)
- free(screen[i].line);
- free(screen);
-}
-
-void
-save_current_screen(void) {
- saved_screen = text_screen;
- text_screen = buffer_create(screen_rows, screen_cols);
-}
-
-void
-restore_saved_screen(void) {
- int i;
-
- buffer_destroy(text_screen);
- text_screen = saved_screen;
- for(i = 0; i < screen_rows; i++)
- text_screen[i].needs_update = 1;
-}
-
-void
-_buffer_resize(text_row_t **s, int rows, int cols) {
- int i;
-
- if(rows < screen_rows) {
- delete_rows(*s, 1, screen_rows - rows);
- moverows(*s, screen_rows - rows + 1, 1, rows);
- }
- *s = realloc(*s, rows * sizeof(text_row_t));
- assert(*s);
- if(rows > screen_rows)
- add_rows(*s, screen_rows + 1, rows - screen_rows);
- if(cols != screen_cols) {
- for(i = 0; i < rows; i++) {
- int j;
-
- (*s)[i].line = realloc((*s)[i].line, cols * sizeof(text_letter_t));
- assert((*s)[i].line);
- for(j = screen_cols; j < cols; j++)
- *(int*)(&((*s)[i]).line[j]) = 0;
- (*s)[i].needs_update = 1;
- }
- }
-}
-
-void
-buffer_resize(int rows, int cols) {
- if(using_alternate_screen)
- _buffer_resize(&saved_screen, rows, cols);
- _buffer_resize(&text_screen, rows, cols);
-}
-
-void
-clear_area(int x1, int y1, int x2, int y2) {
- int i, j;
-
- win_clear_region((x1 - 1) * dc.font.width, (y1 - 1) * dc.font.height,
- x2 * dc.font.width, y2 * dc.font.height,
- GET_BG_COLOR(text_attrs));
- for(i = y1; i <= y2; i++)
- for(j = x1; j <= x2; j++)
- {
- text_screen[i-1].line[j-1] = text_attrs;
- text_screen[i-1].line[j-1].letter = ' ';
- }
-}
-
-void
-clear_row(text_row_t *r) {
- memset(r->line, '\0', screen_cols * sizeof(text_letter_t));
-}
-
-void
-moverows(text_row_t *screen, int from, int to, int n) {
- memmove(&(screen[to-1]), &(screen[from-1]), n * sizeof(text_row_t));
-}
-
-void
-scroll_up(int rows) {
- if(scroll_in_region) {
- /* Only scroll region */
- region_scroll_up(scroll_region_start, scroll_region_end, rows);
- delete_rows(text_screen, scroll_region_start, rows);
- moverows(text_screen, rows + scroll_region_start, scroll_region_start, scroll_region_end - scroll_region_start - rows + 1);
- add_rows(text_screen, scroll_region_end - rows + 1, rows);
- }
- else {
- /* Scroll entire buffer */
- window_scroll_up(rows);
- delete_rows(text_screen, 1, rows);
- moverows(text_screen, rows + 1, 1, screen_rows - rows);
- add_rows(text_screen, screen_rows - rows + 1, rows);
- }
-}
-
-void
-scroll_down(int rows) {
- if(scroll_in_region) {
- /* Only scroll region */
- region_scroll_down(scroll_region_start, scroll_region_end, rows);
- delete_rows(text_screen, scroll_region_end - rows + 1, rows);
- moverows(text_screen, scroll_region_start, scroll_region_start + rows, scroll_region_end - scroll_region_start - rows + 1);
- add_rows(text_screen, scroll_region_start, rows);
- }
- else {
- /* Scroll entire buffer */
- window_scroll_down(rows);
- delete_rows(text_screen, screen_rows - rows + 1, rows);
- moverows(text_screen, 1, rows + 1, screen_rows - rows);
- add_rows(text_screen, 1, rows);
- }
-}
-
-void
-insert_lines(int lines) {
- int a,b;
-
- /* Fake region scroll */
- a = scroll_region_start;
- b = scroll_in_region;
- scroll_region_start = curr_row;
- scroll_in_region = 1;
- scroll_down(lines);
- scroll_region_start = a;
- scroll_in_region = b;
-}
-
-void
-delete_lines(int lines) {
- int a,b;
-
- /* Fake region scroll */
- a = scroll_region_start;
- b = scroll_in_region;
- scroll_region_start = curr_row;
- scroll_in_region = 1;
- scroll_up(lines);
- scroll_region_start = a;
- scroll_in_region = b;
-}
-
-void
-set_buffer_fg_color(int c) {
- text_attrs.fg = c;
-}
-
-void
-set_buffer_bg_color(int c) {
- text_attrs.bg = c;
-}
-
-void
-set_buffer_attrs(int bold) {
- text_attrs.bold = bold ? 1 : 0;
-}
-
-void set_buffer_reverse(int rev)
-{
- text_attrs.rev = rev ? 1 : 0;
-}
-
-struct winsize *
-get_font_dim() {
- static struct winsize w;
-
- w.ws_row = screen_rows;
- w.ws_col = screen_cols;
- w.ws_xpixel = w.ws_ypixel = 0;
- return &w;
-}
-
-void
-write_buffer(unsigned char c) {
- text_attrs.letter = c;
- text_screen[curr_row-1].line[curr_col-1] = text_attrs;
- text_screen[curr_row-1].needs_update = 1;
-}
-
-void
-xterm_seq(int op) {
- unsigned char *buf;
- int len;
- int buflen;
- unsigned char c;
-
- buf = malloc(buflen = 20);
- c = cmdgetc();
- for(len = 0; c != '\007'; len++) {
- if(len > buflen + 1) {
- buflen <<= 1;
- buf = realloc(buf, buflen);
- assert(buf);
- }
- buf[len] = c;
- c = cmdgetc();
- }
- buf[len] = 0;
- switch(op) {
- case 0: /* set window and icon title */
- case 1: /* set icon title */
- case 2: /* set window title */
- win_set_window_title(buf);
- break;
- }
-}
-
-void
-wrap_line(void) {
- while(curr_col > screen_cols) {
- curr_col -= screen_cols;
- if(!wraparound_mode)
- curr_row++;
- if(curr_row > scroll_region_end) {
- scroll_up(curr_row - scroll_region_end);
- curr_row = scroll_region_end;
- }
- }
-}
-
-void
-dispatch_escape(void) {
- int len;
- int pos;
- int args[NPAR];
- int narg = 0;
- int digit;
- int rows, cols;
- int i;
- int questionmark;
- unsigned char c;
-
- for(pos = 0; pos < NPAR; pos++)
- args[pos] = 0;
-
- c = cmdgetc();
- switch(c) {
- default:
- fprintf(stderr, "Unsupported ESC sequence ESC %c\n", c);
- break;
- case '[': /* CSI */
- digit = 0;
- questionmark = 0;
- c = cmdgetc();
- while(isdigit(c) || c == ';' || c == '?') {
- if(c == ';') {
- args[narg] = 0;
- digit = 0;
- }
- else {
- if(c == '?')
- questionmark = 1;
- else {
- if(!digit)
- narg++;
- digit = 1;
- args[narg-1] *= 10;
- args[narg-1] += c - '0';
- }
- }
- c = cmdgetc();
- }
-
- switch(c) {
- default:
- fprintf(stderr, "Unsupported CSI sequence ESC [");
- if(questionmark)
- fprintf(stderr, " ?");
- for(i = 0; i < narg; i++)
- fprintf(stderr, " %d", args[i]);
- fprintf(stderr, " %c\n", c);
- break;
- case 'A':
- cursor_move_up(narg ? args[0] : 1);
- break;
- case 'B':
- cursor_move_down(narg ? args[0] : 1);
- break;
- case 'C':
- cursor_move_right(narg ? args[0] : 1);
- break;
- case 'D':
- cursor_move_left(narg ? args[0] : 1);
- break;
- case 'G':
- cursor_move_col(narg ? args[0] : 1);
- break;
- case 'H':
- cursor_goto(args[1] ? args[1] : 1, args[0] ? args[0] : 1);
- break;
- case 'J':
- if(narg) {
- if(args[0] == 1) {
- /* erase from start to cursor */
- clear_area(1, 1, screen_cols, curr_row);
- }
- if(args[0] == 2) {
- /* erase whole display */
- clear_area(1, 1, screen_cols, screen_rows);
- }
- }
- else {
- /* erase from cursor to end of display */
- clear_area(1, curr_row, screen_cols, screen_rows);
- }
- break;
- case 'K':
- if(narg) {
- if(args[0] == 1) {
- /* erase from start of line to cursor */
- clear_area(1, curr_row, curr_col, curr_row);
- }
- if(args[0] == 2) {
- /* erase whole line */
- clear_area(1, curr_row, screen_cols, curr_row);
- }
- }
- else {
- /* erase from cursor to end of line */
- clear_area(curr_col, curr_row, screen_cols, curr_row);
- }
- break;
- case 'L': /* Insert lines */
- insert_lines(narg ? args[0] : 1);
- break;
- case 'M': /* Delete lines */
- delete_lines(narg ? args[0] : 1);
- break;
- case 'd': /* line position absolute */
- cursor_move_row(narg ? args[0] : 1);
- break;
- case 'P': /* clear # of characters */
- clear_area(curr_col, curr_row, curr_col + args[0], curr_row);
- break;
- case 'h': /* set mode */
- switch(args[0]) {
- default:
- fprintf(stderr, "Unsupported ESC [%s h mode %d\n",
- questionmark?" ?":"",
- args[0]);
- break;
- case 1:
- if(questionmark)
- /* DEC CKM mode */
- decckm_mode = 1;
- break;
- case 4:
- if(!questionmark)
- /* insert mode */
- insert_mode = 1;
- break;
- case 7:
- if(questionmark)
- wraparound_mode = 1;
- break;
- case 25:
- if(questionmark)
- cursor_visible = 1;
- break;
- case 47:
- if(questionmark) {
- using_alternate_screen = 1;
- save_current_screen();
- }
- break;
- }
- break;
- case 'l': /* reset mode */
- switch(args[0]) {
- default:
- fprintf(stderr, "Unsupported ESC [%s l mode %d\n",
- questionmark?" ?":"",
- args[0]);
- break;
- case 1:
- if(questionmark)
- /* DEC CKM mode */
- decckm_mode = 0;
- break;
- case 4: /* insert mode */
- insert_mode = 0;
- break;
- case 7:
- if(questionmark)
- wraparound_mode = 0;
- break;
- case 25:
- if(questionmark)
- cursor_visible = 0;
- break;
- case 47:
- if(questionmark)
- {
- using_alternate_screen = 0;
- restore_saved_screen();
- }
- break;
- }
- break;
- case 'm':
- /* reset attrs */
- if(!narg) {
- set_buffer_attrs(0);
- set_buffer_fg_color(7);
- set_buffer_reverse(0);
- set_buffer_bg_color(0);
- }
- for(i = 0; i < narg; i++) {
- if(args[i] == 0) {
- set_buffer_attrs(0);
- set_buffer_fg_color(7);
- }
- else if(args[i] == 1)
- set_buffer_attrs(1);
- else if(args[i] == 7)
- set_buffer_reverse(1);
- else if(args[i] == 27)
- set_buffer_reverse(0);
- else if(args[i] >= 30 && args[i] <= 37)
- set_buffer_fg_color(args[i] - 30);
- else if(args[i] >= 40 && args[i] <= 47)
- set_buffer_bg_color(args[i] - 40);
- else if(args[i] == 39)
- set_buffer_fg_color(7);
- else if(args[i] == 49)
- set_buffer_bg_color(0);
- else
- fprintf(stderr, "Unsupported mode %d\n",
- args[i]);
- }
- break;
- case 'n':
- /* status report */
- {
- char buf[20];
- switch(args[0]) {
- default:
- fprintf(stderr, "Unknown status request id %d\n", args[0]);
- break;
- case 6:
- /* cursor position */
- snprintf(buf, sizeof(buf), "\033[%d;%dR",
- curr_row, curr_col);
- cmd_write(buf, strlen(buf));
- break;
- }
- }
- break;
- case 'r': /* set scrolling region */
- scroll_region_start = args[0] ? args[0] : 1;
- scroll_region_end = args[1] ? args[1] : screen_rows;
- if(!narg)
- /* Reset scroll region */
- scroll_in_region = 0;
- else if(args[0] == 1 && args[1] == screen_rows)
- scroll_in_region = 0;
- else
- scroll_in_region = 1;
- break;
- case '[': /* echoed function key */
- cmdgetc();
- break;
- }
- break;
- case ']': /* xterm sequence */
- digit = 0;
- c = cmdgetc();
- while(isdigit(c)) {
- if(!digit)
- narg++;
- digit = 1;
- args[narg-1] *= 10;
- args[narg-1] += c - '0';
- c = cmdgetc();
- }
- if(c != ';' || !narg) {
- fprintf(stderr, "Invalid xterm sequence\n");
- break;
- }
- xterm_seq(args[0]);
- break;
- case '7': /* save cursor position */
- saved_cursor_x = curr_col;
- saved_cursor_y = curr_row;
- break;
- case '8': /* restore cursor position */
- curr_col = saved_cursor_x;
- curr_row = saved_cursor_y;
- break;
- case '=': /* set application keypad mode */
- application_keypad_mode = 1;
- break;
- case '>': /* set numeric keypad mode */
- application_keypad_mode = 0;
- break;
- case 'M': /* reverse linefeed */
- curr_row--;
- if(curr_row < scroll_region_start) {
- curr_row = scroll_region_start;
- scroll_down(1);
- }
- break;
- }
-}
diff -r ecbf9d3b38b9 -r 633afd8fecb3 ui.c
--- a/ui.c Fri Mar 02 15:53:26 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-#include "st.h"
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-
-void
-wait_for_specific_event(int event_type) {
- XEvent e;
- for(;;) {
- XNextEvent(dpy, &e);
- if(e.type == event_type)
- break;
- }
-}
-
-void
-win_clear_region(int x1, int y1, int x2, int y2, int color) {
- XSetBackground(dpy, gc, color);
- XClearArea(dpy, win, x1, y1, x2 - x1, y2 - y1, 0);
-}
-
-void
-win_draw_string(int row, int col, char *s, int l) {
- if(dc.font.set)
- XmbDrawString(dpy, win, dc.font.set, gc, col * dc.font.width, row * dc.font.height + dc.font.ascent, s, l);
- else
- XDrawString(dpy, win, gc, col * dc.font.width, row * dc.font.height + dc.font.ascent, s, l);
-}
-
-void
-win_set_window_title(char *title) {
- XStoreName(dpy, win, title);
-}
-
-void
-window_scroll_up(int lines) {
- XCopyArea(dpy, win, win, gc,
- 0, lines * dc.font.height,
- ww, (screen_rows - lines + 1) * dc.font.height,
- 0, 0);
- win_clear_region(0, (screen_rows - lines) * dc.font.height,
- ww, screen_rows * dc.font.height,
- GET_BG_COLOR(text_attrs));
-}
-
-void
-region_scroll_up(int start, int end, int lines) {
- XCopyArea(dpy, win, win, gc,
- 0, (start - 1 + lines) * dc.font.height,
- ww, (end - start + 2 - lines) * dc.font.height,
- 0, (start - 1) * dc.font.height);
- win_clear_region(0, (end - lines) * dc.font.height,
- ww, end * dc.font.height,
- GET_BG_COLOR(text_attrs));
-}
-
-void
-window_scroll_down(int lines) {
- XCopyArea(dpy, win, win, gc,
- 0, 0,
- ww, (screen_rows - lines + 1) * dc.font.height,
- 0, lines * dc.font.height);
- win_clear_region(0, 0,
- ww, (lines) * dc.font.height,
- GET_BG_COLOR(text_attrs));
-}
-
-void
-region_scroll_down(int start, int end, int lines) {
- XCopyArea(dpy, win, win, gc,
- 0, (start - 1) * dc.font.height,
- ww, (end - start + 2 - lines) * dc.font.height,
- 0, (start - 1 + lines) * dc.font.height);
- win_clear_region(0, (start - 1) * dc.font.height,
- ww, (start + lines - 1) * dc.font.height,
- GET_BG_COLOR(text_attrs));
-}
-
-void
-set_text_attrs(text_letter_t l) {
- int fg, bg;
-
- if(l.rev ^ l.sel)
- fg = l.bg, bg = l.fg;
- else
- fg = l.fg, bg = l.bg;
- if(l.bold && fg == 0)
- XSetForeground(dpy, gc, dc.fg[8]);
- else
- XSetForeground(dpy, gc, dc.fg[fg]);
- if(!dc.font.set)
- XSetFont(dpy, gc, dc.font.xfont->fid);
- XSetBackground(dpy, gc, dc.bg[bg]);
-}
-
-/* Max number of characters to be drawn at once */
-#define MAXRUNLENGTH 100
-
-void
-redraw_screen(void) {
- int i, j;
- int a;
- int sl, start;
- unsigned char buf[MAXRUNLENGTH];
-
- a = 0;
- set_text_attrs(text_screen[0].line[0]);
- for(i = 0; i < screen_rows; i++) {
- if(!text_screen[i].needs_update)
- continue;
- sl = 0; start = 0;
- for(j = 0; j <= screen_cols; j++) {
- if(j == screen_cols) {
- if(sl > 0)
- win_draw_string(i, start, &buf[0], sl);
- break;
- }
- if(a != ((*(int*)&(text_screen[i].line[j])) & ~0xff) || sl >= sizeof(buf)) {
- if(sl > 0)
- win_draw_string(i, start, &buf[0], sl);
- set_text_attrs(text_screen[i].line[j]);
- a = (*(int*)&(text_screen[i].line[j])) & ~0xff;
- start = j;
- sl = 0;
- }
- buf[sl] = text_screen[i].line[j].letter;
- sl++;
- }
- text_screen[i].needs_update = 0;
- }
- XFlush(dpy);
-}
-
-void
-force_redraw_screen(void) {
- int i;
- for(i = 0; i < screen_rows; i++)
- text_screen[i].needs_update = 1;
- redraw_screen();
-}
-
-void
-bell(void) {
- XBell(dpy, 0);
-}
-
-void
-redraw_region(int x1, int y1, int x2, int y2) {
- int i, j;
- int a;
- int sl, start;
- unsigned char buf[MAXRUNLENGTH];
-
- a = (*(int*)&(text_screen[y1-1].line[x1-1])) & ~0xff;
- set_text_attrs(text_screen[y1-1].line[x1-1]);
- for(i = y1 - 1; i < y2; i++) {
- sl = 0; start = x1 - 1;
- for(j = x1 - 1; j <= x2; j++) {
- if(j == x2) {
- if(sl > 0)
- win_draw_string(i, start, &buf[0], sl);
- break;
- }
- if(a != ((*(int*)&(text_screen[i].line[j])) & ~0xff) || sl >= sizeof(buf)) {
- if(sl > 0)
- win_draw_string(i, start, &buf[0], sl);
- set_text_attrs(text_screen[i].line[j]);
- a = (*(int*)&(text_screen[i].line[j])) & ~0xff;
- start = j;
- sl = 0;
- }
- buf[sl] = text_screen[i].line[j].letter;
- sl++;
- }
- text_screen[i].needs_update = 0;
- }
- XFlush(dpy);
-}
-
-extern int curr_row, curr_col;
-static int cursor_row, cursor_col;
-static int cursor_is_visible = 0;
-
-void
-show_cursor(void) {
- if(cursor_is_visible)
- return;
- if(!cursor_visible)
- return;
- cursor_row = curr_row;
- cursor_col = curr_col;
- if(curr_col > screen_cols)
- cursor_col = screen_cols;
- if(!dc.font.set)
- XSetFont(dpy, gc, dc.font.xfont->fid);
- win_clear_region((cursor_col - 1) * dc.font.width, (cursor_row - 1) * dc.font.height,
- cursor_col * dc.font.width, cursor_row * dc.font.height, dc.cursor);
- XSetForeground(dpy, gc, dc.fg[0]);
- XSetBackground(dpy, gc, dc.cursor);
- win_draw_string(cursor_row - 1, cursor_col - 1, &(text_screen[cursor_row - 1].line[cursor_col - 1]), 1);
- XFlush(dpy);
- cursor_is_visible = 1;
-}
-
-void
-hide_cursor(void) {
- if(!cursor_is_visible)
- return;
- if(cursor_row <= screen_rows && cursor_col <= screen_cols)
- {
- set_text_attrs(text_screen[cursor_row-1].line[cursor_col-1]);
- win_clear_region((cursor_col - 1) * dc.font.width, (cursor_row - 1) * dc.font.height,
- cursor_col * dc.font.width, cursor_row * dc.font.height,
- GET_BG_COLOR(text_screen[cursor_row-1].line[cursor_col-1]));
- win_draw_string(cursor_row - 1, cursor_col - 1, &(text_screen[cursor_row - 1].line[cursor_col - 1]), 1);
- XFlush(dpy);
- }
- cursor_is_visible = 0;
-}
diff -r ecbf9d3b38b9 -r 633afd8fecb3 vt.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vt.c Fri Mar 02 15:55:30 2007 +0100
@@ -0,0 +1,841 @@
+/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
+ * See LICENSE file for license details.
+ */
+#include "st.h"
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+
+/* Maximum (numerical) parameters to an escape sequence */
+#define NPAR 16
+
+void
+wait_for_specific_event(int event_type) {
+ XEvent e;
+ for(;;) {
+ XNextEvent(dpy, &e);
+ if(e.type == event_type)
+ break;
+ }
+}
+
+void
+win_clear_region(int x1, int y1, int x2, int y2, int color) {
+ XSetBackground(dpy, gc, color);
+ XClearArea(dpy, win, x1, y1, x2 - x1, y2 - y1, 0);
+}
+
+void
+win_draw_string(int row, int col, char *s, int l) {
+ if(dc.font.set)
+ XmbDrawString(dpy, win, dc.font.set, gc, col * dc.font.width, row * dc.font.height + dc.font.ascent, s, l);
+ else
+ XDrawString(dpy, win, gc, col * dc.font.width, row * dc.font.height + dc.font.ascent, s, l);
+}
+
+void
+win_set_window_title(char *title) {
+ XStoreName(dpy, win, title);
+}
+
+void
+window_scroll_up(int lines) {
+ XCopyArea(dpy, win, win, gc,
+ 0, lines * dc.font.height,
+ ww, (screen_rows - lines + 1) * dc.font.height,
+ 0, 0);
+ win_clear_region(0, (screen_rows - lines) * dc.font.height,
+ ww, screen_rows * dc.font.height,
+ GET_BG_COLOR(text_attrs));
+}
+
+void
+region_scroll_up(int start, int end, int lines) {
+ XCopyArea(dpy, win, win, gc,
+ 0, (start - 1 + lines) * dc.font.height,
+ ww, (end - start + 2 - lines) * dc.font.height,
+ 0, (start - 1) * dc.font.height);
+ win_clear_region(0, (end - lines) * dc.font.height,
+ ww, end * dc.font.height,
+ GET_BG_COLOR(text_attrs));
+}
+
+void
+window_scroll_down(int lines) {
+ XCopyArea(dpy, win, win, gc,
+ 0, 0,
+ ww, (screen_rows - lines + 1) * dc.font.height,
+ 0, lines * dc.font.height);
+ win_clear_region(0, 0,
+ ww, (lines) * dc.font.height,
+ GET_BG_COLOR(text_attrs));
+}
+
+void
+region_scroll_down(int start, int end, int lines) {
+ XCopyArea(dpy, win, win, gc,
+ 0, (start - 1) * dc.font.height,
+ ww, (end - start + 2 - lines) * dc.font.height,
+ 0, (start - 1 + lines) * dc.font.height);
+ win_clear_region(0, (start - 1) * dc.font.height,
+ ww, (start + lines - 1) * dc.font.height,
+ GET_BG_COLOR(text_attrs));
+}
+
+void
+set_text_attrs(text_letter_t l) {
+ int fg, bg;
+
+ if(l.rev ^ l.sel)
+ fg = l.bg, bg = l.fg;
+ else
+ fg = l.fg, bg = l.bg;
+ if(l.bold && fg == 0)
+ XSetForeground(dpy, gc, dc.fg[8]);
+ else
+ XSetForeground(dpy, gc, dc.fg[fg]);
+ if(!dc.font.set)
+ XSetFont(dpy, gc, dc.font.xfont->fid);
+ XSetBackground(dpy, gc, dc.bg[bg]);
+}
+
+/* Max number of characters to be drawn at once */
+#define MAXRUNLENGTH 100
+
+void
+redraw_screen(void) {
+ int i, j;
+ int a;
+ int sl, start;
+ unsigned char buf[MAXRUNLENGTH];
+
+ a = 0;
+ set_text_attrs(text_screen[0].line[0]);
+ for(i = 0; i < screen_rows; i++) {
+ if(!text_screen[i].needs_update)
+ continue;
+ sl = 0; start = 0;
+ for(j = 0; j <= screen_cols; j++) {
+ if(j == screen_cols) {
+ if(sl > 0)
+ win_draw_string(i, start, &buf[0], sl);
+ break;
+ }
+ if(a != ((*(int*)&(text_screen[i].line[j])) & ~0xff) || sl >= sizeof(buf)) {
+ if(sl > 0)
+ win_draw_string(i, start, &buf[0], sl);
+ set_text_attrs(text_screen[i].line[j]);
+ a = (*(int*)&(text_screen[i].line[j])) & ~0xff;
+ start = j;
+ sl = 0;
+ }
+ buf[sl] = text_screen[i].line[j].letter;
+ sl++;
+ }
+ text_screen[i].needs_update = 0;
+ }
+ XFlush(dpy);
+}
+
+void
+force_redraw_screen(void) {
+ int i;
+ for(i = 0; i < screen_rows; i++)
+ text_screen[i].needs_update = 1;
+ redraw_screen();
+}
+
+void
+bell(void) {
+ XBell(dpy, 0);
+}
+
+void
+redraw_region(int x1, int y1, int x2, int y2) {
+ int i, j;
+ int a;
+ int sl, start;
+ unsigned char buf[MAXRUNLENGTH];
+
+ a = (*(int*)&(text_screen[y1-1].line[x1-1])) & ~0xff;
+ set_text_attrs(text_screen[y1-1].line[x1-1]);
+ for(i = y1 - 1; i < y2; i++) {
+ sl = 0; start = x1 - 1;
+ for(j = x1 - 1; j <= x2; j++) {
+ if(j == x2) {
+ if(sl > 0)
+ win_draw_string(i, start, &buf[0], sl);
+ break;
+ }
+ if(a != ((*(int*)&(text_screen[i].line[j])) & ~0xff) || sl >= sizeof(buf)) {
+ if(sl > 0)
+ win_draw_string(i, start, &buf[0], sl);
+ set_text_attrs(text_screen[i].line[j]);
+ a = (*(int*)&(text_screen[i].line[j])) & ~0xff;
+ start = j;
+ sl = 0;
+ }
+ buf[sl] = text_screen[i].line[j].letter;
+ sl++;
+ }
+ text_screen[i].needs_update = 0;
+ }
+ XFlush(dpy);
+}
+
+extern int curr_row, curr_col;
+static int cursor_row, cursor_col;
+static int cursor_is_visible = 0;
+
+void
+show_cursor(void) {
+ if(cursor_is_visible)
+ return;
+ if(!cursor_visible)
+ return;
+ cursor_row = curr_row;
+ cursor_col = curr_col;
+ if(curr_col > screen_cols)
+ cursor_col = screen_cols;
+ if(!dc.font.set)
+ XSetFont(dpy, gc, dc.font.xfont->fid);
+ win_clear_region((cursor_col - 1) * dc.font.width, (cursor_row - 1) * dc.font.height,
+ cursor_col * dc.font.width, cursor_row * dc.font.height, dc.cursor);
+ XSetForeground(dpy, gc, dc.fg[0]);
+ XSetBackground(dpy, gc, dc.cursor);
+ win_draw_string(cursor_row - 1, cursor_col - 1, &(text_screen[cursor_row - 1].line[cursor_col - 1]), 1);
+ XFlush(dpy);
+ cursor_is_visible = 1;
+}
+
+void
+hide_cursor(void) {
+ if(!cursor_is_visible)
+ return;
+ if(cursor_row <= screen_rows && cursor_col <= screen_cols)
+ {
+ set_text_attrs(text_screen[cursor_row-1].line[cursor_col-1]);
+ win_clear_region((cursor_col - 1) * dc.font.width, (cursor_row - 1) * dc.font.height,
+ cursor_col * dc.font.width, cursor_row * dc.font.height,
+ GET_BG_COLOR(text_screen[cursor_row-1].line[cursor_col-1]));
+ win_draw_string(cursor_row - 1, cursor_col - 1, &(text_screen[cursor_row - 1].line[cursor_col - 1]), 1);
+ XFlush(dpy);
+ }
+ cursor_is_visible = 0;
+}
+text_row_t *
+buffer_create(int rows, int cols) {
+ int i;
+ text_row_t *tr;
+
+ tr = emallocz(rows * sizeof(text_row_t));
+ for(i = 0; i < rows; i++)
+ tr[i].line = emallocz(cols * sizeof(text_letter_t));
+ return tr;
+}
+
+/* Cursor movement functions */
+int
+cursor_move_up(int n) {
+ curr_row -= n;
+ if(curr_row < 1)
+ curr_row = 0;
+ return curr_row;
+}
+
+int
+cursor_move_down(int n) {
+ curr_row += n;
+ if(curr_row > screen_rows)
+ curr_row = screen_rows;
+ return curr_row;
+}
+
+int
+cursor_move_left(int n) {
+ curr_col -= n;
+ if(curr_col < 1)
+ curr_col = 1;
+ return curr_col;
+}
+
+int
+cursor_move_right(int n) {
+ curr_col += n;
+ if(curr_col > screen_cols)
+ curr_col = screen_cols;
+ return curr_col;
+}
+
+int
+cursor_move_col(int n) {
+ curr_col = n;
+ if(curr_col < 1)
+ curr_col = 1;
+ if(curr_col > screen_cols)
+ curr_col = screen_cols;
+ return curr_col;
+}
+
+int
+cursor_move_row(int n) {
+ curr_row = n;
+ if(curr_row < 1)
+ curr_row = 1;
+ if(curr_row > screen_rows)
+ curr_row = screen_rows;
+ return curr_row;
+}
+
+void
+cursor_goto(int x, int y) {
+ curr_col = x;
+ curr_row = y;
+ if(curr_col < 1)
+ curr_col = 1;
+ if(curr_col > screen_cols)
+ curr_col = screen_cols;
+ if(curr_row < 1)
+ curr_row = 1;
+ if(curr_row > screen_rows)
+ curr_row = screen_rows;
+}
+
+void
+cursor_rego(void) {
+ cursor_goto(curr_col, curr_row);
+}
+
+void
+delete_rows(text_row_t *screen, int start, int n) {
+ int i;
+
+ for(i = 0; i < n; i++)
+ free(screen[start + i - 1].line);
+}
+
+void
+add_rows(text_row_t *screen, int pos, int n) {
+ int i, j;
+
+ text_attrs.letter = ' ';
+ for(i = 0; i < n; i++) {
+ screen[pos + i - 1].line = calloc(screen_cols, sizeof(text_letter_t));
+ assert(screen[pos + i - 1].line);
+ for(j = 0; j < screen_cols; j++)
+ screen[pos + i - 1].line[j] = text_attrs;
+ screen[pos + i - 1].needs_update = 1;
+ }
+}
+
+void
+buffer_destroy(text_row_t *screen) {
+ int i;
+
+ for(i = 0; i < screen_rows; i++)
+ free(screen[i].line);
+ free(screen);
+}
+
+void
+save_current_screen(void) {
+ saved_screen = text_screen;
+ text_screen = buffer_create(screen_rows, screen_cols);
+}
+
+void
+restore_saved_screen(void) {
+ int i;
+
+ buffer_destroy(text_screen);
+ text_screen = saved_screen;
+ for(i = 0; i < screen_rows; i++)
+ text_screen[i].needs_update = 1;
+}
+
+void
+_buffer_resize(text_row_t **s, int rows, int cols) {
+ int i;
+
+ if(rows < screen_rows) {
+ delete_rows(*s, 1, screen_rows - rows);
+ moverows(*s, screen_rows - rows + 1, 1, rows);
+ }
+ *s = realloc(*s, rows * sizeof(text_row_t));
+ assert(*s);
+ if(rows > screen_rows)
+ add_rows(*s, screen_rows + 1, rows - screen_rows);
+ if(cols != screen_cols) {
+ for(i = 0; i < rows; i++) {
+ int j;
+
+ (*s)[i].line = realloc((*s)[i].line, cols * sizeof(text_letter_t));
+ assert((*s)[i].line);
+ for(j = screen_cols; j < cols; j++)
+ *(int*)(&((*s)[i]).line[j]) = 0;
+ (*s)[i].needs_update = 1;
+ }
+ }
+}
+
+void
+buffer_resize(int rows, int cols) {
+ if(using_alternate_screen)
+ _buffer_resize(&saved_screen, rows, cols);
+ _buffer_resize(&text_screen, rows, cols);
+}
+
+void
+clear_area(int x1, int y1, int x2, int y2) {
+ int i, j;
+
+ win_clear_region((x1 - 1) * dc.font.width, (y1 - 1) * dc.font.height,
+ x2 * dc.font.width, y2 * dc.font.height,
+ GET_BG_COLOR(text_attrs));
+ for(i = y1; i <= y2; i++)
+ for(j = x1; j <= x2; j++)
+ {
+ text_screen[i-1].line[j-1] = text_attrs;
+ text_screen[i-1].line[j-1].letter = ' ';
+ }
+}
+
+void
+clear_row(text_row_t *r) {
+ memset(r->line, '\0', screen_cols * sizeof(text_letter_t));
+}
+
+void
+moverows(text_row_t *screen, int from, int to, int n) {
+ memmove(&(screen[to-1]), &(screen[from-1]), n * sizeof(text_row_t));
+}
+
+void
+scroll_up(int rows) {
+ if(scroll_in_region) {
+ /* Only scroll region */
+ region_scroll_up(scroll_region_start, scroll_region_end, rows);
+ delete_rows(text_screen, scroll_region_start, rows);
+ moverows(text_screen, rows + scroll_region_start, scroll_region_start, scroll_region_end - scroll_region_start - rows + 1);
+ add_rows(text_screen, scroll_region_end - rows + 1, rows);
+ }
+ else {
+ /* Scroll entire buffer */
+ window_scroll_up(rows);
+ delete_rows(text_screen, 1, rows);
+ moverows(text_screen, rows + 1, 1, screen_rows - rows);
+ add_rows(text_screen, screen_rows - rows + 1, rows);
+ }
+}
+
+void
+scroll_down(int rows) {
+ if(scroll_in_region) {
+ /* Only scroll region */
+ region_scroll_down(scroll_region_start, scroll_region_end, rows);
+ delete_rows(text_screen, scroll_region_end - rows + 1, rows);
+ moverows(text_screen, scroll_region_start, scroll_region_start + rows, scroll_region_end - scroll_region_start - rows + 1);
+ add_rows(text_screen, scroll_region_start, rows);
+ }
+ else {
+ /* Scroll entire buffer */
+ window_scroll_down(rows);
+ delete_rows(text_screen, screen_rows - rows + 1, rows);
+ moverows(text_screen, 1, rows + 1, screen_rows - rows);
+ add_rows(text_screen, 1, rows);
+ }
+}
+
+void
+insert_lines(int lines) {
+ int a,b;
+
+ /* Fake region scroll */
+ a = scroll_region_start;
+ b = scroll_in_region;
+ scroll_region_start = curr_row;
+ scroll_in_region = 1;
+ scroll_down(lines);
+ scroll_region_start = a;
+ scroll_in_region = b;
+}
+
+void
+delete_lines(int lines) {
+ int a,b;
+
+ /* Fake region scroll */
+ a = scroll_region_start;
+ b = scroll_in_region;
+ scroll_region_start = curr_row;
+ scroll_in_region = 1;
+ scroll_up(lines);
+ scroll_region_start = a;
+ scroll_in_region = b;
+}
+
+void
+set_buffer_fg_color(int c) {
+ text_attrs.fg = c;
+}
+
+void
+set_buffer_bg_color(int c) {
+ text_attrs.bg = c;
+}
+
+void
+set_buffer_attrs(int bold) {
+ text_attrs.bold = bold ? 1 : 0;
+}
+
+void set_buffer_reverse(int rev)
+{
+ text_attrs.rev = rev ? 1 : 0;
+}
+
+struct winsize *
+get_font_dim() {
+ static struct winsize w;
+
+ w.ws_row = screen_rows;
+ w.ws_col = screen_cols;
+ w.ws_xpixel = w.ws_ypixel = 0;
+ return &w;
+}
+
+void
+write_buffer(unsigned char c) {
+ text_attrs.letter = c;
+ text_screen[curr_row-1].line[curr_col-1] = text_attrs;
+ text_screen[curr_row-1].needs_update = 1;
+}
+
+void
+xterm_seq(int op) {
+ unsigned char *buf;
+ int len;
+ int buflen;
+ unsigned char c;
+
+ buf = malloc(buflen = 20);
+ c = cmdgetc();
+ for(len = 0; c != '\007'; len++) {
+ if(len > buflen + 1) {
+ buflen <<= 1;
+ buf = realloc(buf, buflen);
+ assert(buf);
+ }
+ buf[len] = c;
+ c = cmdgetc();
+ }
+ buf[len] = 0;
+ switch(op) {
+ case 0: /* set window and icon title */
+ case 1: /* set icon title */
+ case 2: /* set window title */
+ win_set_window_title(buf);
+ break;
+ }
+}
+
+void
+wrap_line(void) {
+ while(curr_col > screen_cols) {
+ curr_col -= screen_cols;
+ if(!wraparound_mode)
+ curr_row++;
+ if(curr_row > scroll_region_end) {
+ scroll_up(curr_row - scroll_region_end);
+ curr_row = scroll_region_end;
+ }
+ }
+}
+
+void
+dispatch_escape(void) {
+ int len;
+ int pos;
+ int args[NPAR];
+ int narg = 0;
+ int digit;
+ int rows, cols;
+ int i;
+ int questionmark;
+ unsigned char c;
+
+ for(pos = 0; pos < NPAR; pos++)
+ args[pos] = 0;
+
+ c = cmdgetc();
+ switch(c) {
+ default:
+ fprintf(stderr, "Unsupported ESC sequence ESC %c\n", c);
+ break;
+ case '[': /* CSI */
+ digit = 0;
+ questionmark = 0;
+ c = cmdgetc();
+ while(isdigit(c) || c == ';' || c == '?') {
+ if(c == ';') {
+ args[narg] = 0;
+ digit = 0;
+ }
+ else {
+ if(c == '?')
+ questionmark = 1;
+ else {
+ if(!digit)
+ narg++;
+ digit = 1;
+ args[narg-1] *= 10;
+ args[narg-1] += c - '0';
+ }
+ }
+ c = cmdgetc();
+ }
+
+ switch(c) {
+ default:
+ fprintf(stderr, "Unsupported CSI sequence ESC [");
+ if(questionmark)
+ fprintf(stderr, " ?");
+ for(i = 0; i < narg; i++)
+ fprintf(stderr, " %d", args[i]);
+ fprintf(stderr, " %c\n", c);
+ break;
+ case 'A':
+ cursor_move_up(narg ? args[0] : 1);
+ break;
+ case 'B':
+ cursor_move_down(narg ? args[0] : 1);
+ break;
+ case 'C':
+ cursor_move_right(narg ? args[0] : 1);
+ break;
+ case 'D':
+ cursor_move_left(narg ? args[0] : 1);
+ break;
+ case 'G':
+ cursor_move_col(narg ? args[0] : 1);
+ break;
+ case 'H':
+ cursor_goto(args[1] ? args[1] : 1, args[0] ? args[0] : 1);
+ break;
+ case 'J':
+ if(narg) {
+ if(args[0] == 1) {
+ /* erase from start to cursor */
+ clear_area(1, 1, screen_cols, curr_row);
+ }
+ if(args[0] == 2) {
+ /* erase whole display */
+ clear_area(1, 1, screen_cols, screen_rows);
+ }
+ }
+ else {
+ /* erase from cursor to end of display */
+ clear_area(1, curr_row, screen_cols, screen_rows);
+ }
+ break;
+ case 'K':
+ if(narg) {
+ if(args[0] == 1) {
+ /* erase from start of line to cursor */
+ clear_area(1, curr_row, curr_col, curr_row);
+ }
+ if(args[0] == 2) {
+ /* erase whole line */
+ clear_area(1, curr_row, screen_cols, curr_row);
+ }
+ }
+ else {
+ /* erase from cursor to end of line */
+ clear_area(curr_col, curr_row, screen_cols, curr_row);
+ }
+ break;
+ case 'L': /* Insert lines */
+ insert_lines(narg ? args[0] : 1);
+ break;
+ case 'M': /* Delete lines */
+ delete_lines(narg ? args[0] : 1);
+ break;
+ case 'd': /* line position absolute */
+ cursor_move_row(narg ? args[0] : 1);
+ break;
+ case 'P': /* clear # of characters */
+ clear_area(curr_col, curr_row, curr_col + args[0], curr_row);
+ break;
+ case 'h': /* set mode */
+ switch(args[0]) {
+ default:
+ fprintf(stderr, "Unsupported ESC [%s h mode %d\n",
+ questionmark?" ?":"",
+ args[0]);
+ break;
+ case 1:
+ if(questionmark)
+ /* DEC CKM mode */
+ decckm_mode = 1;
+ break;
+ case 4:
+ if(!questionmark)
+ /* insert mode */
+ insert_mode = 1;
+ break;
+ case 7:
+ if(questionmark)
+ wraparound_mode = 1;
+ break;
+ case 25:
+ if(questionmark)
+ cursor_visible = 1;
+ break;
+ case 47:
+ if(questionmark) {
+ using_alternate_screen = 1;
+ save_current_screen();
+ }
+ break;
+ }
+ break;
+ case 'l': /* reset mode */
+ switch(args[0]) {
+ default:
+ fprintf(stderr, "Unsupported ESC [%s l mode %d\n",
+ questionmark?" ?":"",
+ args[0]);
+ break;
+ case 1:
+ if(questionmark)
+ /* DEC CKM mode */
+ decckm_mode = 0;
+ break;
+ case 4: /* insert mode */
+ insert_mode = 0;
+ break;
+ case 7:
+ if(questionmark)
+ wraparound_mode = 0;
+ break;
+ case 25:
+ if(questionmark)
+ cursor_visible = 0;
+ break;
+ case 47:
+ if(questionmark)
+ {
+ using_alternate_screen = 0;
+ restore_saved_screen();
+ }
+ break;
+ }
+ break;
+ case 'm':
+ /* reset attrs */
+ if(!narg) {
+ set_buffer_attrs(0);
+ set_buffer_fg_color(7);
+ set_buffer_reverse(0);
+ set_buffer_bg_color(0);
+ }
+ for(i = 0; i < narg; i++) {
+ if(args[i] == 0) {
+ set_buffer_attrs(0);
+ set_buffer_fg_color(7);
+ }
+ else if(args[i] == 1)
+ set_buffer_attrs(1);
+ else if(args[i] == 7)
+ set_buffer_reverse(1);
+ else if(args[i] == 27)
+ set_buffer_reverse(0);
+ else if(args[i] >= 30 && args[i] <= 37)
+ set_buffer_fg_color(args[i] - 30);
+ else if(args[i] >= 40 && args[i] <= 47)
+ set_buffer_bg_color(args[i] - 40);
+ else if(args[i] == 39)
+ set_buffer_fg_color(7);
+ else if(args[i] == 49)
+ set_buffer_bg_color(0);
+ else
+ fprintf(stderr, "Unsupported mode %d\n",
+ args[i]);
+ }
+ break;
+ case 'n':
+ /* status report */
+ {
+ char buf[20];
+ switch(args[0]) {
+ default:
+ fprintf(stderr, "Unknown status request id %d\n", args[0]);
+ break;
+ case 6:
+ /* cursor position */
+ snprintf(buf, sizeof(buf), "\033[%d;%dR",
+ curr_row, curr_col);
+ cmd_write(buf, strlen(buf));
+ break;
+ }
+ }
+ break;
+ case 'r': /* set scrolling region */
+ scroll_region_start = args[0] ? args[0] : 1;
+ scroll_region_end = args[1] ? args[1] : screen_rows;
+ if(!narg)
+ /* Reset scroll region */
+ scroll_in_region = 0;
+ else if(args[0] == 1 && args[1] == screen_rows)
+ scroll_in_region = 0;
+ else
+ scroll_in_region = 1;
+ break;
+ case '[': /* echoed function key */
+ cmdgetc();
+ break;
+ }
+ break;
+ case ']': /* xterm sequence */
+ digit = 0;
+ c = cmdgetc();
+ while(isdigit(c)) {
+ if(!digit)
+ narg++;
+ digit = 1;
+ args[narg-1] *= 10;
+ args[narg-1] += c - '0';
+ c = cmdgetc();
+ }
+ if(c != ';' || !narg) {
+ fprintf(stderr, "Invalid xterm sequence\n");
+ break;
+ }
+ xterm_seq(args[0]);
+ break;
+ case '7': /* save cursor position */
+ saved_cursor_x = curr_col;
+ saved_cursor_y = curr_row;
+ break;
+ case '8': /* restore cursor position */
+ curr_col = saved_cursor_x;
+ curr_row = saved_cursor_y;
+ break;
+ case '=': /* set application keypad mode */
+ application_keypad_mode = 1;
+ break;
+ case '>': /* set numeric keypad mode */
+ application_keypad_mode = 0;
+ break;
+ case 'M': /* reverse linefeed */
+ curr_row--;
+ if(curr_row < scroll_region_start) {
+ curr_row = scroll_region_start;
+ scroll_down(1);
+ }
+ break;
+ }
+}
Received on Fri Mar 02 2007 - 15:57:19 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:56:22 UTC