mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge pull request #512 from manuel-arguelles/toxic_unicode
Add wide char support in toxic (issue #440)
This commit is contained in:
commit
f249084772
|
@ -19,7 +19,7 @@ if(APPLE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
find_package(Curses REQUIRED)
|
find_package(Cursesw REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_NACL)
|
if(USE_NACL)
|
||||||
|
|
179
cmake/FindCursesw.cmake
Normal file
179
cmake/FindCursesw.cmake
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
# - Find the curses include file and library
|
||||||
|
#
|
||||||
|
# CURSES_FOUND - system has Curses
|
||||||
|
# CURSES_INCLUDE_DIR - the Curses include directory
|
||||||
|
# CURSES_LIBRARIES - The libraries needed to use Curses
|
||||||
|
# CURSES_HAVE_CURSES_H - true if curses.h is available
|
||||||
|
# CURSES_HAVE_NCURSES_H - true if ncurses.h is available
|
||||||
|
# CURSES_HAVE_NCURSES_NCURSES_H - true if ncurses/ncurses.h is available
|
||||||
|
# CURSES_HAVE_NCURSES_CURSES_H - true if ncurses/curses.h is available
|
||||||
|
# CURSES_LIBRARY - set for backwards compatibility with 2.4 CMake
|
||||||
|
#
|
||||||
|
# Set CURSES_NEED_NCURSES to TRUE before the FIND_PACKAGE() command if NCurses
|
||||||
|
# functionality is required.
|
||||||
|
|
||||||
|
# Set CURSES_NEED_WIDE to TRUE before the FIND_PACKAGE() command if unicode
|
||||||
|
# functionality is required
|
||||||
|
|
||||||
|
SET(CURSES_NEED_WIDE TRUE)
|
||||||
|
|
||||||
|
SET(CURSES_LIBRARY_NAME "curses")
|
||||||
|
SET(NCURSES_LIBRARY_NAME "ncurses")
|
||||||
|
IF(CURSES_NEED_WIDE)
|
||||||
|
MESSAGE( STATUS "Searching for wide character curses")
|
||||||
|
SET(CURSES_LIBRARY_NAME "cursesw")
|
||||||
|
SET(NCURSES_LIBRARY_NAME "ncursesw")
|
||||||
|
ENDIF(CURSES_NEED_WIDE)
|
||||||
|
|
||||||
|
FIND_LIBRARY(CURSES_CURSES_LIBRARY "${CURSES_LIBRARY_NAME}")
|
||||||
|
# MESSAGE(STATUS "CURSES! " ${CURSES_CURSES_LIBRARY})
|
||||||
|
|
||||||
|
FIND_LIBRARY(CURSES_NCURSES_LIBRARY "${NCURSES_LIBRARY_NAME}")
|
||||||
|
# MESSAGE(STATUS "NCURSES! " ${CURSES_NCURSES_LIBRARY})
|
||||||
|
|
||||||
|
SET(CURSES_USE_NCURSES FALSE)
|
||||||
|
|
||||||
|
IF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_LIBRARY)
|
||||||
|
SET(CURSES_USE_NCURSES TRUE)
|
||||||
|
ENDIF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_LIBRARY)
|
||||||
|
|
||||||
|
|
||||||
|
# Not sure the logic is correct here.
|
||||||
|
# If NCurses is required, use the function wsyncup() to check if the library
|
||||||
|
# has NCurses functionality (at least this is where it breaks on NetBSD).
|
||||||
|
# If wsyncup is in curses, use this one.
|
||||||
|
# If not, try to find ncurses and check if this has the symbol.
|
||||||
|
# Once the ncurses library is found, search the ncurses.h header first, but
|
||||||
|
# some web pages also say that even with ncurses there is not always a ncurses.h:
|
||||||
|
# http://osdir.com/ml/gnome.apps.mc.devel/2002-06/msg00029.html
|
||||||
|
# So at first try ncurses.h, if not found, try to find curses.h under the same
|
||||||
|
# prefix as the library was found, if still not found, try curses.h with the
|
||||||
|
# default search paths.
|
||||||
|
IF(CURSES_CURSES_LIBRARY AND CURSES_NEED_NCURSES)
|
||||||
|
INCLUDE(CheckLibraryExists)
|
||||||
|
CHECK_LIBRARY_EXISTS("${CURSES_CURSES_LIBRARY}"
|
||||||
|
wsyncup "" CURSES_CURSES_HAS_WSYNCUP)
|
||||||
|
|
||||||
|
IF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_HAS_WSYNCUP)
|
||||||
|
CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
|
||||||
|
wsyncup "" CURSES_NCURSES_HAS_WSYNCUP)
|
||||||
|
IF( CURSES_NCURSES_HAS_WSYNCUP)
|
||||||
|
SET(CURSES_USE_NCURSES TRUE)
|
||||||
|
ENDIF( CURSES_NCURSES_HAS_WSYNCUP)
|
||||||
|
ENDIF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_HAS_WSYNCUP)
|
||||||
|
|
||||||
|
ENDIF(CURSES_CURSES_LIBRARY AND CURSES_NEED_NCURSES)
|
||||||
|
|
||||||
|
|
||||||
|
IF(NOT CURSES_USE_NCURSES)
|
||||||
|
FIND_FILE(CURSES_HAVE_CURSES_H curses.h )
|
||||||
|
FIND_FILE(CURSES_HAVE_CURSESW_H cursesw.h )
|
||||||
|
FIND_PATH(CURSES_CURSES_H_PATH curses.h )
|
||||||
|
FIND_PATH(CURSES_CURSESW_H_PATH cursesw.h )
|
||||||
|
GET_FILENAME_COMPONENT(_cursesLibDir "${CURSES_CURSES_LIBRARY}" PATH)
|
||||||
|
GET_FILENAME_COMPONENT(_cursesParentDir "${_cursesLibDir}" PATH)
|
||||||
|
|
||||||
|
# for compatibility with older FindCurses.cmake this has to be in the cache
|
||||||
|
# FORCE must not be used since this would break builds which preload a cache wqith these variables set
|
||||||
|
SET(CURSES_INCLUDE_PATH "${CURSES_CURSES_H_PATH} ${CURSES_CURSESW_H_PATH}"
|
||||||
|
CACHE FILEPATH "The curses include path")
|
||||||
|
SET(CURSES_LIBRARY "${CURSES_CURSES_LIBRARY}"
|
||||||
|
CACHE FILEPATH "The curses library")
|
||||||
|
ELSE(NOT CURSES_USE_NCURSES)
|
||||||
|
# we need to find ncurses
|
||||||
|
GET_FILENAME_COMPONENT(_cursesLibDir "${CURSES_NCURSES_LIBRARY}" PATH)
|
||||||
|
GET_FILENAME_COMPONENT(_cursesParentDir "${_cursesLibDir}" PATH)
|
||||||
|
|
||||||
|
FIND_FILE(CURSES_HAVE_NCURSES_H ncurses.h)
|
||||||
|
FIND_FILE(CURSES_HAVE_NCURSES_NCURSES_H ncurses/ncurses.h)
|
||||||
|
FIND_FILE(CURSES_HAVE_NCURSES_CURSES_H ncurses/curses.h)
|
||||||
|
FIND_FILE(CURSES_HAVE_CURSES_H curses.h
|
||||||
|
HINTS "${_cursesParentDir}/include")
|
||||||
|
|
||||||
|
FIND_FILE(CURSES_HAVE_NCURSESW_H ncursesw.h)
|
||||||
|
FIND_FILE(CURSES_HAVE_NCURSESW_NCURSES_H ncursesw/ncurses.h)
|
||||||
|
FIND_FILE(CURSES_HAVE_NCURSESW_CURSES_H ncursesw/curses.h)
|
||||||
|
FIND_FILE(CURSES_HAVE_CURSESW_H cursesw.h
|
||||||
|
HINTS "${_cursesParentDir}/include")
|
||||||
|
|
||||||
|
FIND_PATH(CURSES_NCURSES_INCLUDE_PATH curses.h PATH_SUFFIXES ncursesw)
|
||||||
|
|
||||||
|
# for compatibility with older FindCurses.cmake this has to be in the cache
|
||||||
|
# FORCE must not be used since this would break builds which preload
|
||||||
|
# a cache wqith these variables set
|
||||||
|
# only put ncurses include and library into
|
||||||
|
# variables if they are found
|
||||||
|
IF(CURSES_NCURSES_INCLUDE_PATH AND CURSES_NCURSES_LIBRARY)
|
||||||
|
|
||||||
|
SET(CURSES_INCLUDE_PATH "${CURSES_NCURSES_INCLUDE_PATH} ${CURSES_NCURSESW_INCLUDE_PATH}"
|
||||||
|
CACHE FILEPATH "The curses include path")
|
||||||
|
SET(CURSES_LIBRARY "${CURSES_NCURSES_LIBRARY}"
|
||||||
|
CACHE FILEPATH "The curses library")
|
||||||
|
ENDIF(CURSES_NCURSES_INCLUDE_PATH AND CURSES_NCURSES_LIBRARY)
|
||||||
|
|
||||||
|
ENDIF(NOT CURSES_USE_NCURSES)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FIND_LIBRARY(CURSES_EXTRA_LIBRARY cur_colr HINTS "${_cursesLibDir}")
|
||||||
|
FIND_LIBRARY(CURSES_EXTRA_LIBRARY cur_colr )
|
||||||
|
|
||||||
|
SET(CURSES_FORM_LIBRARY_NAME "form")
|
||||||
|
IF(CURSES_NEED_WIDE)
|
||||||
|
SET(CURSES_FORM_LIBRARY_NAME "formw")
|
||||||
|
ENDIF(CURSES_NEED_WIDE)
|
||||||
|
|
||||||
|
FIND_LIBRARY(CURSES_CURSES_LIBRARY "${CURSES_LIBRARY_NAME}")
|
||||||
|
FIND_LIBRARY(CURSES_FORM_LIBRARY "${CURSES_FORM_LIBRARY_NAME}" HINTS "${_cursesLibDir}")
|
||||||
|
FIND_LIBRARY(CURSES_FORM_LIBRARY "${CURSES_FORM_LIBRARY_NAME}" )
|
||||||
|
|
||||||
|
# for compatibility with older FindCurses.cmake this has to be in the cache
|
||||||
|
# FORCE must not be used since this would break builds which preload a cache
|
||||||
|
# qith these variables set
|
||||||
|
SET(FORM_LIBRARY "${CURSES_FORM_LIBRARY}"
|
||||||
|
CACHE FILEPATH "The curses form library")
|
||||||
|
|
||||||
|
# Need to provide the *_LIBRARIES
|
||||||
|
SET(CURSES_LIBRARIES ${CURSES_LIBRARY})
|
||||||
|
|
||||||
|
IF(CURSES_EXTRA_LIBRARY)
|
||||||
|
SET(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_EXTRA_LIBRARY})
|
||||||
|
ENDIF(CURSES_EXTRA_LIBRARY)
|
||||||
|
|
||||||
|
IF(CURSES_FORM_LIBRARY)
|
||||||
|
SET(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_FORM_LIBRARY})
|
||||||
|
ENDIF(CURSES_FORM_LIBRARY)
|
||||||
|
|
||||||
|
# Proper name is *_INCLUDE_DIR
|
||||||
|
SET(CURSES_INCLUDE_DIR ${CURSES_INCLUDE_PATH})
|
||||||
|
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set CURSES_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Curses DEFAULT_MSG
|
||||||
|
CURSES_LIBRARY CURSES_INCLUDE_PATH)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
CURSES_INCLUDE_PATH
|
||||||
|
CURSES_LIBRARY
|
||||||
|
CURSES_CURSES_INCLUDE_PATH
|
||||||
|
CURSES_CURSES_LIBRARY
|
||||||
|
CURSES_NCURSES_INCLUDE_PATH
|
||||||
|
CURSES_NCURSES_LIBRARY
|
||||||
|
CURSES_EXTRA_LIBRARY
|
||||||
|
FORM_LIBRARY
|
||||||
|
CURSES_FORM_LIBRARY
|
||||||
|
CURSES_LIBRARIES
|
||||||
|
CURSES_INCLUDE_DIR
|
||||||
|
CURSES_CURSES_HAS_WSYNCUP
|
||||||
|
CURSES_NCURSES_HAS_WSYNCUP
|
||||||
|
CURSES_HAVE_CURSESW_H
|
||||||
|
CURSES_HAVE_CURSES_H
|
||||||
|
CURSES_HAVE_NCURSESW_CURSES_H
|
||||||
|
CURSES_HAVE_NCURSESW_H
|
||||||
|
CURSES_HAVE_NCURSESW_NCURSES_H
|
||||||
|
CURSES_HAVE_NCURSES_CURSES_H
|
||||||
|
CURSES_HAVE_NCURSES_H
|
||||||
|
CURSES_HAVE_NCURSES_NCURSES_H
|
||||||
|
)
|
||||||
|
|
|
@ -15,7 +15,9 @@ add_executable(${exe_name}
|
||||||
chat.c
|
chat.c
|
||||||
configdir.c)
|
configdir.c)
|
||||||
|
|
||||||
|
include_directories(${CURSES_INCLUDE_DIR})
|
||||||
|
|
||||||
target_link_libraries(${exe_name}
|
target_link_libraries(${exe_name}
|
||||||
curses)
|
${CURSES_LIBRARIES})
|
||||||
|
|
||||||
linkCoreLibraries(${exe_name})
|
linkCoreLibraries(${exe_name})
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
* Toxic -- Tox Curses Client
|
* Toxic -- Tox Curses Client
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <curses.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "../../core/Messenger.h"
|
#include "../../core/Messenger.h"
|
||||||
#include "../../core/network.h"
|
#include "../../core/network.h"
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int friendnum;
|
int friendnum;
|
||||||
char line[MAX_STR_SIZE];
|
wchar_t line[MAX_STR_SIZE];
|
||||||
size_t pos;
|
size_t pos;
|
||||||
WINDOW *history;
|
WINDOW *history;
|
||||||
WINDOW *linewin;
|
WINDOW *linewin;
|
||||||
|
@ -50,8 +50,6 @@ static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg,
|
||||||
getname(m, num, (uint8_t *) &nick);
|
getname(m, num, (uint8_t *) &nick);
|
||||||
msg[len - 1] = '\0';
|
msg[len - 1] = '\0';
|
||||||
nick[MAX_NAME_LENGTH - 1] = '\0';
|
nick[MAX_NAME_LENGTH - 1] = '\0';
|
||||||
fix_name(msg);
|
|
||||||
fix_name(nick);
|
|
||||||
|
|
||||||
wattron(ctx->history, COLOR_PAIR(2));
|
wattron(ctx->history, COLOR_PAIR(2));
|
||||||
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
||||||
|
@ -74,7 +72,6 @@ static void chat_onAction(ToxWindow *self, Messenger *m, int num, uint8_t *actio
|
||||||
return;
|
return;
|
||||||
|
|
||||||
action[len - 1] = '\0';
|
action[len - 1] = '\0';
|
||||||
fix_name(action);
|
|
||||||
|
|
||||||
wattron(ctx->history, COLOR_PAIR(2));
|
wattron(ctx->history, COLOR_PAIR(2));
|
||||||
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
||||||
|
@ -101,7 +98,6 @@ static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t
|
||||||
wattroff(ctx->history, COLOR_PAIR(2));
|
wattroff(ctx->history, COLOR_PAIR(2));
|
||||||
|
|
||||||
nick[len - 1] = '\0';
|
nick[len - 1] = '\0';
|
||||||
fix_name(nick);
|
|
||||||
snprintf(self->title, sizeof(self->title), "[%s (%d)]", nick, num);
|
snprintf(self->title, sizeof(self->title), "[%s (%d)]", nick, num);
|
||||||
|
|
||||||
wattron(ctx->history, COLOR_PAIR(3));
|
wattron(ctx->history, COLOR_PAIR(3));
|
||||||
|
@ -122,7 +118,7 @@ static void chat_onStatusChange(ToxWindow *self, int num, uint8_t *status, uint1
|
||||||
wattroff(ctx->history, COLOR_PAIR(2));
|
wattroff(ctx->history, COLOR_PAIR(2));
|
||||||
|
|
||||||
status[len - 1] = '\0';
|
status[len - 1] = '\0';
|
||||||
fix_name(status);
|
snprintf(self->title, sizeof(self->title), "[%s (%d)]", status, num);
|
||||||
|
|
||||||
wattron(ctx->history, COLOR_PAIR(3));
|
wattron(ctx->history, COLOR_PAIR(3));
|
||||||
wprintw(ctx->history, "* Your partner changed status to '%s'\n", status);
|
wprintw(ctx->history, "* Your partner changed status to '%s'\n", status);
|
||||||
|
@ -140,7 +136,43 @@ int string_is_empty(char *string)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chat_onKey(ToxWindow *self, Messenger *m, int key)
|
/* convert wide characters to null terminated string */
|
||||||
|
static char *wcs_to_char(wchar_t *string)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
char *ret = NULL;
|
||||||
|
|
||||||
|
len = wcstombs(NULL, string, 0);
|
||||||
|
if (len != (size_t) -1) {
|
||||||
|
len++;
|
||||||
|
ret = malloc(len);
|
||||||
|
wcstombs(ret, string, len);
|
||||||
|
} else {
|
||||||
|
ret = malloc(2);
|
||||||
|
ret[0] = ' ';
|
||||||
|
ret[1] = '\0';
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert a wide char to null terminated string */
|
||||||
|
static char *wc_to_char(wchar_t ch)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
static char ret[MB_LEN_MAX + 1];
|
||||||
|
|
||||||
|
len = wctomb(ret, ch);
|
||||||
|
if (len == -1) {
|
||||||
|
ret[0] = ' ';
|
||||||
|
ret[1] = '\0';
|
||||||
|
} else {
|
||||||
|
ret[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void chat_onKey(ToxWindow *self, Messenger *m, wint_t key)
|
||||||
{
|
{
|
||||||
ChatContext *ctx = (ChatContext *) self->x;
|
ChatContext *ctx = (ChatContext *) self->x;
|
||||||
struct tm *timeinfo = get_time();
|
struct tm *timeinfo = get_time();
|
||||||
|
@ -150,18 +182,18 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key)
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
/* Add printable chars to buffer and print on input space */
|
/* Add printable chars to buffer and print on input space */
|
||||||
if (isprint(key)) {
|
if (iswprint(key)) {
|
||||||
if (ctx->pos != sizeof(ctx->line) - 1) {
|
if (ctx->pos != sizeof(ctx->line) - 1) {
|
||||||
mvwaddch(self->window, y, x, key);
|
mvwaddstr(self->window, y, x, wc_to_char(key));
|
||||||
ctx->line[ctx->pos++] = key;
|
ctx->line[ctx->pos++] = key;
|
||||||
ctx->line[ctx->pos] = '\0';
|
ctx->line[ctx->pos] = L'\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BACKSPACE key: Remove one character from line */
|
/* BACKSPACE key: Remove one character from line */
|
||||||
else if (key == 0x107 || key == 0x8 || key == 0x7f) {
|
else if (key == 0x107 || key == 0x8 || key == 0x7f) {
|
||||||
if (ctx->pos > 0) {
|
if (ctx->pos > 0) {
|
||||||
ctx->line[--ctx->pos] = '\0';
|
ctx->line[--ctx->pos] = L'\0';
|
||||||
|
|
||||||
if (x == 0)
|
if (x == 0)
|
||||||
mvwdelch(self->window, y - 1, x2 - 1);
|
mvwdelch(self->window, y - 1, x2 - 1);
|
||||||
|
@ -172,18 +204,18 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key)
|
||||||
|
|
||||||
/* RETURN key: Execute command or print line */
|
/* RETURN key: Execute command or print line */
|
||||||
else if (key == '\n') {
|
else if (key == '\n') {
|
||||||
|
char *line = wcs_to_char(ctx->line);
|
||||||
wclear(ctx->linewin);
|
wclear(ctx->linewin);
|
||||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
||||||
wclrtobot(self->window);
|
wclrtobot(self->window);
|
||||||
|
|
||||||
if (ctx->line[0] == '/')
|
if (line[0] == '/')
|
||||||
execute(self, ctx, m, ctx->line);
|
execute(self, ctx, m, line);
|
||||||
else {
|
else {
|
||||||
/* make sure the string has at least non-space character */
|
/* make sure the string has at least non-space character */
|
||||||
if (!string_is_empty(ctx->line)) {
|
if (!string_is_empty(line)) {
|
||||||
uint8_t selfname[MAX_NAME_LENGTH];
|
uint8_t selfname[MAX_NAME_LENGTH];
|
||||||
getself_name(m, selfname, sizeof(selfname));
|
getself_name(m, selfname, sizeof(selfname));
|
||||||
fix_name(selfname);
|
|
||||||
|
|
||||||
wattron(ctx->history, COLOR_PAIR(2));
|
wattron(ctx->history, COLOR_PAIR(2));
|
||||||
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
|
||||||
|
@ -191,9 +223,9 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key)
|
||||||
wattron(ctx->history, COLOR_PAIR(1));
|
wattron(ctx->history, COLOR_PAIR(1));
|
||||||
wprintw(ctx->history, "%s: ", selfname);
|
wprintw(ctx->history, "%s: ", selfname);
|
||||||
wattroff(ctx->history, COLOR_PAIR(1));
|
wattroff(ctx->history, COLOR_PAIR(1));
|
||||||
wprintw(ctx->history, "%s\n", ctx->line);
|
wprintw(ctx->history, "%s\n", line);
|
||||||
|
|
||||||
if (m_sendmessage(m, ctx->friendnum, (uint8_t *) ctx->line, strlen(ctx->line) + 1) == 0) {
|
if (m_sendmessage(m, ctx->friendnum, (uint8_t *) line, strlen(line) + 1) == 0) {
|
||||||
wattron(ctx->history, COLOR_PAIR(3));
|
wattron(ctx->history, COLOR_PAIR(3));
|
||||||
wprintw(ctx->history, " * Failed to send message.\n");
|
wprintw(ctx->history, " * Failed to send message.\n");
|
||||||
wattroff(ctx->history, COLOR_PAIR(3));
|
wattroff(ctx->history, COLOR_PAIR(3));
|
||||||
|
@ -201,8 +233,9 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->line[0] = '\0';
|
ctx->line[0] = L'\0';
|
||||||
ctx->pos = 0;
|
ctx->pos = 0;
|
||||||
|
free(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +364,7 @@ void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd)
|
||||||
wprintw(ctx->history, "%s\n", id);
|
wprintw(ctx->history, "%s\n", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(ctx->line, "/close") == 0) {
|
else if (strcmp(cmd, "/close") == 0) {
|
||||||
int f_num = ctx->friendnum;
|
int f_num = ctx->friendnum;
|
||||||
delwin(ctx->linewin);
|
delwin(ctx->linewin);
|
||||||
del_window(self);
|
del_window(self);
|
||||||
|
@ -398,7 +431,6 @@ ToxWindow new_chat(Messenger *m, int friendnum)
|
||||||
|
|
||||||
uint8_t nick[MAX_NAME_LENGTH] = {0};
|
uint8_t nick[MAX_NAME_LENGTH] = {0};
|
||||||
getname(m, friendnum, (uint8_t *) &nick);
|
getname(m, friendnum, (uint8_t *) &nick);
|
||||||
fix_name(nick);
|
|
||||||
|
|
||||||
snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);
|
snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ static void printip(ipbuf buf, IP ip)
|
||||||
sprintf((char *)buf, "%u.%u.%u.%u", ip.c[0], ip.c[1], ip.c[2], ip.c[3]);
|
sprintf((char *)buf, "%u.%u.%u.%u", ip.c[0], ip.c[1], ip.c[2], ip.c[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dhtstatus_onKey(ToxWindow *self, Messenger *m, int key)
|
static void dhtstatus_onKey(ToxWindow *self, Messenger *m, wint_t key)
|
||||||
{
|
{
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* Toxic -- Tox Curses Client
|
* Toxic -- Tox Curses Client
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <curses.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -25,21 +24,6 @@ static friend_t friends[MAX_FRIENDS_NUM];
|
||||||
static int num_friends = 0;
|
static int num_friends = 0;
|
||||||
static int num_selected = 0;
|
static int num_selected = 0;
|
||||||
|
|
||||||
void fix_name(uint8_t *name)
|
|
||||||
{
|
|
||||||
/* Remove all non alphanumeric characters */
|
|
||||||
uint8_t *p = name;
|
|
||||||
uint8_t *q = name;
|
|
||||||
|
|
||||||
while (*p != 0) {
|
|
||||||
if (isprint(*p))
|
|
||||||
*q++ = *p;
|
|
||||||
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*q = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len)
|
void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +42,6 @@ void friendlist_onNickChange(ToxWindow *self, int num, uint8_t *str, uint16_t le
|
||||||
|
|
||||||
memcpy((char *) &friends[num].name, (char *) str, len);
|
memcpy((char *) &friends[num].name, (char *) str, len);
|
||||||
friends[num].name[len] = 0;
|
friends[num].name[len] = 0;
|
||||||
fix_name(friends[num].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t len)
|
void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t len)
|
||||||
|
@ -68,7 +51,6 @@ void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t
|
||||||
|
|
||||||
memcpy((char *) &friends[num].status, (char *) str, len);
|
memcpy((char *) &friends[num].status, (char *) str, len);
|
||||||
friends[num].status[len] = 0;
|
friends[num].status[len] = 0;
|
||||||
fix_name(friends[num].status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int friendlist_onFriendAdded(Messenger *m, int num)
|
int friendlist_onFriendAdded(Messenger *m, int num)
|
||||||
|
@ -84,7 +66,7 @@ int friendlist_onFriendAdded(Messenger *m, int num)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void friendlist_onKey(ToxWindow *self, Messenger *m, int key)
|
static void friendlist_onKey(ToxWindow *self, Messenger *m, wint_t key)
|
||||||
{
|
{
|
||||||
if (key == KEY_UP) {
|
if (key == KEY_UP) {
|
||||||
if (--num_selected < 0)
|
if (--num_selected < 0)
|
||||||
|
|
|
@ -7,6 +7,5 @@
|
||||||
ToxWindow new_friendlist();
|
ToxWindow new_friendlist();
|
||||||
int friendlist_onFriendAdded(Messenger *m, int num);
|
int friendlist_onFriendAdded(Messenger *m, int num);
|
||||||
void disable_chatwin(int f_num);
|
void disable_chatwin(int f_num);
|
||||||
void fix_name(uint8_t *name);
|
|
||||||
|
|
||||||
#endif /* end of include guard: FRIENDLIST_H_53I41IM */
|
#endif /* end of include guard: FRIENDLIST_H_53I41IM */
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* Toxic -- Tox Curses Client
|
* Toxic -- Tox Curses Client
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _XOPEN_SOURCE_EXTENDED
|
||||||
#include <curses.h>
|
#include <curses.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -9,6 +10,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#ifdef _win32
|
#ifdef _win32
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
|
@ -40,6 +42,7 @@ static void init_term()
|
||||||
{
|
{
|
||||||
/* Setup terminal */
|
/* Setup terminal */
|
||||||
signal(SIGWINCH, on_window_resize);
|
signal(SIGWINCH, on_window_resize);
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
initscr();
|
initscr();
|
||||||
cbreak();
|
cbreak();
|
||||||
keypad(stdscr, 1);
|
keypad(stdscr, 1);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <curses.h>
|
|
||||||
|
|
||||||
#include "../../core/Messenger.h"
|
#include "../../core/Messenger.h"
|
||||||
#include "../../core/network.h"
|
#include "../../core/network.h"
|
||||||
|
@ -434,7 +433,7 @@ static void execute(ToxWindow *self, Messenger *m, char *u_cmd)
|
||||||
wprintw(self->window, "Invalid command.\n");
|
wprintw(self->window, "Invalid command.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prompt_onKey(ToxWindow *self, Messenger *m, int key)
|
static void prompt_onKey(ToxWindow *self, Messenger *m, wint_t key)
|
||||||
{
|
{
|
||||||
/* Add printable characters to line */
|
/* Add printable characters to line */
|
||||||
if (isprint(key)) {
|
if (isprint(key)) {
|
||||||
|
|
|
@ -226,16 +226,18 @@ void draw_active_window(Messenger *m)
|
||||||
{
|
{
|
||||||
|
|
||||||
ToxWindow *a = active_window;
|
ToxWindow *a = active_window;
|
||||||
|
wint_t ch = 0;
|
||||||
|
|
||||||
prepare_window(a->window);
|
prepare_window(a->window);
|
||||||
a->blink = false;
|
a->blink = false;
|
||||||
draw_bar();
|
draw_bar();
|
||||||
a->onDraw(a, m);
|
a->onDraw(a, m);
|
||||||
|
|
||||||
/* Handle input */
|
/* Handle input */
|
||||||
int ch = getch();
|
get_wch(&ch);
|
||||||
|
|
||||||
if (ch == '\t' || ch == KEY_BTAB)
|
if (ch == '\t' || ch == KEY_BTAB)
|
||||||
set_next_window(ch);
|
set_next_window((int) ch);
|
||||||
else if (ch != ERR)
|
else if (ch != ERR)
|
||||||
a->onKey(a, m, ch);
|
a->onKey(a, m, ch);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,12 @@
|
||||||
#ifndef _windows_h
|
#ifndef _windows_h
|
||||||
#define _windows_h
|
#define _windows_h
|
||||||
|
|
||||||
|
#define _XOPEN_SOURCE_EXTENDED
|
||||||
#include <curses.h>
|
#include <curses.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <wctype.h>
|
||||||
|
#include <wchar.h>
|
||||||
#include "../../core/Messenger.h"
|
#include "../../core/Messenger.h"
|
||||||
#define MAX_WINDOWS_NUM 32
|
#define MAX_WINDOWS_NUM 32
|
||||||
#define MAX_FRIENDS_NUM 100
|
#define MAX_FRIENDS_NUM 100
|
||||||
|
@ -23,7 +26,7 @@
|
||||||
typedef struct ToxWindow_ ToxWindow;
|
typedef struct ToxWindow_ ToxWindow;
|
||||||
|
|
||||||
struct ToxWindow_ {
|
struct ToxWindow_ {
|
||||||
void(*onKey)(ToxWindow *, Messenger *, int);
|
void(*onKey)(ToxWindow *, Messenger *, wint_t);
|
||||||
void(*onDraw)(ToxWindow *, Messenger *);
|
void(*onDraw)(ToxWindow *, Messenger *);
|
||||||
void(*onInit)(ToxWindow *, Messenger *);
|
void(*onInit)(ToxWindow *, Messenger *);
|
||||||
void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t);
|
void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user