background update for favorites data.
auto scroll resview.
use offlaw.so when open a favorite thread that is not listed on the subject.txt.
${OBJ_DIR}/utils/nt_conv_char.o \
${OBJ_DIR}/utils/nt_mutex.o \
${OBJ_DIR}/utils/nt_pthread.o \
+ ${OBJ_DIR}/utils/nt_timer.o \
${OBJ_DIR}/net/nt_socket.o \
${OBJ_DIR}/net/nt_ssl_socket.o \
${OBJ_DIR}/net/nt_http.o \
${INC_DIR}/utils/nt_conv_char.h \
${INC_DIR}/utils/nt_mutex.h \
${INC_DIR}/utils/nt_pthread.h \
+ ${INC_DIR}/utils/nt_timer.h \
${INC_DIR}/utils/nt_std_t.h
SHELL = /bin/sh
@ ${SHELL} prepare_proj.sh
${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
+$(OBJ_DIR)/utils/nt_timer.o : ${SRC_DIR}/utils/nt_timer.c ${INC_FILES}
+ @ ${SHELL} prepare_proj.sh
+ ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
+
$(OBJ_DIR)/_2ch/_2ch.o : ${SRC_DIR}/_2ch/_2ch.c ${INC_FILES}
@ ${SHELL} prepare_proj.sh
${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
${OBJ_DIR}/utils/nt_conv_char.o \
${OBJ_DIR}/utils/nt_mutex.o \
${OBJ_DIR}/utils/nt_pthread.o \
+ ${OBJ_DIR}/utils/nt_timer.o \
${OBJ_DIR}/net/nt_socket.o \
${OBJ_DIR}/net/nt_ssl_socket.o \
${OBJ_DIR}/net/nt_http.o \
${INC_DIR}/utils/nt_conv_char.h \
${INC_DIR}/utils/nt_mutex.h \
${INC_DIR}/utils/nt_pthread.h \
+ ${INC_DIR}/utils/nt_timer.h \
${INC_DIR}/utils/nt_std_t.h
SHELL = /bin/sh
@ ${SHELL} prepare_proj.sh
${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
+$(OBJ_DIR)/utils/nt_timer.o : ${SRC_DIR}/utils/nt_timer.c ${INC_FILES}
+ @ ${SHELL} prepare_proj.sh
+ ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
+
$(OBJ_DIR)/_2ch/_2ch.o : ${SRC_DIR}/_2ch/_2ch.c ${INC_FILES}
@ ${SHELL} prepare_proj.sh
${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
- ntch version 1.0.2.0
+ ntch version 1.0.2.1
This file is part of ntch.
ntch のインストール方法
-ダウンロードファイルを使用する場合、適当なディレクトリにntch-1.0.1.8.tgzファイルを解凍します
+ダウンロードファイルを使用する場合、適当なディレクトリにntch-1.0.2.1.tgzファイルを解凍します
-tar zxvf ntch-1.0.1.8.tgz
+tar zxvf ntch-1.0.2.1.tgz
作成されたディレクトリに移動します
-cd ntch-1.0.1.8
+cd ntch-1.0.2.1
以下のコマンドを実行して、実行ファイルを作成します
#define PACKAGE_NAME "ntch"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "ntch 1.0.2.0"
+#define PACKAGE_STRING "ntch 1.0.2.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "ntch"
#define PACKAGE_URL "https://sourceforge.jp/projects/ntch/"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0.2.0"
+#define PACKAGE_VERSION "1.0.2.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ntch 1.0.2.0.
+# Generated by GNU Autoconf 2.69 for ntch 1.0.2.1.
#
# Report bugs to <akohta001@gmail.com>.
#
# Identity of this package.
PACKAGE_NAME='ntch'
PACKAGE_TARNAME='ntch'
-PACKAGE_VERSION='1.0.2.0'
-PACKAGE_STRING='ntch 1.0.2.0'
+PACKAGE_VERSION='1.0.2.1'
+PACKAGE_STRING='ntch 1.0.2.1'
PACKAGE_BUGREPORT='akohta001@gmail.com'
PACKAGE_URL='https://sourceforge.jp/projects/ntch/'
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures ntch 1.0.2.0 to adapt to many kinds of systems.
+\`configure' configures ntch 1.0.2.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of ntch 1.0.2.0:";;
+ short | recursive ) echo "Configuration of ntch 1.0.2.1:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-ntch configure 1.0.2.0
+ntch configure 1.0.2.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by ntch $as_me 1.0.2.0, which was
+It was created by ntch $as_me 1.0.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by ntch $as_me 1.0.2.0, which was
+This file was extended by ntch $as_me 1.0.2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-ntch config.status 1.0.2.0
+ntch config.status 1.0.2.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
-AC_INIT([ntch], [1.0.2.0], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/])
+AC_INIT([ntch], [1.0.2.1], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADERS([config.h])
- ntch version 1.0.2.0
+ ntch version 1.0.2.1
This file is part of ntch.
デフォルトでregex関数に渡されるので
標準関数の正規表現が使用できます
:n :new 新規取得スレにジャンプ
+ :a :autoscroll 自動スクロール
+ j,k,f,bキー以外の入力で自動スクロール解除
+ k,bキーで反転スクロール
+ .ntchrcファイルにスクロールスピードを指定出来ます
+ 以下の書式でIDとパスワードを指定して下さい。
+ auto-scroll-interval=[数字] ミリ秒で指定(標準値500msec)
お気に入り一覧
d 選択項目をお気に入りから削除
l 直前に表示したお気に入りを再表示
h スレッド選択時にそのスレッドの上位の板を表示
+ .ntchrcファイルにお気に入りの更新頻度を指定出来ます
+ 以下の書式でIDとパスワードを指定して下さい。
+ auto-update-interval=[数字] ミリ秒で指定(標準値60000msec)
free(outp);
return NULL;
}
- //nt_thread_children_free(threadp);
- //threadp->num_res = 0;
if(!feof(fp_src)){
s_src[0] = '\0';
if(!fgets(s_src, S_SIZE, fp_src)){
return FALSE;
boardp = selectp->selected_boardp;
- fwprintf(stderr, L"%ls\n", boardp->name);
+ //fwprintf(stderr, L"%ls\n", boardp->name);
h_mutex = nt_board_get_mutex(&boardp->handle);
if(!h_mutex)
return FALSE;
nt_pthread_release_ref(h_pthread);
nt_2ch_selected_item_release_ref(h_select);
}else{
+ nt_pthread_release_ref(h_pthread);
num_success++;
}
#endif
nt_2ch_selected_item_handle *h_sel_itemp,
nt_searched_thread_handle h_searched_thread, const wchar_t** errorpp)
{
- const wchar_t *board_name, *dat_name;
+ const wchar_t *board_name, *dat_name, *title;
nt_category_handle h_category;
nt_board_handle h_board;
nt_thread_handle h_thread;
assert(board_name);
dat_name = nt_searched_thread_get_dat_name(h_searched_thread);
+ title = nt_searched_thread_get_title(h_searched_thread);
h_board = nt_get_board_by_name(
h_model, board_name, &h_category);
nt_2ch_selected_item_release_ref(h_sel_item);
return FALSE;
}
-
nt_set_selected_board(h_sel_item, h_category, h_board);
}
h_thread = nt_get_thread_by_dat_name(h_board, dat_name);
if(!h_thread){
- *errorpp = L"スレッド情報が見つかりませんでした";
- goto ERROR_TRAP;
+ if(!title)
+ title = L"Dummy";
+ h_thread = nt_thread_dummy_alloc(title, dat_name, 0);
+ if(!h_thread){
+ *errorpp = L"スレッド情報が見つかりませんでした";
+ goto ERROR_TRAP;
+ }
}
nt_set_selected_thread(h_sel_item, h_thread);
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <limits.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
int FORCE_REFRESH = 0;
int THREAD_SORT_TYPE = NT_THREAD_SORT_BY_READ;
int INIT_DISP_STATE = NT_INTI_DISP_BOARDMENU;
-int NT_MAINLOOP_POOLING_INTERVAL;
+int NT_MAINLOOP_POLLING_INTERVAL;
int NT_PTHREAD_POOL_SIZE;
int NT_PTHREAD_POOL_QUEUE_SIZE;
+int NT_AUTO_SCROLL_INTERVAL;
+int NT_AUTO_UPDATE_INTERVAL;
static char *app_name = PACKAGE_NAME;
static char *version_name = PACKAGE_VERSION;
MARU_ID = NULL;
MARU_PW = NULL;
- NT_MAINLOOP_POOLING_INTERVAL = 1000;
+ NT_MAINLOOP_POLLING_INTERVAL = 100;
NT_PTHREAD_POOL_SIZE = 5;
NT_PTHREAD_POOL_QUEUE_SIZE = 20;
+
+ NT_AUTO_SCROLL_INTERVAL = 500;
+ NT_AUTO_UPDATE_INTERVAL = 60000;
uid = getuid();
pw = getpwuid(uid);
char *cptr, *key, *val;
char *sort_type, *init_disp;
char buf[128];
+ long int li;
fp = fopen(path, "r");
if(!fp)
free(init_disp);
continue;
}
+ key = strstr(buf, "auto-scroll-interval");
+ if(key){
+ val = cptr+1;
+ li = strtol(val, NULL, 10);
+ if(li > 0 && li < LONG_MAX )
+ NT_AUTO_SCROLL_INTERVAL = li;
+ continue;
+ }
+ key = strstr(buf, "auto-update-interval");
+ if(key){
+ val = cptr+1;
+ li = strtol(val, NULL, 10);
+ if(li > 0 && li < LONG_MAX )
+ NT_AUTO_UPDATE_INTERVAL = li;
+ continue;
+ }
}
fclose(fp);
return TRUE;
#define PACKAGE_NAME "ntch"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "ntch 1.0.2.0"
+#define PACKAGE_STRING "ntch 1.0.2.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "ntch"
#define PACKAGE_URL "https://sourceforge.jp/projects/ntch/"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0.2.0"
+#define PACKAGE_VERSION "1.0.2.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
extern int FORCE_REFRESH;
extern int THREAD_SORT_TYPE;
extern int INIT_DISP_STATE;
-extern int NT_MAINLOOP_POOLING_INTERVAL;
+extern int NT_MAINLOOP_POLLING_INTERVAL;
extern int NT_PTHREAD_POOL_SIZE;
extern int NT_PTHREAD_POOL_QUEUE_SIZE;
+extern int NT_AUTO_UPDATE_INTERVAL;
+extern int NT_AUTO_SCROLL_INTERVAL;
extern char EDITOR_CMD[];
extern char *MARU_ID;
#define NT_KEY_COMMAND2 '/'
#define NT_KEY_COMMAND3 '?'
#define NT_KEY_CMD_BOARD_UPDATE (65536 + 1)
+#define NT_KEY_CMD_AUTO_SCROLL (65536 + 2)
#define NT_COMMAND1_WRITE_MSG_1 "write"
#define NT_COMMAND1_WRITE_MSG_2 "w"
#define NT_COMMAND1_SEARCH_2 "se"
#define NT_COMMAND1_FAVORITE_1 "favorite"
#define NT_COMMAND1_FAVORITE_2 "f"
+#define NT_COMMAND1_AUTOSCROLL_1 "autoscroll"
+#define NT_COMMAND1_AUTOSCROLL_2 "a"
extern int set_option(int argc, char* argv[]);
#ifndef _NT_SOCKET_H_
#define _NT_SOCKET_H_
+#include "utils/nt_mutex.h"
+
typedef struct tag_nt_socket_t *nt_socket_tp;
typedef struct tag_nt_socket_t{
struct sockaddr_in _sockaddr_in;
+ nt_mutex_handle h_mutex;
} nt_socket_t;
extern nt_socket_tp nt_socket_init(int port, char *addr);
#define DISP_CMD_SEL_FAVORITE_BOARD (5*256)
#define DISP_CMD_SEL_FAVORITE_THREAD (6*256)
#define DISP_CMD_UPDATE_FAVORITE (7*256)
+#define DISP_CMD_AUTO_SCROLL (8*256)
extern int disp_board_menu(nt_window_tp wp,
nt_2ch_model_handle h_model, nt_2ch_selected_item_handle h_select);
#define NT_MUTEX_ROOT_NAME_FILE (L"file:")
+#define NT_MUTEX_ROOT_NAME_NET (L"net:")
typedef struct tag_nt_mutex_handle{
int chk_sum;
extern BOOL nt_mutex_unlock(nt_mutex_handle handle);
extern nt_mutex_handle nt_mutex_get_one_time_handle(const wchar_t *moniker);
extern BOOL nt_mutex_add_moniker(nt_mutex_handle handle, const wchar_t *moniker);
+extern BOOL nt_mutex_add_mbs_moniker(nt_mutex_handle handle, const char *moniker);
#endif /* _NT_MUTEX_H_ */
--- /dev/null
+/* Copyright 2013 Akira Ohta (akohta001@gmail.com)
+ This file is part of ntch.
+
+ The ntch is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The ntch is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ntch. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#ifndef _NT_TIMER_h_
+#define _NT_TIMER_h_
+#include <sys/times.h>
+
+typedef int (*nt_timer_fn)(int id);
+
+typedef struct tag_nt_timer_handle *nt_timer_handle;
+typedef struct tag_nt_timer_handle{
+ int chk_sum;
+}nt_timer_handle_t;
+
+
+extern BOOL nt_timer_lib_init();
+extern void nt_timer_lib_finish();
+extern nt_timer_handle nt_timer_ring_a_bell();
+extern nt_timer_handle nt_timer_alloc(
+ int id, int interval, nt_timer_fn func);
+extern BOOL nt_timer_set_interval(nt_timer_handle h_timer, int interval);
+extern int nt_timer_get_interval(nt_timer_handle h_timer);
+extern int nt_timer_get_id(nt_timer_handle h_timer);
+extern int nt_timer_add_ref(nt_timer_handle h_timer);
+extern int nt_timer_release_ref(nt_timer_handle h_timer);
+
+
+#endif /* _NT_TIMER_h_ */
#include "usr/usr_db_t.h"
#include "utils/nt_mutex.h"
#include "utils/nt_pthread.h"
+#include "utils/nt_timer.h"
#include "usr/favorite_t.h"
#include "_2ch/_2ch.h"
#include "_2ch/maru_2ch.h"
return 1;
}
- if(!nt_2ch_model_init()){
- fputs("Failed to read board menu data.\n", stderr);
- goto ERROR_TRAP;
- }
-
- if(!nt_init_board_menu()){
- fputs("Failed to initialize board menu data.\n", stderr);
- goto ERROR_TRAP;
- }
+ nt_timer_lib_init();
nt_mutex_lib_init();
fputs(err_msg, stderr);
goto ERROR_TRAP;
}
+
+ if(!nt_2ch_model_init()){
+ fputs("Failed to read board menu data.\n", stderr);
+ goto ERROR_TRAP;
+ }
+
+ if(!nt_init_board_menu()){
+ fputs("Failed to initialize board menu data.\n", stderr);
+ goto ERROR_TRAP;
+ }
+
h_favorite = nt_favorite_alloc(L"favorite");
if(!h_favorite){
nt_mutex_lib_finish();
+ nt_timer_lib_finish();
+
return (result);
}
+#define TIMER_ID_AUTO_UPDATE_NONE 0
+#define TIMER_ID_AUTO_UPDATE 1
+#define TIMER_ID_AUTO_SCROLL 2
+static int auto_update_timer_func(int id)
+{
+ switch(id){
+ case TIMER_ID_AUTO_UPDATE:
+ return TIMER_ID_AUTO_UPDATE;
+ case TIMER_ID_AUTO_SCROLL:
+ return TIMER_ID_AUTO_SCROLL;
+ }
+ return TIMER_ID_AUTO_UPDATE_NONE;
+}
static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
nt_favorite_handle h_favorite,
void *handle;
nt_pthread_result_t async_data;
nt_link_tp linkp;
+ BOOL auto_scrolling;
+ nt_timer_handle h_timer_auto_update;
+ nt_timer_handle h_timer_auto_scroll;
+ nt_timer_handle h_timer;
state = DISP_STATE_BOARDMENU;
if(INIT_DISP_STATE == NT_INTI_DISP_FAVORITE){
if(MARU_ID && MARU_PW)
marup = nt_maru_2ch_alloc(MARU_ID, MARU_PW);
+ h_timer_auto_scroll = nt_timer_alloc(
+ TIMER_ID_AUTO_SCROLL, -1, auto_update_timer_func);
+ h_timer_auto_update = nt_timer_alloc(
+ TIMER_ID_AUTO_UPDATE, NT_AUTO_UPDATE_INTERVAL, auto_update_timer_func);
h_write_data = NULL;
marup = NULL;
wclear(scrp);
else
werase(scrp);
+
+
switch(disp_state){
case DISP_STATE_BOARDMENU:
werase(bwinp->wp);
goto END_WHILE;
rwinp->key = ch;
state = disp_reslist(rwinp, state, h_sel_items, db_handle);
+ auto_scrolling = FALSE;
+ if(DISP_CMD(state)){
+ if(DISP_CMD(state) == DISP_CMD_AUTO_SCROLL){
+ if(0 >= nt_timer_get_interval(h_timer_auto_scroll)){
+ nt_timer_set_interval(
+ h_timer_auto_scroll, NT_AUTO_SCROLL_INTERVAL);
+ }
+ auto_scrolling = TRUE;
+ }
+ DISP_CLR_CMD(state);
+ }
+ if(!auto_scrolling){
+ nt_timer_set_interval(h_timer_auto_scroll, -1);
+ }
if(DISP_STATE_ERROR == state){
goto END_WHILE;
}else if(state == DISP_STATE_REFRESH){
touchwin(scrp);
wrefresh(scrp);
- timeout(NT_MAINLOOP_POOLING_INTERVAL);
+ timeout(NT_MAINLOOP_POLLING_INTERVAL);
do{
ch = getch();
if(ch == ERR){
async_data = nt_pthread_get_result_from_que();
if(async_data.code == NT_PTHREAD_RESULT_UPDATE_BOARD){
-
ch = NT_KEY_CMD_BOARD_UPDATE;
+ //fprintf(stderr, "Async result recieved.!\n");
+ }else{
+ h_timer = nt_timer_ring_a_bell();
+ if(h_timer){
+ switch(nt_timer_get_id(h_timer)){
+ case TIMER_ID_AUTO_SCROLL:
+ ch = NT_KEY_CMD_AUTO_SCROLL;
+ break;
+ case TIMER_ID_AUTO_UPDATE:
+ linkp = nt_favorite_get_update_board_list(
+ app_2ch_model, h_favorite);
+ if(linkp){
+ nt_read_board_list(linkp);
+ nt_all_link_free(linkp, _2ch_selected_item_free);
+ //fprintf(stderr, "Update request calling.!\n");
+ }
+ break;
+ }
+ nt_timer_release_ref(h_timer);
+ }
}
}
}while(ch == '\n' || ch == '\r' || ch == ERR);
}/* end switch*/
}/* end while */
END_WHILE:
+ if(h_timer_auto_update)
+ nt_timer_release_ref(h_timer_auto_update);
+ if(h_timer_auto_scroll)
+ nt_timer_release_ref(h_timer_auto_scroll);
if(cookiep)
nt_unload_cookie(cookiep);
if(marup)
nt_socket_tp ptr = malloc(sizeof(nt_socket_t));
if(ptr == NULL)
return NULL;
+
+ ptr->h_mutex = nt_mutex_get_one_time_handle(NT_MUTEX_ROOT_NAME_NET);
+ if(!ptr->h_mutex){
+ free(ptr);
+ return NULL;
+ }
+ if(!nt_mutex_add_mbs_moniker(ptr->h_mutex, addr)){
+ free(ptr);
+ return NULL;
+ }
ptr->_sockaddr_in.sin_family = AF_INET;
ptr->_sockaddr_in.sin_port = htons(port);
if(sockfd == -1)
return -1;
len = sizeof(socketp->_sockaddr_in);
+
+ nt_mutex_lock(socketp->h_mutex);
result = connect(sockfd,
(struct sockaddr *)&(socketp->_sockaddr_in), len);
+ nt_mutex_unlock(socketp->h_mutex);
if(result == -1){
close(sockfd);
return -1;
#include <openssl/err.h>
#include "utils/nt_std_t.h"
+#include "utils/nt_mutex.h"
BOOL result = FALSE;
int n, idx;
int data_len;
+ nt_mutex_handle h_mutex;
+
data_len = *data_lenp;
SSL_load_error_strings();
BIO_set_conn_hostname(bio, connect_host_string);
- if(BIO_do_connect(bio) <= 0)
+ h_mutex = nt_mutex_get_one_time_handle(NT_MUTEX_ROOT_NAME_NET);
+ if(!h_mutex)
+ goto ERROR_TRAP1;
+ if(!nt_mutex_add_mbs_moniker(h_mutex, connect_host_string))
goto ERROR_TRAP1;
+ nt_mutex_lock(h_mutex);
+ if(BIO_do_connect(bio) <= 0){
+ nt_mutex_unlock(h_mutex);
+ goto ERROR_TRAP1;
+ }
+ nt_mutex_unlock(h_mutex);
if(SSL_get_verify_result(ssl) != X509_V_OK){
if(strict_verify)
result_state |= DISP_CMD_DEL_FAVORITE_THREAD;
}else if(sel_flag){
(*h_sel_threadp) = nt_searched_thread_alloc(
- board_name, dat_name, NULL);
+ board_name, dat_name, title);
if((*h_sel_threadp))
result_state |= DISP_CMD_SEL_FAVORITE_THREAD;
}else if(sel_flag2){
#define NT_CMD_ID 4
#define NT_CMD_SEARCH_THREAD 5
#define NT_CMD_FAVORITE 6
+#define NT_CMD_AUTO_SCROLL 7
+
+#define AUTO_SCROLL_NONE 0
+#define AUTO_SCROLL_UP -1
+#define AUTO_SCROLL_DOWN 1
typedef struct tag_ctx_reslist_t *ctx_reslist_tp;
typedef struct tag_ctx_reslist_t
BOOL regex_init;
int sel_res_no;
int sel_res_line;
+
+ int auto_scroll;
nt_link_tp res_disp_list;
nt_usr_db_handle usr_db_handle);
static BOOL reslist_clone(nt_thread_handle h_thread, ctx_reslist_tp ctxp);
static void int_ptr_free(void *ptr);
-static int parse_cmd1(const char *param, int *statep, const char **end);
+static int parse_cmd1(const char *param, const char **end);
static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp,
int *sel_res_no, int *sel_res_line, int column);
static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp,
wchar_t buf[1024*3+1];
wchar_t *cptr;
nt_link_tp link_curp;
- int state;
BOOL search_asc;
BOOL adjust;
BOOL set_value;
int cmd;
attr_t new_res_attr;
const char *endp;
-
+ int result_state;
+ int auto_scroll_state;
+
ctxp = (ctx_reslist_tp)wp->data;
if(!ctxp){
ctxp = init_context(h_select, usr_db_handle);
ctxp->prev_state = prev_state;
ch = wp->key;
-
+ result_state = DISP_STATE_RESLIST;
if(ctxp->max_cur_res < 0 || ctxp->max_cur_offset < 0){
wlines = wp->lines;
clistp = clistp->prev;
}
}
+
+ auto_scroll_state = ctxp->auto_scroll;
+ if(ch == NT_KEY_CMD_AUTO_SCROLL){
+ result_state |= DISP_CMD_AUTO_SCROLL;
+ if(ctxp->auto_scroll == AUTO_SCROLL_UP){
+ ch = NT_KEY_UP;
+ }else{
+ ch = NT_KEY_DOWN;
+ ctxp->auto_scroll = AUTO_SCROLL_DOWN;
+ }
+ }else{
+ ctxp->auto_scroll = AUTO_SCROLL_NONE;
+ }
switch(ch){
+ case NT_KEY_CMD_BOARD_UPDATE:
+ if(auto_scroll_state != AUTO_SCROLL_NONE){
+ result_state |= DISP_CMD_AUTO_SCROLL;
+ ctxp->auto_scroll = auto_scroll_state;
+ }
+ break;
case NT_KEY_REFRESH:
return DISP_STATE_REFRESH;
case NT_KEY_CLOSE:
break;
case NT_KEY_COMMAND1:
assert(wp->cmd_param);
- cmd = parse_cmd1(wp->cmd_param, &state, &endp);
+ cmd = parse_cmd1(wp->cmd_param, &endp);
switch(cmd){
+ case NT_CMD_AUTO_SCROLL:
+ return DISP_CMD_AUTO_SCROLL | DISP_STATE_RESLIST;
case NT_CMD_SEARCH_THREAD:
return DISP_STATE_SEARCH_THREAD;
case NT_CMD_FAVORITE:
return DISP_STATE_FAVORITE;
case NT_CMD_WRITE:
- return state;
+ return DISP_STATE_EDITOR;
case NT_CMD_JMP_NEW:
if(ctxp->prev_read_cnt <= 0)
ctxp->cur_res = 0;
break;
case NT_KEY_UP:
case KEY_UP:
+ if(auto_scroll_state != AUTO_SCROLL_NONE){
+ result_state |= DISP_CMD_AUTO_SCROLL;
+ ctxp->auto_scroll = AUTO_SCROLL_UP;
+ }
ctxp->cur_res_offset--;
if(0 <= ctxp->cur_res_offset){
break;
break;
case NT_KEY_DOWN:
case KEY_DOWN:
+ if(auto_scroll_state != AUTO_SCROLL_NONE){
+ result_state |= DISP_CMD_AUTO_SCROLL;
+ ctxp->auto_scroll = AUTO_SCROLL_DOWN;
+ }
ctxp->cur_res_offset++;
clistp = ctxp->res_disp_list;
for(i = 0; i < ctxp->res_num; i++){
break;
case NT_KEY_PAGEUP:
case KEY_PPAGE:
+ if(auto_scroll_state != AUTO_SCROLL_NONE){
+ result_state |= DISP_CMD_AUTO_SCROLL;
+ ctxp->auto_scroll = AUTO_SCROLL_UP;
+ }
ctxp->cur_res_offset -= wp->lines;
if(ctxp->cur_res_offset >= 0){
break;
break;
case NT_KEY_PAGEDOWN:
case KEY_NPAGE:
+ if(auto_scroll_state != AUTO_SCROLL_NONE){
+ result_state |= DISP_CMD_AUTO_SCROLL;
+ ctxp->auto_scroll = AUTO_SCROLL_DOWN;
+ }
clistp = ctxp->res_disp_list;
if(0 > ctxp->cur_res)
ctxp->cur_res = 0;
}/* end for */
END_FOR:
- return DISP_STATE_RESLIST;
+ return result_state;
}
static int get_id_num(ctx_reslist_tp ctxp, const wchar_t *misc)
return TRUE;
}
-static int parse_cmd1(const char *param, int *statep, const char **end)
+static int parse_cmd1(const char *param, const char **end)
{
int len;
const char *start;
if(0 == strncmp(NT_COMMAND1_WRITE_MSG_1, start,len) ||
0 == strncmp(NT_COMMAND1_WRITE_MSG_2, start,len)){
- *statep = DISP_STATE_EDITOR;
return NT_CMD_WRITE;
}else if(0 == strncmp(NT_COMMAND1_JMP_NEW_1,start,len) ||
0 == strncmp(NT_COMMAND1_JMP_NEW_2, start,len)){
0 == strncmp(NT_COMMAND1_FAVORITE_2,param,
strlen(NT_COMMAND1_FAVORITE_2))){
return NT_CMD_FAVORITE;
+ }else if(0 == strncmp(NT_COMMAND1_AUTOSCROLL_1,param,
+ strlen(NT_COMMAND1_AUTOSCROLL_1)) ||
+ 0 == strncmp(NT_COMMAND1_AUTOSCROLL_2,param,
+ strlen(NT_COMMAND1_AUTOSCROLL_2))){
+ return NT_CMD_AUTO_SCROLL;
}
return NT_CMD_NONE;
}
ctxp->sel_res_line = -1;
ctxp->child_ctx_stackp = NULL;
ctxp->prev_state = DISP_STATE_THREADTITLE;
+ ctxp->auto_scroll = AUTO_SCROLL_NONE;
b_result = reslist_clone(h_thread, ctxp);
nt_thread_release_ref(h_thread);
if(!h_thread)
break;
nt_set_selected_thread(h_select, h_thread);
+ nt_thread_release_ref(h_thread);
result_state |= DISP_CMD_ADD_FAVORITE;
+ break;
}
clistp = ctxp->thread_disp_list;
threadp->title = title;
threadp->parent = NULL;
threadp->ref_count = 1;
-
+ threadp->num_read = 0;
+ threadp->num_res = 0;
return threadp;
}
return TRUE;
}
+BOOL nt_mutex_add_mbs_moniker(nt_mutex_handle handle, const char *moniker)
+{
+ nt_mutex_tp mutexp;
+ nt_link_tp linkp;
+ wchar_t *wc;
+ int len;
+
+ assert(handle);
+ mutexp = (nt_mutex_tp)handle;
+ assert(mutexp->handle.chk_sum == NT_MUTEX_CHK_SUM);
+ assert(mutexp->moniker);
+
+ len = strlen(moniker);
+ if(len == 0)
+ return FALSE;
+
+ wc = malloc(sizeof(wchar_t)*(len+2));
+ if(!wc)
+ return FALSE;
+
+ if(0 >= mbstowcs(wc, moniker, len+2)){
+ free(wc);
+ return FALSE;
+ }
+
+ linkp = nt_link_add_data(mutexp->moniker, wc);
+ if(!linkp){
+ free(wc);
+ return FALSE;
+ }
+ return TRUE;
+}
+
BOOL nt_mutex_lock(nt_mutex_handle handle)
{
nt_mutex_tp mutexp;
int err;
assert(handle);
+ assert(handle->chk_sum == NT_MUTEX_CHK_SUM);
mutexp = (nt_mutex_tp)handle;
- assert(mutexp->handle.chk_sum == NT_MUTEX_CHK_SUM);
err = pthread_mutex_unlock(&mutexp->mutex);
if(err != 0)
return FALSE;
static nt_pthread_result_t nt_pthread_call_result_func(nt_pthread_handle h_pthread);
static BOOL nt_pthread_has_result(nt_pthread_handle h_pthread);
-
BOOL nt_pthread_lib_init(int thread_pool_size, int queue_size,
const char **error_msg)
{
free(g_sem.pthreads);
pthread_mutex_destroy(&(g_sem.mutex));
sem_destroy(&g_sem.sem);
+
+ nt_queue_free(g_sem.h_que, NULL);
+ nt_queue_free(g_sem.h_que_result, NULL);
}
BOOL nt_pthread_put_que(nt_pthread_handle h_pthread)
if(!nt_queue_push(g_sem.h_que, h_pthread))
goto ERROR_TRAP;
+ nt_pthread_add_ref(h_pthread);
+
err = sem_post(&g_sem.sem);
if(err != 0)
goto ERROR_TRAP;
--- /dev/null
+/* Copyright 2013 Akira Ohta (akohta001@gmail.com)
+ This file is part of ntch.
+
+ The ntch is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ The ntch is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ntch. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <wchar.h>
+#include <assert.h>
+
+#include "error.h"
+#include "utils/nt_std_t.h"
+#include "utils/nt_timer.h"
+
+#define NT_TIMER_CHK_SUM (1378428)
+
+
+struct _timer_ctx{
+ nt_link_tp timers;
+}g_timer_ctx;
+
+
+typedef struct tag_nt_timer_t *nt_timer_tp;
+typedef struct tag_nt_timer_t{
+ nt_timer_handle_t handle;
+ int ref_count;
+ int interval;/* -1. desable timer 0. immidiate expire NNN. inteval milli sec.
+ */
+ struct timespec expire;
+
+ int id;
+ int status;
+ nt_timer_fn func;
+
+}nt_timer_t;
+
+static BOOL set_current_time(struct timespec *pts);
+static void add_interval(struct timespec *pts, int interval);
+static void timer_free(void *ptr);
+static BOOL is_expired(const struct timespec *pts, nt_timer_tp);
+
+
+BOOL nt_timer_lib_init()
+{
+ g_timer_ctx.timers = NULL;
+ return TRUE;
+}
+
+
+void nt_timer_lib_finish()
+{
+ if(g_timer_ctx.timers)
+ nt_all_link_free(g_timer_ctx.timers, timer_free);
+}
+
+static BOOL is_expired(const struct timespec *pts, nt_timer_tp timerp)
+{
+ if(timerp->interval == 0)
+ return TRUE;
+ else if(timerp->interval < 0)
+ return FALSE;
+ else if(timerp->expire.tv_sec < pts->tv_sec)
+ return TRUE;
+ else if(timerp->expire.tv_sec > pts->tv_sec)
+ return FALSE;
+ else if(timerp->expire.tv_nsec < pts->tv_nsec)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+nt_timer_handle nt_timer_ring_a_bell()
+{
+ struct timespec ts;
+ nt_timer_tp timerp;
+ nt_link_tp linkp;
+
+ if(!set_current_time(&ts))
+ return NULL;
+
+ if(!g_timer_ctx.timers)
+ return NULL;
+ linkp = g_timer_ctx.timers;
+ do{
+ timerp = linkp->data;
+ if(is_expired(&ts, timerp)){
+ timerp->status =
+ (timerp->func)(timerp->id);
+ add_interval(&timerp->expire, timerp->interval);
+ nt_timer_add_ref(&timerp->handle);
+ return &timerp->handle;
+ }
+ linkp = linkp->next;
+ }while(linkp != g_timer_ctx.timers);
+ return NULL;
+}
+
+
+nt_timer_handle nt_timer_alloc(
+ int id, int interval, nt_timer_fn func)
+{
+ nt_timer_tp timerp;
+ struct timespec ts;
+ nt_link_tp linkp;
+
+ if(interval > 0){
+ if(!set_current_time(&ts))
+ return NULL;
+ add_interval(&ts, interval);
+ }else{
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+
+ timerp = malloc(sizeof(nt_timer_t));
+ if(!timerp)
+ return NULL;
+ timerp->id = id;
+ timerp->status = 0;
+ timerp->interval = interval;
+ timerp->func = func;
+ timerp->expire = ts;
+ timerp->handle.chk_sum = NT_TIMER_CHK_SUM;
+ timerp->ref_count = 1;
+ linkp = nt_link_add_data(g_timer_ctx.timers, timerp);
+ if(!linkp){
+ free(timerp);
+ return NULL;
+ }
+ if(!g_timer_ctx.timers)
+ g_timer_ctx.timers = linkp;
+
+ return &timerp->handle;
+}
+
+BOOL nt_timer_set_interval(nt_timer_handle h_timer, int interval)
+{
+ nt_timer_tp timerp;
+ assert(h_timer);
+ assert(h_timer->chk_sum == NT_TIMER_CHK_SUM);
+ timerp = (nt_timer_tp)h_timer;
+ assert(timerp->ref_count > 0);
+ if(interval > 0){
+ if(!set_current_time(&timerp->expire))
+ return FALSE;
+ add_interval(&timerp->expire, interval);
+ }else{
+ timerp->expire.tv_sec = 0;
+ timerp->expire.tv_nsec = 0;
+ }
+ timerp->interval = interval;
+ return TRUE;
+}
+int nt_timer_get_interval(nt_timer_handle h_timer)
+{
+ nt_timer_tp timerp;
+ assert(h_timer);
+ assert(h_timer->chk_sum == NT_TIMER_CHK_SUM);
+ timerp = (nt_timer_tp)h_timer;
+ assert(timerp->ref_count > 0);
+ return timerp->interval;
+}
+int nt_timer_get_id(nt_timer_handle h_timer)
+{
+ nt_timer_tp timerp;
+ assert(h_timer);
+ assert(h_timer->chk_sum == NT_TIMER_CHK_SUM);
+ timerp = (nt_timer_tp)h_timer;
+ assert(timerp->ref_count > 0);
+ return timerp->id;
+}
+
+
+int nt_timer_add_ref(nt_timer_handle h_timer)
+{
+ nt_timer_tp timerp;
+ assert(h_timer);
+ assert(h_timer->chk_sum == NT_TIMER_CHK_SUM);
+ timerp = (nt_timer_tp)h_timer;
+ assert(timerp->ref_count > 0);
+ return ++timerp->ref_count;
+}
+
+int nt_timer_release_ref(nt_timer_handle h_timer)
+{
+ nt_timer_tp timerp;
+ nt_link_tp linkp;
+
+ assert(h_timer);
+ assert(h_timer->chk_sum == NT_TIMER_CHK_SUM);
+ timerp = (nt_timer_tp)h_timer;
+ assert(timerp->ref_count > 0);
+ if(0 != --timerp->ref_count)
+ return timerp->ref_count;
+
+ if(g_timer_ctx.timers){
+ linkp = g_timer_ctx.timers;
+ do{
+ if(timerp == linkp->data){
+ g_timer_ctx.timers =
+ nt_link_remove2(g_timer_ctx.timers, linkp);
+ free(linkp);
+ free(h_timer);
+ return 0;
+ }
+ linkp = linkp->next;
+ }while(linkp != g_timer_ctx.timers);
+ }
+ assert(0);
+ return 0;
+}
+
+static void timer_free(void *ptr)
+{
+ nt_timer_release_ref((nt_timer_handle)ptr);
+}
+
+static BOOL set_current_time(struct timespec *pts)
+{
+#ifdef CLOCK_MONOTONIC_COARSE
+ if(-1 == clock_gettime(CLOCK_MONOTONIC_COARSE , pts)){
+#else
+ if(-1 == clock_gettime(CLOCK_MONOTONIC , pts)){
+#endif
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void add_interval(struct timespec *pts, int interval)
+{
+ int i_sec, i_nsec;
+ i_sec = interval / 1000;
+ i_nsec = interval % 1000;
+ i_nsec *= 1000000;
+ pts->tv_sec += i_sec;
+ pts->tv_nsec += i_nsec;
+ if(pts->tv_nsec > 1000000000){
+ pts->tv_sec++;
+ pts->tv_nsec -= 1000000000;
+ }
+}
+
+