Beispiel #1
0
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{
    ChatContext *ctx = self->chatwin;

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    if (x2 <= 0)
        return;

    /* ignore non-menu related input if active */
    if (self->help->active) {
        help_onKey(self, key);
        return;
    }

    if (ltr) {    /* char is printable */
        input_new_char(self, key, x, y, x2, y2);
        return;
    }

    if (line_info_onKey(self, key))
        return;

    input_handle(self, key, x, y, x2, y2);

    if (key == '\t') {    /* TAB key: auto-completes command */
        if (ctx->len > 1 && ctx->line[0] == '/') {
            int diff = -1;

            if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0)
                diff = dir_match(self, m, ctx->line, L"/avatar");
            else if (wcsncmp(ctx->line, L"/status ", wcslen(L"/status ")) == 0){
                const char status_cmd_list[3][8] = {
                  {"online"},
                  {"away"},
                  {"busy"},
                };
                diff = complete_line(self, status_cmd_list, 3, 8);
            } else
                diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);

            if (diff != -1) {
                if (x + diff > x2 - 1) {
                    int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
                    ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
                }
            } else {
                sound_notify(self, notif_error, 0, NULL);
            }
        } else {
            sound_notify(self, notif_error, 0, NULL);
        }
    } else if (key == '\n') {
        rm_trailing_spaces_buf(ctx);

        char line[MAX_STR_SIZE] = {0};

        if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
            memset(&line, 0, sizeof(line));

        if (!string_is_empty(line))
            add_line_to_hist(ctx);

        line_info_add(self, NULL, NULL, NULL, PROMPT, 0, 0, "%s", line);
        execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);

        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        reset_buf(ctx);
    }
}
Beispiel #2
0
static void groupchat_onDraw(ToxWindow *self, Tox *m)
{
    int x2, y2;
    getmaxyx(self->window, y2, x2);

    ChatContext *ctx = self->chatwin;

    line_info_print(self);
    wclear(ctx->linewin);

    curs_set(1);

    if (ctx->len > 0)
        mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);

    wclear(ctx->sidebar);
    mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);

    if (self->show_peerlist) {
        mvwvline(ctx->sidebar, 0, 0, ACS_VLINE, y2 - CHATBOX_HEIGHT);
        mvwaddch(ctx->sidebar, y2 - CHATBOX_HEIGHT, 0, ACS_BTEE);

        int num_peers = groupchats[self->num].num_peers;

        wmove(ctx->sidebar, 0, 1);
        wattron(ctx->sidebar, A_BOLD);
        wprintw(ctx->sidebar, "Peers: %d\n", num_peers);
        wattroff(ctx->sidebar, A_BOLD);

        mvwaddch(ctx->sidebar, 1, 0, ACS_LTEE);
        mvwhline(ctx->sidebar, 1, 1, ACS_HLINE, SIDEBAR_WIDTH - 1);

        int N = TOX_MAX_NAME_LENGTH;
        int maxlines = y2 - SDBAR_OFST - CHATBOX_HEIGHT;
        int i;

        for (i = 0; i < num_peers && i < maxlines; ++i) {
            wmove(ctx->sidebar, i + 2, 1);
            int peer = i + groupchats[self->num].side_pos;

            /* truncate nick to fit in side panel without modifying list */
            char tmpnck[TOX_MAX_NAME_LENGTH];
            int maxlen = SIDEBAR_WIDTH - 2;
            memcpy(tmpnck, &groupchats[self->num].peer_names[peer * N], maxlen);
            tmpnck[maxlen] = '\0';

            wprintw(ctx->sidebar, "%s\n", tmpnck);
        }
    }

    int y, x;
    getyx(self->window, y, x);
    (void) x;
    int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos);
    wmove(self->window, y + 1, new_x);

    wrefresh(self->window);

    if (self->help->active)
        help_onDraw(self);
}
Beispiel #3
0
static void redraw_view(struct view *view)
{
    wclear(view->win);
    redraw_view_from(view, 0);
}
Beispiel #4
0
/* Funzione poco chiara che gestisce il posizionamento delle navi sullo schermo */
int posiziona_navi() {
    int nave=0;
    int ch;
    int x=0,y=0,v=1;
    wprintw(score, "POSIZIONAMENTO NAVI\n"
            "Comandi: frecce: muovi nave\n"
            "         n: nave successiva\n"
            "         r: ruota nave\n"
            "         c: conferma disposizione\n");
    wrefresh(score);
    wclear(msg);
    wprintw(msg, "Posizionamento nave %d/%d\nNave di tipo %s", nave, numero_navi, navi[nave].name);
    wrefresh(msg);
    build_matrix(0);
    updateA();
    while ((ch=getch())) {
        switch(ch) {
        case KEY_LEFT:
            if (x>0) x--;
            break;
        case KEY_RIGHT:
            x++;
            if (!posiziona_nave(nave, y, x, v)) {
                x--;
            }
            break;
        case KEY_UP:
            if (y>0) y--;
            break;
        case KEY_DOWN:
            y++;
            if (!posiziona_nave(nave, y, x, v)) {
                y--;
            }
            break;
        case 'r':
            v = v ? 0 : 1;
            if (!posiziona_nave(nave, y, x, v)) {
                v = v ? 0 : 1;
            }
            break;
        case 'n':
            nave++;
            if (nave >= numero_navi) nave=0;
            x=navi[nave].x;
            y=navi[nave].y;
            v=navi[nave].orientamento;
            break;
        case 'c':
            if (build_matrix(0)>0) {
                wclear(msg);
                wprintw(msg, "Sono preseti delle collisioni: risolvere prima di confermare!\n");
                wrefresh(msg);
            } else {
                if (conferma("Confermare disposizione corrente ? \nNB: una volta confermata non sarà possibile\n effettuare ulteriori modifiche")) {
                    build_matrix(1);
                    return 1;
                }
            }
        }
        mvwprintw(msg, 0, 0, "Posizionamento nave %d/%d\nNave di tipo %s, rotazione %d", nave, numero_navi, navi[nave].name, v);
        wrefresh(msg);
        posiziona_nave(nave, y, x, v);
        build_matrix(0);
        updateA();
    }
    return 0;
}
Beispiel #5
0
/* This opens and handles the site options window. */
void HostWinEdit(void)
{
	int c, field;
	int needUpdate;
	char bmname[128];
	BookmarkPtr rsip;

	if (gCurHostListItem != NULL) {
		gEditHostWin = newwin(LINES, COLS, 0, 0);
		if (gEditHostWin == NULL)
			return;
	
		STRNCPY(bmname, gCurHostListItem->bookmarkName);
		
		/* Set the clear flag for the first update. */
		wclear(gEditHostWin);

		/* leaveok(gEditHostWin, TRUE);	* Not sure if I like this... */
		WAttr(gEditHostWin, kBold, 1);
		WAddCenteredStr(gEditHostWin, 0, "Bookmark Options");
		WAttr(gEditHostWin, kBold, 0);
		
		/* We'll be editing a copy of the current host's settings. */
		gEditRsi = *gCurHostListItem;

		EditHostWinDraw(kAllWindowItems, kNoHilite);
		field = 1;
		for (;;) {
			EditHostWinMsg("Select an item to edit by typing its corresponding letter.");
			c = wgetch(gEditHostWin);
			if (islower(c))
				c = toupper(c);
			if (!isupper(c))
				continue;
			if (c == 'X')
				break;
			field = c - 'A';
			needUpdate = 1;
			
			/* Hilite the current item to edit. */
			EditHostWinDraw(BIT(field), kHilite);
			switch(field) {
				case kNicknameEditWindowItem:
					EditHostWinMsg("Type a new bookmark name, or hit <RETURN> to continue.");
					EditHostWinGetStr(gEditRsi.bookmarkName, sizeof(gEditRsi.bookmarkName), kNotOkayIfEmpty, kGetAndEcho);
					break;
					
				case kHostnameEditWindowItem:
					EditHostWinMsg("Type a new hostname, or hit <RETURN> to continue.");
					EditHostWinGetStr(gEditRsi.name, sizeof(gEditRsi.name), kNotOkayIfEmpty, kGetAndEcho);
					gEditRsi.lastIP[0] = '\0';	/* In case it changed. */
					break;

				case kUserEditWindowItem:
					EditHostWinMsg("Type a username, or hit <RETURN> to signify anonymous.");
					EditHostWinGetStr(gEditRsi.user, sizeof(gEditRsi.user), kOkayIfEmpty, kGetAndEcho);
					break;

				case kPassEditWindowItem:
					EditHostWinMsg("Type a password, or hit <RETURN> if no password is required.");
					EditHostWinGetStr(gEditRsi.pass, sizeof(gEditRsi.pass), kOkayIfEmpty, kGetNoEcho);
					break;

				case kAcctEditWindowItem:
					EditHostWinMsg("Type an account name, or hit <RETURN> if no account is required.");
					EditHostWinGetStr(gEditRsi.acct, sizeof(gEditRsi.acct), kOkayIfEmpty, kGetAndEcho);
					break;

				case kDirEditWindowItem:
					EditHostWinMsg("Type a remote directory path to start in after a connection is established.");
					EditHostWinGetStr(gEditRsi.dir, sizeof(gEditRsi.dir), kOkayIfEmpty, kGetAndEcho);
					break;

				case kLDirEditWindowItem:
					EditHostWinMsg("Type a local directory path to start in after a connection is established.");
					EditHostWinGetStr(gEditRsi.ldir, sizeof(gEditRsi.ldir), kOkayIfEmpty, kGetAndEcho);
					break;

				case kXferTypeEditWindowItem:
					EditHostWinMsg(kToggleMsg);
					ToggleXferType();
					break;

				case kPortEditWindowItem:
					EditHostWinMsg("Type a port number to use for FTP.");
					EditHostWinGetNum((int *) &gEditRsi.port);
					break;

#if 0
				case kSizeEditWindowItem:
					EditHostWinMsg(kToggleMsg);
					EditWinToggle(&gEditRsi.hasSIZE, field, 0, 1);
					break;

				case kMdtmEditWindowItem:
					EditHostWinMsg(kToggleMsg);
					EditWinToggle(&gEditRsi.hasMDTM, field, 0, 1);
					break;

				case kPasvEditWindowItem:
					EditHostWinMsg(kToggleMsg);
					EditWinToggle(&gEditRsi.hasPASV, field, 0, 1);
					break;

				case kOSEditWindowItem:
					EditHostWinMsg(kToggleMsg);
					EditWinToggle(&gEditRsi.isUnix, field, 0, 1);
					break;
#endif

				case kCommentEditWindowItem:
					EditHostWinMsg("Enter a line of information to store about this site.");
					EditHostWinGetStr(gEditRsi.comment, sizeof(gEditRsi.comment), kOkayIfEmpty, kGetAndEcho);
					break;
				
				default:
					needUpdate = 0;
					break;
			}
			if (needUpdate)
				EditHostWinDraw(BIT(field), kNoHilite);
		}
		delwin(gEditHostWin);
		gEditHostWin = NULL;
		*gCurHostListItem = gEditRsi;

		SaveAndReload();
		/* Note:  newly reallocated array, modified gNumBookmarks */

		rsip = SearchBookmarkTable(bmname);
		if (rsip == NULL)
			rsip = &gBookmarkTable[0];
		gCurHostListItem = rsip;
		gHilitedHost = BMTINDEX(rsip);
		gHostListWinStart = BMTINDEX(rsip) - gHostListPageSize + 1;
		if (gHostListWinStart < 0)
			gHostListWinStart = 0;
		UpdateHostWindows(1);
	}
}	/* HostWinEdit */
Beispiel #6
0
int
hgd_update_console_win(struct ui *u)
{
	char		  buf[HGD_LOG_BACKBUFFER + 1], *start = buf, *end, *copy;
	long		  pos, endpos, read;
	long		  toread = HGD_LOG_BACKBUFFER;
	ITEM		**items = NULL;
	int		  cur_index = 0;

	DPRINTF(HGD_D_INFO, "Update console window");

	wclear(u->content_wins[HGD_WIN_CONSOLE]);
	hgd_unpost_and_free_content_menu(u, HGD_WIN_CONSOLE);

	memset(buf, 0, HGD_LOG_BACKBUFFER + 1);

	/* find how long the log is */
	if ((fseek(logs.rd, 0, SEEK_END)) != 0)
		DPRINTF(HGD_D_WARN, "fseek: %s", SERROR);

	endpos = ftell(logs.rd);
	if (endpos < HGD_LOG_BACKBUFFER)
		toread = endpos;

	/* rewind at most HGD_LOG_BACKBUFFER and read into buffer */
	if ((fseek(logs.rd, -toread, SEEK_END)) != 0)
		DPRINTF(HGD_D_WARN, "fseek: %s", SERROR);

	pos = ftell(logs.rd);
	if ((read = fread(buf, toread, 1, logs.rd)) == 0) {
		if (ferror(logs.rd)) {
		    DPRINTF(HGD_D_WARN,
			"Failed to read console log: %s", SERROR);
		}
	}

	/* ensure we dont start printing the middle of a line */
	if (pos < 0)
		DPRINTF(HGD_D_WARN, "ftell failed: %s", SERROR);
	else if (pos != 0) {
		/* if not at the start of file, find a \n */
		while ((*start != '\n') && (*start != '\0'))
			start++;
	}

	/* this SHOULD happen, but not guaraunteed */
	if (*start == '\n')
		start++;

	items = xcalloc(sizeof(ITEM *), 1);

	/* scan for lines and add them as menu items */
	end = start;
	while (*start != 0) {
		while ((*end != 0) && (*end != '\n'))
			end++;

		if (*end == 0) {
			DPRINTF(HGD_D_WARN, "Unexpected end of log");
			break;
		}
		*end = 0;

		/* could be more efficient */
		items = xrealloc(items, sizeof(ITEM *) * (cur_index + 2));
		items[cur_index + 1] = NULL;

		hgd_prepare_item_string(&copy, start);
		items[cur_index] = new_item(copy, NULL);

		if (items[cur_index] == NULL) {
			DPRINTF(HGD_D_WARN,
			    "Could not make new menu item '%s'", start);
			free(copy);
		}

		end++;
		start = end;

		if (items[cur_index] == NULL)
			continue;

		cur_index++;
	}

	/* now we have our items, make the menu */
	if (u->content_menus[HGD_WIN_CONSOLE] != NULL) {
		/* XXX clean up old menu */
	}

	u->content_menus[HGD_WIN_CONSOLE] = new_menu(items);

	keypad(u->content_wins[HGD_WIN_CONSOLE], TRUE);
	set_menu_win(u->content_menus[HGD_WIN_CONSOLE],
	    u->content_wins[HGD_WIN_CONSOLE]);
	set_menu_mark(u->content_menus[HGD_WIN_CONSOLE], "");
	set_menu_format(u->content_menus[HGD_WIN_CONSOLE],
	    LINES - 2, 1);
	set_menu_fore(u->content_menus[HGD_WIN_CONSOLE],
	    COLOR_PAIR(HGD_CPAIR_SELECTED));

	if ((post_menu(u->content_menus[HGD_WIN_CONSOLE])) != E_OK)
		DPRINTF(HGD_D_WARN, "Could not post menu");

	menu_driver(u->content_menus[HGD_WIN_CONSOLE], REQ_LAST_ITEM);

	return (HGD_OK);
}
Beispiel #7
0
int
hgd_ui_queue_track(struct ui *u, char *filename)
{
	char			*full_path = NULL;
	char			*title = "[ File Upload ]";
	int			 ret = HGD_FAIL;
	WINDOW			*bwin = NULL, *win = NULL, *bar = NULL;
	int			 x, y, h, w;
	char			*msg_centre;

	DPRINTF(HGD_D_INFO, "Upload track: %s", filename);

	xasprintf(&full_path, "%s/%s", u->cwd, filename);

	hgd_calc_dialog_win_dims(&y, &x, &h, &w);
	hgd_centre_dialog_text(&msg_centre, filename);

	if ((bwin = newwin(h + 2, w + 2, y - 1, x - 1)) == NULL) {
		DPRINTF(HGD_D_ERROR, "Could not initialise progress window");
		goto clean;
	}

	if ((win = newwin(h, w, y, x)) == NULL) {
		DPRINTF(HGD_D_ERROR, "Could not initialise progress window");
		goto clean;
	}

	wattron(win, COLOR_PAIR(HGD_CPAIR_DIALOG));
	wattron(bwin, COLOR_PAIR(HGD_CPAIR_DIALOG));

	wclear(win);
	wclear(bwin);

	wbkgd(win, COLOR_PAIR(HGD_CPAIR_DIALOG));
	wbkgd(bar, COLOR_PAIR(HGD_CPAIR_PBAR_BG));
	box(bwin, '|', '-');

	mvwprintw(bwin, 0, w / 2 - (strlen(title) / 2), title);
	mvwprintw(win, 1, 0, msg_centre);

	redrawwin(bwin);
	redrawwin(win);
	wrefresh(bwin);
	wrefresh(win);

	ret = hgd_cli_queue_track(full_path, u, hgd_ui_q_callback);

	/* XXX */
	//hgd_resize_app(u);
clean:
	if (full_path)
		free(full_path);

	if (ret == HGD_OK) 
		hgd_set_statusbar_text(u, "Upload of '%s' succesful", filename);
	else
		hgd_set_statusbar_text(u, "Upload of '%s' failed", filename);

	delwin(win);
	delwin(bwin);

	free(msg_centre);

	hgd_refresh_ui(u);

	return (ret);
}
Beispiel #8
0
static void execute(ToxWindow *self, ChatContext *ctx, StatusBar *statusbar, Tox *m, char *cmd)
{
    if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
        wclear(self->window);
        wclear(ctx->history);
        wprintw(ctx->history, "\n\n");
        int x, y;
        getmaxyx(self->window, y, x);
        (void) x;
        wmove(self->window, y - CURS_Y_OFFSET, 0);
    }

    else if (!strcmp(cmd, "/help") || !strcmp(cmd, "/h"))
        print_help(ctx);

    else if (!strcmp(cmd, "/quit") || !strcmp(cmd, "/exit") || !strcmp(cmd, "/q")) {
        exit_toxic(m);
    }

    else if (!strncmp(cmd, "/me ", strlen("/me "))) {
        struct tm *timeinfo = get_time();
        uint8_t *action = strchr(cmd, ' ');

        if (action == NULL) {
            wprintw(self->window, "Invalid syntax.\n");
            return;
        }

        action++;

        wattron(ctx->history, COLOR_PAIR(CYAN));
        wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
        wattroff(ctx->history, COLOR_PAIR(CYAN));

        uint8_t selfname[TOX_MAX_NAME_LENGTH];
        tox_getselfname(m, selfname, TOX_MAX_NAME_LENGTH);

        wattron(ctx->history, COLOR_PAIR(YELLOW));
        wprintw(ctx->history, "* %s %s\n", selfname, action);
        wattroff(ctx->history, COLOR_PAIR(YELLOW));

        if (!statusbar->is_online
                || tox_sendaction(m, self->friendnum, action, strlen(action) + 1) == 0) {
            wattron(ctx->history, COLOR_PAIR(RED));
            wprintw(ctx->history, " * Failed to send action\n");
            wattroff(ctx->history, COLOR_PAIR(RED));
        }
    }

    else if (!strncmp(cmd, "/status ", strlen("/status "))) {
        char *status = strchr(cmd, ' ');

        if (status == NULL) {
            wprintw(ctx->history, "Invalid syntax.\n");
            return;
        }

        status++;
        TOX_USERSTATUS status_kind;

        if (!strncmp(status, "online", strlen("online"))) {
            status_kind = TOX_USERSTATUS_NONE;
            wprintw(ctx->history, "Status set to: ");
            wattron(ctx->history, COLOR_PAIR(GREEN) | A_BOLD);
            wprintw(ctx->history, "[Online]\n");
            wattroff(ctx->history, COLOR_PAIR(GREEN) | A_BOLD);
        }

        else if (!strncmp(status, "away", strlen("away"))) {
            status_kind = TOX_USERSTATUS_AWAY;
            wprintw(ctx->history, "Status set to: ");
            wattron(ctx->history, COLOR_PAIR(YELLOW) | A_BOLD);
            wprintw(ctx->history, "[Away]\n");
            wattroff(ctx->history, COLOR_PAIR(YELLOW) | A_BOLD);
        }

        else if (!strncmp(status, "busy", strlen("busy"))) {
            status_kind = TOX_USERSTATUS_BUSY;
            wprintw(ctx->history, "Status set to: ");
            wattron(ctx->history, COLOR_PAIR(RED) | A_BOLD);
            wprintw(ctx->history, "[Busy]\n");
            wattroff(ctx->history, COLOR_PAIR(RED) | A_BOLD);
        }

        else {
            wprintw(ctx->history, "Invalid status.\n");
            return;
        }

        tox_set_userstatus(m, status_kind);
        prompt_update_status(self->prompt, status_kind); 

        uint8_t *msg = strchr(status, ' ');
        if (msg != NULL) {
            msg++;
            uint16_t len = strlen(msg) + 1;
            tox_set_statusmessage(m, msg, len);
            prompt_update_statusmessage(self->prompt, msg, len);
            wprintw(ctx->history, "Personal note set to: %s\n", msg);
        }
    }

    else if (!strncmp(cmd, "/note ", strlen("/note "))) {
        uint8_t *msg = strchr(cmd, ' ');
        msg++;
        uint16_t len = strlen(msg) + 1;
        tox_set_statusmessage(m, msg, len);
        prompt_update_statusmessage(self->prompt, msg, len);
        wprintw(ctx->history, "Personal note set to: %s\n", msg);
    }

    else if (!strncmp(cmd, "/nick ", strlen("/nick "))) {
        uint8_t *nick = strchr(cmd, ' ');

        if (nick == NULL) {
            wprintw(ctx->history, "Invalid syntax.\n");
            return;
        }

        nick++;
        tox_setname(m, nick, strlen(nick) + 1);
        prompt_update_nick(self->prompt, nick);
        wprintw(ctx->history, "Nickname set to: %s\n", nick);
    }

    else if (!strcmp(cmd, "/myid")) {
        char id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1] = {'\0'};
        size_t i;
        uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
        tox_getaddress(m, address);

        for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) {
            char xx[3];
            snprintf(xx, sizeof(xx), "%02X",  address[i] & 0xff);
            strcat(id, xx);
        }

        wprintw(ctx->history, "%s\n", id);
    }

    else
        wprintw(ctx->history, "Invalid command.\n");
}
Beispiel #9
0
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    ChatContext *ctx = (ChatContext *) self->x;
    StatusBar *statusbar = (StatusBar *) self->s;

    struct tm *timeinfo = get_time();

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    /* Add printable chars to buffer and print on input space */
#if HAVE_WIDECHAR
    if (iswprint(key)) {
#else
    if (isprint(key)) {
#endif
        if (ctx->pos < (MAX_STR_SIZE-1)) {
            mvwaddstr(self->window, y, x, wc_to_char(key));
            ctx->line[ctx->pos++] = key;
            ctx->line[ctx->pos] = L'\0';
        }
    }

    /* BACKSPACE key: Remove one character from line */
    else if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            ctx->line[--ctx->pos] = L'\0';

            if (x == 0)
                mvwdelch(self->window, y - 1, x2 - 1);
            else
                mvwdelch(self->window, y, x - 1);
        }
    }

    /* RETURN key: Execute command or print line */
    else if (key == '\n') {
        uint8_t *line = wcs_to_char(ctx->line);
        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        wclrtobot(self->window);
        bool close_win = false;

        if (line[0] == '/') {
            if (close_win = !strncmp(line, "/close", strlen("/close"))) {
                int f_num = self->friendnum;
                delwin(ctx->linewin);
                delwin(statusbar->topline);
                del_window(self);
                disable_chatwin(f_num);
            } else
                execute(self, ctx, statusbar, m, line);
        } else {
            /* make sure the string has at least non-space character */
            if (!string_is_empty(line)) {
                uint8_t selfname[TOX_MAX_NAME_LENGTH];
                tox_getselfname(m, selfname, TOX_MAX_NAME_LENGTH);

                wattron(ctx->history, COLOR_PAIR(CYAN));
                wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
                wattroff(ctx->history, COLOR_PAIR(CYAN));
                wattron(ctx->history, COLOR_PAIR(GREEN));
                wprintw(ctx->history, "%s: ", selfname);
                wattroff(ctx->history, COLOR_PAIR(GREEN));
                wprintw(ctx->history, "%s\n", line);

                if (!statusbar->is_online
                        || tox_sendmessage(m, self->friendnum, line, strlen(line) + 1) == 0) {
                    wattron(ctx->history, COLOR_PAIR(RED));
                    wprintw(ctx->history, " * Failed to send message.\n");
                    wattroff(ctx->history, COLOR_PAIR(RED));
                }
            }
        }

        if (close_win) {
            free(ctx);
            free(statusbar);
        } else {
            ctx->line[0] = L'\0';
            ctx->pos = 0;
        }

        free(line);
    }
}

static void chat_onDraw(ToxWindow *self, Tox *m)
{
    curs_set(1);

    int x, y;
    getmaxyx(self->window, y, x);

    ChatContext *ctx = (ChatContext *) self->x;

    /* Draw status bar */
    StatusBar *statusbar = (StatusBar *) self->s;
    mvwhline(statusbar->topline, 1, 0, '-', x);
    wmove(statusbar->topline, 0, 0);

    /* Draw name, status and note in statusbar */
    if (statusbar->is_online) {
        char *status_text = "Unknown";
        int colour = WHITE;

        TOX_USERSTATUS status = statusbar->status;

        switch(status) {
        case TOX_USERSTATUS_NONE:
            status_text = "Online";
            colour = GREEN;
            break;
        case TOX_USERSTATUS_AWAY:
            status_text = "Away";
            colour = YELLOW;
            break;
        case TOX_USERSTATUS_BUSY:
            status_text = "Busy";
            colour = RED;
            break;
        }

        wattron(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, " %s ", self->name);
        wattroff(statusbar->topline, A_BOLD);
        wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
        wprintw(statusbar->topline, "[%s]", status_text);
        wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);

    } else {
        wattron(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, " %s ", self->name);
        wattroff(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, "[Offline]");
    }

    /* Truncate note if it doesn't fit in statusbar */
    uint16_t maxlen = x - getcurx(statusbar->topline) - 5;
    if (statusbar->statusmsg_len > maxlen) {
        statusbar->statusmsg[maxlen] = '\0';
        statusbar->statusmsg_len = maxlen;
    }

    wattron(statusbar->topline, A_BOLD);
    wprintw(statusbar->topline, " | %s |", statusbar->statusmsg);
    wattroff(statusbar->topline, A_BOLD);

    wprintw(statusbar->topline, "\n");

    mvwhline(ctx->linewin, 0, 0, '_', x);
    wrefresh(self->window);
}
void MapEditor::printwdlg(std::string str) {
    wclear(wdlg);
    mvwprintw(wdlg, 0, 0, str.c_str());
    wrefresh(wdlg);
}
Beispiel #11
0
void OEditor::SendMessage(char *msg) {
  wclear(msgWin);
  wprintw(msgWin, "%s", msg);
  wrefresh(msgWin);
}
Beispiel #12
0
int clear(void)
{
    PDC_LOG(("clear() - called\n"));

    return wclear(stdscr);
}
Beispiel #13
0
int
cmdsensors(const char *cmd, char *args)
{
	if (prefix(cmd, "type")) {
		const char *t;
		int i, has_type = 0;

		for (i = 0; i < SENSOR_MAX_TYPES; ++i)
			sensors_enabled[i] = 0;

		while ((t = strsep(&args, " ")) != NULL) {
			if (*t == '\0')
				continue;

			has_type = 1;
			for (i = 0; i < SENSOR_MAX_TYPES; ++i) {
				if (strcmp(t, sensor_type_s[i]) == 0) {
					sensors_enabled[i] = 1;
					break;
				}
			}
		}

		if (!has_type) {
			for (i = 0; i < SENSOR_MAX_TYPES; ++i)
				sensors_enabled[i] = 1;
		}
	} else if (prefix(cmd, "match")) {
		const char *xname;

		sensordev_xname_cnt = 0;
		while ((xname = strsep(&args, " ")) != NULL) {
			struct sensordev_xname *x;
			int xname_len, cp_len;

			xname_len = strlen(xname);
			if (xname_len == 0)
				continue;

			x = &sensordev_xname[sensordev_xname_cnt];
			x->flags = 0;

			if (xname[xname_len - 1] == '*') {
				--xname_len;
				if (xname_len == 0)
					continue;
				x->flags |= XNAME_FLAG_WILDCARD;
			}
			cp_len = xname_len;
			if (cp_len >= (int)sizeof(x->xname))
				cp_len = sizeof(x->xname) - 1;

			memcpy(x->xname, xname, cp_len);
			x->xname[cp_len] = '\0';
			x->xname_len = strlen(x->xname);

			sensordev_xname_cnt++;
			if (sensordev_xname_cnt == XNAME_MAX)
				break;
		}
	}

	wclear(wnd);
	labelsensors();
	refresh();
	return (1);
}
Beispiel #14
0
static void prompt_onDraw(ToxWindow *self, Tox *m)
{
    int x2, y2;
    getmaxyx(self->window, y2, x2);

    ChatContext *ctx = self->chatwin;

    pthread_mutex_lock(&Winthread.lock);
    line_info_print(self);
    pthread_mutex_unlock(&Winthread.lock);

    wclear(ctx->linewin);

    curs_set(1);

    if (ctx->len > 0)
        mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);

    StatusBar *statusbar = self->stb;

    mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2);
    wmove(statusbar->topline, 0, 0);

    pthread_mutex_lock(&Winthread.lock);
    TOX_CONNECTION connection = statusbar->connection;
    pthread_mutex_unlock(&Winthread.lock);

    if (connection != TOX_CONNECTION_NONE) {
        int colour = MAGENTA;
        const char *status_text = "ERROR";

        pthread_mutex_lock(&Winthread.lock);
        TOX_USER_STATUS status = statusbar->status;
        pthread_mutex_unlock(&Winthread.lock);

        switch (status) {
            case TOX_USER_STATUS_NONE:
                status_text = "Online";
                colour = GREEN;
                break;
            case TOX_USER_STATUS_AWAY:
                status_text = "Away";
                colour = YELLOW;
                break;
            case TOX_USER_STATUS_BUSY:
                status_text = "Busy";
                colour = RED;
                break;
        }

        wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
        wprintw(statusbar->topline, " [%s]", status_text);
        wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);

        wattron(statusbar->topline, A_BOLD);
        pthread_mutex_lock(&Winthread.lock);
        wprintw(statusbar->topline, " %s", statusbar->nick);
        pthread_mutex_unlock(&Winthread.lock);
        wattroff(statusbar->topline, A_BOLD);
    } else {
        wprintw(statusbar->topline, " [Offline]");
        wattron(statusbar->topline, A_BOLD);
        pthread_mutex_lock(&Winthread.lock);
        wprintw(statusbar->topline, " %s", statusbar->nick);
        pthread_mutex_unlock(&Winthread.lock);
        wattroff(statusbar->topline, A_BOLD);
    }

    /* Reset statusbar->statusmsg on window resize */
    if (x2 != self->x) {
        char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH];

        pthread_mutex_lock(&Winthread.lock);
        size_t slen = tox_self_get_status_message_size(m);
        tox_self_get_status_message (m, (uint8_t*) statusmsg);
        statusmsg[slen] = '\0';
        snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
        statusbar->statusmsg_len = strlen(statusbar->statusmsg);
        pthread_mutex_unlock(&Winthread.lock);
    }

    self->x = x2;

    /* Truncate note if it doesn't fit in statusbar */
    uint16_t maxlen = x2 - getcurx(statusbar->topline) - 3;

    pthread_mutex_lock(&Winthread.lock);

    if (statusbar->statusmsg_len > maxlen) {
        statusbar->statusmsg[maxlen - 3] = '\0';
        strcat(statusbar->statusmsg, "...");
        statusbar->statusmsg_len = maxlen;
    }

    if (statusbar->statusmsg[0])
        wprintw(statusbar->topline, " : %s", statusbar->statusmsg);

    pthread_mutex_unlock(&Winthread.lock);

    mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);

    int y, x;
    getyx(self->window, y, x);
    (void) x;

    int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
    wmove(self->window, y + 1, new_x);

    wrefresh(self->window);

    if (self->help->active)
        help_onDraw(self);
}
Beispiel #15
0
int
hgd_update_playlist_win(struct ui *u)
{
	ITEM			**items = NULL;
	int			  i, ret = HGD_FAIL;
	char			 *item_str;
	struct hgd_playlist	 *playlist = NULL;
	char			 *track_str;

	DPRINTF(HGD_D_INFO, "Update playlist window");

	hgd_set_statusbar_text(u, "Connected >>> Fetching playlist");

	if (sock_fd == -1) {
		ret = HGD_OK;
		goto clean;
	}

	wclear(u->content_wins[HGD_WIN_PLAYLIST]);
	hgd_unpost_and_free_content_menu(u, HGD_WIN_PLAYLIST);

	/* and now populate the menu */
	if (hgd_cli_get_playlist(&playlist) != HGD_OK) {
		goto clean;
	}

	if (playlist->n_items == 0) {
		ret = HGD_OK;
		mvwprintw(u->content_wins[HGD_WIN_PLAYLIST], 0, 0, "Playlist Empty - Saddest of times!");
		goto clean;
	}

	items = xcalloc(playlist->n_items + 1, sizeof(ITEM *));
	for (i = 0; i < playlist->n_items; i++) {

		DPRINTF(HGD_D_DEBUG, "Adding item \"%s\"",
		    playlist->items[i]->tags.title);

		if ((strcmp(playlist->items[i]->tags.artist, "")) ||
		    (strcmp(playlist->items[i]->tags.title, ""))) {

			xasprintf(&track_str, "#%03d from %-8s: '%s' by '%s'",
			    playlist->items[i]->id,
			    playlist->items[i]->user,
			    playlist->items[i]->tags.title,
			    playlist->items[i]->tags.artist);
		} else  {
			xasprintf(&track_str, "#%03d from %-8s: '%s'",
			    playlist->items[i]->id,
			    playlist->items[i]->user,
			    playlist->items[i]->filename);
		}

		hgd_prepare_item_string(&item_str, track_str);
		free(track_str);

		items[i] = new_item(item_str, NULL);
		if (items[i] == NULL)
			DPRINTF(HGD_D_WARN, "Could not make new item: %s", SERROR);
	}

	u->content_menus[HGD_WIN_PLAYLIST] = new_menu(items);
	if (u->content_menus[HGD_WIN_PLAYLIST] == NULL) {
			DPRINTF(HGD_D_ERROR, "Could not make menu");
			goto clean;
	}

	set_menu_win(u->content_menus[HGD_WIN_PLAYLIST],
	    u->content_wins[HGD_WIN_PLAYLIST]);
	set_menu_mark(u->content_menus[HGD_WIN_PLAYLIST], "");
	set_menu_format(u->content_menus[HGD_WIN_PLAYLIST], LINES - 2, 1);
	set_menu_fore(u->content_menus[HGD_WIN_PLAYLIST],
	    COLOR_PAIR(HGD_CPAIR_SELECTED));

	if ((post_menu(u->content_menus[HGD_WIN_PLAYLIST])) != E_OK) {
		DPRINTF(HGD_D_ERROR, "Could not post menu");
		goto clean;
	}

	hgd_set_standard_statusbar_text(u);

	ret = HGD_OK;
clean:
	if (playlist)
		hgd_free_playlist(playlist);
#if 0
	if (items)
		free(items);
#endif
	if (playlist)
		free(playlist);

	return (ret);
}
const char* Sys_ConsoleInput()
{
	if (!didWeHaveConsole)
	{
		ShowConsolePrompt();
		wrefresh(inputWindow);
		didWeHaveConsole = true;
	}

	int currentTime = GetTickCount();
	if ((currentTime - lastRefresh) > 250)
	{
		RefreshOutput();
		lastRefresh = currentTime;
	}

	UpdateConsoleStatus();

	int c = wgetch(inputWindow);

	if (c == ERR)
	{
		return NULL;
	}

	switch (c)
	{
		case '\r':
			wattron(outputWindow, COLOR_PAIR(10) | A_BOLD);
			wprintw(outputWindow, "]%s\n", consoleLineBuffer);
			wattroff(outputWindow, A_BOLD);
			wclear(inputWindow);
			ShowConsolePrompt();
			wrefresh(inputWindow);
			
			ScrollOutput(1);
			RefreshOutput();

			if (consoleLineBufferIndex)
			{
				strcpy(consoleLineBuffer2, consoleLineBuffer);
				strcat(consoleLineBuffer, "\n");
				consoleLineBufferIndex = 0;
				return consoleLineBuffer;
			}

			break;
		case 'c' - 'a' + 1: // ctrl-c
		case 27:
			consoleLineBuffer[0] = '\0';
			consoleLineBufferIndex = 0;
			wclear(inputWindow);
			ShowConsolePrompt();
			wrefresh(inputWindow);
			break;
		case 8: // backspace
			if (consoleLineBufferIndex > 0)
			{
				consoleLineBufferIndex--;
				consoleLineBuffer[consoleLineBufferIndex] = '\0';

				wprintw(inputWindow, "%c %c", (char)c, (char)c);
				wrefresh(inputWindow);
			}
			break;
		case KEY_PPAGE:
			ScrollOutput(-1);
			RefreshOutput();
			break;
		case KEY_NPAGE:
			ScrollOutput(1);
			RefreshOutput();
			break;
		case KEY_UP:
			wclear(inputWindow);
			ShowConsolePrompt();
			wprintw(inputWindow, "%s", consoleLineBuffer2);
			wrefresh(inputWindow);

			strcpy(consoleLineBuffer, consoleLineBuffer2);
			consoleLineBufferIndex = strlen(consoleLineBuffer);
			break;
		default:
			if (c <= 127 && consoleLineBufferIndex < 1022)
			{
				// temporary workaround for issue #9, find out what overwrites our index later on
				consoleLineBufferIndex = strlen(consoleLineBuffer);

				consoleLineBuffer[consoleLineBufferIndex++] = (char)c;
				consoleLineBuffer[consoleLineBufferIndex] = '\0';
				wprintw(inputWindow, "%c", (char)c);
				wrefresh(inputWindow);
			}
			break;
	}

	return NULL;
}
Beispiel #17
0
int
hgd_update_files_win(struct ui *u)
{
	ITEM			**items = NULL;
	char			 *slash_append, *prep_item_str;
	struct dirent		**dirents_dirs = 0, **dirents_files = 0, *d, *d_copy;
	int			  n_dirs = 0, n_files = 0;
	int			  i, cur_item = 0, ret = HGD_FAIL;

	DPRINTF(HGD_D_INFO, "Update files window");

	wclear(u->content_wins[HGD_WIN_FILES]);
	hgd_unpost_and_free_content_menu(u, HGD_WIN_FILES);

	if ((n_dirs = scandir(
	    u->cwd, &dirents_dirs, hgd_filter_dirs, alphasort)) < 0) {
		 DPRINTF(HGD_D_WARN, "Failed to scan directory: '%s'", u->cwd);
		 goto clean;
	}

	if ((n_files = scandir(
	    u->cwd, &dirents_files, hgd_filter_files, alphasort)) < 0) {
		 DPRINTF(HGD_D_WARN, "Failed to scan directory: '%s'", u->cwd);
		 goto clean;
	}

	/* make our menu items */
	DPRINTF(HGD_D_INFO, "allocating %d menu items", n_files + n_dirs);
	items = xcalloc(n_files + n_dirs + 1, sizeof(ITEM *));

	/* add dirs */
	for (i = 0; i < n_dirs; i++) {
		d = dirents_dirs[i];

		xasprintf(&slash_append, "%s/", d->d_name);
		hgd_prepare_item_string(&prep_item_str, slash_append);
		free(slash_append);

		items[cur_item] = new_item(prep_item_str, NULL);

		if (items[cur_item] == NULL) {
			DPRINTF(HGD_D_WARN,
			    "Could not make new menu item: %s", SERROR);
			free(prep_item_str);
			continue;
		}

		/*
		 * jam away the dirent for later use
		 * Note! scandir does notallocate a full struct dirent
		 */
#if !defined(__linux__)
		d_copy = xcalloc(1, sizeof(struct dirent));
		d_copy->d_fileno = d->d_fileno;2
		d_copy->d_reclen = d->d_reclen;
		d_copy->d_type = d->d_type;
		d_copy->d_namlen = d->d_namlen;
		strlcpy(d_copy->d_name, d->d_name, d->d_namlen + 1);
#else
		d_copy = xcalloc(1, d->d_reclen);
		memcpy(d_copy, d, d->d_reclen);
#endif

		set_item_userptr(items[cur_item], d_copy);

		cur_item++;
	}

	/* add files */
	for (i = 0; i < n_files; i++) {
		d = dirents_files[i];

		hgd_prepare_item_string(&prep_item_str, d->d_name);

		items[cur_item] = new_item(prep_item_str, NULL);

		if (items[cur_item] == NULL) {
			DPRINTF(HGD_D_WARN,
			    "Could not make new menu item: %s", SERROR);
			free(prep_item_str);
			continue;
		}

		/*
		 * copy manually, do not use memcpy, as scandir does not
		 * allocate a full struct dirent
		 */
#if !defined(__linux__)
		d_copy = xcalloc(1, sizeof(struct dirent));
		d_copy->d_fileno = d->d_fileno;2
		d_copy->d_reclen = d->d_reclen;
		d_copy->d_type = d->d_type;
		d_copy->d_namlen = d->d_namlen;
		strlcpy(d_copy->d_name, d->d_name, d->d_namlen + 1);
#else
		d_copy = xcalloc(1, d->d_reclen);
		memcpy(d_copy, d, d->d_reclen);
#endif

		set_item_userptr(items[cur_item], d_copy);

		cur_item++;
	}

	DPRINTF(HGD_D_INFO, "Actually allocated %d menu items", cur_item);
	items[cur_item] = NULL;

	u->content_menus[HGD_WIN_FILES] = new_menu(items);

	keypad(u->content_wins[HGD_WIN_FILES], TRUE);
	set_menu_win(u->content_menus[HGD_WIN_FILES],
	    u->content_wins[HGD_WIN_FILES]);
	set_menu_mark(u->content_menus[HGD_WIN_FILES], "");
	set_menu_format(u->content_menus[HGD_WIN_FILES],
	    LINES - 2, 1);
	set_menu_fore(u->content_menus[HGD_WIN_FILES],
	    COLOR_PAIR(HGD_CPAIR_SELECTED));

	if ((post_menu(u->content_menus[HGD_WIN_FILES])) != E_OK)
		DPRINTF(HGD_D_WARN, "Could not post menu");

	ret = HGD_OK;

clean:
	if (dirents_files) {
		for (i = 0; i < n_files; i ++)
			free(dirents_files[i]);
		free(dirents_files);
	}

	if (dirents_dirs) {
		for (i = 0; i < n_dirs; i ++)
			free(dirents_dirs[i]);
		free(dirents_dirs);
	}

#if 0
	if (items)
		free(items);
#endif

	return (ret);

}
Beispiel #18
0
main() 
{
	int i;
	CHTYPE ch;
	menu ostate;

/* Setup GL environment */
(void) GLenvsetup();

/* Read in chart of accounts file into array, charttab.
** This array will be queried to validate account numbers.
*/
(void)CHload();

/*
** Initialize curses environment
*/
if (ERR == initscr() ) {
	fprintf(stderr, "JSedit: cannot initialize curses\n");
	JEinthand();
}
/* Function key translation */
keypad(stdscr, TRUE);
/* let the program echo characters */
noecho();
/* do not return after linefeed */
nonl();

/*
** Create and initialize windows
*/
menuline=newwin(1,80,0,0);
leaveok(menuline,TRUE);
wattrset(menuline, A_COLOR(A_BRIGHTWHITE,A_BLUE) );
wclear(menuline);

prompt=newwin(3,35,16,22);
leaveok(prompt,TRUE);
wclear(prompt);

message = newwin(1,80,22,0);
leaveok(message,TRUE);
wclear(message);

wrefresh(stdscr);


/*
** Display initial menu
*/
ostate=quit;
state=start;
strcpy(filename,"");
strcpy(filetmp,"");
fileopened=JEFALSE;
filechgd=JEFALSE;

while( state!=quit ) {

	if (ostate != state) {
		wclear(prompt);
		wrefresh(prompt);
		wclear(message);
		wrefresh(message);
		JSdspmenu(state);
		ostate = state;
		strcpy(filetmp,filename);
	}

	ch=getch();
	switch(state) {
	case start:
		state = JMstart(ch);
		break;

	case file:
		state = JMfile(ch);
		break;

	case edit:
		state = JMedit(ch);
		break;

	default:
		fprintf(stderr,"JSedit: unknown state\n");
		JEinthand();
		break;
	}
}
/* Close curses */
endwin();
/* Restore working directory */
chdir(cwdstr);
} /* end of main */
Beispiel #19
0
int
hgd_show_dialog(struct ui *u, const char *title, const char *msg, int secs)
{
	WINDOW			*bwin, *win;
	int			 x, y, h, w;
	char			*msg_centre;
	int			 ch = 0, again = 0;

	/* we will need to redisplay the dialog if we get a resize */
	do {
		again = 0;

		hgd_calc_dialog_win_dims(&y, &x, &h, &w);
		hgd_centre_dialog_text(&msg_centre, msg);

		DPRINTF(HGD_D_INFO, "Show dialog: '%s'", title);

		if ((bwin = newwin(h + 2, w + 2, y - 1, x - 1)) == NULL) {
			DPRINTF(HGD_D_ERROR, "Could not initialise progress window");
			return (HGD_FAIL);
		}

		if ((win = newwin(h, w, y, x)) == NULL) {
			DPRINTF(HGD_D_ERROR, "Could not initialise progress window");
			return (HGD_FAIL);
		}

		wattron(win, COLOR_PAIR(HGD_CPAIR_DIALOG));
		wattron(bwin, COLOR_PAIR(HGD_CPAIR_DIALOG));

		wclear(win);
		wclear(bwin);

		wbkgd(win, COLOR_PAIR(HGD_CPAIR_DIALOG));
		box(bwin, '|', '-');

		mvwprintw(bwin, 0, w / 2 - (strlen(title) / 2), title);
		mvwprintw(win, 1, 0, msg_centre);

		redrawwin(bwin);
		redrawwin(win);
		wrefresh(bwin);
		wrefresh(win);

		if (secs)
			sleep(secs);
		else
			ch = wgetch(win);

		if (ch == KEY_RESIZE) {
			DPRINTF(HGD_D_INFO, "redraw dialog");
			hgd_resize_app(u);
			again = 1;
		}

		delwin(win);
		delwin(bwin);

		free(msg_centre);

	} while(again);

	hgd_refresh_ui(u);

	return (HGD_OK);
}
Beispiel #20
0
//Clears windows 0 (stdscr)     I'm not sure if its suppose to do this?
int clear(void)
{
    return wclear(mainwin);
};
Beispiel #21
0
void print_message(const char *str) {
    wclear(msg);
    wprintw(msg, str);
    wrefresh(msg);
}
Beispiel #22
0
int main(int argc, char * argv[]) {

	int c;

	while ((c = getopt(argc, argv, "hp:n:")) != -1) {
		switch (c) {

			case 'n':
				nick = optarg;
				break;

			case 'p':
				port = atoi(optarg);
				break;

			case 'h':
			default:
				show_usage(argc,argv);
		}
	}

	if (optind >= argc) {
		show_usage(argc,argv);
	}

	setlocale (LC_ALL, "");

	host = argv[optind];

	char tmphost[512];
	sprintf(tmphost, "/dev/net/%s:%d", host, port);
	int sockfd = open(tmphost, O_RDWR);
	sock = fdopen(sockfd, "w");
	sockb = fdopen(sockfd, "r");

	if (!sock) {
		fprintf(stderr, "%s: Connection failed or network not available.\n", argv[0]);
		return 1;
	}

	main_win = initscr();
	start_color();
	use_default_colors();
	assume_default_colors(-1,-1);

	for (int bg = 1; bg < 16; ++bg) {
		for (int fg = 0; fg < 16; ++fg) {
			init_pair(fg+bg*16, fg, bg);
		}
	}

	for (int fg = 1; fg < 16; ++fg) {
		init_pair(fg, fg, -1);
	}


	int w, h;
	getmaxyx(main_win, h, w);

	topic_win  = newwin(1, w, 0, 0);
	body_win   = newwin(h-3, w, 1, 0);
	status_win = newwin(1, w, h-2, 0);
	input_win  = newwin(1, w, h-1, 0);

	signal(SIGWINCH, SIGWINCH_handler);

	scrollok(body_win, TRUE);

	wbkgd(topic_win, COLOR_PAIR(COLOR_WHITE+COLOR_BLUE*16));
	wbkgd(body_win, COLOR_PAIR(0));
	wbkgd(status_win, COLOR_PAIR(COLOR_WHITE+COLOR_BLUE*16));
	wbkgd(input_win, COLOR_PAIR(0));

	/* Write the welcome thing to the body */
	wprintw(body_win, " - Toaru IRC v. %s - \n", VERSION_STRING);
	wprintw(body_win, " Copyright 2015 K Lange\n");
	wprintw(body_win, " http://toaruos.org - http://github.com/klange/toaruos\n");
	wprintw(body_win, "\n");
	wprintw(body_win, " For help, type /help.\n");

	wmove(topic_win, 0, 0);
	wprintw(topic_win, " Toaru IRC v. %s", VERSION_STRING);

	/* Update status */
	wmove(status_win, 0, 0);
	wprintw(status_win, "[%s] ", nick);

	refresh_all();

	pthread_create(&read_thread, NULL, irc_read_thread, NULL);

	fprintf(sock, "NICK %s\r\nUSER %s * 0 :%s\r\n", nick, nick, nick);
	fflush(sock);

	char * buf = malloc(1024);

	while (1) {
		spin_lock(&c_lock);
		wmove(input_win, 0, 0);
		wprintw(input_win, "[%s] ", channel ? channel : "(none)");
		memset(buf, 0, sizeof(buf));
		spin_unlock(&c_lock);
		wgetstr(input_win, buf);

		do_thing(buf);

		spin_lock(&c_lock);
		wclear(input_win);
		wrefresh(input_win);
		spin_unlock(&c_lock);
	}

	endwin();

	return 0;
}
Beispiel #23
0
/* Runs the host editor.  Another big use for this is to open sites
 * that are in your host list.
 */
int HostWindow(void)
{
	int c;
	char cmd[256];
	volatile BookmarkPtr toOpen;
	vsigproc_t si;
	int maxy, maxx;
	int lmaxy;

	si = (sigproc_t) (-1);
	if (gWinInit) {
		gHostListWin = NULL;
		gHostWin = NULL;

		gHostWin = newwin(LINES, COLS, 0, 0);
		if (gHostWin == NULL)
			return (-1);

		curs_set(0);
		cbreak();
		
		/* Set the clear flag for the first update. */
		wclear(gHostWin);
		keypad(gHostWin, TRUE);		/* For arrow keys. */
#ifdef HAVE_NOTIMEOUT
		notimeout(gHostWin, TRUE);
#endif

#ifdef HAVE_SIGSETJMP
		if (sigsetjmp(gHostWinJmp, 1) == 0) {
#else	/* HAVE_SIGSETJMP */
		if (setjmp(gHostWinJmp) == 0) {
#endif	/* HAVE_SIGSETJMP */
			/* Gracefully cleanup the screen if the user ^C's. */
			si = NcSignal(SIGINT, SigIntHostWin);
			
			/* Initialize the page start and select a host to be
			 * the current one.
			 */
			gHostListWinStart = 0;
			gHilitedHost = 0;
			if (gNumBookmarks == 0)
				gCurHostListItem = NULL;
			else
				gCurHostListItem = &gBookmarkTable[gHilitedHost];
			
			/* Initially, we don't want to connect to any site in
			 * the host list.
			 */
			toOpen = NULL;
	
			getmaxyx(gHostWin, maxy, maxx);
			WAttr(gHostWin, kBold, 1);
			WAddCenteredStr(gHostWin, 0, "NcFTP Bookmark Editor");
			WAttr(gHostWin, kBold, 0);
			
			DrawStrAt(gHostWin, 3, 2, "Open selected site:       <enter>");
			DrawStrAt(gHostWin, 4, 2, "Edit selected site:       /ed");
			DrawStrAt(gHostWin, 5, 2, "Delete selected site:     /del");
			DrawStrAt(gHostWin, 6, 2, "Duplicate selected site:  /dup");
			DrawStrAt(gHostWin, 7, 2, "Add a new site:           /new");
			DrawStrAt(gHostWin, 9, 2, "Up one:                   <u>");
			DrawStrAt(gHostWin, 10, 2, "Down one:                 <d>");
			DrawStrAt(gHostWin, 11, 2, "Previous page:            <p>");
			DrawStrAt(gHostWin, 12, 2, "Next page:                <n>");
			DrawStrAt(gHostWin, 14, 2, "Capital letters selects first");
			DrawStrAt(gHostWin, 15, 2, "  site starting with the letter.");
			DrawStrAt(gHostWin, 17, 2, "Exit the bookmark editor: <x>");
		
			/* Initialize the scrolling host list window. */
			if (maxx < 110) {
				gHostListWinWide = 0;
				gHostListWin = subwin(
					gHostWin,
					LINES - 7,
					40,
					3,
					COLS - 40 - 2
				);
			} else {
				gHostListWinWide = COLS - 42;
				gHostListWin = subwin(
					gHostWin,
					LINES - 7,
					gHostListWinWide,
					3,
					38	
				);
			}

			if (gHostListWin == NULL)
				return (-1);
			lmaxy = getmaxy(gHostListWin);
			gHostListPageSize = lmaxy;
			DrawHostList();
			wmove(gHostWin, maxy - 1, 0);
			UpdateHostWindows(1);

			for (;;) {
				c = HostWinGetKey();
				if (gNeedToClearMsg) {
					wmove(gHostWin, maxy - 2, 0);
					wclrtoeol(gHostWin);
					wrefresh(gHostWin);
				}
				if ((c >= 'A') && (c <= 'Z')) {
					/* isupper can coredump if wgetch returns a meta key. */
					HostWinZoomTo(c);
				} else if (c == '/') {
					/* Get an "extended" command.  Sort of like vi's
					 * :colon commands.
					 */
					HostWinGetStr(cmd, sizeof(cmd));
	
					if (ISTREQ(cmd, "ed"))
						HostWinEdit();
					else if (ISTREQ(cmd, "dup"))
						HostWinDup();
					else if (ISTREQ(cmd, "del"))
						HostWinDelete();
					else if (ISTREQ(cmd, "new"))
						HostWinNew();
					else
						HostWinMsg("Invalid bookmark editor command.");
				} else switch(c) {
					case 10:	/* ^J == newline */
						goto enter;
					case 13:	/* ^M == carriage return */
						goto enter;
#ifdef KEY_ENTER
					case KEY_ENTER:
						Trace(1, "  [0x%04X, %s]\n", c, "ENTER");
#endif
enter:
						if (gCurHostListItem == NULL)
							HostWinMsg("Nothing to open.  Try 'open sitename' from the main screen.");
						else {
							toOpen = (BookmarkPtr) gCurHostListItem;
							goto done;
						}
						break;
	
					case kControl_L:
						UpdateHostWindows(1);
						break;
	
					case 'u':
					case 'k':	/* vi up key */
					case 'h':	/* vi left key */
						HostListLineUp();
						break;
#ifdef KEY_UP
					case KEY_UP:
						Trace(1, "  [0x%04X, %s]\n", c, "UP");
						HostListLineUp();
						break;
#endif

#ifdef KEY_LEFT
					case KEY_LEFT:
						Trace(1, "  [0x%04X, %s]\n", c, "LEFT");
						HostListLineUp();
						break;
#endif
					
					case 'd':
					case 'j':	/* vi down key */
					case 'l':	/* vi right key */
						HostListLineDown();
						break;

#ifdef KEY_DOWN
					case KEY_DOWN:
						Trace(1, "  [0x%04X, %s]\n", c, "DOWN");
						HostListLineDown();
						break;
#endif

#ifdef KEY_RIGHT
					case KEY_RIGHT:
						Trace(1, "  [0x%04X, %s]\n", c, "RIGHT");
						HostListLineDown();
						break;
#endif
						
					case 'p':
						HostListPageUp();
						break;

#ifdef KEY_PPAGE
					case KEY_PPAGE:
						Trace(1, "  [0x%04X, %s]\n", c, "PPAGE");
						HostListPageUp();
						break;
#endif

					case 'n':
						HostListPageDown();
						break;

#ifdef KEY_NPAGE
					case KEY_NPAGE:
						Trace(1, "  [0x%04X, %s]\n", c, "NPAGE");
						HostListPageDown();
						break;
#endif

					case 'x':
					case 'q':
						goto done;
	
					default:
						HostWinMsg("Invalid key.");
						Trace(1, "  [0x%04X, %s]\n", c, "<invalid>");
						break;
				}
			}
		}
		NcSignal(SIGINT, (FTPSigProc) SIG_IGN);
done:
		if (gHostListWin != NULL)
			delwin(gHostListWin);
		if (gHostWin != NULL)
			delwin(gHostWin);
		gHostListWin = gHostWin = NULL;
		if (si != (sigproc_t) (-1))
			NcSignal(SIGINT, si);
		if (toOpen != (BookmarkPtr) 0) {
			/* If the user selected a site to open, connect to it now. */
			if (gStandAlone != 0) {
				LaunchNcFTP(toOpen->bookmarkName);
				/*NOTREACHED*/
				Exit(0);
			} else if (gBookmarkSelectionFile != NULL) {
				WriteSelectedBMToFile(toOpen->bookmarkName);
			}
			return (kNoErr);
		}
	}
	return (kNoErr);
}	/* HostWindow */




main_void_return_t
main(int argc, const char **argv)
{
	int result;
	int argi;

	gStandAlone = 1;
	gBookmarkSelectionFile = NULL;

	InitUserInfo();
	if (LoadBookmarkTable() < 0) {
		exit(7);
	}
	if (argc > 1) {
		/* The following hack is used by NcFTP
		 * to get the number of columns without
		 * having to link with curses/termcap.
		 * This simplifies things since the
		 * system may or may not have a good
		 * curses implementation, and we don't
		 * want to complicate NcFTP itself with
		 * that.
		 */
		argi = 1;
		if (strcmp(argv[1], "--dimensions") == 0) {
			result = PrintDimensions(0);
			exit((result == 0) ? 0 : 1);
		} else if (strcmp(argv[1], "--dimensions-terse") == 0) {
			result = PrintDimensions(1);
			exit((result == 0) ? 0 : 1);
		} else if (strcmp(argv[1], "--debug") == 0) {
			SetDebug(1);
			argi++;
		}
		/* Requested that we were run from ncftp. */
		gStandAlone = 0;
		if ((argc > argi) && (argv[argi][0] == '/'))
			gBookmarkSelectionFile = (const char *) argv[argi];
		if (gNumBookmarks < 1)
			exit(7);
	}

	result = FTPInitLibrary(&gLib);
	if (result < 0) {
		(void) fprintf(stderr, "ncftp: init library error %d (%s).\n", result, FTPStrError(result));
		exit(1);
	}

	result = FTPInitConnectionInfo(&gLib, &gConn, kDefaultFTPBufSize);
	if (result < 0) {
		(void) fprintf(stderr, "ncftp: init connection info error %d (%s).\n", result, FTPStrError(result));
		exit(1);
	}

	if (gDebug > 0)
		OpenTrace();
	InitPrefs();
	LoadFirewallPrefs(0);
	LoadPrefs();

	InitWindows();
	Trace(1, "Terminal size is %d columns by %d rows.\n", gScreenWidth, gScreenHeight);
	HostWindow();
	if (gDebug > 0)
		CloseTrace();
	EndWin();
	exit(0);
}	/* main */
Beispiel #24
0
/*
 * Display a dialog box with a list of options that can be turned on or off
 */
int
dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
		 int cnt, void *it, unsigned char *result)
{
    int i, j, x, y, cur_x, cur_y, old_x, old_y, box_x, box_y, key = 0, button,
	choice, l, k, scroll, max_choice, *status, item_no = 0, was_on = 0;
    int redraw_menu = FALSE, cursor_reset = FALSE;
    int rval = 0, onlist = 1, ok_space, cancel_space;
    char okButton, cancelButton;
    WINDOW *dialog, *list;
    unsigned char **items = NULL;
    dialogMenuItem *ditems;
    
    /* Allocate space for storing item on/off status */
    if ((status = alloca(sizeof(int) * abs(cnt))) == NULL) {
	endwin();
	fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
	exit(-1);
    }
    
draw:
    button = choice = scroll = 0;
    /* Previous calling syntax, e.g. just a list of strings? */
    if (cnt >= 0) {
	items = it;
	ditems = NULL;
	item_no = cnt;
	/* Initializes status */
	for (i = 0; i < item_no; i++) {
	    status[i] = !strcasecmp(items[i*3 + 2], "on");
	    if (status[i]) {
		if (was_on)
		    status[i] = FALSE;
		else
		    was_on = 1;
	    }
	}
    }
    /* It's the new specification format - fake the rest of the code out */
    else {
	item_no = abs(cnt);
	ditems = it;
	if (!items)
	    items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
	/* Initializes status */
	for (i = 0; i < item_no; i++) {
	    status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
	    if (status[i]) {
		if (was_on)
		    status[i] = FALSE;
		else
		    was_on = 1;
	    }
	    items[i*3] = ditems[i].prompt;
	    items[i*3 + 1] = ditems[i].title;
	    items[i*3 + 2] = status[i] ? "on" : "off";
	}
    }
    max_choice = MIN(list_height, item_no);
    
    check_x = 0;
    item_x = 0;
    /* Find length of longest item in order to center radiolist */
    for (i = 0; i < item_no; i++) {
	l = strlen(items[i * 3]);
	for (j = 0; j < item_no; j++) {
	    k = strlen(items[j * 3 + 1]);
	    check_x = MAX(check_x, l + k + 6);
	}
	item_x = MAX(item_x, l);
    }
    if (height < 0)
	height = strheight(prompt) + list_height + 4 + 2;
    if (width < 0) {
	i = strwidth(prompt);
	j = ((title != NULL) ? strwidth(title) : 0);
	width = MAX(i, j);
	width = MAX(width, check_x + 4) + 4;
    }
    width = MAX(width, 24);
    
    if (width > COLS)
	width = COLS;
    if (height > LINES)
	height = LINES;
    /* center dialog box on screen */
    x = DialogX ? DialogX : (COLS - width) / 2;
    y = DialogY ? DialogY : (LINES - height) / 2;

#ifdef HAVE_NCURSES
    if (use_shadow)
	draw_shadow(stdscr, y, x, height, width);
#endif
    dialog = newwin(height, width, y, x);
    if (dialog == NULL) {
	endwin();
	fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height, width, y, x);
	return -1;
    }
    keypad(dialog, TRUE);
    
    draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
    wattrset(dialog, border_attr);
    wmove(dialog, height - 3, 0);
    waddch(dialog, ACS_LTEE);
    for (i = 0; i < width - 2; i++)
	waddch(dialog, ACS_HLINE);
    wattrset(dialog, dialog_attr);
    waddch(dialog, ACS_RTEE);
    wmove(dialog, height - 2, 1);
    for (i = 0; i < width - 2; i++)
	waddch(dialog, ' ');
    
    if (title != NULL) {
	wattrset(dialog, title_attr);
	wmove(dialog, 0, (width - strlen(title)) / 2 - 1);
	waddch(dialog, ' ');
	waddstr(dialog, title);
	waddch(dialog, ' ');
    }
    wattrset(dialog, dialog_attr);
    wmove(dialog, 1, 2);
    print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
    
    list_width = width - 6;
    getyx(dialog, cur_y, cur_x);
    box_y = cur_y + 1;
    box_x = (width - list_width) / 2 - 1;
    
    /* create new window for the list */
    list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
    if (list == NULL) {
	delwin(dialog);
	endwin();
	fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width,
		y + box_y + 1,x + box_x + 1);
	return -1;
    }
    keypad(list, TRUE);
    
    /* draw a box around the list items */
    draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
    
    check_x = (list_width - check_x) / 2;
    item_x = check_x + item_x + 6;
    
    /* Print the list */
    for (i = 0; i < max_choice; i++)
	print_item(list, items[i * 3], items[i * 3 + 1], status[i], i, i == choice, DREF(ditems, i));
    wnoutrefresh(list);
    print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
    
    display_helpline(dialog, height-1, width);
    
    x = width/ 2 - 11;
    y = height - 2;
    if (ditems && result) {
	cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
	print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
		     ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
	okButton = toupper(ditems[OK_BUTTON].prompt[0]);
	print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
		     ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
    }
    else {
	cancelButton = 'C';
	print_button(dialog, "Cancel", y, x + 14, FALSE);
	okButton = 'O';
	print_button(dialog, "  OK  ", y, x, TRUE);
    }
    wnoutrefresh(dialog);
    wmove(list, choice, check_x+1);
    wrefresh(list);

    while (key != ESC) {
	key = wgetch(dialog);
	
	/* See if its the short-cut to "OK" */
	if (toupper(key) == okButton) {
	    if (ditems) {
		if (result && ditems[OK_BUTTON].fire) {
		    int st;
		    WINDOW *save;

		    save = dupwin(newscr);
		    st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
		    if (st & DITEM_RESTORE) {
			touchwin(save);
			wrefresh(save);
		    }
		    delwin(save);
		}
	    }
	    else if (result) {
		*result = '\0';
		for (i = 0; i < item_no; i++) {
		    if (status[i]) {
			strcat(result, items[i*3]);
			break;
		    }
		}
	    }
	    rval = 0;
	    key = ESC;
	    break;
	}

	/* Shortcut to cancel */
	if (toupper(key) == cancelButton) {
	    if (ditems && result && ditems[CANCEL_BUTTON].fire) {
		int st;
		WINDOW *save;

		save = dupwin(newscr);
		st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
		if (st & DITEM_RESTORE) {
		    touchwin(save);
		    wrefresh(save);
		}
		delwin(save);
	    }
	    rval = 1;
	    key = ESC;
	    break;
	}
	
	/* Check if key pressed matches first character of any item tag in list */
	for (i = 0; i < max_choice; i++)
	    if (key != ' ' && toupper(key) == toupper(items[(scroll + i) * 3][0]))
		break;

	if (i < max_choice || (key >= '1' && key <= MIN('9', '0' + max_choice)) ||
	    KEY_IS_UP(key) || KEY_IS_DOWN(key) || ((key == ' ' || key == '\r' || key == '\n') && onlist == 1)) {

	    /* if moving from buttons to the list, reset and redraw buttons */
	    if (!onlist) {
		onlist = 1;
		button = 0;

	    	if (ditems && result ) {
		    print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
			ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
		    print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
			ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
		}
		else {
		    print_button(dialog, "Cancel", y, x + 14, button);
		    print_button(dialog, "  OK  ", y, x, !button);
		}
	    }
	    wmove(list, choice, check_x+1);
	    wnoutrefresh(dialog);
	    wrefresh(list);

	    if (key >= '1' && key <= MIN('9', '0' + max_choice))
		i = key - '1';
	    else if (KEY_IS_UP(key)) {
		if (!choice) {
		    if (scroll) {
			/* Scroll list down */
			getyx(dialog, cur_y, cur_x);    /* Save cursor position */
			if (list_height > 1) {
			    /* De-highlight current first item before scrolling down */
			    print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0,
				       FALSE, DREF(ditems, scroll));
			    scrollok(list, TRUE);
			    wscrl(list, -1);
			    scrollok(list, FALSE);
			}
			scroll--;
			print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0,
				   TRUE, DREF(ditems, scroll));
			print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
			wmove(list, choice, check_x+1);
			wnoutrefresh(dialog);
			wrefresh(list);
		    }
		    continue;    /* wait for another key press */
		}
		else
		    i = choice - 1;
	    }
	    else if (KEY_IS_DOWN(key)) {
		if (choice == max_choice - 1) {
		    if (scroll + choice < item_no - 1) {
			/* Scroll list up */
			getyx(dialog, cur_y, cur_x);    /* Save cursor position */
			if (list_height > 1) {
			    /* De-highlight current last item before scrolling up */
			    print_item(list, items[(scroll + max_choice - 1) * 3],
				       items[(scroll + max_choice - 1) * 3 + 1],
				       status[scroll + max_choice - 1], max_choice - 1,
				       FALSE, DREF(ditems, scroll + max_choice - 1));
			    scrollok(list, TRUE);
			    scroll(list);
			    scrollok(list, FALSE);
			}
			scroll++;
			print_item(list, items[(scroll + max_choice - 1) * 3],
				   items[(scroll + max_choice - 1) * 3 + 1],
				   status[scroll + max_choice - 1], max_choice - 1,
				   TRUE, DREF(ditems, scroll + max_choice - 1));
			print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
			wmove(list, choice, check_x+1);
			wnoutrefresh(dialog);
			wrefresh(list);
		    }
		    continue;    /* wait for another key press */
		}
		else
		    i = choice + 1;
	    }
	    else if ((key == ' ' || key == '\r' || key == '\n') && onlist) {    /* Toggle item status */
		getyx(list, old_y, old_x);     /* Save cursor position */
		if (status[scroll + choice])
		    continue;
		else if (ditems) {
		    if (ditems[scroll + choice].fire) {
			int st;
			WINDOW *save;

			save = dupwin(newscr);
			st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
			if (st & DITEM_RESTORE) {
			    touchwin(save);
			    wrefresh(save);
			}
			delwin(save);
			if (st & DITEM_REDRAW) {
			    wclear(list);
			    for (i = 0; i < item_no; i++)
				status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;

			    for (i = 0; i < max_choice; i++) {
				print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1],
					   status[scroll + i], i, i == choice,
					   DREF(ditems, scroll + i));
			    }
/*			    wmove(list, old_y, old_x);*/  /* Restore cursor to previous position */
/*			    wrefresh(list); */
			}
			if (st & DITEM_LEAVE_MENU) {
			    /* Allow a fire action to take us out of the menu */
			    key = ESC;
			    break;
			}
			else if (st & DITEM_RECREATE) {
			    delwin(list);
			    delwin(dialog);
			    dialog_clear();
			    goto draw;
			}
		    }
		    for (i = 0; i < item_no; i++)
			status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
		}
		else {
		    for (i = 0; i < item_no; i++)
			status[i] = 0;
		    status[scroll + choice] = TRUE;
		}
		for (i = 0; i < max_choice; i++)
		    print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1],
			       status[scroll + i], i, i == choice, DREF(ditems, scroll + i));
		wmove(list, choice, check_x+1);  /* Restore cursor position */
		wrefresh(list);
		continue;    /* wait for another key press */
	    }
	    
	    if (i != choice) {
		/* De-highlight current item */
		print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 +1],
			   status[scroll + choice], choice, FALSE, DREF(ditems, scroll + choice));
		/* Highlight new item */
		choice = i;
		print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1],
			   status[scroll + choice], choice, TRUE, DREF(ditems, scroll + choice));
		wmove(list, choice, check_x+1);  /* Restore cursor position */
		wrefresh(list);
	    }
	    continue;    /* wait for another key press */
	}
	
	switch (key) {
	case KEY_PPAGE:
	    if (scroll > height-4)		/* can we go up? */
		scroll -= (height-4);
	    else
		scroll = 0;
	    redraw_menu = TRUE;
	    if (!onlist) {
		onlist = 1;
		button = 0;
	    }
	    break;
	    
	case KEY_NPAGE:
	    if (scroll + list_height >= item_no-1 - list_height) { /* can we go down a full page? */
		scroll = item_no - list_height;
		if (scroll < 0)
		    scroll = 0;
	    }
	    else
		scroll += list_height;
	    redraw_menu = TRUE;
	    if (!onlist) {
		onlist = 1;
		button = 0;
	    }
	    break;
	    
	case KEY_HOME:
	    scroll = 0;
	    choice = 0;
	    redraw_menu = TRUE;
	    cursor_reset = TRUE;
	    onlist = 1;
	    break;
	    
	case KEY_END:
	    scroll = item_no - list_height;
	    if (scroll < 0)
		scroll = 0;
	    choice = max_choice - 1;
	    redraw_menu = TRUE;
	    cursor_reset = TRUE;
	    onlist = 1;
	    break;
	    
	case TAB:
	case KEY_BTAB:
	    /* move to next component */
	    if (onlist) {      /* on list, next is ok button */
		onlist = 0;
		if (ditems && result)
		    ok_space = 1;
		else
		    ok_space = 3;
		wmove(dialog, y, x + ok_space);
		wrefresh(dialog);
		break;
	    }
	    else if (button) {      /* on cancel button, next is list */
		button = 0;
		onlist = 1;
		redraw_menu = TRUE;
		break;
	    }
	    /* on ok button, next is cancel button, same as left/right case */

	case KEY_LEFT:
	case KEY_RIGHT:
	    onlist = 0;
	    button = !button;
	    if (ditems && result) {
		print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
			     ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
		print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
			     ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
		ok_space = 1;
		cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6;
	    }
	    else {
		print_button(dialog, "Cancel", y, x + 14, button);
		print_button(dialog, "  OK  ", y, x, !button);
		ok_space = 3;
		cancel_space = 15;
	    }
	    if (button)
		wmove(dialog, y, x + cancel_space);
	    else
		wmove(dialog, y, x + ok_space);
	    wrefresh(dialog);
	    break;

	case ' ':	    
	case '\r':
	case '\n':
	    if (!onlist) {
		if (ditems) {
		    if (result && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
			int st;
			WINDOW *save;

			save = dupwin(newscr);
			st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
			if (st & DITEM_RESTORE) {
			    touchwin(save);
			    wrefresh(save);
			}
			delwin(save);
		    }
		}
		else if (result) {
		    *result = '\0';
		    for (i = 0; i < item_no; i++) {
			if (status[i]) {
			    strcpy(result, items[i*3]);
			    break;
			}
		    }
		}
		rval = button;
		key = ESC;
		break;
	    }
	    
	case ESC:
	    rval = -1;
	    break;
	    
	case KEY_F(1):
	case '?':
	    display_helpfile();
	    break;
	}
	
	if (redraw_menu) {
	    getyx(list, old_y, old_x);
	    wclear(list);
	    for (i = 0; i < max_choice; i++)
		print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i],
			   i, i == choice, DREF(ditems, scroll + i));
	    print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);

	    /* redraw buttons to fix highlighting */
	    if (ditems && result) {
		print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
			ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
		print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
			ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
	    }
	    else {
		print_button(dialog, "Cancel", y, x + 14, button);
		print_button(dialog, "  OK  ", y, x, !button);
	    }
	    wnoutrefresh(dialog);
	    if (cursor_reset) {
		wmove(list, choice, check_x+1);
		cursor_reset = FALSE;
	    }
	    else {
		wmove(list, old_y, old_x);
	    }
	    wrefresh(list);
	    redraw_menu = FALSE;
	}
    }
    
    delwin(list);
    delwin(dialog);
    return rval;    /* ESC pressed */
}
Beispiel #25
0
static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{
    ChatContext *ctx = self->chatwin;

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    if (x2 <= 0)
        return;

    if (self->help->active) {
        help_onKey(self, key);
        return;
    }

    if (ltr) {    /* char is printable */
        input_new_char(self, key, x, y, x2, y2);
        return;
    }

    if (line_info_onKey(self, key))
        return;

    if (input_handle(self, key, x, y, x2, y2))
        return;

    if (key == '\t') {  /* TAB key: auto-completes peer name or command */
        if (ctx->len > 0) {
            int diff;

            /* TODO: make this not suck */
            if (ctx->line[0] != L'/' || wcscmp(ctx->line, L"/me") == 0) {
                diff = complete_line(self, groupchats[self->num].peer_names, groupchats[self->num].num_peers, 
                                     TOX_MAX_NAME_LENGTH);
            } else if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) {
                diff = dir_match(self, m, ctx->line, L"/avatar");
            } else {
                diff = complete_line(self, group_cmd_list, AC_NUM_GROUP_COMMANDS, MAX_CMDNAME_SIZE);
            }

            if (diff != -1) {
                if (x + diff > x2 - 1) {
                    int wlen = wcswidth(ctx->line, sizeof(ctx->line));
                    ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
                }
            } else {
                sound_notify(self, error, 0, NULL);
            }
        } else {
            sound_notify(self, error, 0, NULL);
        }
    } else if (key == user_settings->key_peer_list_down) {    /* Scroll peerlist up and down one position */
        int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;

        if (groupchats[self->num].side_pos < groupchats[self->num].num_peers - L)
            ++groupchats[self->num].side_pos;
    } else if (key == user_settings->key_peer_list_up) {
        if (groupchats[self->num].side_pos > 0)
            --groupchats[self->num].side_pos;
    } else if (key == '\n') {
        rm_trailing_spaces_buf(ctx);

        char line[MAX_STR_SIZE];

        if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
            memset(&line, 0, sizeof(line));

        if (!string_is_empty(line))
            add_line_to_hist(ctx);

        if (line[0] == '/') {
            if (strcmp(line, "/close") == 0) {
                close_groupchat(self, m, self->num);
                return;
            } else if (strncmp(line, "/me ", strlen("/me ")) == 0) {
                send_group_action(self, ctx, m, line + strlen("/me "));
            } else {
                execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE);
            }
        } else if (!string_is_empty(line)) {
            if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) {
                const char *errmsg = " * Failed to send message.";
                line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg);
            }
        }

        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        reset_buf(ctx);
    }
}
int
sc_clear ()
{
  return (wclear(stdscr) != ERR);
}
Beispiel #27
0
void cmd_clear(ToxWindow *self, Tox *m, char **args)
{
    wclear(self->window);
}
Beispiel #28
0
/* This function reads the input from the parameters of the SCTP_PathStatus structure
   and displays the data on a window of ncurses. */
void ncurses_display_PathStatus(unsigned int assocID)

{
    SCTP_AssociationStatus assocStatus;
    SCTP_PathStatus pathStatus;
    unsigned short pathID;
    unsigned int Rto[SCTP_MAX_NUM_ADDRESSES], HB_Interval[SCTP_MAX_NUM_ADDRESSES];
    unsigned int SRTT[SCTP_MAX_NUM_ADDRESSES],RTTVar[SCTP_MAX_NUM_ADDRESSES];
    unsigned int SlowStThres[SCTP_MAX_NUM_ADDRESSES], PartBytesAck[SCTP_MAX_NUM_ADDRESSES];
    unsigned int CongestWin[SCTP_MAX_NUM_ADDRESSES],CongestWin2[SCTP_MAX_NUM_ADDRESSES];
    unsigned int MTU[SCTP_MAX_NUM_ADDRESSES], OutBytesPerAddr[SCTP_MAX_NUM_ADDRESSES];
    short State[SCTP_MAX_NUM_ADDRESSES];
    char destaddr[SCTP_MAX_NUM_ADDRESSES][SCTP_MAX_IP_LEN];
    unsigned char IPTos[SCTP_MAX_NUM_ADDRESSES];

    wclear(pathWin);
    wrefresh(pathWin);

    sctp_getAssocStatus(assocID, &assocStatus);
    for (pathID=0; pathID < assocStatus.numberOfAddresses; pathID++)
    {
        sctp_getPathStatus(assocID, pathID, &pathStatus);
        strcpy((char *)destaddr[pathID], (const char *)pathStatus.destinationAddress);
        State[pathID] = pathStatus.state;
        Rto[pathID] = pathStatus.rto;
        HB_Interval[pathID] = pathStatus.heartbeatIntervall;
        SRTT[pathID] = pathStatus.srtt;
        RTTVar[pathID] = pathStatus.rttvar;
        SlowStThres[pathID] = pathStatus.ssthresh;
        PartBytesAck[pathID] = pathStatus.partialBytesAcked;
        CongestWin[pathID] = pathStatus.cwnd;
        CongestWin2[pathID] = pathStatus.cwnd2;
        MTU[pathID] = pathStatus.mtu;
        OutBytesPerAddr[pathID] = pathStatus.outstandingBytesPerAddress;
        IPTos[pathID] = pathStatus.ipTos;

        if (displayPathDetails == 0)
        {
            /* Check if the current path is the primary path */
            if (pathID == sctp_getPrimary(assocID))
            {
                sprintf(pathInfo," Primary Path ID : %d, state of path : %s\n",
                        pathID, pathStateName(State[pathID]));
                waddstr(pathWin,pathInfo);
                wrefresh(pathWin);
            }
            else
            {
                sprintf(pathInfo," Path ID : %d, state of path : %s\n",
                        pathID, pathStateName(State[pathID]));
                waddstr(pathWin,pathInfo);
                wrefresh(pathWin);
            }
        }

        else if (displayPathDetails == 1)
        {
            mvwaddstr(pathWin,0,0,"[Hit Backspace to return to main menu]\n");
            wrefresh(pathWin);

            if (pathID == chosenPath)
            {
                sprintf(pathInfo,"\n Path ID : %d, State of path : %s\t\t Destination address : %s\n Heartbeat Interval : %-8u\t\t Retransmisson time(msecs) : %-8d\n Smooth Round Trip time(msecs) : %-8d\t Round Trip time Variations(msecs) : %-8d\n Slow start threshold : %-8d\t\t Congestion Window Size : %-8d\n Outstanding Bytes per Address : %-8d\t Congestion Window Size 2 : %-8d\n Partial bytes acknowledge : %-8d\t\t IP type of service : %x\n MTU : %d bytes\n\n",
                        pathID, pathStateName(State[pathID]),
                        destaddr[pathID],HB_Interval[pathID],Rto[pathID],
                        SRTT[pathID],RTTVar[pathID],SlowStThres[pathID],CongestWin[pathID],
                        OutBytesPerAddr[pathID], CongestWin2[pathID],PartBytesAck[pathID],
                        IPTos[pathID],MTU[pathID]);

                waddstr(pathWin,pathInfo);
                wrefresh(pathWin);
            }
        }
    }
    wrefresh(textWin);
    displayPathDetails = 0;
}
Beispiel #29
0
void w_display_cpu_pstates(void)
{
#ifndef DISABLE_NCURSES
	WINDOW *win;
	char buffer[128];
	char linebuf[1024];
	unsigned int package, core, cpu;
	int line;
	class abstract_cpu *_package, * _core, * _cpu;
	int ctr = 0;

	win = get_ncurses_win("Frequency stats");
	if (!win)
		return;

	wclear(win);
        wmove(win, 2,0);


	for (package = 0; package < system_level.children.size(); package++) {
		int first_pkg = 0;
		_package = system_level.children[package];
		if (!_package)
			continue;


		for (core = 0; core < _package->children.size(); core++) {
			_core = _package->children[core];
			if (!_core)
				continue;

			for (line = LEVEL_HEADER; line < 10; line++) {
				int first = 1;
				ctr = 0;
				linebuf[0] = 0;

				if (!_package->has_pstate_level(line))
					continue;


				buffer[0] = 0;
				if (first_pkg == 0) {
					strcat(linebuf, _package->fill_pstate_name(line, buffer));
					expand_string(linebuf, ctr + 10);
					strcat(linebuf, _package->fill_pstate_line(line, buffer));
				}
				ctr += 20;
				expand_string(linebuf, ctr);

				strcat(linebuf, "| ");
				ctr += strlen("| ");

				if (!_core->can_collapse()) {
					buffer[0] = 0;
					strcat(linebuf, _core->fill_pstate_name(line, buffer));
					expand_string(linebuf, ctr + 10);
					strcat(linebuf, _core->fill_pstate_line(line, buffer));
					ctr += 20;
					expand_string(linebuf, ctr);

					strcat(linebuf, "| ");
					ctr += strlen("| ");
				}

				for (cpu = 0; cpu < _core->children.size(); cpu++) {
					_cpu = _core->children[cpu];
					if (!_cpu)
						continue;

					if (first == 1) {
						strcat(linebuf, _cpu->fill_pstate_name(line, buffer));
						expand_string(linebuf, ctr + 10);
						first = 0;
						ctr += 12;
					}
					buffer[0] = 0;
					strcat(linebuf, _cpu->fill_pstate_line(line, buffer));
					ctr += 10;
					expand_string(linebuf, ctr);

				}
				strcat(linebuf, "\n");
				wprintw(win, "%s", linebuf);
			}

			wprintw(win, "\n");
			first_pkg++;
		}


	}
#endif // DISABLE_NCURSES
}
Beispiel #30
0
static void chat_onKey(ToxWindow *self, Messenger *m, wint_t key)
{
    ChatContext *ctx = (ChatContext *) self->x;
    struct tm *timeinfo = get_time();

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    /* Add printable chars to buffer and print on input space */
#if HAVE_WIDECHAR
    if (iswprint(key)) {
#else
    if (isprint(key)) {
#endif
        if (ctx->pos != sizeof(ctx->line) - 1) {
            mvwaddstr(self->window, y, x, wc_to_char(key));
            ctx->line[ctx->pos++] = key;
            ctx->line[ctx->pos] = L'\0';
        }
    }

    /* BACKSPACE key: Remove one character from line */
    else if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            ctx->line[--ctx->pos] = L'\0';

            if (x == 0)
                mvwdelch(self->window, y - 1, x2 - 1);
            else
                mvwdelch(self->window, y, x - 1);
        }
    }

    /* RETURN key: Execute command or print line */
    else if (key == '\n') {
        char *line = wcs_to_char(ctx->line);
        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        wclrtobot(self->window);

        if (line[0] == '/')
            execute(self, ctx, m, line);
        else {
            /* make sure the string has at least non-space character */
            if (!string_is_empty(line)) {
                uint8_t selfname[MAX_NAME_LENGTH];
                getself_name(m, selfname, sizeof(selfname));

                wattron(ctx->history, COLOR_PAIR(2));
                wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
                wattroff(ctx->history, COLOR_PAIR(2));
                wattron(ctx->history, COLOR_PAIR(1));
                wprintw(ctx->history, "%s: ", selfname);
                wattroff(ctx->history, COLOR_PAIR(1));
                wprintw(ctx->history, "%s\n", line);

                if (m_sendmessage(m, ctx->friendnum, (uint8_t *) line, strlen(line) + 1) == 0) {
                    wattron(ctx->history, COLOR_PAIR(3));
                    wprintw(ctx->history, " * Failed to send message.\n");
                    wattroff(ctx->history, COLOR_PAIR(3));
                }
            }
        }

        ctx->line[0] = L'\0';
        ctx->pos = 0;
        free(line);
    }
}

void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd)
{
    if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
        wclear(self->window);
        wclear(ctx->history);
        int x, y;
        getmaxyx(self->window, y, x);
        (void) x;
        wmove(self->window, y - CURS_Y_OFFSET, 0);
    }

    else if (!strcmp(cmd, "/help") || !strcmp(cmd, "/h"))
        print_help(ctx);

    else if (!strcmp(cmd, "/quit") || !strcmp(cmd, "/exit") || !strcmp(cmd, "/q")) {
        endwin();
        exit(0);
    }

    else if (!strncmp(cmd, "/me ", strlen("/me "))) {
        struct tm *timeinfo = get_time();
        char *action = strchr(cmd, ' ');

        if (action == NULL) {
            wprintw(self->window, "Invalid syntax.\n");
            return;
        }

        action++;

        wattron(ctx->history, COLOR_PAIR(2));
        wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
        wattroff(ctx->history, COLOR_PAIR(2));

        uint8_t selfname[MAX_NAME_LENGTH];
        int len = getself_name(m, selfname, sizeof(selfname));
        char msg[MAX_STR_SIZE - len - 4];
        snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t *) selfname, action);

        wattron(ctx->history, COLOR_PAIR(5));
        wprintw(ctx->history, msg);
        wattroff(ctx->history, COLOR_PAIR(5));

        if (m_sendaction(m, ctx->friendnum, (uint8_t *) msg, strlen(msg) + 1) < 0) {
            wattron(ctx->history, COLOR_PAIR(3));
            wprintw(ctx->history, " * Failed to send action\n");
            wattroff(ctx->history, COLOR_PAIR(3));
        }
    }

    else if (!strncmp(cmd, "/status ", strlen("/status "))) {
        char *status = strchr(cmd, ' ');
        char *msg;
        char *status_text;

        if (status == NULL) {
            wprintw(ctx->history, "Invalid syntax.\n");
            return;
        }

        status++;
        USERSTATUS status_kind;

        if (!strncmp(status, "online", strlen("online"))) {
            status_kind = USERSTATUS_NONE;
            status_text = "ONLINE";
        }

        else if (!strncmp(status, "away", strlen("away"))) {
            status_kind = USERSTATUS_AWAY;
            status_text = "AWAY";
        }

        else if (!strncmp(status, "busy", strlen("busy"))) {
            status_kind = USERSTATUS_BUSY;
            status_text = "BUSY";
        }

        else {
            wprintw(ctx->history, "Invalid status.\n");
            return;
        }

        msg = strchr(status, ' ');

        if (msg == NULL) {
            m_set_userstatus(m, status_kind);
            wprintw(ctx->history, "Status set to: %s\n", status_text);
        } else {
            msg++;
            m_set_userstatus(m, status_kind);
            m_set_statusmessage(m, ( uint8_t *) msg, strlen(msg) + 1);
            wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg);
        }
    }

    else if (!strncmp(cmd, "/nick ", strlen("/nick "))) {
        char *nick;
        nick = strchr(cmd, ' ');

        if (nick == NULL) {
            wprintw(ctx->history, "Invalid syntax.\n");
            return;
        }

        nick++;
        setname(m, (uint8_t *) nick, strlen(nick) + 1);
        wprintw(ctx->history, "Nickname set to: %s\n", nick);
    }

    else if (!strcmp(cmd, "/myid")) {
        char id[FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
        uint8_t address[FRIEND_ADDRESS_SIZE];
        size_t i;
        getaddress(m, address);

        for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
            char xx[3];
            snprintf(xx, sizeof(xx), "%02X",  address[i] & 0xff);
            strcat(id, xx);
        }

        wprintw(ctx->history, "%s\n", id);
    }

    else if (strcmp(cmd, "/close") == 0) {
        int f_num = ctx->friendnum;
        delwin(ctx->linewin);
        del_window(self);
        disable_chatwin(f_num);
    }

    else
        wprintw(ctx->history, "Invalid command.\n");
}

static void chat_onDraw(ToxWindow *self, Messenger *m)
{
    curs_set(1);
    int x, y;
    getmaxyx(self->window, y, x);
    (void) y;
    ChatContext *ctx = (ChatContext *) self->x;
    mvwhline(ctx->linewin, 0, 0, '_', x);
    wrefresh(self->window);
}