steps towards an ncurses API
This commit is contained in:
parent
523725f375
commit
e9bf4d0986
@ -1,5 +1,7 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
|
||||||
|
|
||||||
|
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
FIND_PACKAGE(PkgConfig)
|
FIND_PACKAGE(PkgConfig)
|
||||||
FIND_PACKAGE(Threads)
|
FIND_PACKAGE(Threads)
|
||||||
|
|
||||||
|
49
cmake/FindReadline.cmake
Normal file
49
cmake/FindReadline.cmake
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Code copied from sethhall@github
|
||||||
|
#
|
||||||
|
# - Try to find readline include dirs and libraries
|
||||||
|
#
|
||||||
|
# Usage of this module as follows:
|
||||||
|
#
|
||||||
|
# find_package(Readline)
|
||||||
|
#
|
||||||
|
# Variables used by this module, they can change the default behaviour and need
|
||||||
|
# to be set before calling find_package:
|
||||||
|
#
|
||||||
|
# Readline_ROOT_DIR Set this variable to the root installation of
|
||||||
|
# readline if the module has problems finding the
|
||||||
|
# proper installation path.
|
||||||
|
#
|
||||||
|
# Variables defined by this module:
|
||||||
|
#
|
||||||
|
# READLINE_FOUND System has readline, include and lib dirs found
|
||||||
|
# Readline_INCLUDE_DIR The readline include directories.
|
||||||
|
# Readline_LIBRARY The readline library.
|
||||||
|
|
||||||
|
find_path(Readline_ROOT_DIR
|
||||||
|
NAMES include/readline/readline.h
|
||||||
|
)
|
||||||
|
|
||||||
|
find_path(Readline_INCLUDE_DIR
|
||||||
|
NAMES readline/readline.h
|
||||||
|
HINTS ${Readline_ROOT_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(Readline_LIBRARY
|
||||||
|
NAMES readline
|
||||||
|
HINTS ${Readline_ROOT_DIR}/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
if(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||||
|
set(READLINE_FOUND TRUE)
|
||||||
|
else(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||||
|
FIND_LIBRARY(Readline_LIBRARY NAMES readline)
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG Readline_INCLUDE_DIR Readline_LIBRARY )
|
||||||
|
MARK_AS_ADVANCED(Readline_INCLUDE_DIR Readline_LIBRARY)
|
||||||
|
endif(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||||
|
|
||||||
|
mark_as_advanced(
|
||||||
|
Readline_ROOT_DIR
|
||||||
|
Readline_INCLUDE_DIR
|
||||||
|
Readline_LIBRARY
|
||||||
|
)
|
@ -3,11 +3,13 @@
|
|||||||
|
|
||||||
#include <dc/apisync.h>
|
#include <dc/apisync.h>
|
||||||
#include <dc/account.h>
|
#include <dc/account.h>
|
||||||
|
#include <dc/guild.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <event.h>
|
#include <event.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
struct dc_api_;
|
struct dc_api_;
|
||||||
typedef struct dc_api_ *dc_api_t;
|
typedef struct dc_api_ *dc_api_t;
|
||||||
@ -48,7 +50,11 @@ bool dc_api_authenticate(dc_api_t api, dc_account_t account);
|
|||||||
bool dc_api_get_userinfo(dc_api_t api, dc_account_t login,
|
bool dc_api_get_userinfo(dc_api_t api, dc_account_t login,
|
||||||
dc_account_t user);
|
dc_account_t user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a list of guilds fro the specified login user. Warning if you
|
||||||
|
* unref the pointer array, you will also unref all the dc_guild_t objects.
|
||||||
|
*/
|
||||||
bool dc_api_get_userguilds(dc_api_t api, dc_account_t login,
|
bool dc_api_get_userguilds(dc_api_t api, dc_account_t login,
|
||||||
GPtrArray *guilds);
|
GPtrArray **guilds);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -126,8 +126,11 @@ bool dc_account_has_token(dc_account_t a)
|
|||||||
void dc_account_set_id(dc_account_t a, char const *id)
|
void dc_account_set_id(dc_account_t a, char const *id)
|
||||||
{
|
{
|
||||||
return_if_true(a == NULL,);
|
return_if_true(a == NULL,);
|
||||||
free(a->id);
|
|
||||||
a->id = strdup(id);
|
if (a->id == NULL || strcmp(a->id, "@me")) {
|
||||||
|
free(a->id);
|
||||||
|
a->id = strdup(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char const *dc_account_id(dc_account_t a)
|
char const *dc_account_id(dc_account_t a)
|
||||||
|
@ -354,32 +354,58 @@ bool dc_api_get_userinfo(dc_api_t api, dc_account_t login,
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
if (reply != NULL) {
|
free(url);
|
||||||
json_decref(reply);
|
json_decref(reply);
|
||||||
reply = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dc_api_get_userguilds(dc_api_t api, dc_account_t login,
|
bool dc_api_get_userguilds(dc_api_t api, dc_account_t login, GPtrArray **out)
|
||||||
|
|
||||||
{
|
{
|
||||||
char *url = NULL;
|
char *url = NULL;
|
||||||
json_t *reply = NULL, *val = NULL;
|
json_t *reply = NULL, *c = NULL, *val = NULL;
|
||||||
|
size_t i = 0;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
GPtrArray *guilds = g_ptr_array_new_with_free_func((GDestroyNotify)dc_unref);
|
||||||
|
|
||||||
return_if_true(api == NULL, false);
|
return_if_true(api == NULL, false);
|
||||||
return_if_true(login == NULL, false);
|
return_if_true(login == NULL, false);
|
||||||
return_if_true(user == NULL, false);
|
|
||||||
|
|
||||||
asprintf(&url, "users/%s/guilds", dc_account_id(user));
|
asprintf(&url, "users/%s/guilds", dc_account_id(login));
|
||||||
|
|
||||||
reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
|
reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL);
|
||||||
goto_if_true(reply == NULL, cleanup);
|
goto_if_true(reply == NULL, cleanup);
|
||||||
|
|
||||||
|
goto_if_true(!json_is_array(reply), cleanup);
|
||||||
|
|
||||||
|
json_array_foreach(reply, i, c) {
|
||||||
|
dc_guild_t g = dc_guild_new();
|
||||||
|
|
||||||
|
val = json_object_get(c, "id");
|
||||||
|
goto_if_true(val == NULL || !json_is_string(val), cleanup);
|
||||||
|
dc_guild_set_id(g, json_string_value(val));
|
||||||
|
|
||||||
|
val = json_object_get(c, "name");
|
||||||
|
goto_if_true(val == NULL || !json_is_string(val), cleanup);
|
||||||
|
dc_guild_set_name(g, json_string_value(val));
|
||||||
|
|
||||||
|
g_ptr_array_add(guilds, g);
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = guilds;
|
||||||
|
guilds = NULL;
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
|
free(url);
|
||||||
json_decref(reply);
|
json_decref(reply);
|
||||||
|
|
||||||
|
if (guilds) {
|
||||||
|
g_ptr_array_unref(guilds);
|
||||||
|
guilds = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ dc_guild_t dc_guild_new(void)
|
|||||||
|
|
||||||
p->ref.cleanup = (dc_cleanup_t)dc_guild_free;
|
p->ref.cleanup = (dc_cleanup_t)dc_guild_free;
|
||||||
|
|
||||||
return p;
|
return dc_ref(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
char const *dc_guild_name(dc_guild_t d)
|
char const *dc_guild_name(dc_guild_t d)
|
||||||
|
@ -199,7 +199,7 @@ bool dc_loop_once(dc_loop_t l)
|
|||||||
struct CURLMsg *msg = NULL;
|
struct CURLMsg *msg = NULL;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
ret = event_base_loop(l->base, EVLOOP_ONCE|EVLOOP_NONBLOCK);
|
ret = event_base_loop(l->base, EVLOOP_ONCE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(NCURSES REQUIRED ncurses)
|
||||||
|
PKG_CHECK_MODULES(PANEL REQUIRED panel)
|
||||||
|
FIND_PACKAGE(Readline)
|
||||||
|
|
||||||
SET(TARGET "ncdc")
|
SET(TARGET "ncdc")
|
||||||
|
|
||||||
SET(SOURCES
|
SET(SOURCES
|
||||||
|
"include/ncdc/mainwindow.h"
|
||||||
|
"include/ncdc/ncdc.h"
|
||||||
|
"src/mainwindow.c"
|
||||||
"src/ncdc.c"
|
"src/ncdc.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,10 +20,16 @@ INCLUDE_DIRECTORIES(
|
|||||||
${CURL_INCLUDE_DIRS}
|
${CURL_INCLUDE_DIRS}
|
||||||
${EVENT_INCLUDE_DIRS}
|
${EVENT_INCLUDE_DIRS}
|
||||||
${GLIB2_INCLUDE_DIRS}
|
${GLIB2_INCLUDE_DIRS}
|
||||||
|
${NCURSES_INCLUDE_DIRS}
|
||||||
|
${PANEL_INCLUDE_DIRS}
|
||||||
|
${Readline_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE(${TARGET} ${SOURCES})
|
ADD_EXECUTABLE(${TARGET} ${SOURCES})
|
||||||
TARGET_LINK_LIBRARIES(${TARGET}
|
TARGET_LINK_LIBRARIES(${TARGET}
|
||||||
${DC_LIBRARIES}
|
${DC_LIBRARIES}
|
||||||
${GLIB2_LIBRARIES}
|
${GLIB2_LIBRARIES}
|
||||||
|
${NCURSES_LIBRARIES}
|
||||||
|
${PANEL_LIBRARIES}
|
||||||
|
${Readline_LIBRARY}
|
||||||
)
|
)
|
||||||
|
14
ncdc/include/ncdc/mainwindow.h
Normal file
14
ncdc/include/ncdc/mainwindow.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef NCDC_MAINWINDOW_H
|
||||||
|
#define NCDC_MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <ncdc/ncdc.h>
|
||||||
|
|
||||||
|
struct ncdc_mainwindow_;
|
||||||
|
typedef struct ncdc_mainwindow_ *ncdc_mainwindow_t;
|
||||||
|
|
||||||
|
bool ncdc_mainwindow_init(void);
|
||||||
|
|
||||||
|
void ncdc_mainwindow_feed(int ch);
|
||||||
|
void ncdc_mainwindow_refresh(void);
|
||||||
|
|
||||||
|
#endif
|
@ -21,7 +21,14 @@
|
|||||||
#include <event.h>
|
#include <event.h>
|
||||||
#include <event2/thread.h>
|
#include <event2/thread.h>
|
||||||
|
|
||||||
//#define DEBUG
|
#include <curses.h>
|
||||||
|
#include <panel.h>
|
||||||
|
#include <readline/history.h>
|
||||||
|
#include <readline/readline.h>
|
||||||
|
|
||||||
|
#include <dc/refable.h>
|
||||||
|
#include <dc/api.h>
|
||||||
|
#include <dc/loop.h>
|
||||||
|
|
||||||
#define return_if_true(v,r) do { if (v) return r; } while(0)
|
#define return_if_true(v,r) do { if (v) return r; } while(0)
|
||||||
#define goto_if_true(v,l) do { if (v) goto l; } while(0)
|
#define goto_if_true(v,l) do { if (v) goto l; } while(0)
|
||||||
|
213
ncdc/src/mainwindow.c
Normal file
213
ncdc/src/mainwindow.c
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
#include <ncdc/mainwindow.h>
|
||||||
|
#include <ncdc/ncdc.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FOCUS_GUILDS = 0,
|
||||||
|
FOCUS_CHAT,
|
||||||
|
FOCUS_INPUT,
|
||||||
|
} focus_t;
|
||||||
|
|
||||||
|
struct ncdc_mainwindow_
|
||||||
|
{
|
||||||
|
dc_refable_t ref;
|
||||||
|
|
||||||
|
WINDOW *guilds;
|
||||||
|
int guilds_w;
|
||||||
|
int guilds_h;
|
||||||
|
int guilds_y;
|
||||||
|
int guilds_x;
|
||||||
|
|
||||||
|
WINDOW *chat;
|
||||||
|
int chat_h;
|
||||||
|
int chat_w;
|
||||||
|
int chat_y;
|
||||||
|
int chat_x;
|
||||||
|
|
||||||
|
WINDOW *input;
|
||||||
|
int input_w;
|
||||||
|
int input_h;
|
||||||
|
int input_y;
|
||||||
|
int input_x;
|
||||||
|
|
||||||
|
char *cmd;
|
||||||
|
int cin;
|
||||||
|
bool cin_ready;
|
||||||
|
|
||||||
|
int focus;
|
||||||
|
};
|
||||||
|
|
||||||
|
static ncdc_mainwindow_t mainwin = NULL;
|
||||||
|
|
||||||
|
static void mainwin_resize(void);
|
||||||
|
static void mainwin_update_focus(void);
|
||||||
|
static void mainwin_command(char *s);
|
||||||
|
|
||||||
|
static int readline_input_avail(void)
|
||||||
|
{
|
||||||
|
return mainwin->cin_ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int readline_getc(FILE *dummy)
|
||||||
|
{
|
||||||
|
mainwin->cin_ready = false;
|
||||||
|
return mainwin->cin;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int measure(char const *string)
|
||||||
|
{
|
||||||
|
size_t needed = mbstowcs(NULL, string, 0) + 1;
|
||||||
|
wchar_t *wcstring = calloc(needed, sizeof(wchar_t));
|
||||||
|
size_t ret = 0;
|
||||||
|
|
||||||
|
return_if_true(wcstring == NULL, -1);
|
||||||
|
|
||||||
|
ret = mbstowcs(wcstring, string, needed);
|
||||||
|
if (ret == (size_t)-1) {
|
||||||
|
free(wcstring);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = wcswidth(wcstring, needed);
|
||||||
|
free(wcstring);
|
||||||
|
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readline_redisplay(void)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
char *line = NULL;
|
||||||
|
int diff = 0;
|
||||||
|
|
||||||
|
asprintf(&line, "%s%s",
|
||||||
|
(rl_display_prompt != NULL ? rl_display_prompt : ""),
|
||||||
|
(rl_line_buffer != NULL ? rl_line_buffer : "")
|
||||||
|
);
|
||||||
|
len = measure(line);
|
||||||
|
|
||||||
|
diff = len - mainwin->input_w + 3;
|
||||||
|
if (diff > 0) {
|
||||||
|
memmove(line, line + diff, len - diff);
|
||||||
|
line[len-diff] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
werase(mainwin->input);
|
||||||
|
mvwprintw(mainwin->input, 1, 1, "%s", line);
|
||||||
|
free(line);
|
||||||
|
|
||||||
|
wrefresh(mainwin->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ncdc_mainwindow_init(void)
|
||||||
|
{
|
||||||
|
mainwin = calloc(1, sizeof(struct ncdc_mainwindow_));
|
||||||
|
return_if_true(mainwin == NULL, false);
|
||||||
|
|
||||||
|
mainwin->guilds = newwin(5, 5, 1, 1);
|
||||||
|
mainwin->chat = newwin(5, 5, 4, 4);
|
||||||
|
mainwin->input = newwin(5, 5, 8, 8);
|
||||||
|
mainwin_resize();
|
||||||
|
|
||||||
|
mainwin->focus = FOCUS_INPUT;
|
||||||
|
mainwin_update_focus();
|
||||||
|
|
||||||
|
rl_getc_function = readline_getc;
|
||||||
|
rl_input_available_hook = readline_input_avail;
|
||||||
|
rl_redisplay_function = readline_redisplay;
|
||||||
|
rl_callback_handler_install("", mainwin_command);
|
||||||
|
|
||||||
|
rl_catch_signals = 0;
|
||||||
|
rl_catch_sigwinch = 0;
|
||||||
|
rl_deprep_term_function = NULL;
|
||||||
|
rl_prep_term_function = NULL;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mainwin_resize(void)
|
||||||
|
{
|
||||||
|
mainwin->guilds_h = LINES;
|
||||||
|
mainwin->guilds_w = (COLS / 5);
|
||||||
|
mainwin->guilds_y = 0;
|
||||||
|
mainwin->guilds_x = 0;
|
||||||
|
|
||||||
|
wresize(mainwin->guilds, mainwin->guilds_h, mainwin->guilds_w);
|
||||||
|
mvwin(mainwin->guilds, mainwin->guilds_y, mainwin->guilds_x);
|
||||||
|
wnoutrefresh(mainwin->guilds);
|
||||||
|
|
||||||
|
mainwin->input_h = 3;
|
||||||
|
mainwin->input_w = COLS - mainwin->guilds_w;
|
||||||
|
mainwin->input_y = LINES - mainwin->input_h;
|
||||||
|
mainwin->input_x = mainwin->guilds_w;
|
||||||
|
|
||||||
|
wresize(mainwin->input, mainwin->input_h, mainwin->input_w);
|
||||||
|
mvwin(mainwin->input, mainwin->input_y, mainwin->input_x);
|
||||||
|
wnoutrefresh(mainwin->input);
|
||||||
|
|
||||||
|
mainwin->chat_h = LINES - mainwin->input_h;
|
||||||
|
mainwin->chat_w = COLS - mainwin->guilds_w;
|
||||||
|
mainwin->chat_y = 0;
|
||||||
|
mainwin->chat_x = mainwin->guilds_w;
|
||||||
|
|
||||||
|
wresize(mainwin->chat, mainwin->chat_h, mainwin->chat_w);
|
||||||
|
mvwin(mainwin->chat, mainwin->chat_y, mainwin->chat_x);
|
||||||
|
wnoutrefresh(mainwin->chat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mainwin_command(char *s)
|
||||||
|
{
|
||||||
|
free(mainwin->cmd);
|
||||||
|
mainwin->cmd = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mainwin_update_focus(void)
|
||||||
|
{
|
||||||
|
switch (mainwin->focus) {
|
||||||
|
case FOCUS_GUILDS:
|
||||||
|
{
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FOCUS_CHAT:
|
||||||
|
{
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case FOCUS_INPUT:
|
||||||
|
{
|
||||||
|
int x = 1, y = 1;
|
||||||
|
wmove(mainwin->input, y, x);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ncdc_mainwindow_feed(int ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case KEY_RESIZE: mainwin_resize(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mainwin->focus) {
|
||||||
|
case FOCUS_INPUT:
|
||||||
|
{
|
||||||
|
mainwin->cin = ch;
|
||||||
|
mainwin->cin_ready = true;
|
||||||
|
rl_callback_read_char();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ncdc_mainwindow_refresh(void)
|
||||||
|
{
|
||||||
|
/* move windows
|
||||||
|
*/
|
||||||
|
box(mainwin->guilds, 0, 0);
|
||||||
|
box(mainwin->chat, 0, 0);
|
||||||
|
box(mainwin->input, 0, 0);
|
||||||
|
|
||||||
|
wrefresh(mainwin->guilds);
|
||||||
|
wrefresh(mainwin->chat);
|
||||||
|
wrefresh(mainwin->input);
|
||||||
|
|
||||||
|
doupdate();
|
||||||
|
}
|
@ -1,8 +1,5 @@
|
|||||||
#include <ncdc/ncdc.h>
|
#include <ncdc/ncdc.h>
|
||||||
|
#include <ncdc/mainwindow.h>
|
||||||
#include <dc/refable.h>
|
|
||||||
#include <dc/api.h>
|
|
||||||
#include <dc/loop.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -11,10 +8,13 @@
|
|||||||
*/
|
*/
|
||||||
struct event *stdin_ev = NULL;
|
struct event *stdin_ev = NULL;
|
||||||
|
|
||||||
|
/* main window
|
||||||
|
*/
|
||||||
|
ncdc_mainwindow_t mainwin = NULL;
|
||||||
|
|
||||||
/* we loop in a different thread
|
/* we loop in a different thread
|
||||||
*/
|
*/
|
||||||
static bool done = false;
|
static bool done = false;
|
||||||
static pthread_t looper;
|
|
||||||
|
|
||||||
char *dc_private_dir = NULL;
|
char *dc_private_dir = NULL;
|
||||||
char *dc_config_file = NULL;
|
char *dc_config_file = NULL;
|
||||||
@ -26,11 +26,14 @@ dc_api_t api = NULL;
|
|||||||
|
|
||||||
static void sighandler(int sig)
|
static void sighandler(int sig)
|
||||||
{
|
{
|
||||||
|
endwin();
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cleanup(void)
|
static void cleanup(void)
|
||||||
{
|
{
|
||||||
|
endwin();
|
||||||
|
|
||||||
if (stdin_ev != NULL) {
|
if (stdin_ev != NULL) {
|
||||||
event_del(stdin_ev);
|
event_del(stdin_ev);
|
||||||
event_free(stdin_ev);
|
event_free(stdin_ev);
|
||||||
@ -38,7 +41,6 @@ static void cleanup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
done = true;
|
done = true;
|
||||||
pthread_join(looper, NULL);
|
|
||||||
|
|
||||||
dc_unref(api);
|
dc_unref(api);
|
||||||
dc_unref(loop);
|
dc_unref(loop);
|
||||||
@ -46,6 +48,12 @@ static void cleanup(void)
|
|||||||
|
|
||||||
static void stdin_handler(int sock, short what, void *data)
|
static void stdin_handler(int sock, short what, void *data)
|
||||||
{
|
{
|
||||||
|
int ch = 0;
|
||||||
|
|
||||||
|
if ((what & EV_READ) == EV_READ) {
|
||||||
|
ch = getch();
|
||||||
|
ncdc_mainwindow_feed(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool init_everything(void)
|
static bool init_everything(void)
|
||||||
@ -79,20 +87,7 @@ static bool init_everything(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *loop_thread(void *arg)
|
dc_account_t account_from_config(void)
|
||||||
{
|
|
||||||
while (!done) {
|
|
||||||
if (!dc_loop_once(loop)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(10 * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dc_account_t account_from_config(void)
|
|
||||||
{
|
{
|
||||||
char const *email = NULL;
|
char const *email = NULL;
|
||||||
char const *password = NULL;
|
char const *password = NULL;
|
||||||
@ -138,25 +133,32 @@ int main(int ac, char **av)
|
|||||||
}
|
}
|
||||||
|
|
||||||
done = false;
|
done = false;
|
||||||
if (pthread_create(&looper, NULL, loop_thread, &done)) {
|
|
||||||
|
initscr();
|
||||||
|
cbreak();
|
||||||
|
noecho();
|
||||||
|
nonl();
|
||||||
|
intrflush(NULL, FALSE);
|
||||||
|
|
||||||
|
if (has_colors()) {
|
||||||
|
start_color();
|
||||||
|
use_default_colors();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ncdc_mainwindow_init()) {
|
||||||
|
fprintf(stderr, "failed to init ncurses\n");
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_account_t a = account_from_config();
|
while (!done) {
|
||||||
if (a == NULL) {
|
ncdc_mainwindow_refresh();
|
||||||
fprintf(stderr, "no account specified in config file; sho-sho!\n");
|
|
||||||
return 3;
|
if (!dc_loop_once(loop)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dc_api_authenticate(api, a)) {
|
endwin();
|
||||||
fprintf(stderr, "authentication failed, wrong password?\n");
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dc_api_userinfo(api, a, a)) {
|
|
||||||
fprintf(stderr, "failed to get user information\n");
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user