diff --git a/Makefile b/Makefile index b669a204..5b73ac8f 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ WARNS = -Werror -Wall -Wextra -Wno-unused-parameter -Wno-unused-but-set-variable LIBS = -lxml2 -lexpat -lssl -lresolv -lncurses -L ~/lib -lstrophe CFLAGS = -I ~/include -O3 $(WARNS) $(LIBS) OBJS = log.o windows.o title_bar.o status_bar.o input_win.o jabber.o \ - profanity.o util.o command.o main.o + profanity.o util.o command.o input_buffer.o main.o profanity: $(OBJS) $(CC) -o profanity $(OBJS) $(LIBS) @@ -14,9 +14,10 @@ title_bar.o: windows.h status_bar.o: windows.h util.h input_win.o: windows.h jabber.o: jabber.h log.h windows.h -profanity.o: log.h windows.h jabber.h command.h +profanity.o: log.h windows.h jabber.h command.h input_buffer.h util.o: util.h -command.o: command.h util.h +command.o: command.h util.h input_buffer.h +input_buffer.o: input_buffer.h main.o: log.h windows.h profanity.h .PHONY: clean diff --git a/command.c b/command.c index f76f0948..1b1368aa 100644 --- a/command.c +++ b/command.c @@ -24,6 +24,7 @@ #include #include #include "command.h" +#include "input_buffer.h" #include "jabber.h" #include "windows.h" #include "util.h" @@ -41,6 +42,9 @@ int process_input(char *inp) { int result = FALSE; + if (strlen(inp) > 0) + inpbuf_append(inp); + if (strlen(inp) == 0) { result = TRUE; } else if (inp[0] == '/') { diff --git a/command.h b/command.h index 93f11203..7efc4acf 100644 --- a/command.h +++ b/command.h @@ -23,6 +23,7 @@ #ifndef COMMAND_H #define COMMAND_H +void cmd_init(void); int process_input(char *inp); #endif diff --git a/input_buffer.c b/input_buffer.c new file mode 100644 index 00000000..42eecfd4 --- /dev/null +++ b/input_buffer.c @@ -0,0 +1,54 @@ +/* + * input_buffer.c + * + * Copyright (C) 2012 James Booth + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see . + * + */ + +#include + +#define BUFMAX 100 + +static char *_inp_buf[BUFMAX]; +static int _buf_size; +static int _buf_prev; + +void inpbuf_init(void) +{ + _buf_size = 0; + _buf_prev = -1; +} + +void inpbuf_append(char *inp) +{ + if (_buf_size < BUFMAX) { + _inp_buf[_buf_size] = (char*) malloc(strlen(inp) * sizeof(char)); + strcpy(_inp_buf[_buf_size], inp); + _buf_prev = _buf_size; + _buf_size++; + } +} + +char *inp_buf_get_previous(void) +{ + if (_buf_size == 0 || _buf_prev == -1) + return NULL; + return _inp_buf[_buf_prev--]; +} + + diff --git a/input_buffer.h b/input_buffer.h new file mode 100644 index 00000000..a2008859 --- /dev/null +++ b/input_buffer.h @@ -0,0 +1,31 @@ +/* + * input_buffer.h + * + * Copyright (C) 2012 James Booth + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see . + * + */ + + +#ifndef INPUT_BUFFER_H +#define INPUT_BUFFER_H + +void inpbuf_init(void); +void inpbuf_append(char *inp); +char *inp_buf_get_previous(void); + +#endif diff --git a/input_win.c b/input_win.c index 97a89dca..94c4d203 100644 --- a/input_win.c +++ b/input_win.c @@ -23,6 +23,7 @@ #include #include #include "windows.h" +#include "input_buffer.h" static WINDOW *inp_win; @@ -41,6 +42,7 @@ void inp_clear(void) { wclear(inp_win); wmove(inp_win, 0, 1); + touchwin(inp_win); wrefresh(inp_win); } @@ -55,12 +57,21 @@ void inp_block(void) } /* + * Non blocking input char handling + * + * *size - holds the current size of input + * *input - holds the current input string + * *ch - getch will put a charater here if there was any input + * + * The example below shows the values of size, input, a call to wgetyx to + * find the current cursor location, and the index if the input string. + * * size : " 7 " * input : " example " * inp_x : "012345678" * index : " 0123456 " (inp_x - 1) */ -void inp_poll_char(int *ch, char *command, int *size) +void inp_poll_char(int *ch, char *input, int *size) { int inp_y = 0; int inp_x = 0; @@ -77,9 +88,25 @@ void inp_poll_char(int *ch, char *command, int *size) if (*ch == 127) { if (*size > 0) { getyx(inp_win, inp_y, inp_x); - wmove(inp_win, inp_y, inp_x-1); - wdelch(inp_win); - (*size)--; + + // if at end, delete last char + if (inp_x > *size) { + wmove(inp_win, inp_y, inp_x-1); + wdelch(inp_win); + (*size)--; + + // if in middle, delete and shift chars left + } else if (inp_x > 1 && inp_x <= *size) { + int i; + for (i = inp_x-1; i < *size; i++) + input[i-1] = input[i]; + (*size)--; + + inp_clear(); + for (i = 0; i < *size; i++) + waddch(inp_win, input[i]); + wmove(inp_win, 0, inp_x -1); + } } // left arrow @@ -96,6 +123,18 @@ void inp_poll_char(int *ch, char *command, int *size) wmove(inp_win, inp_y, inp_x+1); } + // up arrow + } else if (*ch == KEY_UP) { + char *prev = inp_buf_get_previous(); + if (prev) { + strcpy(input, prev); + *size = strlen(input); + inp_clear(); + int i; + for (i = 0; i < *size; i++) + waddch(inp_win, input[i]); + } + // else if not error, newline or special key, // show it and store it } else if (*ch != ERR && @@ -124,15 +163,15 @@ void inp_poll_char(int *ch, char *command, int *size) int i; for (i = *size; i > inp_x -1; i--) - command[i] = command[i-1]; - command[inp_x -1] = *ch; + input[i] = input[i-1]; + input[inp_x -1] = *ch; (*size)++; // otherwise just append } else { waddch(inp_win, *ch); - command[(*size)++] = *ch; + input[(*size)++] = *ch; } } diff --git a/jabber.c b/jabber.c index 18a2df17..693b946d 100644 --- a/jabber.c +++ b/jabber.c @@ -65,7 +65,7 @@ static int _jabber_message_handler(xmpp_conn_t * const conn, static int _roster_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); -void init_jabber(int disable_tls) +void jabber_init(int disable_tls) { jabber_conn.conn_status = JABBER_STARTED; jabber_conn.tls_disabled = disable_tls; diff --git a/jabber.h b/jabber.h index a50d1734..4bffc56a 100644 --- a/jabber.h +++ b/jabber.h @@ -30,7 +30,7 @@ typedef enum { JABBER_DISCONNECTED } jabber_status_t; -void init_jabber(int disable_tls); +void jabber_init(int disable_tls); jabber_status_t jabber_connection_status(void); jabber_status_t jabber_connect(char *user, char *passwd); void jabber_disconnect(void); diff --git a/profanity.c b/profanity.c index 063a7d6f..d9fbd257 100644 --- a/profanity.c +++ b/profanity.c @@ -30,15 +30,22 @@ #include "windows.h" #include "jabber.h" #include "command.h" +#include "input_buffer.h" static void _profanity_event_loop(int *ch, char *cmd, int *size); static void _process_special_keys(int *ch); +static void profanity_init(int disable_tls) +{ + jabber_init(disable_tls); + inpbuf_init(); +} + void profanity_main(int disable_tls) { int cmd_result = TRUE; - init_jabber(disable_tls); + profanity_init(disable_tls); inp_non_block(); while(cmd_result == TRUE) { diff --git a/windows.h b/windows.h index f12f7773..0b478952 100644 --- a/windows.h +++ b/windows.h @@ -78,7 +78,7 @@ void status_bar_active(int win); void status_bar_update_time(void); // input window actions -void inp_poll_char(int *ch, char command[], int *size); +void inp_poll_char(int *ch, char *input, int *size); void inp_clear(void); void inp_put_back(void); void inp_non_block(void);