初始化提交 master
authorfranki <frankizhong@gamil.com>
Tue, 22 Nov 2022 08:33:41 +0000 (16:33 +0800)
committerfranki <frankizhong@gamil.com>
Tue, 22 Nov 2022 08:33:41 +0000 (16:33 +0800)
200 files changed:
Makefile [new file with mode: 0644]
bak/sgi_data.cpp [new file with mode: 0644]
bak/sgi_data.h [new file with mode: 0644]
cabinet/cabinet [new file with mode: 0755]
drivers/mfcard/.tmp_versions/mfcard.mod [new file with mode: 0644]
drivers/mfcard/Makefile [new file with mode: 0644]
drivers/mfcard/mfcard.c [new file with mode: 0644]
drivers/mfcard/mfcard.h [new file with mode: 0644]
drivers/mfcard/mfcard.ko [new file with mode: 0644]
obj/crc.o [new file with mode: 0644]
obj/finger_intf.o [new file with mode: 0644]
obj/fingerprint.o [new file with mode: 0644]
obj/fm_alarm.o [new file with mode: 0644]
obj/fm_alarm_pwd.o [new file with mode: 0644]
obj/fm_borrow_card_manager.o [new file with mode: 0644]
obj/fm_borrow_card_user.o [new file with mode: 0644]
obj/fm_borrow_fpr_manager.o [new file with mode: 0644]
obj/fm_borrow_fpr_user.o [new file with mode: 0644]
obj/fm_borrow_photo_user.o [new file with mode: 0644]
obj/fm_borrow_pwd_manager.o [new file with mode: 0644]
obj/fm_borrow_pwd_user.o [new file with mode: 0644]
obj/fm_borrow_unlock.o [new file with mode: 0644]
obj/fm_box_manage.o [new file with mode: 0644]
obj/fm_chpwd.o [new file with mode: 0644]
obj/fm_download.o [new file with mode: 0644]
obj/fm_info_choice.o [new file with mode: 0644]
obj/fm_info_register.o [new file with mode: 0644]
obj/fm_info_stat.o [new file with mode: 0644]
obj/fm_level.o [new file with mode: 0644]
obj/fm_log_alarm.o [new file with mode: 0644]
obj/fm_log_borrow.o [new file with mode: 0644]
obj/fm_log_main.o [new file with mode: 0644]
obj/fm_log_manager.o [new file with mode: 0644]
obj/fm_log_return.o [new file with mode: 0644]
obj/fm_log_system.o [new file with mode: 0644]
obj/fm_main.o [new file with mode: 0644]
obj/fm_menu.o [new file with mode: 0644]
obj/fm_menu_pwd.o [new file with mode: 0644]
obj/fm_mon_setting.o [new file with mode: 0644]
obj/fm_reg_box.o [new file with mode: 0644]
obj/fm_reg_bullet.o [new file with mode: 0644]
obj/fm_reg_fpr1_1.o [new file with mode: 0644]
obj/fm_reg_fpr1_2.o [new file with mode: 0644]
obj/fm_reg_fpr1_3.o [new file with mode: 0644]
obj/fm_reg_gun.o [new file with mode: 0644]
obj/fm_reg_person.o [new file with mode: 0644]
obj/fm_reg_photo.o [new file with mode: 0644]
obj/fm_reg_pwd.o [new file with mode: 0644]
obj/fm_reg_unit.o [new file with mode: 0644]
obj/fm_return_card_manager.o [new file with mode: 0644]
obj/fm_return_card_user.o [new file with mode: 0644]
obj/fm_return_fpr_manager.o [new file with mode: 0644]
obj/fm_return_fpr_user.o [new file with mode: 0644]
obj/fm_return_photo_user.o [new file with mode: 0644]
obj/fm_return_pwd_manager.o [new file with mode: 0644]
obj/fm_return_pwd_user.o [new file with mode: 0644]
obj/fm_return_unlock.o [new file with mode: 0644]
obj/fm_safecheck.o [new file with mode: 0644]
obj/fm_stat_box.o [new file with mode: 0644]
obj/fm_stat_bullet.o [new file with mode: 0644]
obj/fm_stat_gun.o [new file with mode: 0644]
obj/fm_stat_person.o [new file with mode: 0644]
obj/fm_stat_unit.o [new file with mode: 0644]
obj/fm_system.o [new file with mode: 0644]
obj/fm_timing.o [new file with mode: 0644]
obj/fm_unlock.o [new file with mode: 0644]
obj/fm_unlock_pwd.o [new file with mode: 0644]
obj/fm_user_level.o [new file with mode: 0644]
obj/main.o [new file with mode: 0644]
obj/monitor.o [new file with mode: 0644]
obj/net.o [new file with mode: 0644]
obj/pinyin.o [new file with mode: 0644]
obj/raw_i2c.o [new file with mode: 0644]
obj/sgi_base.o [new file with mode: 0644]
obj/sgi_base_box.o [new file with mode: 0644]
obj/sgi_base_button.o [new file with mode: 0644]
obj/sgi_base_check.o [new file with mode: 0644]
obj/sgi_base_edit.o [new file with mode: 0644]
obj/sgi_base_form.o [new file with mode: 0644]
obj/sgi_base_grid.o [new file with mode: 0644]
obj/sgi_base_ime.o [new file with mode: 0644]
obj/sgi_base_indicator.o [new file with mode: 0644]
obj/sgi_base_label.o [new file with mode: 0644]
obj/sgi_base_msgbox.o [new file with mode: 0644]
obj/sgi_base_picture.o [new file with mode: 0644]
obj/sgi_base_radio.o [new file with mode: 0644]
obj/sgi_base_updown.o [new file with mode: 0644]
obj/sgi_base_window.o [new file with mode: 0644]
obj/sgi_data.o [new file with mode: 0644]
obj/sgi_form_manage.o [new file with mode: 0644]
obj/sgi_ime.o [new file with mode: 0644]
obj/sgi_log.o [new file with mode: 0644]
obj/sgi_msgbox.o [new file with mode: 0644]
obj/sgi_resource.o [new file with mode: 0644]
obj/sgi_string.o [new file with mode: 0644]
obj/uart.o [new file with mode: 0644]
obj/udisk.o [new file with mode: 0644]
src/crc.cpp [new file with mode: 0644]
src/finger_intf.cpp [new file with mode: 0644]
src/fingerprint.cpp [new file with mode: 0755]
src/fingerprint.h [new file with mode: 0755]
src/fm_alarm.cpp [new file with mode: 0644]
src/fm_alarm_pwd.cpp [new file with mode: 0644]
src/fm_borrow_card_manager.cpp [new file with mode: 0644]
src/fm_borrow_card_user.cpp [new file with mode: 0644]
src/fm_borrow_fpr_manager.cpp [new file with mode: 0644]
src/fm_borrow_fpr_user.cpp [new file with mode: 0644]
src/fm_borrow_photo_user.cpp [new file with mode: 0644]
src/fm_borrow_pwd_manager.cpp [new file with mode: 0644]
src/fm_borrow_pwd_user.cpp [new file with mode: 0644]
src/fm_borrow_unlock.cpp [new file with mode: 0644]
src/fm_box_manage.cpp [new file with mode: 0644]
src/fm_chpwd.cpp [new file with mode: 0644]
src/fm_download.cpp [new file with mode: 0644]
src/fm_info_choice.cpp [new file with mode: 0644]
src/fm_info_register.cpp [new file with mode: 0644]
src/fm_info_stat.cpp [new file with mode: 0644]
src/fm_level.cpp [new file with mode: 0644]
src/fm_log_alarm.cpp [new file with mode: 0644]
src/fm_log_borrow.cpp [new file with mode: 0644]
src/fm_log_main.cpp [new file with mode: 0644]
src/fm_log_manager.cpp [new file with mode: 0644]
src/fm_log_return.cpp [new file with mode: 0644]
src/fm_log_system.cpp [new file with mode: 0644]
src/fm_main.cpp [new file with mode: 0644]
src/fm_menu.cpp [new file with mode: 0644]
src/fm_menu_pwd.cpp [new file with mode: 0644]
src/fm_mon_setting.cpp [new file with mode: 0644]
src/fm_reg_box.cpp [new file with mode: 0644]
src/fm_reg_bullet.cpp [new file with mode: 0644]
src/fm_reg_fpr1_1.cpp [new file with mode: 0644]
src/fm_reg_fpr1_2.cpp [new file with mode: 0644]
src/fm_reg_fpr1_3.cpp [new file with mode: 0644]
src/fm_reg_gun.cpp [new file with mode: 0644]
src/fm_reg_person.cpp [new file with mode: 0644]
src/fm_reg_photo.cpp [new file with mode: 0644]
src/fm_reg_pwd.cpp [new file with mode: 0644]
src/fm_reg_unit.cpp [new file with mode: 0644]
src/fm_return_card_manager.cpp [new file with mode: 0644]
src/fm_return_card_user.cpp [new file with mode: 0644]
src/fm_return_fpr_manager.cpp [new file with mode: 0644]
src/fm_return_fpr_user.cpp [new file with mode: 0644]
src/fm_return_photo_user.cpp [new file with mode: 0644]
src/fm_return_pwd_manager.cpp [new file with mode: 0644]
src/fm_return_pwd_user.cpp [new file with mode: 0644]
src/fm_return_unlock.cpp [new file with mode: 0644]
src/fm_safecheck.cpp [new file with mode: 0644]
src/fm_stat_box.cpp [new file with mode: 0644]
src/fm_stat_bullet.cpp [new file with mode: 0644]
src/fm_stat_gun.cpp [new file with mode: 0644]
src/fm_stat_person.cpp [new file with mode: 0644]
src/fm_stat_unit.cpp [new file with mode: 0644]
src/fm_system.cpp [new file with mode: 0644]
src/fm_timing.cpp [new file with mode: 0644]
src/fm_unlock.cpp [new file with mode: 0644]
src/fm_unlock_pwd.cpp [new file with mode: 0644]
src/fm_user_level.cpp [new file with mode: 0644]
src/global_def.h [new file with mode: 0644]
src/global_func.h [new file with mode: 0644]
src/global_macro.h [new file with mode: 0644]
src/lock.h [new file with mode: 0644]
src/main.cpp [new file with mode: 0644]
src/monitor.cpp [new file with mode: 0644]
src/net.cpp [new file with mode: 0644]
src/pinyin.cpp [new file with mode: 0755]
src/raw_i2c.cpp [new file with mode: 0644]
src/sgi_base.cpp [new file with mode: 0755]
src/sgi_base_box.cpp [new file with mode: 0644]
src/sgi_base_button.cpp [new file with mode: 0644]
src/sgi_base_check.cpp [new file with mode: 0644]
src/sgi_base_edit.cpp [new file with mode: 0644]
src/sgi_base_form.cpp [new file with mode: 0644]
src/sgi_base_grid.cpp [new file with mode: 0644]
src/sgi_base_ime.cpp [new file with mode: 0644]
src/sgi_base_indicator.cpp [new file with mode: 0644]
src/sgi_base_label.cpp [new file with mode: 0644]
src/sgi_base_msgbox.cpp [new file with mode: 0644]
src/sgi_base_picture.cpp [new file with mode: 0644]
src/sgi_base_radio.cpp [new file with mode: 0644]
src/sgi_base_updown.cpp [new file with mode: 0644]
src/sgi_base_window.cpp [new file with mode: 0644]
src/sgi_data.cpp [new file with mode: 0644]
src/sgi_data.h [new file with mode: 0644]
src/sgi_form_manage.cpp [new file with mode: 0644]
src/sgi_ime.cpp [new file with mode: 0644]
src/sgi_log.cpp [new file with mode: 0644]
src/sgi_log.h [new file with mode: 0644]
src/sgi_msgbox.cpp [new file with mode: 0644]
src/sgi_resource.cpp [new file with mode: 0755]
src/sgi_resource.h [new file with mode: 0755]
src/sgi_string.c [new file with mode: 0644]
src/sgi_string.h [new file with mode: 0644]
src/sgi_types.h [new file with mode: 0644]
src/uart.cpp [new file with mode: 0644]
src/udisk.cpp [new file with mode: 0644]
temp/sgi_data.cpp [new file with mode: 0644]
temp/sgi_data.h [new file with mode: 0644]
templet/fm_xxx.cpp [new file with mode: 0644]
templet/grid-temp.c [new file with mode: 0644]
templet/sgi_form_xxx.cpp [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..47d3fcf
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,52 @@
+#Makefile for emulator
+TARGET = cabinet
+
+SRCS_DIR       = src
+OBJS_DIR       = obj
+HPP_SRCS       = $(wildcard $(SRCS_DIR)/*.h)
+CC_SRCS        = $(wildcard $(SRCS_DIR)/*.c)
+ASM_SRCS       = $(wildcard $(SRCS_DIR)/*.S)
+CXX_SRCS       = $(wildcard $(SRCS_DIR)/*.cpp)
+CC_OBJS        = $(CC_SRCS:$(SRCS_DIR)/%.c=$(OBJS_DIR)/%.o)
+ASM_OBJS       = $(ASM_SRCS:$(SRCS_DIR)/%.S=$(OBJS_DIR)/%.o)
+CXX_OBJS       = $(CXX_SRCS:$(SRCS_DIR)/%.cpp=$(OBJS_DIR)/%.o)
+OBJS           = $(CC_OBJS) $(ASM_OBJS) $(CXX_OBJS)
+
+CROSS          = arm-linux-
+CC             = $(CROSS)gcc
+CXX            = $(CROSS)g++
+CC_FLAGS       = -pipe -Wall -W -Wno-write-strings -O2
+CXX_FLAGS      = -pipe -Wall -W -Wno-write-strings -O2
+INCS           = -I. -I./src -I/opt/crosstool/arm-linux-sdl/include/SDL
+LIBS           = -L/opt/crosstool/arm-linux-sdl/lib -Wl,-rpath,/opt/crosstool/arm-linux-sdl/lib -lSDL -lSDL_image -lSDL_ttf -lSDL_mixer -lpthread -lm -lz 
+
+#all : check_dir $(TARGET)
+       
+$(TARGET): $(OBJS) $(HPP_SRCS)
+       $(CXX) -o $@ $^  $(INCS) $(LIBS)
+       arm-linux-strip $(TARGET)
+
+
+$(CC_OBJS): $(OBJS_DIR)/%.o : $(SRCS_DIR)/%.c
+       $(CC) $(CC_FLAGS) $(INCS) -o $@ -c $< 
+       
+$(ASM_OBJS): $(OBJS_DIR)/%.o : $(SRCS_DIR)/%.S
+       $(CC) $(CC_FLAGS) $(INCS) -o $@ -c $<
+       
+$(CXX_OBJS): $(OBJS_DIR)/%.o : $(SRCS_DIR)/%.cpp
+       $(CXX) $(CXX_FLAGS) $(INCS) -o $@ -c $< 
+
+.PHONY : check_dir     
+check_dir:
+       @echo $(OBJS_DIR)
+       test -d $(OBJS_DIR) || mkdir -p $(OBJS_DIR)
+
+.PHONY : install
+install:
+       rm -f /home/franki/minicom/upload/$(TARGET)
+       cp $(TARGET) /home/franki/minicom/upload/.
+
+.PHONY : clean
+clean:
+       rm -f $(TARGET)
+       rm -rf $(OBJS_DIR)/*
diff --git a/bak/sgi_data.cpp b/bak/sgi_data.cpp
new file mode 100644 (file)
index 0000000..1569c68
--- /dev/null
@@ -0,0 +1,237 @@
+#include "global_func.h"
+
+static std::vector <struct person_data > s_person_vec;
+       
+s32 data_open(void)
+{
+       u32 i;
+       u32 count;
+       struct person_data person;
+       
+       /* 清空人员记录数据 */
+       s_person_vec.clear();
+       
+       /* 打开人员数据文件 */
+       FILE *fp = fopen(DATA_FILE(person), "rb");
+       if (fp == NULL) {
+               return FAIL;    
+       }       
+       
+       /* 获取记录数 */
+       fseek(fp, 0, SEEK_END);
+       count = ftell(fp) / sizeof(struct person_data);
+       fseek(fp, 0, SEEK_SET);
+       
+       /* 读取人员数据 */
+       for (i = 0; i < count; ++i) {
+               fread(&person, 1, sizeof(struct person_data), fp);
+               s_person_vec.push_back(person);
+       }
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+               
+       return 0;
+}
+
+s32 search_uid(struct sgi_passport *pass, s32 type, u32 param)
+{
+       assert(pass != NULL);
+       
+       u32 i;
+       s32 found = 0;
+       
+       if (type == SR_FPR) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].level == LV_USER
+                               && (s_person_vec[i].fpr1 == param ||
+                               s_person_vec[i].fpr2 == param)) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].uid, 
+                                       COUNTOF(s_person_vec[i].uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].name,
+                                       COUNTOF(s_person_vec[i].name));
+                               found = 1;
+                               break;          
+                       }       
+               }               
+       }
+       else if (type == SR_CARD) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].level == LV_USER
+                               && s_person_vec[i].idcard == param) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].uid, 
+                                       COUNTOF(s_person_vec[i].uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].name,
+                                       COUNTOF(s_person_vec[i].name));
+                               found = 1;
+                               break;          
+                       }       
+               }       
+       }
+       
+       if (!found) {
+               return FAIL;
+       }
+               
+       return 0;
+}
+
+s32 search_mid(struct sgi_passport *pass, s32 type, u32 param)
+{
+       assert(pass != NULL);
+       
+       u32 i;
+       s32 found = 0;
+       
+       if (type == SR_FPR) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].level == LV_MANAGER
+                               && (s_person_vec[i].fpr1 == param ||
+                               s_person_vec[i].fpr2 == param)) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].uid, 
+                                       COUNTOF(s_person_vec[i].uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].name,
+                                       COUNTOF(s_person_vec[i].name));
+                               found = 1;
+                               break;          
+                       }       
+               }               
+       }
+       else if (type == SR_CARD) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].level == LV_MANAGER
+                               && s_person_vec[i].idcard == param) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].uid, 
+                                       COUNTOF(s_person_vec[i].uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].name,
+                                       COUNTOF(s_person_vec[i].name));
+                               found = 1;
+                               break;          
+                       }       
+               }       
+       }
+       
+       if (!found) {
+               return FAIL;
+       }
+               
+       return 0;
+}
+
+s32 verify_user_pwd(struct sgi_passport *pass, u16 *uid, u16 *pwd)
+{
+       assert(uid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (s_person_vec[i].level != LV_USER
+                       || (sgi_ncmp16(s_person_vec[i].uid, uid, 
+                       COUNTOF(s_person_vec[i].uid)) != 0)) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].pwd, pwd,
+                       COUNTOF(s_person_vec[i].pwd)) == 0) {
+                       if (pass) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].uid, 
+                                       COUNTOF(s_person_vec[i].uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].name,
+                                       COUNTOF(s_person_vec[i].name));
+                       }
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+s32 verify_manager_pwd(struct sgi_passport *pass, u16 *mid, u16 *pwd)
+{
+       assert(mid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (s_person_vec[i].level != LV_MANAGER
+                       || (sgi_ncmp16(s_person_vec[i].uid, mid, 
+                       COUNTOF(s_person_vec[i].uid)) != 0)) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].pwd, pwd,
+                       COUNTOF(s_person_vec[i].pwd)) == 0) {
+                       if (pass) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].uid, 
+                                       COUNTOF(s_person_vec[i].uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].name,
+                                       COUNTOF(s_person_vec[i].name));
+                       }
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+static s32 verify_all_user_pwd(u16 *uid, u16 *pwd)
+{
+       assert(uid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (sgi_ncmp16(s_person_vec[i].uid, uid, 
+                       COUNTOF(s_person_vec[i].uid)) != 0) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].pwd, pwd,
+                       COUNTOF(s_person_vec[i].pwd)) == 0) {
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+s32 change_pwd(u16 *uid, u16 *old_pwd, u16 *new_pwd)
+{
+       assert(uid != NULL || old_pwd != NULL || new_pwd != NULL);
+       
+       s32 r;
+       
+       /* 校验旧密码是否有效 */
+       r = verify_all_user_pwd(uid, old_pwd);
+       if (r < 0) {
+               return r;
+       }
+       
+       /* 修改为新密码 */
+       sgi_ncp16(s_person_vec[r].pwd, new_pwd, COUNTOF(s_person_vec[r].pwd));
+       
+       return 0;
+}
+
+void data_close(void)
+{
+       s_person_vec.clear();   
+}
diff --git a/bak/sgi_data.h b/bak/sgi_data.h
new file mode 100644 (file)
index 0000000..436f26b
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef SGI_DATA_H
+#define SGI_DATA_H
+
+#include "sgi_types.h"
+
+struct person_data {
+       u16 uid[16];
+       u16 name[16];
+       u8 sex;
+       u8 age;
+       u8 dept;
+       u8 level;
+       u16 fpr1;
+       u16 fpr2;
+       u32 idcard;
+       u16 pwd[16];    
+};
+
+struct gun_data {
+       u16 code[16];
+       u16 model[16];
+       u16 caliber[8];
+       u16 bullet[8];
+       u16 holder[16];
+       u16 unit[16];
+       u16 stock_date[16];
+       u16 lock_code;
+       u16 status;
+};
+
+struct box_data {
+       u16 type;
+       u16 cap;
+       u16 code[16];
+       u16 model[16];
+       u16 manager[16];
+       u16 unit[16];   
+};
+
+struct sgi_passport {
+       u32 visit;
+       u16 uid[16];
+       u16 name[16];
+       u16 dept[16];
+       u16 mid[16];
+       u16 mname[16];
+       u16 mdept[16];
+       char photo[64];
+};
+
+#endif
diff --git a/cabinet/cabinet b/cabinet/cabinet
new file mode 100755 (executable)
index 0000000..f6e1492
Binary files /dev/null and b/cabinet/cabinet differ
diff --git a/drivers/mfcard/.tmp_versions/mfcard.mod b/drivers/mfcard/.tmp_versions/mfcard.mod
new file mode 100644 (file)
index 0000000..a487164
--- /dev/null
@@ -0,0 +1,2 @@
+/home/franki/projects/franki/drivers/mfcard/mfcard.ko
+/home/franki/projects/franki/drivers/mfcard/mfcard.o
diff --git a/drivers/mfcard/Makefile b/drivers/mfcard/Makefile
new file mode 100644 (file)
index 0000000..abc93d1
--- /dev/null
@@ -0,0 +1,14 @@
+obj-m:=mfcard.o
+KDIR:=/opt/crosstool/source/linux-3.0.8
+PWD:=$(shell pwd)
+all:
+       $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+       @rm -rf *.mod.*
+       @rm -rf .*.cmd
+       @rm -rf *.o
+       @rm -rf modules.*
+       @rm -rf Module.*
+       
+clean:
+       rm -rf *.ko
+       
diff --git a/drivers/mfcard/mfcard.c b/drivers/mfcard/mfcard.c
new file mode 100644 (file)
index 0000000..c415ad7
--- /dev/null
@@ -0,0 +1,466 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+//#include <asm/irq.h>
+//#include <asm/io.h>
+//#include <asm/system.h>
+#include <asm/uaccess.h>
+
+//#include <mach/hardware.h>
+//#include <linux/sched.h>
+#include <linux/interrupt.h>
+
+#include "mfcard.h"
+
+#if 0
+#define GPG2CON (mfcard_devp->gpio + S5P_GPG2CON)
+#define GPG2DAT        (mfcard_devp->gpio + S5P_GPG2DAT)
+#define GPG2PUD        (mfcard_devp->gpio + S5P_GPG2PUD)
+#define GPH1CON (mfcard_devp->gpio + S5P_GPH1CON)
+#define GPH1DAT        (mfcard_devp->gpio + S5P_GPH1DAT)
+#define GPH1PUD        (mfcard_devp->gpio + S5P_GPH1PUD)
+
+#define WD0()  ((__raw_readl(GPH1DAT) & (1 << 3)) == 0)
+#define WD1()  ((__raw_readl(GPG1DAT) & (1 << 1)) == 0)
+#endif
+
+struct mfcard_dev_t *mfcard_devp = NULL;
+static int s_mfcard_major = MFCARD_MAJOR;
+
+struct mfcard_gpio_desc mfcard[] = {
+       {S5PV210_GPH2(0), 0, "WD0"},
+       {S5PV210_GPH2(1), 1, "WD1"},    
+};
+
+static atomic_t s_card_id = {0};
+static atomic_t s_card_read_state = {0};
+static volatile int s_card_bit = 0;
+static volatile int s_card_bit_count = 0;
+
+static int data_check(void)
+{
+       int d = atomic_read(&s_card_id);
+       int nums1 = 0;
+       int nums2 = 0;
+       int i;
+       
+       int b0 = (d >> 25) & 1; /* 前12bit偶校验 */
+       int b25 = d & 1; /* 后12bit奇校验 */
+       
+       for (i = 0; i < 12; ++i) {
+               nums1 += (d >> (25 - 1 - i)) & 1;
+               nums2 += (d >> (12 - i)) & 1;
+       }
+       
+       printk(KERN_INFO "b0: %x, b1: %x\n", nums1, nums2);
+       if (b0 == (nums1 & 1) && b25 == (~nums2 & 1)) {
+               d = (d >> 1) & 0x00ffffff;
+               atomic_set(&s_card_id, d);
+               return 1;
+       }
+       
+       return 0;               
+}
+
+static void mfcard_timer(unsigned long data)
+{      
+       atomic_set(&s_card_id, s_card_bit);
+       if (data_check()) {
+               atomic_set(&s_card_read_state, 1);
+       }
+       else {
+               atomic_set(&s_card_read_state, -1);
+       }
+       printk(KERN_INFO "card id: %08X\n", atomic_read(&s_card_id));   
+       s_card_bit = 0;
+       s_card_bit_count = 0;
+}
+
+static irqreturn_t mfcard_interrupt(int irq, void *dev_id)
+{
+       struct mfcard_gpio_desc *bdata = (struct mfcard_gpio_desc *)dev_id;
+       
+       //printk(KERN_INFO "v: %d\n", bdata->val);
+       s_card_bit_count++;
+               
+       if (s_card_bit_count < 26) {
+               s_card_bit <<= 1;
+               s_card_bit |= bdata->val;
+       }
+       else if (s_card_bit_count == 26) {
+               s_card_bit <<= 1;
+               s_card_bit |= bdata->val;
+               mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(1));        
+       }
+
+       return IRQ_HANDLED;     
+}
+
+static void s5p_mfcard_port_open(void)
+{
+       unsigned int reg_val;
+       int irq;
+       int i;
+       int err = 0;
+       
+#if 0
+       if (mfcard_devp == NULL) {
+               return;
+       }
+#endif
+       
+       /* 配置声光报警控制引脚 */
+       err = gpio_request(BJ_SPK, "BJ-SPK");
+       if (err) {
+               printk(KERN_INFO "request BJ_SPK fail.\n");
+       }
+       gpio_set_value(BJ_SPK, 0);
+       s3c_gpio_cfgpin(BJ_SPK, S3C_GPIO_OUTPUT);
+       
+       /* 配置指纹电源控制引脚 */
+       err = gpio_request(PW_CTRL, "PW_CTRL");
+       if (err) {
+               printk(KERN_INFO "request PW_CTRL fail.\n");
+       }
+       gpio_set_value(PW_CTRL, 1);
+       s3c_gpio_cfgpin(PW_CTRL, S3C_GPIO_OUTPUT);
+       
+       /* 配置大门锁控制引脚 */
+       err = gpio_request(DOOR_CTRL, "DOOR_CTRL");
+       if (err) {
+               printk(KERN_INFO "request DOOR_CTRL fail.\n");
+       }
+       gpio_set_value(DOOR_CTRL, 1);
+       s3c_gpio_cfgpin(DOOR_CTRL, S3C_GPIO_OUTPUT);
+       
+       /* 配置大门锁反馈引脚 */
+       err = gpio_request(DOOR_FB, "DOOR_FB");
+       if (err) {
+               printk(KERN_INFO "request DOOR_FB fail.\n");
+       }
+       s3c_gpio_cfgpin(DOOR_FB, S3C_GPIO_INPUT);
+       
+       /* 指纹按下检测 */
+       err = gpio_request(FPR_DETECT, "FPR_DETECT");
+       if (err) {
+               printk(KERN_INFO "request FPR_DETECT fail.\n");
+       }
+       s3c_gpio_cfgpin(FPR_DETECT, S3C_GPIO_INPUT);
+       
+       /* 供电检测 */
+       err = gpio_request(PW_JC, "PW_JC");
+       if (err) {
+               printk(KERN_INFO "request PW_JC fail.\n");
+       }
+       s3c_gpio_cfgpin(PW_JC, S3C_GPIO_INPUT);
+       
+       /* 在位检测1 */
+       err = gpio_request(QWZ1, "QWZ1");
+       if (err) {
+               printk(KERN_INFO "request QWZ1 fail.\n");
+       }
+       s3c_gpio_cfgpin(QWZ1, S3C_GPIO_INPUT);
+       
+       /* 在位检测2 */
+       err = gpio_request(QWZ2, "QWZ2");
+       if (err) {
+               printk(KERN_INFO "request QWZ2 fail.\n");
+       }
+       s3c_gpio_cfgpin(QWZ2, S3C_GPIO_INPUT);
+       
+       /* 获取GPIO访问指针 */
+       //mfcard_devp->gpio = ioremap(GPIO_BASE, GPIO_SIZE);
+       
+       for (i = 0; i < ARRAY_SIZE(mfcard); i++) {
+               setup_timer(&mfcard[i].timer, mfcard_timer, 
+                       (unsigned long)&mfcard[i]);
+                       
+               irq = gpio_to_irq(mfcard[i].gpio);
+               printk(KERN_INFO "%s: %d\n", mfcard[i].name, irq);
+               err = request_irq(irq, mfcard_interrupt, IRQ_TYPE_EDGE_FALLING,
+                       mfcard[i].name, (void *)&mfcard[i]);
+               
+               if (err) {
+                       break;
+               }
+       }
+       
+       if (err) {
+               for (; i > 0; i--) {
+                       irq = gpio_to_irq(mfcard[i - 1].gpio);
+                       disable_irq(irq);
+                       free_irq(irq, (void *)&mfcard[i - 1]);
+                       
+                       del_timer_sync(&mfcard[i - 1].timer);   
+               }
+               printk(KERN_INFO "request fail: %x.\n", err);
+       }
+
+#if 0  
+       /* 配置MFCARD通讯端口 */
+       /* GPG1_1 = input */
+       reg_val = __raw_readl(GPG2CON);
+       reg_val &= ~(0xf << 4); 
+       __raw_writel(reg_val, GPG2CON); 
+
+       /* GPH1_3 = input */
+       reg_val = __raw_readl(GPH1CON);
+       reg_val &= ~(0xf << 12);
+       reg_val |= 1 << 12;     
+       __raw_writel(reg_val, GPH1CON);
+       
+       reg_val = __raw_readl(GPH1DAT);
+       reg_val |= 1 << 3;
+       __raw_writel(reg_val, GPH1DAT); 
+       
+       printk(KERN_INFO "GPH1CON: 0x%x.\n", __raw_readl(GPH1CON));
+       printk(KERN_INFO "GPG2CON: 0x%x.\n", __raw_readl(GPG2CON));
+#endif
+}
+
+static void s5p_mfcard_port_close(void)
+{
+       //iounmap(mfcard_devp->gpio);   
+}
+
+int mfcard_open(struct inode *inodep, struct file *filep)
+{
+       printk(KERN_INFO "mfcard open()\n");
+       filep->private_data = mfcard_devp;
+       
+       return 0;       
+}
+
+int mfcard_release(struct inode *inodep, struct file *filep)
+{
+       printk(KERN_INFO "mfcard release()\n");
+       
+       return 0;
+}
+
+static long mfcard_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+       long val;
+       
+       switch (cmd) {          
+       case MFCARD_IOCTL_ALARM:
+               if (get_user(val, (long *)arg)) {
+                       return -EFAULT; 
+               }
+                       
+               gpio_set_value(BJ_SPK, val & 1);                
+               break;
+               
+       case MFCARD_IOCTL_PW_CTRL:
+               if (get_user(val, (long *)arg)) {
+                       return -EFAULT; 
+               }
+                       
+               gpio_set_value(PW_CTRL, val & 1);
+               break;
+               
+       case MFCARD_IOCTL_CARD_START:
+               atomic_set(&s_card_id, 0);
+               atomic_set(&s_card_read_state, 0);
+               break;
+               
+       case MFCARD_IOCTL_CARD_STATE:
+               val = atomic_read(&s_card_read_state);
+               if (put_user(val, (long *)arg)) {
+                       return -EFAULT;
+               }
+               break;
+               
+               
+       case MFCARD_IOCTL_CARD_READ:
+               val = atomic_read(&s_card_id);
+               if (put_user(val, (long *)arg)) {
+                       return -EFAULT;
+               }
+               break;
+               
+       case MFCARD_IOCTL_FPR_STATE:
+               val = gpio_get_value(FPR_DETECT);
+               if (put_user(val, (long *)arg)) {
+                       return -EFAULT;
+               }
+               break;
+               
+       case MFCARD_IOCTL_DOOR_CTRL:
+               if (get_user(val, (long *)arg)) {
+                       return -EFAULT; 
+               }
+                       
+               gpio_set_value(DOOR_CTRL, val & 1);
+               break;
+               
+       case MFCARD_IOCTL_DOOR_FB:
+               val = gpio_get_value(DOOR_FB);
+               if (put_user(val, (long *)arg)) {
+                       return -EFAULT;
+               }
+               break;
+               
+       case MFCARD_IOCTL_PW_JC:
+               val = gpio_get_value(PW_JC);
+               if (put_user(val, (long *)arg)) {
+                       return -EFAULT;
+               }
+               break;
+               
+       case MFCARD_IOCTL_QWZ1:
+               val = gpio_get_value(QWZ1);
+               if (put_user(val, (long *)arg)) {
+                       return -EFAULT;
+               }
+               break;
+               
+       case MFCARD_IOCTL_QWZ2:
+               val = gpio_get_value(QWZ2);
+               if (put_user(val, (long *)arg)) {
+                       return -EFAULT;
+               }
+               break;
+               
+       default:
+               return -EINVAL;
+       }
+       
+       return 0;       
+}
+
+static ssize_t mfcard_read(struct file *filep, char __user *buf, size_t size,
+                               loff_t *ppos)
+{
+       printk(KERN_INFO "mfcard read()\n");
+       
+       return 0;       
+}
+
+static ssize_t mfcard_write(struct file *filep, const char __user *buf,
+                               size_t size, loff_t *ppos)
+{
+       printk(KERN_INFO "mfcard write()\n");
+       
+       return 0;       
+}
+
+static const struct file_operations mfcard_fops =
+{
+       .owner = THIS_MODULE,
+       .read = mfcard_read,
+       .write = mfcard_write,
+       .unlocked_ioctl = mfcard_ioctl,
+       .open = mfcard_open,
+       .release = mfcard_release,
+};
+
+static struct miscdevice misc_mfcard_dev = {
+       .minor  = MISC_DYNAMIC_MINOR,
+       .name   = "mfcard",
+       .fops   = &mfcard_fops,
+};
+
+static void mfcard_setup_cdev(struct mfcard_dev_t *devp, int index)
+{
+       int err;
+       dev_t devno = MKDEV(s_mfcard_major, index);
+
+       cdev_init(&devp->cdev, &mfcard_fops);
+       devp->cdev.owner = THIS_MODULE;
+       err = cdev_add(&devp->cdev, devno, 1);
+       if (err) {
+               printk(KERN_NOTICE "Error %d adding mfcard %d\n", err, index);
+       }
+}
+
+int __init mfcard_init(void)
+{
+       int result;
+       dev_t devno = MKDEV(s_mfcard_major, 0);
+       
+       printk(KERN_INFO "mfcard init()\n");
+
+#if 0
+       /* 申请设备号 */
+       if (s_mfcard_major) {
+               /* 静态申请设备号 */
+               result = register_chrdev_region(devno, 1, "mfcard");
+       }
+       else {
+               /* 动态申请设备号 */
+               result = alloc_chrdev_region(&devno, 0, 1, "mfcard");
+               s_mfcard_major = MAJOR(devno);
+       }
+
+       if (result < 0) {
+               return result;
+       }
+
+       /* 动态申请设备结构体内存 */
+       mfcard_devp = kmalloc(sizeof(struct mfcard_dev_t), GFP_KERNEL);
+       if (mfcard_devp == NULL) {
+               result = -ENOMEM;
+               goto fail_kmalloc;
+       }
+               
+       memset(mfcard_devp, 0, sizeof(struct mfcard_dev_t));
+       mfcard_setup_cdev(mfcard_devp, 1);
+#endif
+       
+       /* 配置通讯端口 */
+       printk(KERN_INFO "config mfcard gpio.\n");
+       s5p_mfcard_port_open();
+       
+       result = misc_register(&misc_mfcard_dev);
+       
+       return result;
+       
+//fail_kmalloc:
+//     unregister_chrdev_region(devno, 1);
+//     return result;
+}
+
+void __exit mfcard_exit(void)
+{
+       int irq;
+       int i;
+       
+       printk(KERN_INFO "mfcard exit.\n");
+       
+       for (i = 0; i < ARRAY_SIZE(mfcard); ++i) {
+               irq = gpio_to_irq(mfcard[i].gpio);
+               free_irq(irq, (void *)&mfcard[i]);
+               
+               del_timer_sync(&mfcard[i].timer);       
+       }
+
+#if 0
+       cdev_del(&mfcard_devp->cdev);
+       kfree(mfcard_devp);
+       unregister_chrdev_region(MKDEV(s_mfcard_major, 0), 1);
+#endif
+       
+       /* 释放已影射的通讯IO端口 */
+       s5p_mfcard_port_close();
+       
+       misc_deregister(&misc_mfcard_dev);
+}
+
+module_param(s_mfcard_major, int, S_IRUGO);
+module_init(mfcard_init);
+module_exit(mfcard_exit);
+
+MODULE_AUTHOR("franki");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("Mifeare card driver");
diff --git a/drivers/mfcard/mfcard.h b/drivers/mfcard/mfcard.h
new file mode 100644 (file)
index 0000000..04fbfef
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef MFCARD_H
+#define MFCARD_H
+
+#include <linux/ioctl.h>
+#include <mach/gpio.h>
+#include <mach/regs-gpio.h>
+#include <plat/gpio-cfg.h>
+
+#define MFCARD_MAGIC           'E'
+#define MFCARD_MAJOR           250
+#define MFCARD_IOCTL_ALARM     _IOW(MFCARD_MAGIC, 1, int)
+#define MFCARD_IOCTL_PW_CTRL   _IOW(MFCARD_MAGIC, 2, int)
+#define MFCARD_IOCTL_DOOR_CTRL _IOW(MFCARD_MAGIC, 3, int)
+#define MFCARD_IOCTL_CARD_START        _IOW(MFCARD_MAGIC, 4, int)
+#define MFCARD_IOCTL_CARD_STATE        _IOR(MFCARD_MAGIC, 5, int)
+#define MFCARD_IOCTL_CARD_READ _IOR(MFCARD_MAGIC, 6, int)
+#define MFCARD_IOCTL_FPR_STATE _IOR(MFCARD_MAGIC, 7, int)
+#define MFCARD_IOCTL_DOOR_FB   _IOR(MFCARD_MAGIC, 8, int)
+#define MFCARD_IOCTL_PW_JC     _IOR(MFCARD_MAGIC, 9, int)
+#define MFCARD_IOCTL_QWZ1      _IOR(MFCARD_MAGIC, 10, int)
+#define MFCARD_IOCTL_QWZ2      _IOR(MFCARD_MAGIC, 11, int)     
+
+#define GPIO_BASE              0xE0200000
+#define GPIO_SIZE              0x1000          /* Page size */
+
+#define S5P_GPG2CON            0x01E0
+#define S5P_GPG2DAT            0x01E4
+#define S5P_GPG2PUD            0x01E8
+#define S5P_GPG2DRV            0x01EC
+
+#define S5P_GPH1CON            0x0C20
+#define S5P_GPH1DAT            0x0C24
+#define S5P_GPH1PUD            0x0C28
+#define S5P_GPH1DRV            0x0C2C
+
+#if 0
+#define PW_CTRL                        S5PV210_GPH1(3)
+#define DOOR_FB                        S5PV210_GPG2(3)
+#define DOOR_CTRL              S5PV210_GPG2(5)
+#define FPR_DETECT             S5PV210_GPG2(4)
+#define BJ_SPK                 S5PV210_GPG2(6)
+#else
+#define PW_CTRL                        S5PV210_GPG2(0)
+#define DOOR_FB                        S5PV210_GPG2(2)
+#define DOOR_CTRL              S5PV210_GPG2(3)
+#define FPR_DETECT             S5PV210_GPG2(4)
+#define BJ_SPK                 S5PV210_GPG2(5)
+#define PW_JC                  S5PV210_GPH1(3)
+#define QWZ1                   S5PV210_GPH2(2)
+#define QWZ2                   S5PV210_GPH2(3)
+#endif
+       
+struct mfcard_dev_t {
+       struct cdev cdev;
+       void __iomem *gpio;
+};
+
+struct mfcard_gpio_desc {
+       int gpio;
+       int val;
+       char *name;
+       struct timer_list timer;
+};
+
+#endif /* MFCARD_H */
diff --git a/drivers/mfcard/mfcard.ko b/drivers/mfcard/mfcard.ko
new file mode 100644 (file)
index 0000000..4781c37
Binary files /dev/null and b/drivers/mfcard/mfcard.ko differ
diff --git a/obj/crc.o b/obj/crc.o
new file mode 100644 (file)
index 0000000..e781b6a
Binary files /dev/null and b/obj/crc.o differ
diff --git a/obj/finger_intf.o b/obj/finger_intf.o
new file mode 100644 (file)
index 0000000..52f39a7
Binary files /dev/null and b/obj/finger_intf.o differ
diff --git a/obj/fingerprint.o b/obj/fingerprint.o
new file mode 100644 (file)
index 0000000..05ee92f
Binary files /dev/null and b/obj/fingerprint.o differ
diff --git a/obj/fm_alarm.o b/obj/fm_alarm.o
new file mode 100644 (file)
index 0000000..8f059e6
Binary files /dev/null and b/obj/fm_alarm.o differ
diff --git a/obj/fm_alarm_pwd.o b/obj/fm_alarm_pwd.o
new file mode 100644 (file)
index 0000000..9379c59
Binary files /dev/null and b/obj/fm_alarm_pwd.o differ
diff --git a/obj/fm_borrow_card_manager.o b/obj/fm_borrow_card_manager.o
new file mode 100644 (file)
index 0000000..73bbd1d
Binary files /dev/null and b/obj/fm_borrow_card_manager.o differ
diff --git a/obj/fm_borrow_card_user.o b/obj/fm_borrow_card_user.o
new file mode 100644 (file)
index 0000000..b9f1163
Binary files /dev/null and b/obj/fm_borrow_card_user.o differ
diff --git a/obj/fm_borrow_fpr_manager.o b/obj/fm_borrow_fpr_manager.o
new file mode 100644 (file)
index 0000000..c37c8a2
Binary files /dev/null and b/obj/fm_borrow_fpr_manager.o differ
diff --git a/obj/fm_borrow_fpr_user.o b/obj/fm_borrow_fpr_user.o
new file mode 100644 (file)
index 0000000..7057b03
Binary files /dev/null and b/obj/fm_borrow_fpr_user.o differ
diff --git a/obj/fm_borrow_photo_user.o b/obj/fm_borrow_photo_user.o
new file mode 100644 (file)
index 0000000..b05e568
Binary files /dev/null and b/obj/fm_borrow_photo_user.o differ
diff --git a/obj/fm_borrow_pwd_manager.o b/obj/fm_borrow_pwd_manager.o
new file mode 100644 (file)
index 0000000..65ac49d
Binary files /dev/null and b/obj/fm_borrow_pwd_manager.o differ
diff --git a/obj/fm_borrow_pwd_user.o b/obj/fm_borrow_pwd_user.o
new file mode 100644 (file)
index 0000000..1a968d1
Binary files /dev/null and b/obj/fm_borrow_pwd_user.o differ
diff --git a/obj/fm_borrow_unlock.o b/obj/fm_borrow_unlock.o
new file mode 100644 (file)
index 0000000..6978e69
Binary files /dev/null and b/obj/fm_borrow_unlock.o differ
diff --git a/obj/fm_box_manage.o b/obj/fm_box_manage.o
new file mode 100644 (file)
index 0000000..6f6c06e
Binary files /dev/null and b/obj/fm_box_manage.o differ
diff --git a/obj/fm_chpwd.o b/obj/fm_chpwd.o
new file mode 100644 (file)
index 0000000..6e4d5e5
Binary files /dev/null and b/obj/fm_chpwd.o differ
diff --git a/obj/fm_download.o b/obj/fm_download.o
new file mode 100644 (file)
index 0000000..d7983a6
Binary files /dev/null and b/obj/fm_download.o differ
diff --git a/obj/fm_info_choice.o b/obj/fm_info_choice.o
new file mode 100644 (file)
index 0000000..de1f0a8
Binary files /dev/null and b/obj/fm_info_choice.o differ
diff --git a/obj/fm_info_register.o b/obj/fm_info_register.o
new file mode 100644 (file)
index 0000000..61dec24
Binary files /dev/null and b/obj/fm_info_register.o differ
diff --git a/obj/fm_info_stat.o b/obj/fm_info_stat.o
new file mode 100644 (file)
index 0000000..d9d188d
Binary files /dev/null and b/obj/fm_info_stat.o differ
diff --git a/obj/fm_level.o b/obj/fm_level.o
new file mode 100644 (file)
index 0000000..b67b559
Binary files /dev/null and b/obj/fm_level.o differ
diff --git a/obj/fm_log_alarm.o b/obj/fm_log_alarm.o
new file mode 100644 (file)
index 0000000..3edb69f
Binary files /dev/null and b/obj/fm_log_alarm.o differ
diff --git a/obj/fm_log_borrow.o b/obj/fm_log_borrow.o
new file mode 100644 (file)
index 0000000..db1ab53
Binary files /dev/null and b/obj/fm_log_borrow.o differ
diff --git a/obj/fm_log_main.o b/obj/fm_log_main.o
new file mode 100644 (file)
index 0000000..e904804
Binary files /dev/null and b/obj/fm_log_main.o differ
diff --git a/obj/fm_log_manager.o b/obj/fm_log_manager.o
new file mode 100644 (file)
index 0000000..22c7150
Binary files /dev/null and b/obj/fm_log_manager.o differ
diff --git a/obj/fm_log_return.o b/obj/fm_log_return.o
new file mode 100644 (file)
index 0000000..9467515
Binary files /dev/null and b/obj/fm_log_return.o differ
diff --git a/obj/fm_log_system.o b/obj/fm_log_system.o
new file mode 100644 (file)
index 0000000..502e14d
Binary files /dev/null and b/obj/fm_log_system.o differ
diff --git a/obj/fm_main.o b/obj/fm_main.o
new file mode 100644 (file)
index 0000000..8b12950
Binary files /dev/null and b/obj/fm_main.o differ
diff --git a/obj/fm_menu.o b/obj/fm_menu.o
new file mode 100644 (file)
index 0000000..d9e04d2
Binary files /dev/null and b/obj/fm_menu.o differ
diff --git a/obj/fm_menu_pwd.o b/obj/fm_menu_pwd.o
new file mode 100644 (file)
index 0000000..56768f3
Binary files /dev/null and b/obj/fm_menu_pwd.o differ
diff --git a/obj/fm_mon_setting.o b/obj/fm_mon_setting.o
new file mode 100644 (file)
index 0000000..ff19063
Binary files /dev/null and b/obj/fm_mon_setting.o differ
diff --git a/obj/fm_reg_box.o b/obj/fm_reg_box.o
new file mode 100644 (file)
index 0000000..6953a33
Binary files /dev/null and b/obj/fm_reg_box.o differ
diff --git a/obj/fm_reg_bullet.o b/obj/fm_reg_bullet.o
new file mode 100644 (file)
index 0000000..028145c
Binary files /dev/null and b/obj/fm_reg_bullet.o differ
diff --git a/obj/fm_reg_fpr1_1.o b/obj/fm_reg_fpr1_1.o
new file mode 100644 (file)
index 0000000..f909571
Binary files /dev/null and b/obj/fm_reg_fpr1_1.o differ
diff --git a/obj/fm_reg_fpr1_2.o b/obj/fm_reg_fpr1_2.o
new file mode 100644 (file)
index 0000000..5e609b1
Binary files /dev/null and b/obj/fm_reg_fpr1_2.o differ
diff --git a/obj/fm_reg_fpr1_3.o b/obj/fm_reg_fpr1_3.o
new file mode 100644 (file)
index 0000000..287a2d2
Binary files /dev/null and b/obj/fm_reg_fpr1_3.o differ
diff --git a/obj/fm_reg_gun.o b/obj/fm_reg_gun.o
new file mode 100644 (file)
index 0000000..e6bf331
Binary files /dev/null and b/obj/fm_reg_gun.o differ
diff --git a/obj/fm_reg_person.o b/obj/fm_reg_person.o
new file mode 100644 (file)
index 0000000..84b1d0f
Binary files /dev/null and b/obj/fm_reg_person.o differ
diff --git a/obj/fm_reg_photo.o b/obj/fm_reg_photo.o
new file mode 100644 (file)
index 0000000..39de94e
Binary files /dev/null and b/obj/fm_reg_photo.o differ
diff --git a/obj/fm_reg_pwd.o b/obj/fm_reg_pwd.o
new file mode 100644 (file)
index 0000000..0afbeb4
Binary files /dev/null and b/obj/fm_reg_pwd.o differ
diff --git a/obj/fm_reg_unit.o b/obj/fm_reg_unit.o
new file mode 100644 (file)
index 0000000..7eee749
Binary files /dev/null and b/obj/fm_reg_unit.o differ
diff --git a/obj/fm_return_card_manager.o b/obj/fm_return_card_manager.o
new file mode 100644 (file)
index 0000000..3c75ae8
Binary files /dev/null and b/obj/fm_return_card_manager.o differ
diff --git a/obj/fm_return_card_user.o b/obj/fm_return_card_user.o
new file mode 100644 (file)
index 0000000..c9df17f
Binary files /dev/null and b/obj/fm_return_card_user.o differ
diff --git a/obj/fm_return_fpr_manager.o b/obj/fm_return_fpr_manager.o
new file mode 100644 (file)
index 0000000..3b17154
Binary files /dev/null and b/obj/fm_return_fpr_manager.o differ
diff --git a/obj/fm_return_fpr_user.o b/obj/fm_return_fpr_user.o
new file mode 100644 (file)
index 0000000..501df31
Binary files /dev/null and b/obj/fm_return_fpr_user.o differ
diff --git a/obj/fm_return_photo_user.o b/obj/fm_return_photo_user.o
new file mode 100644 (file)
index 0000000..de2bcff
Binary files /dev/null and b/obj/fm_return_photo_user.o differ
diff --git a/obj/fm_return_pwd_manager.o b/obj/fm_return_pwd_manager.o
new file mode 100644 (file)
index 0000000..b0a8332
Binary files /dev/null and b/obj/fm_return_pwd_manager.o differ
diff --git a/obj/fm_return_pwd_user.o b/obj/fm_return_pwd_user.o
new file mode 100644 (file)
index 0000000..a86d2a2
Binary files /dev/null and b/obj/fm_return_pwd_user.o differ
diff --git a/obj/fm_return_unlock.o b/obj/fm_return_unlock.o
new file mode 100644 (file)
index 0000000..764c8cc
Binary files /dev/null and b/obj/fm_return_unlock.o differ
diff --git a/obj/fm_safecheck.o b/obj/fm_safecheck.o
new file mode 100644 (file)
index 0000000..4f6f4f8
Binary files /dev/null and b/obj/fm_safecheck.o differ
diff --git a/obj/fm_stat_box.o b/obj/fm_stat_box.o
new file mode 100644 (file)
index 0000000..20109bc
Binary files /dev/null and b/obj/fm_stat_box.o differ
diff --git a/obj/fm_stat_bullet.o b/obj/fm_stat_bullet.o
new file mode 100644 (file)
index 0000000..1418140
Binary files /dev/null and b/obj/fm_stat_bullet.o differ
diff --git a/obj/fm_stat_gun.o b/obj/fm_stat_gun.o
new file mode 100644 (file)
index 0000000..a877592
Binary files /dev/null and b/obj/fm_stat_gun.o differ
diff --git a/obj/fm_stat_person.o b/obj/fm_stat_person.o
new file mode 100644 (file)
index 0000000..9c61d4a
Binary files /dev/null and b/obj/fm_stat_person.o differ
diff --git a/obj/fm_stat_unit.o b/obj/fm_stat_unit.o
new file mode 100644 (file)
index 0000000..7f99fff
Binary files /dev/null and b/obj/fm_stat_unit.o differ
diff --git a/obj/fm_system.o b/obj/fm_system.o
new file mode 100644 (file)
index 0000000..1ed3c7c
Binary files /dev/null and b/obj/fm_system.o differ
diff --git a/obj/fm_timing.o b/obj/fm_timing.o
new file mode 100644 (file)
index 0000000..c3575c3
Binary files /dev/null and b/obj/fm_timing.o differ
diff --git a/obj/fm_unlock.o b/obj/fm_unlock.o
new file mode 100644 (file)
index 0000000..7e915ab
Binary files /dev/null and b/obj/fm_unlock.o differ
diff --git a/obj/fm_unlock_pwd.o b/obj/fm_unlock_pwd.o
new file mode 100644 (file)
index 0000000..898786e
Binary files /dev/null and b/obj/fm_unlock_pwd.o differ
diff --git a/obj/fm_user_level.o b/obj/fm_user_level.o
new file mode 100644 (file)
index 0000000..40bb459
Binary files /dev/null and b/obj/fm_user_level.o differ
diff --git a/obj/main.o b/obj/main.o
new file mode 100644 (file)
index 0000000..b12869e
Binary files /dev/null and b/obj/main.o differ
diff --git a/obj/monitor.o b/obj/monitor.o
new file mode 100644 (file)
index 0000000..c4ebb2c
Binary files /dev/null and b/obj/monitor.o differ
diff --git a/obj/net.o b/obj/net.o
new file mode 100644 (file)
index 0000000..f0f1f7f
Binary files /dev/null and b/obj/net.o differ
diff --git a/obj/pinyin.o b/obj/pinyin.o
new file mode 100644 (file)
index 0000000..4303f6a
Binary files /dev/null and b/obj/pinyin.o differ
diff --git a/obj/raw_i2c.o b/obj/raw_i2c.o
new file mode 100644 (file)
index 0000000..a541b73
Binary files /dev/null and b/obj/raw_i2c.o differ
diff --git a/obj/sgi_base.o b/obj/sgi_base.o
new file mode 100644 (file)
index 0000000..af3807b
Binary files /dev/null and b/obj/sgi_base.o differ
diff --git a/obj/sgi_base_box.o b/obj/sgi_base_box.o
new file mode 100644 (file)
index 0000000..1f601bf
Binary files /dev/null and b/obj/sgi_base_box.o differ
diff --git a/obj/sgi_base_button.o b/obj/sgi_base_button.o
new file mode 100644 (file)
index 0000000..a635c46
Binary files /dev/null and b/obj/sgi_base_button.o differ
diff --git a/obj/sgi_base_check.o b/obj/sgi_base_check.o
new file mode 100644 (file)
index 0000000..7e337c0
Binary files /dev/null and b/obj/sgi_base_check.o differ
diff --git a/obj/sgi_base_edit.o b/obj/sgi_base_edit.o
new file mode 100644 (file)
index 0000000..45c1d2f
Binary files /dev/null and b/obj/sgi_base_edit.o differ
diff --git a/obj/sgi_base_form.o b/obj/sgi_base_form.o
new file mode 100644 (file)
index 0000000..9593abf
Binary files /dev/null and b/obj/sgi_base_form.o differ
diff --git a/obj/sgi_base_grid.o b/obj/sgi_base_grid.o
new file mode 100644 (file)
index 0000000..aaea4be
Binary files /dev/null and b/obj/sgi_base_grid.o differ
diff --git a/obj/sgi_base_ime.o b/obj/sgi_base_ime.o
new file mode 100644 (file)
index 0000000..330d3cf
Binary files /dev/null and b/obj/sgi_base_ime.o differ
diff --git a/obj/sgi_base_indicator.o b/obj/sgi_base_indicator.o
new file mode 100644 (file)
index 0000000..cf6c41f
Binary files /dev/null and b/obj/sgi_base_indicator.o differ
diff --git a/obj/sgi_base_label.o b/obj/sgi_base_label.o
new file mode 100644 (file)
index 0000000..77f24b9
Binary files /dev/null and b/obj/sgi_base_label.o differ
diff --git a/obj/sgi_base_msgbox.o b/obj/sgi_base_msgbox.o
new file mode 100644 (file)
index 0000000..e32ac6d
Binary files /dev/null and b/obj/sgi_base_msgbox.o differ
diff --git a/obj/sgi_base_picture.o b/obj/sgi_base_picture.o
new file mode 100644 (file)
index 0000000..812119f
Binary files /dev/null and b/obj/sgi_base_picture.o differ
diff --git a/obj/sgi_base_radio.o b/obj/sgi_base_radio.o
new file mode 100644 (file)
index 0000000..8c9c45a
Binary files /dev/null and b/obj/sgi_base_radio.o differ
diff --git a/obj/sgi_base_updown.o b/obj/sgi_base_updown.o
new file mode 100644 (file)
index 0000000..08f36a3
Binary files /dev/null and b/obj/sgi_base_updown.o differ
diff --git a/obj/sgi_base_window.o b/obj/sgi_base_window.o
new file mode 100644 (file)
index 0000000..240be48
Binary files /dev/null and b/obj/sgi_base_window.o differ
diff --git a/obj/sgi_data.o b/obj/sgi_data.o
new file mode 100644 (file)
index 0000000..6ef277f
Binary files /dev/null and b/obj/sgi_data.o differ
diff --git a/obj/sgi_form_manage.o b/obj/sgi_form_manage.o
new file mode 100644 (file)
index 0000000..238d41e
Binary files /dev/null and b/obj/sgi_form_manage.o differ
diff --git a/obj/sgi_ime.o b/obj/sgi_ime.o
new file mode 100644 (file)
index 0000000..f2544e5
Binary files /dev/null and b/obj/sgi_ime.o differ
diff --git a/obj/sgi_log.o b/obj/sgi_log.o
new file mode 100644 (file)
index 0000000..1336d8e
Binary files /dev/null and b/obj/sgi_log.o differ
diff --git a/obj/sgi_msgbox.o b/obj/sgi_msgbox.o
new file mode 100644 (file)
index 0000000..99e6aaa
Binary files /dev/null and b/obj/sgi_msgbox.o differ
diff --git a/obj/sgi_resource.o b/obj/sgi_resource.o
new file mode 100644 (file)
index 0000000..6b573e7
Binary files /dev/null and b/obj/sgi_resource.o differ
diff --git a/obj/sgi_string.o b/obj/sgi_string.o
new file mode 100644 (file)
index 0000000..2ebdd72
Binary files /dev/null and b/obj/sgi_string.o differ
diff --git a/obj/uart.o b/obj/uart.o
new file mode 100644 (file)
index 0000000..20ed053
Binary files /dev/null and b/obj/uart.o differ
diff --git a/obj/udisk.o b/obj/udisk.o
new file mode 100644 (file)
index 0000000..5c45b2e
Binary files /dev/null and b/obj/udisk.o differ
diff --git a/src/crc.cpp b/src/crc.cpp
new file mode 100644 (file)
index 0000000..c153f5a
--- /dev/null
@@ -0,0 +1,49 @@
+#include "sgi_types.h"\r
+\r
+static const u32 crc32_table[256] =\r
+{\r
+       0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, \r
+       0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, \r
+       0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, \r
+       0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, \r
+       0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, \r
+       0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, \r
+       0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, \r
+       0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, \r
+       0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, \r
+       0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, \r
+       0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, \r
+       0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, \r
+       0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, \r
+       0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, \r
+       0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, \r
+       0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, \r
+       0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, \r
+       0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, \r
+       0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, \r
+       0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, \r
+       0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, \r
+       0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, \r
+       0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, \r
+       0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, \r
+       0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, \r
+       0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, \r
+       0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, \r
+       0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, \r
+       0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, \r
+       0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, \r
+       0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, \r
+       0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,         \r
+};\r
+\r
+u32 crc32_calc(u8 *src, s32 bytes)\r
+{\r
+       u32 crc32 = 0xffffffff;\r
+\r
+       while (bytes-- > 0) {\r
+               crc32 = (crc32 >> 8) ^ crc32_table[(crc32 & 0xff) ^ *src++];\r
+       }\r
+\r
+       return (~crc32);\r
+    \r
+}//end of crc32_calc()\r
diff --git a/src/finger_intf.cpp b/src/finger_intf.cpp
new file mode 100644 (file)
index 0000000..742f472
--- /dev/null
@@ -0,0 +1,402 @@
+#include <pthread.h>
+#include <signal.h>
+#include "global_func.h"
+
+static volatile s32 s_cancel_flag;     /* user cancel operate */
+static volatile s32 s_busy_flag;       /* module busy */
+static volatile u32 s_result;          /* module result */
+static volatile s32 s_error_flag;      /* module error */
+static volatile s32 s_ops;             /* module operate type */
+
+pthread_t g_fpr_thread;
+
+s32 fpr_get_cancel_flag(void)
+{
+       return __sync_fetch_and_or(&s_cancel_flag, 0);          
+}
+
+void fpr_set_cancel_flag(void)
+{
+       __sync_lock_test_and_set(&s_cancel_flag, 1);    
+}
+
+static inline void fpr_reset_cancel_flag(void)
+{
+       __sync_lock_release(&s_cancel_flag);    
+}
+
+s32 fpr_get_busy_flag(void)
+{
+       return __sync_fetch_and_or(&s_busy_flag, 0);    
+}
+
+static inline void fpr_set_busy_flag(void)
+{
+       __sync_lock_test_and_set(&s_busy_flag, 1);
+}
+
+static inline void fpr_reset_busy_flag(void)
+{
+       __sync_lock_release(&s_busy_flag);
+}
+
+u32 fpr_get_result(void)
+{
+       return __sync_fetch_and_or(&s_result, 0);
+}
+
+static inline void fpr_set_result(u32 result)
+{
+       __sync_lock_test_and_set(&s_result, result);
+}
+
+static inline void fpr_reset_result(void)
+{
+       __sync_lock_release(&s_result);
+}
+
+s32 fpr_get_error_flag(void)
+{
+       return __sync_fetch_and_or(&s_error_flag, 0);
+}
+
+static void fpr_set_error_flag(void)
+{
+       __sync_lock_test_and_set(&s_error_flag, 1);
+}
+
+static inline void fpr_reset_error_flag(void)
+{
+       __sync_lock_release(&s_error_flag);
+}
+
+static inline s32 fpr_get_ops(void)
+{
+       return __sync_fetch_and_or(&s_ops, 0);  
+}
+
+static inline void fpr_set_ops(s32 ops)
+{
+       __sync_lock_test_and_set(&s_ops, ops);  
+}
+
+static inline void fpr_reset_ops(void)
+{
+       __sync_lock_release(&s_ops);
+}
+
+static void finger_enroll_1(void)
+{
+       s32 r;
+       s32 id;
+       u32 uid;
+       
+       /* 清除cancel标志,置错误标志 */
+       fpr_reset_cancel_flag();
+       fpr_set_error_flag();
+       
+       /* 寻找空的指纹存储位置 */
+       id = fpr_find_free_area();
+       if (id == COMM_ERR) {
+               goto err;       
+       }
+       
+       /* 发送开始登记指令 */
+       uid = id | (0 << 16);
+       if (fpr_enroll_start(uid) != 0) {
+               goto err;
+       }
+       
+       /* 捕捉指纹并进行第一次登记 */
+       r = fpr_capture_finger(TIMEOUT_IDENT);  
+       if (r == 0) {
+               if (fpr_enroll_1() == 0) {
+                       /* 更新返回结果,置成功标志 */
+                       fpr_set_result(uid);
+                       fpr_reset_error_flag();
+                       
+                       printf("Enroll 1 ok, id: %d\n", uid);
+                               
+               }
+               else {
+                       printf("fpr enroll fail.\n");   
+               }
+       }
+       else if (r == CANCEL_ERR) { /* 用户取消操作 */
+               fpr_capture_cancel();
+               printf("fpt user cancel operate.\n");   
+       }
+       else {
+               printf("fpr capture finger fail: 0x%x\n", r);
+               close_comm();
+               SDL_Delay(1000);
+               open_comm();
+               SDL_Delay(1000);        
+       }
+
+err:   
+       /* 清除busy标志 */
+       fpr_reset_busy_flag();  
+}
+
+static void finger_enroll_2(void)
+{
+       s32 r;
+       
+       /* 清除cancel标志,置错误标志 */
+       fpr_reset_cancel_flag();
+       fpr_set_error_flag();
+       
+       /* 捕捉指纹并进行第二次登记 */
+       r = fpr_capture_finger(TIMEOUT_IDENT);  
+       if (r == 0) {
+               if (fpr_enroll_2() == 0) {
+                       /* 更新返回结果,置成功标志 */
+                       //fpr_set_result(uid);
+                       fpr_reset_error_flag();
+                       
+                       printf("Enroll 2 ok\n");
+                               
+               }
+               else {
+                       printf("fpr enroll fail.\n");   
+               }
+       }
+       else if (r == CANCEL_ERR) { /* 用户取消操作 */
+               fpr_capture_cancel();
+               printf("fpt user cancel operate.\n");   
+       }
+       else {
+               printf("fpr capture finger fail: 0x%x\n", r);
+               close_comm();
+               SDL_Delay(1000);
+               open_comm();
+               SDL_Delay(1000);        
+       }
+       
+       /* 清除busy标志 */
+       fpr_reset_busy_flag();  
+}
+
+static void finger_enroll_3(void)
+{
+       s32 r;
+       
+       /* 清除cancel标志,置错误标志 */
+       fpr_reset_cancel_flag();
+       fpr_set_error_flag();
+       
+       /* 捕捉指纹并进行第三次登记 */
+       r = fpr_capture_finger(TIMEOUT_IDENT);  
+       if (r == 0) {
+               if (fpr_enroll_3() == 0) {
+                       /* 更新返回结果,置成功标志 */
+                       //fpr_set_result(uid);
+                       fpr_reset_error_flag();
+                       
+                       printf("Enroll 3 ok\n");
+                               
+               }
+               else {
+                       printf("fpr enroll fail.\n");   
+               }
+       }
+       else if (r == CANCEL_ERR) { /* 用户取消操作 */
+               fpr_capture_cancel();
+               printf("fpt user cancel operate.\n");   
+       }
+       else {
+               printf("fpr capture finger fail: 0x%x\n", r);
+               close_comm();
+               SDL_Delay(1000);
+               open_comm();
+               SDL_Delay(1000);        
+       }
+
+       /* 清除busy标志 */
+       fpr_reset_busy_flag();  
+}
+
+static void finger_identify(void)
+{
+       s32 r;
+       u32 uid = 0;
+       
+       // test
+       printf("start finger identify.\n");
+       
+       /* 清除cancel标志,置错误标志 */
+       fpr_reset_cancel_flag();
+       fpr_set_error_flag();
+       
+       /* 捕捉指纹并进行比对,返回结果 */
+       r = fpr_capture_finger(TIMEOUT_IDENT);  
+       if (r == 0) {
+               if (fpr_identify(&uid) == 0) {
+                       /* 更新返回结果,置成功标志 */
+                       fpr_set_result(uid);
+                       fpr_reset_error_flag();
+                       
+                       printf("Found match finger, id: %d\n", uid);
+                               
+               }
+               else {
+                       printf("fpr identify fail.\n"); 
+               }
+       }
+       else if (r == CANCEL_ERR) { /* 用户取消操作 */
+               fpr_capture_cancel();
+               printf("fpt user cancel operate.\n");   
+       }
+       else {
+               printf("fpr capture finger fail: 0x%x\n", r);
+               close_comm();
+               SDL_Delay(1000);
+               open_comm();
+               SDL_Delay(1000);        
+       }
+       
+       /* 清除busy标志 */
+       fpr_reset_busy_flag();
+       
+}
+
+static s32 module_signal_handle(void)
+{
+       s32 ops;
+       
+       /* 获取操作类型 */
+       ops = fpr_get_ops();
+       printf("ops: %d\n", ops);
+       switch(ops) {
+       case FPR_IDENTIFY:
+               finger_identify();
+               break;
+               
+       case FPR_ENROLL_1:
+               finger_enroll_1();
+               break;
+               
+       case FPR_ENROLL_2:
+               finger_enroll_2();
+               break;
+               
+       case FPR_ENROLL_3:
+               finger_enroll_3();
+               break;
+               
+       case FPR_QUIT:
+               return FPR_QUIT;
+               
+       default:
+               break;          
+       }
+       
+       return 0;
+}
+
+static void *comm_thread(void *arg)
+{
+       int s,sig;
+       sigset_t set;
+       
+       /* 初始指纹模块 */
+       if (fpr_init() != 0) {
+               printf("fpr init fail.\n");
+               return NULL;
+       }
+       printf("fpr init ok.\n");
+       
+#if 1
+       if (fpr_open() != 0) {
+               printf("fpr open fail.\n");
+               return NULL;            
+       }
+       printf("fpr open ok.\n");
+#endif
+       
+       // test
+       printf("thread start().\n");
+       
+       /* 等待堵塞的信号 */
+       sigemptyset(&set);
+       sigaddset(&set, FPR_SIGNAL);
+       
+       /* 通讯循环,等待信号触发 */
+       for (;;) {
+               s = sigwait(&set, &sig);
+               if (s != 0) {
+                       printf("sigwait error: %d\n", s);
+               }
+               
+               if (sig == FPR_SIGNAL) {
+                       s = module_signal_handle();
+                       if (s == FPR_QUIT) {
+                               printf("thread is quit.\n");
+                               break;
+                       }               
+               }
+               else {
+                       printf("sigwait(): %d.\n", sig);
+               }
+       }
+       
+       printf("thread end().\n");
+       
+       return NULL;
+}
+
+s32 fpr_module_init(void)
+{
+       int s;  
+#if 0  
+       /* 初始指纹模块 */
+       if (fpr_init() != 0) {
+               printf("fpr init fail.\n");
+               return FAIL;
+       }
+       
+       if (fpr_open() != 0) {
+               printf("fpr open fail.\n");
+               return FAIL;            
+       }
+#endif
+       
+       /* 初始化线程属性,均设为默认值,创建线程并开始通讯 */
+       pthread_attr_t attr;
+       sched_param param;      
+       pthread_attr_init(&attr); 
+       pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+       pthread_attr_getschedparam(&attr, &param);
+       param.sched_priority = 20;
+       pthread_attr_getschedparam(&attr, &param);      
+       s = pthread_create(&g_fpr_thread, &attr, &comm_thread, NULL);
+       if (s != 0) {
+               printf("pthread_create error: %d\n", s);
+               return FAIL;
+       }
+       
+       return 0;       
+}
+
+void fpr_module_deinit(void)
+{
+       /* 关闭指纹模块 */
+       fpr_close();
+       fpr_deinit();
+       
+       /* 退出模块线程 */
+       fpr_module_trigger(FPR_QUIT);
+       
+       /* 等待模块线程退出 */
+       pthread_join(g_fpr_thread, NULL);       
+}
+
+void fpr_module_trigger(s32 ops)
+{
+       /* 置忙标志 */
+       fpr_set_busy_flag();
+       
+       fpr_set_ops(ops);
+       pthread_kill(g_fpr_thread, FPR_SIGNAL);
+}
diff --git a/src/fingerprint.cpp b/src/fingerprint.cpp
new file mode 100755 (executable)
index 0000000..f5fcf07
--- /dev/null
@@ -0,0 +1,303 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "fingerprint.h"
+#include "global_def.h"
+#include "global_func.h"
+
+static u8 s_receive_buffer[128 * 1024] = {0};
+static u32 s_user[2000];
+
+static u16 s_devid = 0x0001;
+
+static u16 checksum(u8 *data, int size)
+{
+       u16 cks = 0;
+       
+       for (; size > 0; size--) {
+               cks += *data++; 
+       }       
+       
+       return cks;
+}
+
+static void encode_cmd(struct command_packet *packet, u32 param, u16 cmd)
+{      
+       /* fill data */
+       packet->prefix = IPREFIX;
+       packet->devid = s_devid;
+       packet->param = param;
+       packet->cmd = cmd;
+               
+       /* calc checksum */
+       packet->checksum = checksum((u8 *)packet, 
+               sizeof(struct command_packet) - sizeof(packet->checksum));      
+}
+
+static int decode_cmd(struct command_packet *packet, u32 *response)
+{
+       u32 r;
+       
+       if (packet->cmd == ACK) {
+               if (response != NULL) {
+                       *response = packet->param;
+               }
+               r = 0;
+       }
+       else {
+               r = packet->param | MODULE_ERR;
+       }       
+       
+       return r;       
+}
+
+static int transfer_cmd(u16 cmd, u32 in_param, u32 *out_param, u32 timeout)
+{
+       s32 r;
+       u16 cks;
+       struct command_packet tx;
+       struct command_packet rx;
+       
+       /* 准备发送数据 */
+       encode_cmd(&tx, in_param, cmd);
+       
+       /* 发送并接收数据 */
+       if ((r = transfer((u8 *)&tx, sizeof(tx), (u8 *)&rx, sizeof(rx), 
+               timeout)) == 0) {
+#if 0
+               // test
+               int i;
+               u8 *p = (u8 *)&rx;
+               printf("rx: ");
+               for (i = 0; i < sizeof(rx); ++i) {
+                       printf("0x%02X, ", *p++);
+               }
+               printf("\n");
+#endif
+               do {
+                       if (rx.prefix != IPREFIX) {
+                               break;
+                       }
+       
+                       cks = checksum((u8 *)&rx, sizeof(rx) - sizeof(rx.checksum));
+                       if (cks != rx.checksum) {
+                               break;
+                       }
+       
+                       r = decode_cmd(&rx, out_param);
+               } while (0);
+       } 
+       
+       return r;       
+}
+
+static int transfer_data(u16 cmd, u32 in_param, u32 *out_param, u8 *data)
+{
+       return 0;       
+}
+
+static int receive_data(u8 *buffer, u32 len, u32 timeout)
+{
+       u16 cks;
+       u32 rx_len;
+       u32 r = COMM_ERR;
+       
+       rx_len = len + 6;
+       memset(s_receive_buffer, 0, sizeof(s_receive_buffer));
+       if (uart_receive(s_receive_buffer, rx_len, timeout) == 0) {
+               do {
+                       if (*(u16 *)s_receive_buffer != DPREFIX) {
+                               break;
+                       }
+                       
+                       cks = checksum(s_receive_buffer, rx_len - sizeof(cks));
+                       if (cks != *(u16 *)(s_receive_buffer + rx_len - sizeof(cks))) {
+                               break;
+                       }
+                       
+                       /* output data */
+                       memcpy(buffer, s_receive_buffer + PARAM_LL_OF, len);
+                       
+                       /* set success flag */
+                       r = 0;
+               } while (0);
+       }
+       
+       return r;
+}
+
+int fpr_init(void)
+{
+    return open_comm();
+}
+
+void fpr_deinit(void)
+{
+    close_comm();
+}
+
+int fpr_open(void)
+{
+       return transfer_cmd(CMD_OPEN, 0, NULL, TIMEOUT_N);
+}
+
+int fpr_close(void)
+{
+       return transfer_cmd(CMD_CLOSE, 0, NULL, TIMEOUT_N);
+}
+
+int fpr_get_ver(u32 *ver)
+{
+       return transfer_cmd(CMD_VER, 0, ver, TIMEOUT_N);
+}
+
+int fpr_get_security_level(u32 *level)
+{
+       return transfer_cmd(CMD_LEVEL, 0, level, TIMEOUT_N);    
+}
+
+int fpr_set_security_level(u32 level)
+{
+       return transfer_cmd(CMD_LEVEL, level, NULL, TIMEOUT_N);
+}
+
+int fpr_set_baudrate(u32 baudrate)
+{
+       return transfer_cmd(CMD_BAUDRATE, baudrate, NULL, TIMEOUT_N);   
+}
+
+int fpr_get_devid(u32 *devid)
+{
+       if (transfer_cmd(CMD_GET_DEVID, 0, devid, TIMEOUT_N) == 0) {
+               s_devid = *devid;
+               return 0;
+       }
+       
+       return COMM_ERR;        
+}
+
+int fpr_set_devid(u32 devid)
+{
+       return transfer_cmd(CMD_SET_DEVID, devid, NULL, TIMEOUT_N);     
+}
+
+int fpr_get_enroll_count(u32 *count)
+{
+       return transfer_cmd(CMD_GET_ENROLL_COUNT, 0, count, TIMEOUT_N); 
+}
+
+int fpr_check_enrolled(u32 *enrolled)
+{
+       return transfer_cmd(CMD_CHECK_ENROLLED, 0, enrolled, TIMEOUT_N);        
+}
+
+int fpr_enroll_start(u32 uid)
+{
+       return transfer_cmd(CMD_ENROLL_START, uid, NULL, TIMEOUT_N);    
+}
+
+int fpr_enroll_1(void)
+{
+       return transfer_cmd(CMD_ENROLL_1, 1, NULL, TIMEOUT_E);
+}
+
+int fpr_enroll_2(void)
+{
+       return transfer_cmd(CMD_ENROLL_2, 2, NULL, TIMEOUT_E);
+}
+
+int fpr_enroll_3(void)
+{
+       return transfer_cmd(CMD_ENROLL_3, 3, NULL, TIMEOUT_E);  
+}
+
+int fpr_check_press_finger(u32 *state)
+{
+       return transfer_cmd(CMD_PRESS_FINGER, 0, state, TIMEOUT_N);     
+}
+
+int fpr_get_all_user(u32 *count, u32 *list)
+{
+       u32 r;
+       
+       *count = 0;
+       r = transfer_cmd(CMD_GET_ALL_USER, 0, count, TIMEOUT_N);
+       if (r == 0) {
+               return receive_data((u8 *)list, *count * 4, TIMEOUT_U);
+       }
+       else if ((r & 0xffff) == 0x100A) {  /* database empty */
+               return 0;
+       }
+       
+       return COMM_ERR;
+}
+
+int fpr_set_user_priv(u32 new_priv, u32 *old_priv)
+{
+       return transfer_cmd(CMD_SET_USER_PRIV, new_priv, old_priv, TIMEOUT_N);          
+}
+
+int fpr_delete_user(u32 uid)
+{
+       return transfer_cmd(CMD_DEL_ID, uid, NULL, TIMEOUT_N);  
+}
+
+int fpr_delete_all(void)
+{
+       return transfer_cmd(CMD_DEL_ALL, 0, NULL, TIMEOUT_N);   
+}
+
+int fpr_verify(u32 uid)
+{
+       return transfer_cmd(CMD_VERIFY, uid, NULL, TIMEOUT_N);  
+}
+
+int fpr_identify(u32 *match_id)
+{
+       return transfer_cmd(CMD_IDENTIFY, 0, match_id, TIMEOUT_I);      
+}
+
+int fpr_capture_finger(u32 timeout)
+{
+       return transfer_cmd(CMD_CAPTURE_FINGER, timeout, NULL, (timeout + 2) * 1000);
+}
+
+int fpr_capture_cancel(void)
+{
+       return transfer_cmd(CMD_CAPTURE_CANCEL, 0, NULL, TIMEOUT_N);    
+}
+
+int fpr_get_image(u8 *image)
+{
+    if (transfer_cmd(CMD_UP_IMAGE, 0, NULL, TIMEOUT_N) == 0) {
+        return receive_data(image, 256 * 256, TIMEOUT_D);
+    }
+
+    return COMM_ERR;   
+}
+
+int fpr_find_free_area(void)
+{
+    u32 count;
+    u32 i,j;
+    int find;
+    
+    if (fpr_get_all_user(&count, s_user) == 0) {
+        for (i = RESERVED_CAP; i < MODULE_CAP; ++i) {
+            find = 0;
+            for (j = 0; j < count; ++j) {
+                if (i == (s_user[j] & 0xffff)) {
+                    find = 1;
+                    break;
+                }
+            }
+
+            /* ID is exist ? */
+            if (!find) {
+                return i;
+            }
+        } 
+    }
+
+    return COMM_ERR;
+}
diff --git a/src/fingerprint.h b/src/fingerprint.h
new file mode 100755 (executable)
index 0000000..3f735e4
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef FINGERPRINT_H
+#define FINGERPRINT_H
+
+#include "sgi_types.h"
+
+/* Common define */
+#define IPR0                   0x55    /* 指令前缀 1 */
+#define IPR1                   0xAA    /* 指令前缀 2 */
+#define IPREFIX                0xAA55
+#define DPREFIX                0xA55A
+
+#define RPR0                   0x55    /* 应答前缀 1 */
+#define RPR1                   0xAA    /* 应答前缀 2 */
+#define ACK                    0x30    /* 正常响应 */
+#define NACK                   0x31    /* 非正常响应 */
+
+#define NTX_SIZE               12
+#define NRX_SIZE               12
+#define CHKSUM_SIZE            2
+#define PARAM_SIZE             4
+#define CMD_SIZE               2
+
+#define MODULE_CAP             2000
+#define RESERVED_CAP           5
+
+#define TIMEOUT_N              1000
+#define TIMEOUT_E              2000
+#define TIMEOUT_U              3000
+#define TIMEOUT_I              15000
+#define TIMEOUT_D              15000
+
+#define TEMPLATE_SIZE          1404
+#define IMAGE_SIZE             65536
+
+#define COMM_ERR               -1
+#define MODULE_ERR             0x80000000
+
+#define PR0_OF                 0       
+#define PR1_OF                 1
+#define DEVID_LL_OF            2
+#define DEVID_LH_OF            3
+#define PARAM_LL_OF            4
+#define PARAM_LH_OF            5
+#define PARAM_HL_OF            6
+#define PARAM_HH_OF            7
+#define CMD_LL_OF              8
+#define CMD_LH_OF              9
+#define RESP_LL_OF             8
+#define RESP_LH_OF             9
+
+/* Command define */
+#define CMD_OPEN               0x01    /* 初始化模块 */
+#define CMD_CLOSE              0x02    /* 终止模块使用 */
+#define CMD_VER                        0x04    /* 读取模块版本 */
+#define CMD_SLEEP              0x05    /* 使用模块进入休眠状态 */
+#define CMD_LEVEL              0x06    /* 设置/读取比对等级 */
+#define CMD_BAUDRATE           0x11    /* 设置波特率 */
+#define CMD_GET_DEVID          0x12    /* 读取模块序列号 */
+#define CMD_SET_DEVID          0x13    /* 设置模块序列号 */
+#define CMD_GET_ENROLL_COUNT   0x20    /* 读取用户总数 */
+#define CMD_CHECK_ENROLLED     0x21    /* 检查指定ID是否占用 */
+#define CMD_ENROLL_START       0x22    /* 启动指纹登记 */
+#define CMD_ENROLL_1           0x23    /* 指纹登记第一次模板生成 */
+#define CMD_ENROLL_2           0x24    /* 指纹登记第二次模板生成 */
+#define CMD_ENROLL_3           0x25    /* 指纹登记第三次模板生成 */
+#define CMD_PRESS_FINGER       0x26    /* 检查手指是否放在指纹采集仓上 */
+#define CMD_GET_ALL_USER       0x32    /* 获取已登录的所有用户ID */
+#define CMD_SET_USER_PRIV      0x33    /* 设置读取用户权限 */
+#define CMD_DEL_ID             0x40    /* 删除指定ID用户 */
+#define CMD_DEL_ALL            0x41    /* 删除所有用户 */
+#define CMD_VERIFY             0x50    /* 已获取的指纹图像与指定ID的指纹模板进行1:1比对 */
+#define CMD_IDENTIFY           0x51    /* 已获取的指纹图像与所有指纹模板进行1:N比对 */ 
+#define CMD_VERIFY_TEMPLATE    0x52    /* 下载指纹模板与指定ID的指纹模板进行1:1比对 */
+#define CMD_IDENTIFY_TEMPLATE  0x53    /* 下载指纹o模板与所有指纹模板进行1:N比对 */
+#define CMD_CAPTURE_FINGER     0x60    /* 采集指纹图像 */
+#define CMD_CAPTURE_CANCEL     0x61    /* 取消指纹采集 */
+#define CMD_UP_IMAGE           0x62    /* 上传指纹图像到主机 */
+#define CMD_EXTRACT_TEMPLATE   0x65    /* 从指纹图像中提取指纹模板并上传到主机 */
+#define CMD_UP_TEMPLATE                0x70    /* 上传指定ID的指纹模板到主机 */
+#define CMD_DOWN_TEMPLATE      0x71    /* 下载指纹模板到指定ID号 */
+#define CMD_AUTO_ADJUST                0x80    /* 自动调整图像传感器参数 */
+#define CMD_DUPLICATION_CHECK  0x81    /* 设置/读取指纹注册时的重复检查 */
+#define CMD_SET_LED            0x82    /* 打开/关闭指纹模块LED */
+
+struct command_packet {
+       u16 prefix;
+       u16 devid;
+       u32 param;
+       u16 cmd;
+       u16 checksum;
+}__attribute__((packed));
+
+struct template_packet {
+       u16 prefix;
+       u16 devid;
+       u8 data[TEMPLATE_SIZE];
+       u16 checksum;
+}__attribute__((packed));
+
+struct image_packet {
+       u16 prefix;
+       u16 devid;
+       u8 data[IMAGE_SIZE];
+       u16 checksum;
+}__attribute__((packed));                      
+
+#endif
\ No newline at end of file
diff --git a/src/fm_alarm.cpp b/src/fm_alarm.cpp
new file mode 100644 (file)
index 0000000..0a78163
--- /dev/null
@@ -0,0 +1,144 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_alarm
+
+FORM_MODULE(MODULE_NAME);                      /*  */          
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_alarm;           /*  */
+static union sgi_object s_btn_cancel;          /*  */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static s32 s_alarm_flash = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {125, 118, 545, 172, {"alarm.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_alarm_flash = 0;      
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_cancel_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_alarm_pwd));       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_menu));  
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_main));  
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       static u32 cycle = 0;
+       s32 flash = 0;
+       u16 *info;
+       
+       /* per 6s update dispaly */
+       if (TIME_AFTER(SDL_GetTicks(), cycle)) {
+               info = get_current_alarm_info(&flash);
+               if (info) {
+                       set_object_text_u(&s_lbl_alarm.label, info);
+               }
+               else {
+                       set_object_text_w(&s_lbl_alarm.label, L"枪弹柜异常报警!");       
+               }
+               s_lbl_alarm.label.redraw = 1;
+               
+               if (!s_alarm_flash && flash) {
+                       alarm_ctrl(ALARM_ON);           
+               }
+               cycle = SDL_GetTicks() + 4000;  
+       }
+               
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /*  */
+       LABEL_CREATE(s_lbl_alarm, FORM_CLASS(MODULE_NAME), 142, 174, 516, 60, 1,
+                "jht.ttf", 26, color);
+       s_lbl_alarm.label.align = DT_CENTER;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_cancel, FORM_CLASS(MODULE_NAME), 346, 318, 107, 44, 1,
+               "btn-free-u.png", "btn-free-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_cancel.button.up = btn_cancel_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;     
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_alarm_pwd.cpp b/src/fm_alarm_pwd.cpp
new file mode 100644 (file)
index 0000000..0f818e9
--- /dev/null
@@ -0,0 +1,188 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_alarm_pwd
+
+FORM_MODULE(MODULE_NAME);                      /*  */          
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_uid;             /* 用户编号 */
+static union sgi_object s_edt_pwd;             /* 密码输入框 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {165, 59, 377, 95, {"pwd-2.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       set_object_text_u(&s_edt_uid.edit, NULL);
+       set_object_text_u(&s_edt_pwd.edit, NULL);
+       set_object_focus(&s_edt_uid);
+       
+       s_timer = 60;   
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_alarm));   
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       FORM_CLASS(MODULE_NAME).msgbox = NULL;
+       sgi_form_show(&FORM_CLASS(fm_alarm));   
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == ID_INVALID) {
+               set_object_focus(&s_edt_uid);   
+       }
+       else if (user == PWD_INVALID) {
+               set_object_focus(&s_edt_pwd);   
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       s32 r = verify_manager_pwd(&g_passport, s_edt_uid.edit.text, 
+               s_edt_pwd.edit.text);
+       
+       if (r >= 0) {   
+               /* 取消警报 */              
+               cancel_alarm();
+               sgi_form_show(&FORM_CLASS(fm_main));
+               
+               /* log */
+               record_manager_log(g_passport.mname, L"解除系统警报");
+       }
+       else if (r == ID_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户信息不存在!", 
+                       ID_INVALID, callback);          
+       }
+       else if (r == PWD_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码无效!", 
+                       PWD_INVALID, callback);         
+       }               
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号输入框 */
+       EDIT_CREATE(s_edt_uid, FORM_CLASS(MODULE_NAME), 346, 86, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /* 密码输入框 */
+       EDIT_CREATE(s_edt_pwd, FORM_CLASS(MODULE_NAME), 346, 126, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_pwd.edit.pwdchar = 1; 
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 556, 106, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_main_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_borrow_card_manager.cpp b/src/fm_borrow_card_manager.cpp
new file mode 100644 (file)
index 0000000..a5abed8
--- /dev/null
@@ -0,0 +1,194 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_borrow_card_manager
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,管理员刷卡验证 */              
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_fpr;             /* 指纹按钮 */
+static union sgi_object s_btn_card;            /* 刷卡按钮 */
+static union sgi_object s_btn_pwd;             /* 密码按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_card_start = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {333, 88, 273, 234, {"card.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {71, 145, 209, 127, {"tip1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_timer = 60;
+       s_card_start = 0;
+       card_start();   
+}
+
+static void form_exit(struct sgi_form *)
+{
+       FORM_CLASS(MODULE_NAME).msgbox = NULL;          
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static void btn_fpr_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_borrow_fpr_user)); 
+}
+
+static void btn_card_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_borrow_pwd_user)); 
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       s32 card;
+       
+       do {
+               r = card_state();
+               if (r == -1) {
+                       card_start();   
+               }
+               else if (r == 1) {
+                       card = get_card_id();
+                       r = search_mid(&g_passport, SR_CARD, card);
+                       if (r == 0) {
+                               g_passport.visit &= MGR_CARD_MASK;
+                               g_passport.visit |= MGR_CARD_VALID; 
+                               sgi_form_show(&FORM_CLASS(fm_borrow_photo_user));
+                       }
+                       else {
+                               msgbox(&FORM_CLASS(MODULE_NAME), L"卡号无对应的用户信息!", 
+                                       0, NULL);
+                               card_start();   
+                       }       
+               }
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-1.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 600, 50, 200, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 指纹按钮 */
+       BUTTON_CREATE(s_btn_fpr, FORM_CLASS(MODULE_NAME), 201, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-fpr.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr.button.up = btn_fpr_up;
+       
+       /* 刷卡按钮 */
+       BUTTON_CREATE(s_btn_card, FORM_CLASS(MODULE_NAME), 340, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-card.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_card.button.state |= 2;
+       s_btn_card.button.up = btn_card_up;
+               
+       /* 密码验证按钮 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 480, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-pwd-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+               
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_borrow_card_user.cpp b/src/fm_borrow_card_user.cpp
new file mode 100644 (file)
index 0000000..1b7cc3d
--- /dev/null
@@ -0,0 +1,202 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_borrow_card_user
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,警员刷卡验证 */         
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_fpr;             /* 指纹按钮 */
+static union sgi_object s_btn_card;            /* 刷卡按钮 */
+static union sgi_object s_btn_pwd;             /* 密码按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_card_start = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {288, 18, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {333, 88, 273, 234, {"card.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {71, 145, 209, 127, {"tip1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_timer = 60;
+       s_card_start = 0;
+       card_start();   
+}
+
+static void form_exit(struct sgi_form *)
+{
+       FORM_CLASS(MODULE_NAME).msgbox = NULL;          
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static void btn_fpr_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_borrow_fpr_user)); 
+}
+
+static void btn_card_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_borrow_pwd_user)); 
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       s32 card;
+       
+       do {
+               //if (!s_card_start) {
+               //      break;          
+               //}
+               r = card_state();
+               if (r == -1) {
+                       card_start();   
+               }
+               else if (r == 1) {
+                       card = get_card_id();
+                       r = search_uid(&g_passport, SR_CARD, card);
+                       if (r == 0) {
+                               g_passport.visit |= VALID_PASSPORT;
+                               g_passport.visit &= USR_CARD_MASK;
+                               g_passport.visit |= USR_CARD_VALID; 
+                               sgi_form_show(&FORM_CLASS(fm_borrow_fpr_manager));
+                       }
+                       else {
+                               msgbox(&FORM_CLASS(MODULE_NAME), L"卡号无对应的用户信息!", 
+                                       0, NULL);
+                               card_start();   
+                       }       
+               }
+
+               //s_card_start = 0;
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-1.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 24, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 70, 150, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 指纹按钮 */
+       BUTTON_CREATE(s_btn_fpr, FORM_CLASS(MODULE_NAME), 201, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-fpr.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr.button.up = btn_fpr_up;
+       
+       /* 刷卡按钮 */
+       BUTTON_CREATE(s_btn_card, FORM_CLASS(MODULE_NAME), 340, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-card.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_card.button.state |= 2;
+       s_btn_card.button.up = btn_card_up;
+               
+       /* 密码验证按钮 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 480, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-pwd-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+               
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_borrow_fpr_manager.cpp b/src/fm_borrow_fpr_manager.cpp
new file mode 100644 (file)
index 0000000..f60102f
--- /dev/null
@@ -0,0 +1,266 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_borrow_fpr_manager
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,管理员指纹验证 */
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_fpr;             /* 指纹按钮 */
+static union sgi_object s_btn_card;            /* 刷卡按钮 */
+static union sgi_object s_btn_pwd;             /* 密码按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_fpr_start = 0;
+static s32 s_fpr_fail = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[5] = {
+       {288, 18, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {323, 90, 272, 234, {"fpr.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {71, 145, 209, 127, {"tip2.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_lbl_time.label.tag = 60;
+       s_timer = 60;
+       s_fpr_start = 0;
+       s_fpr_fail = 0;
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//     }               
+}
+
+static void form_exit(struct sgi_form *)
+{
+       FORM_CLASS(MODULE_NAME).msgbox = NULL;          
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+//     if (s_fpr_start && fpr_get_busy_flag()) {
+//             fpr_set_cancel_flag();
+//     }       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static void btn_fpr_up(struct sgi_button *)
+{
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//             s_timer = 60;
+//     }       
+}
+
+static void btn_card_up(struct sgi_button *)
+{
+       /* 取消指纹识别操作 */
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       
+       sgi_form_show(&FORM_CLASS(fm_borrow_card_manager));             
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       /* 取消指纹识别操作 */
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       
+       sgi_form_show(&FORM_CLASS(fm_borrow_pwd_manager));      
+}
+
+static void callback(s32 user)
+{
+       if (user == FPR_FAIL) {
+               s_fpr_fail = 0;         
+       }                       
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       u32 state = 0;
+       
+       do {
+//             if (!s_fpr_start) {
+//                     break;          
+//             }
+
+               if (s_fpr_fail) {
+                       break;
+               }
+               
+               if (!s_fpr_start) {
+                       //if (fpr_check_press_finger(&state) != 0) {
+                       //      break;  
+                       //}
+                       if (fpr_press_detect() != 0) {
+                               break;
+                       }
+                       
+                       play_effect_fpr();
+                       fpr_module_trigger(FPR_IDENTIFY);
+                       s_fpr_start = 1;
+                       printf("start identify.\n");    
+               }
+               
+               if (fpr_get_busy_flag()) {
+                       break;  
+               }       
+               
+               printf("module is not busy.\n");        
+               if (fpr_get_error_flag()) {
+                       s_fpr_fail = 1;
+                       printf("fpr_get_error_flag is true.\n");
+                       msgbox(&FORM_CLASS(MODULE_NAME), L"指纹无效,请重新采集!", 
+                               FPR_FAIL, callback);
+               }
+               else {
+                       r = fpr_get_result();
+                       r = search_mid(&g_passport, SR_FPR, r);
+                       printf("fpr result: %d\n", r);
+                       if (r == 0) {
+                               g_passport.visit &= MGR_FPR_MASK;
+                               g_passport.visit |= MGR_FPR_VALID; 
+                               sgi_form_show(&FORM_CLASS(fm_borrow_photo_user));
+                       }
+                       else {
+                               s_fpr_fail = 1;
+                               msgbox(&FORM_CLASS(MODULE_NAME), L"指纹无对应的用户信息!", 
+                                       FPR_FAIL, callback);    
+                       }       
+                                               
+               }
+               s_fpr_start = 0;
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-1.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 24, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 70, 150, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 指纹按钮 */
+       BUTTON_CREATE(s_btn_fpr, FORM_CLASS(MODULE_NAME), 201, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-fpr.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr.button.state |= 2;
+       s_btn_fpr.button.up = btn_fpr_up;
+       
+       /* 刷卡按钮 */
+       BUTTON_CREATE(s_btn_card, FORM_CLASS(MODULE_NAME), 340, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-card.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_card.button.up = btn_card_up;
+               
+       /* 密码验证按钮 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 480, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-pwd-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_borrow_fpr_user.cpp b/src/fm_borrow_fpr_user.cpp
new file mode 100644 (file)
index 0000000..5c482fe
--- /dev/null
@@ -0,0 +1,270 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_borrow_fpr_user
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,警员指纹验证 */ 
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_fpr;             /* 指纹按钮 */
+static union sgi_object s_btn_card;            /* 刷卡按钮 */
+static union sgi_object s_btn_pwd;             /* 密码按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_fpr_start = 0;
+static s32 s_fpr_fail = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[5] = {
+       {288, 18, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {323, 90, 272, 234, {"fpr.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {71, 145, 209, 127, {"tip0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_lbl_time.label.tag = 60;
+       s_timer = 60;
+       s_fpr_start = 0;
+       s_fpr_fail = 0;
+       
+//     if (fpr_open() != 0) {
+//             printf("fpr open fail.\n");     
+//     }
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//     }               
+}
+
+static void form_exit(struct sgi_form *)
+{
+       FORM_CLASS(MODULE_NAME).msgbox = NULL;          
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       //sgi_form_show(&g_sgi_form_get_001);   
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static void btn_fpr_up(struct sgi_button *)
+{
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//             s_timer = 60;
+//     }       
+}
+
+static void btn_card_up(struct sgi_button *)
+{
+       /* 取消指纹识别操作 */
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       
+       sgi_form_show(&FORM_CLASS(fm_borrow_card_user));                
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       /* 取消指纹识别操作 */
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       
+       sgi_form_show(&FORM_CLASS(fm_borrow_pwd_user)); 
+}
+
+static void callback(s32 user)
+{
+       if (user == FPR_FAIL) {
+               s_fpr_fail = 0;         
+       }                       
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       u32 state = 0;
+       
+       do {
+               //if (!s_fpr_start) {
+               //      break;          
+               //}
+               if (s_fpr_fail) {
+                       break;
+               }
+               
+               if (!s_fpr_start) {
+                       //if (fpr_check_press_finger(&state) != 0) {
+                       //      break;  
+                       //}
+                       if (fpr_press_detect() != 0) {
+                               break;
+                       }                       
+
+                       play_effect_fpr();
+                       fpr_module_trigger(FPR_IDENTIFY);
+                       s_fpr_start = 1;
+                       printf("start identify.\n");
+               }
+               
+               if (fpr_get_busy_flag()) {
+                       break;  
+               }       
+               
+               printf("module is not busy.\n");        
+               if (fpr_get_error_flag()) {
+                       s_fpr_fail = 1;
+                       printf("fpr_get_error_flag is true.\n");
+                       msgbox(&FORM_CLASS(MODULE_NAME), L"指纹无效,请重新采集!", 
+                               FPR_FAIL, callback);                                    
+               }
+               else {
+                       r = fpr_get_result();
+                       printf("fpr result: %d\n", r);
+                       r = search_uid(&g_passport, SR_FPR, r);
+                       if (r == 0) {
+                               g_passport.visit |= VALID_PASSPORT;
+                               g_passport.visit &= USR_FPR_MASK;
+                               g_passport.visit |= USR_FPR_VALID; 
+                               sgi_form_show(&FORM_CLASS(fm_borrow_fpr_manager));
+                       }
+                       else {
+                               s_fpr_fail = 1;
+                               msgbox(&FORM_CLASS(MODULE_NAME), L"指纹无对应的用户信息!", 
+                                       FPR_FAIL, callback);    
+                       }                       
+               }
+               s_fpr_start = 0;
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-1.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 24, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 70, 150, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 指纹按钮 */
+       BUTTON_CREATE(s_btn_fpr, FORM_CLASS(MODULE_NAME), 201, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-fpr.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr.button.state |= 2;
+       s_btn_fpr.button.up = btn_fpr_up;
+       
+       /* 刷卡按钮 */
+       BUTTON_CREATE(s_btn_card, FORM_CLASS(MODULE_NAME), 340, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-card.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_card.button.up = btn_card_up;
+               
+       /* 密码验证按钮 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 480, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-pwd-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_borrow_photo_user.cpp b/src/fm_borrow_photo_user.cpp
new file mode 100644 (file)
index 0000000..b5e177f
--- /dev/null
@@ -0,0 +1,210 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_borrow_photo_user
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,警员照片比对 */ 
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_lbl_uid;             /* 编号标签 */
+static union sgi_object s_lbl_name;            /* 姓名标签 */
+static union sgi_object s_lbl_dept;            /* 部门标签 */
+//static union sgi_object s_lbl_timing;                /* 用时标签 */
+static union sgi_object s_upd_time;            /* 用时 */
+static union sgi_object s_pho_sample;          /* 照片样本 */
+static union sgi_object s_pho_real;            /* 实时照片 */
+static union sgi_object s_btn_confirm;         /* 确定按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {112, 64, 574, 302, {"photo-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_timer = 60;
+       
+       /* 获取照片样本 */
+       s_pho_sample.photo.surface = load_photo(&g_passport, PHO_SAMPLE);
+       if (s_pho_sample.photo.surface) {
+               s_pho_sample.photo.redraw = 1;  
+       }
+       
+       /* 获取实时照片 */
+       s_pho_real.photo.surface = load_photo(&g_passport, PHO_REAL);
+       if (s_pho_real.photo.surface) {
+               s_pho_real.photo.redraw = 1;    
+       }
+       printf("load photo end.\n");
+       
+       /* 为人员信息框赋值 */
+       set_object_text_u(&s_lbl_uid.label, g_passport.uid);
+       set_object_text_u(&s_lbl_name.label, g_passport.name);
+       set_object_text_u(&s_lbl_dept.label, g_passport.dept);  
+}
+
+static void form_exit(struct sgi_form *)
+{
+       printf("unload photo.\n");
+       unload_photo(&s_pho_sample.photo);
+       unload_photo(&s_pho_real.photo);        
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       time(&g_passport.borrow_time);
+       g_passport.return_time = g_passport.borrow_time 
+               + s_upd_time.updown.value * 3600;
+       sgi_form_show(&FORM_CLASS(fm_borrow_unlock));   
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_borrow_unlock)); 
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       do {
+
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号 */
+       LABEL_CREATE(s_lbl_uid, FORM_CLASS(MODULE_NAME), 546, 92, 120, 25, 1,
+                "jht.ttf", 20, text_cl);
+                
+       /* 姓名 */
+       LABEL_CREATE(s_lbl_name, FORM_CLASS(MODULE_NAME), 546, 134, 120, 25, 1,
+                "jht.ttf", 20, text_cl);
+                
+       /* 部门 */
+       LABEL_CREATE(s_lbl_dept, FORM_CLASS(MODULE_NAME), 546, 176, 120, 25, 1,
+                "jht.ttf", 20, text_cl);
+                
+       /* 用时 */
+       //LABEL_CREATE(s_lbl_timing, FORM_CLASS(MODULE_NAME), 588, 220, 35, 40, 1,
+       //       "jht.ttf", 20, text_cl);
+       //s_lbl_timing.label.align = DT_CENTER;
+       //set_object_text_w(&s_lbl_timing.label, L"24");
+       UPDOWN_CREATE(s_upd_time, FORM_CLASS(MODULE_NAME), 541, 216, 132, 47, 1,
+               38, "jht.ttf", 20, text_cl, "updown-u.png", "updown-d.png", 
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_upd_time.updown.value = 24;
+       
+       /* 照片样本 */
+       PHOTO_CREATE(s_pho_sample, FORM_CLASS(MODULE_NAME), 135, 87, 158, 178, 1);
+       
+       /* 实时照片 */
+       PHOTO_CREATE(s_pho_real, FORM_CLASS(MODULE_NAME), 307, 87, 158, 178, 1);
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 310, 302, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_borrow_pwd_manager.cpp b/src/fm_borrow_pwd_manager.cpp
new file mode 100644 (file)
index 0000000..66e0a12
--- /dev/null
@@ -0,0 +1,183 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_borrow_pwd_manager
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,警员密码验证 */         
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_uid;             /* 用户编号 */
+static union sgi_object s_edt_pwd;             /* 密码输入框 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_pwd_retries = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {165, 59, 377, 95, {"pwd-2.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       set_object_text_u(&s_edt_uid.edit, NULL);
+       set_object_text_u(&s_edt_pwd.edit, NULL);
+       set_object_focus(&s_edt_uid);
+       
+       s_timer = 60;
+       s_pwd_retries = 0;      
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == ID_INVALID) {
+               set_object_focus(&s_edt_uid);   
+       }
+       else if (user == PWD_INVALID) {
+               set_object_focus(&s_edt_pwd);   
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       s32 r = verify_manager_pwd(&g_passport, s_edt_uid.edit.text, 
+               s_edt_pwd.edit.text);
+       
+       if (r >= 0) {   
+               g_passport.visit &= MGR_PWD_MASK;
+               g_passport.visit |= MGR_PWD_VALID;
+               sgi_form_show(&FORM_CLASS(fm_borrow_photo_user));
+       }
+       else if (r == ID_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户信息不存在!", 
+                       ID_INVALID, callback);          
+       }
+       else if (r == PWD_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码无效!", 
+                       PWD_INVALID, callback);
+               if (++s_pwd_retries >= PWD_MAX_RETRIES) {
+                       pwd_alarm();    
+               }               
+       }               
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号输入框 */
+       EDIT_CREATE(s_edt_uid, FORM_CLASS(MODULE_NAME), 346, 86, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /* 密码输入框 */
+       EDIT_CREATE(s_edt_pwd, FORM_CLASS(MODULE_NAME), 346, 126, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_pwd.edit.pwdchar = 1; 
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 556, 106, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_borrow_pwd_user.cpp b/src/fm_borrow_pwd_user.cpp
new file mode 100644 (file)
index 0000000..4a16384
--- /dev/null
@@ -0,0 +1,192 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_borrow_pwd_user
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,警员密码验证 */         
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_uid;             /* 用户编号 */
+static union sgi_object s_edt_pwd;             /* 密码输入框 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_pwd_retries = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {188, 58, 353, 106, {"pwd-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       set_object_text_u(&s_edt_uid.edit, NULL);
+       set_object_text_u(&s_edt_pwd.edit, NULL);
+       set_object_focus(&s_edt_uid);
+       
+       s_timer = 60;
+       s_pwd_retries = 0;      
+}
+
+static void form_exit(struct sgi_form *)
+{
+       FORM_CLASS(MODULE_NAME).msgbox = NULL;          
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == ID_INVALID) {
+               set_object_focus(&s_edt_uid);   
+       }
+       else if (user == PWD_INVALID) {
+               set_object_focus(&s_edt_pwd);   
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       s32 r = verify_user_pwd(&g_passport, s_edt_uid.edit.text, 
+               s_edt_pwd.edit.text);
+       
+       if (r >= 0) {
+               g_passport.visit |= VALID_PASSPORT;
+               g_passport.visit &= USR_PWD_MASK;
+               g_passport.visit |= USR_PWD_VALID;
+               sgi_form_show(&FORM_CLASS(fm_borrow_fpr_manager));
+       }
+       else if (r == ID_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户信息不存在!", 
+                       ID_INVALID, callback);          
+       }
+       else if (r == PWD_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码无效!", 
+                       PWD_INVALID, callback); 
+               if (++s_pwd_retries >= PWD_MAX_RETRIES) {
+                       pwd_alarm();    
+               }
+               
+       }       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号输入框 */
+       EDIT_CREATE(s_edt_uid, FORM_CLASS(MODULE_NAME), 346, 83, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /* 密码输入框 */
+       EDIT_CREATE(s_edt_pwd, FORM_CLASS(MODULE_NAME), 346, 123, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_pwd.edit.pwdchar = 1; 
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 556, 106, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_borrow_unlock.cpp b/src/fm_borrow_unlock.cpp
new file mode 100644 (file)
index 0000000..2b7ad9d
--- /dev/null
@@ -0,0 +1,258 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_borrow_unlock
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,枪柜开锁 */       
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_box;                 /* 枪柜 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_cell s_box_cell[BOX_NUMS] = {
+       CELL(15,11,61,40),CELL(79,11,61,40),CELL(143,11,61,40),
+       CELL(205,11,61,40),CELL(268,11,61,40),CELL(332,11,61,40),
+       CELL(395,11,61,40),CELL(457,11,61,40),CELL(520,11,61,40),
+       CELL(584,11,61,40),
+       
+       CELL(15,54,61,40),CELL(79,54,61,40),CELL(143,54,61,40),
+       CELL(205,54,61,40),CELL(268,54,61,40),CELL(332,54,61,40),
+       CELL(395,54,61,40),CELL(457,54,61,40),CELL(520,54,61,40),
+       CELL(584,54,61,40),
+       
+       CELL(15,96,61,40),CELL(79,96,61,40),CELL(143,96,61,40),
+       CELL(205,96,61,40),CELL(268,96,61,40),CELL(332,96,61,40),
+       CELL(395,96,61,40),CELL(457,96,61,40),CELL(520,96,61,40),
+       CELL(584,96,61,40),
+       
+       CELL(15,138,102,77),CELL(121,138,102,77),CELL(227,138,102,77),
+       CELL(331,138,102,77),CELL(438,138,102,77),CELL(541,138,102,77),
+       
+       CELL(15,218,102,77),CELL(121,218,102,77),CELL(227,218,102,77),
+       CELL(331,218,102,77),CELL(438,218,102,77),CELL(541,218,102,77), 
+};
+
+static struct sgi_widget s_widget[] = {
+       {69, 55, 658, 308, {"photo-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       u32 i;
+       struct box_info *info = get_box_info(); 
+       
+       /* 暂停锁监控 */
+       pause_lock_monitor();
+       
+       /* */
+       for (i = 0; i < BOX_NUMS; ++i) {
+               s_box.box.cell[i].state = 0;
+               s_box.box.cell[i].tag = info[i].state;
+               //printf("cells[%d].tag: %d\n", i, s_box.box.cell[i].tag);
+       }       
+       
+       s_timer = 600;                  
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_main.button.up(&s_btn_main.button);
+       }       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       int i;
+       u32 cells[4] = {0};
+       struct box_info *info = get_box_info();
+       
+       int has = 0;
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if (s_box.box.cell[i].state & 1) {
+                       has = 1;
+                       break;
+               }       
+       }
+       
+       if (!has) {
+               return; 
+       }
+       
+       /* 登记取枪信息 */
+       for (i = 0; i < BOX_NUMS; ++i) {
+               cells[i / 32] |= (s_box.box.cell[i].state & 1) << (i % 32);
+       }
+       if (enroll_borrow(&g_passport, cells) != 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"登记取枪信息失败!", 0, NULL);
+               return;
+       }
+       
+       /* 记录取枪日志 */
+       //struct log_borrow borrow;
+       int nums = 0;
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if (s_box.box.cell[i].state & 1) {
+                       record_borrow_log(&g_passport, &info[i]);
+                       nums++;
+//                     memset(&borrow, 0, sizeof(struct log_borrow));
+//                     borrow.id = get_log_no(LOG_BORROW);
+//                     time(&borrow.time);
+//                     sgi_ncp16(borrow.name, g_passport.name, 
+//                             COUNTOF(borrow.name));
+//                     sgi_ncp16(borrow.gun_type, info[i].gun_model,
+//                             COUNTOF(borrow.gun_type));
+//                     sgi_ncp16(borrow.gun_code, info[i].gun_code,
+//                             COUNTOF(borrow.gun_code));
+//                     sgi_append_log(DBL(borrow), &borrow, 
+//                             sizeof(struct log_borrow));
+               }
+       }
+       
+       /* 记录上报数据 */
+       recorcd_borrow_report(&g_passport, 0, nums);
+       
+       /* 打开枪柜门 */
+       authorize_open_door();
+       
+       /* 打开对应枪锁 */
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if (s_box.box.cell[i].state & 1) {
+                       if (i2c_comm_unlock(s_box.box.cell_addr[i]) == 0) {
+                               SDL_Delay(2000);        
+                       }
+               }       
+       }
+       
+       msgbox(&FORM_CLASS(MODULE_NAME), L"请在规定的时间内领取枪械并关闭柜门!", 
+               SUCCESS, callback);     
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       do {
+
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 32, 150, 22, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 枪柜表格 */
+       BOX_CREATE(s_box, FORM_CLASS(MODULE_NAME), 69, 55, 658, 308, 1,
+               "jht.ttf", 20, color, "box-0.png", "box-1.png", "box-2.png", 
+               "box-3.png",IMG_OPTIMIZE | IMG_ALPHA, s_box_cell);
+       s_box.box.cell_addr = g_box_addr;
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 346, 383, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_box_manage.cpp b/src/fm_box_manage.cpp
new file mode 100644 (file)
index 0000000..933904b
--- /dev/null
@@ -0,0 +1,159 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_box_manage
+
+FORM_MODULE(MODULE_NAME);                      /* 权限管理模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_btn_init;            /* 枪弹柜初始化 */
+static union sgi_object s_btn_info;            /* 枪械信息查询 */
+static union sgi_object s_btn_status;          /* 枪弹柜状态 */
+static union sgi_object s_btn_remote_unlock;   /* 远程开锁 */
+static union sgi_object s_btn_urgent_unlock;   /* 紧急开锁 */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_init_up(struct sgi_button *)
+{      
+       //sgi_form_show(&FORM_CLASS(fm_return_fpr_user));       
+}
+
+static void btn_info_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_chpwd)); 
+}
+
+static void btn_status_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_chpwd)); 
+}
+
+static void btn_remote_unlock_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_chpwd)); 
+}
+
+static void btn_urgent_unlock_up(struct sgi_button *)
+{
+       /* 进入紧急开开锁必须由两个管理确认, 调用管理员密码验证窗口 */
+       sgi_form_show(&FORM_CLASS(fm_unlock_pwd));
+       //sgi_form_show(&FORM_CLASS(fm_unlock));        
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_menu));    
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       swprintf(buf, sizeof(buf), L"枪弹柜编号: A%03d", 1);
+       set_object_text_w(&s_lbl_code.label, buf);
+       
+       /* 枪弹柜初始化 */
+       BUTTON_CREATE(s_btn_init, FORM_CLASS(MODULE_NAME), 266, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-init.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_init.button.up = btn_init_up;
+       
+       /* 枪械信息查询 */
+       BUTTON_CREATE(s_btn_info, FORM_CLASS(MODULE_NAME), 409, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-info-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_info.button.up = btn_info_up;
+       
+       /* 枪弹柜状态查询 */
+       BUTTON_CREATE(s_btn_status, FORM_CLASS(MODULE_NAME), 200, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-status.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_status.button.up = btn_status_up;
+       
+       /* 远程开锁 */
+       BUTTON_CREATE(s_btn_remote_unlock, FORM_CLASS(MODULE_NAME), 340, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-unlock.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_remote_unlock.button.up = btn_remote_unlock_up;
+       
+       /* 远程开锁 */
+       BUTTON_CREATE(s_btn_urgent_unlock, FORM_CLASS(MODULE_NAME), 480, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-unlock-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_urgent_unlock.button.up = btn_urgent_unlock_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_chpwd.cpp b/src/fm_chpwd.cpp
new file mode 100644 (file)
index 0000000..12ed6d6
--- /dev/null
@@ -0,0 +1,230 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_chpwd
+
+FORM_MODULE(MODULE_NAME);                      /* 密码修改模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_uid;             /* 用户编号 */
+static union sgi_object s_edt_old_pwd;         /* 旧密码 */
+static union sgi_object s_edt_new_pwd;         /* 新密码 */
+static union sgi_object s_edt_confirm_pwd;     /* 确认新密码 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_pwd_retries = 0;
+
+static struct sgi_widget s_widget[] = {
+       {100, 44, 519, 173, {"chpwd.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       set_object_text_u(&s_edt_uid.edit, NULL);
+       set_object_text_u(&s_edt_old_pwd.edit, NULL);
+       set_object_text_u(&s_edt_new_pwd.edit, NULL);
+       set_object_text_u(&s_edt_confirm_pwd.edit, NULL);
+       set_object_focus(&s_edt_uid);
+       
+       s_timer = 120;
+       s_pwd_retries = 0;      
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_main.button.up(&s_btn_main.button);       
+       }
+       else if (user == PWD_NOT_MATCH) {
+               set_object_focus(&s_edt_confirm_pwd);   
+       }
+       else if (user == PWD_SHORTEST) {
+               set_object_focus(&s_edt_new_pwd);       
+       }
+       else if (user == ID_INVALID) {
+               set_object_focus(&s_edt_uid);   
+       }
+       else if (user == PWD_INVALID) {
+               set_object_focus(&s_edt_old_pwd);       
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       s32 r;
+       
+       /* 检查两次所输入新密码是否一致 */
+       if (sgi_ncmp16(s_edt_new_pwd.edit.text, s_edt_confirm_pwd.edit.text,
+               COUNTOF(s_edt_new_pwd.edit.text)) != 0) {
+               printf("confirm pwd fail.\n");
+               msgbox(&FORM_CLASS(MODULE_NAME), L"两次输入密码不一致!", 
+                       PWD_NOT_MATCH, callback);
+               return; 
+       }
+       
+       /* 检查密码长度是否符合要求 */
+       if ((r = sgi_len16(s_edt_new_pwd.edit.text)) < MIN_PWD_LEN) {
+               printf("pwd is shortest.\n");
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码长度应大于6个字符!", 
+                       PWD_SHORTEST, callback);
+               return; 
+       }
+       printf("pwd len: %d\n", r);
+       
+       /* 提交修改并验证用户及旧密码是否有效 */
+       r = change_pwd(s_edt_uid.edit.text, s_edt_old_pwd.edit.text,
+               s_edt_new_pwd.edit.text);
+       if (r == 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码修改成功!", 
+                       SUCCESS, callback);
+               
+               /* log */
+               record_system_log(s_edt_uid.edit.text, L"成功修改用户密码"); 
+       }
+       else if (r == ID_INVALID) {
+               printf("invalid user.\n");
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户信息不存在!", 
+                       ID_INVALID, callback);  
+       }
+       else if (r == PWD_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"旧密码无效!", 
+                       PWD_INVALID, callback);
+               
+               if (++s_pwd_retries >= PWD_MAX_RETRIES) {
+                       pwd_alarm();    
+               }                       
+       }       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号输入框 */
+       EDIT_CREATE(s_edt_uid, FORM_CLASS(MODULE_NAME), 375, 65, 222, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /* 旧密码 */
+       EDIT_CREATE(s_edt_old_pwd, FORM_CLASS(MODULE_NAME), 375, 101, 222, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_old_pwd.edit.pwdchar = 1; 
+               
+       /* 新密码 */
+       EDIT_CREATE(s_edt_new_pwd, FORM_CLASS(MODULE_NAME), 375, 137, 222, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_new_pwd.edit.pwdchar = 1;
+               
+       /* 确认新密码 */
+       EDIT_CREATE(s_edt_confirm_pwd, FORM_CLASS(MODULE_NAME), 375, 173, 222, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_confirm_pwd.edit.pwdchar = 1;
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 623, 156, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_download.cpp b/src/fm_download.cpp
new file mode 100644 (file)
index 0000000..4095ef9
--- /dev/null
@@ -0,0 +1,240 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_download
+
+FORM_MODULE(MODULE_NAME);                      /*  */          
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_vendor;          /*  */
+static union sgi_object s_lbl_product;         /*  */
+static union sgi_object s_lbl_sn;              /*  */
+static union sgi_object s_lbl_total;           /*  */
+static union sgi_object s_lbl_avail;           /*  */
+static union sgi_object s_btn_incre;           /*  */
+static union sgi_object s_btn_full;            /*  */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {130, 25, 541, 276, {"download.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 s_udisk_exist = 0;
+static struct udisk_info s_udisk;
+
+static void form_enter(struct sgi_form *)
+{
+       set_object_text_u(&s_lbl_vendor.label, NULL);
+       set_object_text_u(&s_lbl_product.label, NULL);
+       set_object_text_u(&s_lbl_sn.label, NULL);
+       set_object_text_u(&s_lbl_total.label, NULL);
+       set_object_text_u(&s_lbl_avail.label, NULL);
+       
+       s_udisk_exist = 0;
+       s_btn_incre.button.state |= 2;
+       s_btn_full.button.state |= 2;   
+}
+
+static void form_exit(struct sgi_form *)
+{
+                       
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       s_btn_back.button.up(&s_btn_back.button);               
+}
+
+static void btn_incre_up(struct sgi_button *)
+{
+       s32 count = 0;
+       wchar_t buf[64];
+               
+       if (!s_udisk_exist) {
+               return;
+       }
+       
+       count = download_log(0);
+       swprintf(buf, COUNTOF(buf), L"[%d]条数据下载完成!", count);
+       msgbox(&FORM_CLASS(MODULE_NAME), buf, 0, callback);             
+}
+
+static void btn_full_up(struct sgi_button *)
+{
+       if (!s_udisk_exist) {
+               return;
+       }
+       
+       download_log(1);
+       
+       msgbox(&FORM_CLASS(MODULE_NAME), L"数据下载完成!", 0, callback);        
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_menu));    
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       static u32 cycle = 0;
+       
+       /* per 1s check device */
+       if (TIME_AFTER(SDL_GetTicks(), cycle)) {
+               if (!s_udisk_exist) {
+                       if (udisk_insert_detect(&s_udisk) == 0) {
+                               sgi_cpa2u(s_lbl_vendor.label.caption,
+                                       s_udisk.vendor);
+                               sgi_cpa2u(s_lbl_product.label.caption,
+                                       s_udisk.product);
+                               sgi_cpa2u(s_lbl_sn.label.caption, s_udisk.sn);
+                               
+                               if (s_udisk.total > 1024) {
+                                       sgi_sprintf16(s_lbl_total.label.caption,
+                                               L"%.2f GB",
+                                               s_udisk.total / 1024.0f);       
+                               }
+                               else {
+                                       sgi_sprintf16(s_lbl_total.label.caption,
+                                               L"%d MB", s_udisk.total);       
+                               }
+                               
+                               if (s_udisk.avail > 1024) {
+                                       sgi_sprintf16(s_lbl_avail.label.caption,
+                                               L"%.2f GB",
+                                               s_udisk.avail / 1024.0f);       
+                               }
+                               else {
+                                       sgi_sprintf16(s_lbl_avail.label.caption,
+                                               L"%d MB", s_udisk.avail);       
+                               }
+                               
+                               s_udisk_exist = 1;
+                               s_btn_incre.button.state &= ~2;
+                               s_btn_full.button.state &= ~2;
+                               
+                               FORM_CLASS(MODULE_NAME).redraw = 1;     
+                       }       
+               }
+               else {
+                       if (udisk_remove_detect()) {
+                               set_object_text_u(&s_lbl_vendor.label, NULL);
+                               set_object_text_u(&s_lbl_product.label, NULL);
+                               set_object_text_u(&s_lbl_sn.label, NULL);
+                               set_object_text_u(&s_lbl_total.label, NULL);
+                               set_object_text_u(&s_lbl_avail.label, NULL);
+                               
+                               s_udisk_exist = 0;      
+                               s_btn_incre.button.state |= 2;
+                               s_btn_full.button.state |= 2;
+                               
+                               FORM_CLASS(MODULE_NAME).redraw = 1;
+                       }       
+               }
+               cycle = SDL_GetTicks() + 1000;  
+       }
+               
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       LABEL_CREATE(s_lbl_vendor, FORM_CLASS(MODULE_NAME), 353, 128, 338, 25, 1,
+                "jht.ttf", 24, color);
+                
+       LABEL_CREATE(s_lbl_product, FORM_CLASS(MODULE_NAME), 353, 166, 338, 25, 1,
+                "jht.ttf", 24, color);
+                
+       LABEL_CREATE(s_lbl_sn, FORM_CLASS(MODULE_NAME), 353, 199, 338, 25, 1,
+                "jht.ttf", 24, color);
+                
+       LABEL_CREATE(s_lbl_total, FORM_CLASS(MODULE_NAME), 353, 231, 338, 25, 1,
+                "jht.ttf", 24, color);
+                
+       LABEL_CREATE(s_lbl_avail, FORM_CLASS(MODULE_NAME), 353, 262, 338, 25, 1,
+                "jht.ttf", 24, color);
+       
+       /*  */
+       BUTTON_CREATE(s_btn_incre, FORM_CLASS(MODULE_NAME), 265, 319, 110, 45, 1,
+               "btn-incre-u.png", "btn-incre-d.png", "btn-incre-e.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_incre.button.up = btn_incre_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_full, FORM_CLASS(MODULE_NAME), 425, 319, 110, 45, 1,
+               "btn-full-u.png", "btn-full-d.png", "btn-full-e.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_full.button.up = btn_full_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;     
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_info_choice.cpp b/src/fm_info_choice.cpp
new file mode 100644 (file)
index 0000000..233d4b6
--- /dev/null
@@ -0,0 +1,121 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_info_choice
+
+FORM_MODULE(MODULE_NAME);                      /* 权限管理模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_btn_register;                /* 注册 */
+static union sgi_object s_btn_stat;            /* 统计 */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_register_up(struct sgi_button *)
+{      
+       sgi_form_show(&FORM_CLASS(fm_info_register));   
+}
+
+static void btn_stat_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_stat));       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_menu));    
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       swprintf(buf, sizeof(buf), L"枪弹柜编号: A%03d", 1);
+       set_object_text_w(&s_lbl_code.label, buf);
+       
+       /* 注册 */
+       BUTTON_CREATE(s_btn_register, FORM_CLASS(MODULE_NAME), 269, 176, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-reg.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_register.button.up = btn_register_up;
+       
+       /* 统计 */
+       BUTTON_CREATE(s_btn_stat, FORM_CLASS(MODULE_NAME), 409, 176, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-stat.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_stat.button.up = btn_stat_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_info_register.cpp b/src/fm_info_register.cpp
new file mode 100644 (file)
index 0000000..94fae9b
--- /dev/null
@@ -0,0 +1,162 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_info_register
+
+FORM_MODULE(MODULE_NAME);                      /* 权限管理模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_btn_unit;            /* 单位信息 */
+static union sgi_object s_btn_person;          /* 人员信息 */
+static union sgi_object s_btn_gun;             /* 枪支信息 */
+static union sgi_object s_btn_bullet;          /* 弹药信息 */
+static union sgi_object s_btn_box;             /* 枪弹柜信息 */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_unit_up(struct sgi_button *)
+{      
+       sgi_form_show(&FORM_CLASS(fm_reg_unit));        
+}
+
+static void btn_person_up(struct sgi_button *)
+{
+       /* */
+       person_reg_data_clear();
+       g_passport.reg_flag = REG_NEW;
+       g_data_update_state = REG_NEW;
+       sgi_form_show(&FORM_CLASS(fm_reg_person));      
+}
+
+static void btn_gun_up(struct sgi_button *)
+{
+       //g_data_update_state = REG_NEW;
+       sgi_form_show(&FORM_CLASS(fm_reg_gun)); 
+}
+
+static void btn_bullet_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_reg_bullet));      
+}
+
+static void btn_box_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_reg_box)); 
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_choice));     
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       swprintf(buf, sizeof(buf), L"枪弹柜编号: A%03d", 1);
+       set_object_text_w(&s_lbl_code.label, buf);
+       
+       /* 单位信息 */
+       BUTTON_CREATE(s_btn_unit, FORM_CLASS(MODULE_NAME), 265, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-unit.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_unit.button.up = btn_unit_up;
+       
+       /* 人员信息 */
+       BUTTON_CREATE(s_btn_person, FORM_CLASS(MODULE_NAME), 409, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-person.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_person.button.up = btn_person_up;
+       
+       /* 枪支信息 */
+       BUTTON_CREATE(s_btn_gun, FORM_CLASS(MODULE_NAME), 201, 243, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-gun.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_gun.button.up = btn_gun_up;
+       
+       /* 弹药信息 */
+       BUTTON_CREATE(s_btn_bullet, FORM_CLASS(MODULE_NAME), 340, 243, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-bullet.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_bullet.button.up = btn_bullet_up;
+       
+       /* 枪弹柜信息 */
+       BUTTON_CREATE(s_btn_box, FORM_CLASS(MODULE_NAME), 479, 243, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-box-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_box.button.up = btn_box_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_info_stat.cpp b/src/fm_info_stat.cpp
new file mode 100644 (file)
index 0000000..19e9d6f
--- /dev/null
@@ -0,0 +1,157 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_info_stat
+
+FORM_MODULE(MODULE_NAME);                      /* 权限管理模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_btn_unit;            /* 单位信息 */
+static union sgi_object s_btn_person;          /* 人员信息 */
+static union sgi_object s_btn_gun;             /* 枪支信息 */
+static union sgi_object s_btn_bullet;          /* 弹药信息 */
+static union sgi_object s_btn_box;             /* 枪弹柜信息 */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_unit_up(struct sgi_button *)
+{      
+       sgi_form_show(&FORM_CLASS(fm_reg_unit));        
+}
+
+static void btn_person_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_stat_person));     
+}
+
+static void btn_gun_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_stat_gun));        
+}
+
+static void btn_bullet_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_stat_bullet));     
+}
+
+static void btn_box_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_reg_box)); 
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_choice));     
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       swprintf(buf, sizeof(buf), L"枪弹柜编号: A%03d", 1);
+       set_object_text_w(&s_lbl_code.label, buf);
+       
+       /* 单位信息 */
+       BUTTON_CREATE(s_btn_unit, FORM_CLASS(MODULE_NAME), 265, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-unit.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_unit.button.up = btn_unit_up;
+       
+       /* 人员信息 */
+       BUTTON_CREATE(s_btn_person, FORM_CLASS(MODULE_NAME), 409, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-person.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_person.button.up = btn_person_up;
+       
+       /* 枪支信息 */
+       BUTTON_CREATE(s_btn_gun, FORM_CLASS(MODULE_NAME), 201, 243, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-gun.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_gun.button.up = btn_gun_up;
+       
+       /* 弹药信息 */
+       BUTTON_CREATE(s_btn_bullet, FORM_CLASS(MODULE_NAME), 340, 243, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-bullet.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_bullet.button.up = btn_bullet_up;
+       
+       /* 枪弹柜信息 */
+       BUTTON_CREATE(s_btn_box, FORM_CLASS(MODULE_NAME), 479, 243, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-box-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_box.button.up = btn_box_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_level.cpp b/src/fm_level.cpp
new file mode 100644 (file)
index 0000000..0100b36
--- /dev/null
@@ -0,0 +1,145 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_level
+
+FORM_MODULE(MODULE_NAME);                      /* 权限管理模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_btn_level;           /* 身份权限设置 */
+static union sgi_object s_btn_spec;            /* 特殊权限设置 */
+static union sgi_object s_btn_pwd;             /* 管理员密码设置 */
+static union sgi_object s_btn_logon;           /* 登录方式设定 */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_level_up(struct sgi_button *)
+{      
+       sgi_form_show(&FORM_CLASS(fm_user_level));      
+}
+
+static void btn_spec_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_chpwd)); 
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_chpwd)); 
+}
+
+static void btn_logon_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_chpwd)); 
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_menu));    
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       swprintf(buf, sizeof(buf), L"枪弹柜编号: A%03d", 1);
+       set_object_text_w(&s_lbl_code.label, buf);
+       
+       /* 身份权限设置 */
+       BUTTON_CREATE(s_btn_level, FORM_CLASS(MODULE_NAME), 269, 127, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-level-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_level.button.up = btn_level_up;
+       
+       /* 特殊权限设置 */
+       BUTTON_CREATE(s_btn_spec, FORM_CLASS(MODULE_NAME), 408, 127, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-spec.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_spec.button.up = btn_spec_up;
+       
+       /* 管理员密码设置 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 269, 240, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-pwd.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+       
+       /*登录方式设置 */
+       BUTTON_CREATE(s_btn_logon, FORM_CLASS(MODULE_NAME), 408, 240, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-logon.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_logon.button.up = btn_logon_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_log_alarm.cpp b/src/fm_log_alarm.cpp
new file mode 100644 (file)
index 0000000..391c558
--- /dev/null
@@ -0,0 +1,343 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_log_alarm
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_grid;
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_page = 0;
+static u32 s_data_size = 0;
+static s32 s_record_count = 0;
+static struct log_alarm *s_grid_data = NULL;
+
+static void grid_load_data(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 space_row_start = 0;
+       s32 index;
+       struct log_alarm *p;
+       s32 offset;
+       s32 read_count;
+       struct tm *tmlocal;
+       
+       /* 页数检查 */
+       offset = s_page * object->row;
+       if (!s_grid_data || offset > s_record_count) {
+               return;
+       }
+       
+       read_count = s_record_count - offset;
+       p = s_grid_data + read_count - 1;
+       for (i = 0; i < object->row; ) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%d", s_page * object->row + i + 1);
+                               break;
+                               
+                       case 1: /* column 1 */
+                               //sgi_ncpa2u(object->cells[index].string, p->id,
+                               //      COUNTOF(p->id));
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%05d", p->id);
+                               break;
+                               
+                       case 2: /* column 2 */
+                               tmlocal = localtime(&p->time);
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%02d/%02d", tmlocal->tm_mon + 1,
+                                       tmlocal->tm_mday);
+                               break;
+                               
+                       case 3: /* column 3 */
+                               sgi_ncp16(object->cells[index].string, p->content,
+                                       COUNTOF(p->content));
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               i++;
+               if (--read_count <= 0) {
+                       break;
+               }
+               p--;                    
+       }
+       
+       printf("space row start: %d\n", i);
+       
+       /* 剩余行清零 */
+       for (; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;                    
+                       memset(object->cells[index].string, 0,
+                               sizeof(object->cells[index].string));
+               }
+       }
+}
+
+static void grid_init(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       s32 y0;
+       const s32 row_offset = 62;
+       const s32 row_h = 26;
+       
+       /* */
+       object->col = 4;
+       object->row = 10;
+       
+       /* */
+       object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+               object->col * object->row);
+               
+       if (!object->cells) {
+               return;
+       }
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * row_h + row_offset;
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 33;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 55;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 89;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 98;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 188;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 99;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 3: /* column 3 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 289;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 313;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }       
+}
+
+static void grid_deinit(struct sgi_grid *object)
+{
+       free(object->cells);
+       object->cells = NULL;   
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /* */
+       s_page = 0;
+       s_data_size = 0;
+       
+       /* 初始表格 */
+       grid_init(&s_grid.grid);
+       
+       /* 加载表格数据 */
+       s_grid_data = (struct log_alarm *)sgi_log_open(DBL(alarm), &s_data_size);
+       s_record_count = s_data_size / sizeof(struct log_alarm);
+       grid_load_data(&s_grid.grid);
+       
+       printf("load data: %d\n", s_record_count);
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       grid_deinit(&s_grid.grid);
+       
+       printf("close data: %d\n", s_data_size);
+       
+       /* 关闭数据 */
+       if (s_grid_data) {
+               close_r(s_grid_data, s_data_size);
+       }       
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_main));        
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       if (s_page > 0) {
+               s_page--;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;         
+       }
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       if (((s_page + 1) * s_grid.grid.row) < s_record_count) {
+               s_page++;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1; 
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* */
+       GRID_CREATE(s_grid, FORM_CLASS(MODULE_NAME), 82, 44, 636, 333, 1,
+               "jht.ttf", 20, color, "log-alarm.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_grid.grid.readonly = 1;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 482, 388, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 572, 388, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_log_borrow.cpp b/src/fm_log_borrow.cpp
new file mode 100644 (file)
index 0000000..bf281b0
--- /dev/null
@@ -0,0 +1,382 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_log_borrow
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_grid;
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_page = 0;
+static u32 s_data_size = 0;
+static s32 s_record_count = 0;
+static struct log_borrow *s_grid_data = NULL;
+
+static void grid_load_data(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 space_row_start = 0;
+       s32 index;
+       struct log_borrow *p;
+       s32 offset;
+       s32 read_count;
+       struct tm *tmlocal;
+       
+       /* 页数检查 */
+       offset = s_page * object->row;
+       if (!s_grid_data || offset > s_record_count) {
+               return;
+       }
+       
+       read_count = s_record_count - offset;
+       p = s_grid_data + read_count - 1;
+       for (i = 0; i < object->row; ) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%d", s_page * object->row + i + 1);
+                               break;
+                               
+                       case 1: /* column 1 */
+                               //sgi_ncpa2u(object->cells[index].string, p->id,
+                               //      COUNTOF(p->id));
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%05d", p->id);
+                               break;
+                               
+                       case 2: /* column 2 */
+                               sgi_ncp16(object->cells[index].string, p->name,
+                                       COUNTOF(p->name));
+                               break;
+                               
+                       case 3: /* column 3 */
+                               tmlocal = localtime(&p->time);
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%02d/%02d", tmlocal->tm_mon + 1,
+                                       tmlocal->tm_mday);
+                               break;
+                               
+                       case 4: /* column 4 */
+                               sgi_ncp16(object->cells[index].string, p->gun_type,
+                                       COUNTOF(p->gun_type));
+                               break;
+                               
+                       case 5: /* column 5 */
+                               sgi_ncp16(object->cells[index].string, p->gun_code,
+                                       COUNTOF(p->gun_code));
+                               break;
+                               
+                       case 6: /* column 6 */
+                               sgi_sprintf16(object->cells[index].string, 
+                                       L"%d", p->bullets);
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               i++;
+               if (--read_count <= 0) {
+                       break;
+               }
+               p--;                    
+       }
+       
+       printf("space row start: %d\n", i);
+       
+       /* 剩余行清零 */
+       for (; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;                    
+                       memset(object->cells[index].string, 0,
+                               sizeof(object->cells[index].string));
+               }
+       }
+}
+
+static void grid_init(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       s32 y0;
+       const s32 row_offset = 62;
+       const s32 row_h = 26;
+       
+       /* */
+       object->col = 7;
+       object->row = 10;
+       
+       /* */
+       object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+               object->col * object->row);
+               
+       if (!object->cells) {
+               return;
+       }
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * row_h + row_offset;
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 23;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 44;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 68;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 158;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 3: /* column 3 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 249;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 4: /* column 4 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 340;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 89;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 5: /* column 5 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 430;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 6: /* column 6 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 521;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }       
+}
+
+static void grid_deinit(struct sgi_grid *object)
+{
+       free(object->cells);
+       object->cells = NULL;   
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /* */
+       s_page = 0;
+       s_data_size = 0;
+       
+       /* 初始表格 */
+       grid_init(&s_grid.grid);
+       
+       /* 加载表格数据 */
+       s_grid_data = (struct log_borrow *)sgi_log_open(DBL(borrow), &s_data_size);
+       s_record_count = s_data_size / sizeof(struct log_borrow);
+       grid_load_data(&s_grid.grid);
+       
+       printf("load data: %d\n", s_record_count);
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       grid_deinit(&s_grid.grid);
+       
+       printf("close data: %d\n", s_data_size);
+       
+       /* 关闭数据 */
+       if (s_grid_data) {
+               close_r(s_grid_data, s_data_size);
+       }       
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_main));        
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       if (s_page > 0) {
+               s_page--;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;         
+       }
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       if (((s_page + 1) * s_grid.grid.row) < s_record_count) {
+               s_page++;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* */
+       GRID_CREATE(s_grid, FORM_CLASS(MODULE_NAME), 82, 44, 636, 333, 1,
+               "jht.ttf", 20, color, "log-borrow.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_grid.grid.readonly = 1;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 482, 388, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 572, 388, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_log_main.cpp b/src/fm_log_main.cpp
new file mode 100644 (file)
index 0000000..b12bed5
--- /dev/null
@@ -0,0 +1,157 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_log_main
+
+FORM_MODULE(MODULE_NAME);                      /* 权限管理模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_btn_borrow;          /* 领取枪弹日志 */
+static union sgi_object s_btn_return;          /* 归还枪弹日志 */
+static union sgi_object s_btn_alarm;           /* 异常报警日志 */
+static union sgi_object s_btn_system;          /* 系统操作日志 */
+static union sgi_object s_btn_manager;         /* 管理员日志 */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_borrow_up(struct sgi_button *)
+{              
+       sgi_form_show(&FORM_CLASS(fm_log_borrow));      
+}
+
+static void btn_return_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_return));      
+}
+
+static void btn_alarm_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_alarm));       
+}
+
+static void btn_system_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_system));      
+}
+
+static void btn_manager_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_manager));     
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_menu));    
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       swprintf(buf, sizeof(buf), L"枪弹柜编号: A%03d", 1);
+       set_object_text_w(&s_lbl_code.label, buf);
+       
+       /* 领取枪弹日志 */
+       BUTTON_CREATE(s_btn_borrow, FORM_CLASS(MODULE_NAME), 409, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-borrow.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_borrow.button.up = btn_borrow_up;
+       
+       /* 归还枪弹日志 */
+       BUTTON_CREATE(s_btn_return, FORM_CLASS(MODULE_NAME), 200, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-return.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_return.button.up = btn_return_up;
+       
+       /* 异常报警日志 */
+       BUTTON_CREATE(s_btn_alarm, FORM_CLASS(MODULE_NAME), 340, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-alarm.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_alarm.button.up = btn_alarm_up;
+       
+       /* 系统操作日志 */
+       BUTTON_CREATE(s_btn_system, FORM_CLASS(MODULE_NAME), 480, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-system-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_system.button.up = btn_system_up;
+       
+       /* 管理员日志 */
+       BUTTON_CREATE(s_btn_manager, FORM_CLASS(MODULE_NAME), 266, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-manager.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_manager.button.up = btn_manager_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_log_manager.cpp b/src/fm_log_manager.cpp
new file mode 100644 (file)
index 0000000..7aa69cb
--- /dev/null
@@ -0,0 +1,356 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_log_manager
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_grid;
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_page = 0;
+static u32 s_data_size = 0;
+static s32 s_record_count = 0;
+static struct log_manager *s_grid_data = NULL;
+
+static void grid_load_data(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 space_row_start = 0;
+       s32 index;
+       struct log_manager *p;
+       s32 offset;
+       s32 read_count;
+       struct tm *tmlocal;
+       
+       /* 页数检查 */
+       offset = s_page * object->row;
+       if (!s_grid_data || offset > s_record_count) {
+               return;
+       }
+       
+       read_count = s_record_count - offset;
+       p = s_grid_data + read_count - 1;
+       for (i = 0; i < object->row; ) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%d", s_page * object->row + i + 1);
+                               break;
+                               
+                       case 1: /* column 1 */
+                               //sgi_ncpa2u(object->cells[index].string, p->id,
+                               //      COUNTOF(p->id));
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%05d", p->id);
+                               break;
+                               
+                       case 2: /* column 2 */
+                               tmlocal = localtime(&p->time);
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%02d/%02d", tmlocal->tm_mon + 1,
+                                       tmlocal->tm_mday);
+                               break;
+                               
+                       case 3: /* column 3 */
+                               sgi_ncp16(object->cells[index].string, p->name,
+                                       COUNTOF(p->name));
+                               break;
+                               
+                       case 4: /* column 4 */
+                               sgi_ncp16(object->cells[index].string, p->content,
+                                       COUNTOF(p->content));
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               i++;
+               if (--read_count <= 0) {
+                       break;
+               }
+               p--;                    
+       }
+       
+       printf("space row start: %d\n", i);
+       
+       /* 剩余行清零 */
+       for (; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;                    
+                       memset(object->cells[index].string, 0,
+                               sizeof(object->cells[index].string));
+               }
+       }
+}
+
+static void grid_init(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       s32 y0;
+       const s32 row_offset = 62;
+       const s32 row_h = 26;
+       
+       /* */
+       object->col = 5;
+       object->row = 10;
+       
+       /* */
+       object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+               object->col * object->row);
+               
+       if (!object->cells) {
+               return;
+       }
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * row_h + row_offset;
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 27;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 44;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 71;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 99;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 170;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 99;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 3: /* column 3 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 270;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 99;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 4: /* column 4 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 369;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 237;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }       
+}
+
+static void grid_deinit(struct sgi_grid *object)
+{
+       free(object->cells);
+       object->cells = NULL;   
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /* */
+       s_page = 0;
+       s_data_size = 0;
+       
+       /* 初始表格 */
+       grid_init(&s_grid.grid);
+       
+       /* 加载表格数据 */
+       s_grid_data = (struct log_manager *)sgi_log_open(DBL(manager), &s_data_size);
+       s_record_count = s_data_size / sizeof(struct log_manager);
+       grid_load_data(&s_grid.grid);
+       
+       printf("load data: %d\n", s_record_count);
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       grid_deinit(&s_grid.grid);
+       
+       printf("close data: %d\n", s_data_size);
+       
+       /* 关闭数据 */
+       if (s_grid_data) {
+               close_r(s_grid_data, s_data_size);
+       }       
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_main));        
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       if (s_page > 0) {
+               s_page--;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;         
+       }
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       if (((s_page + 1) * s_grid.grid.row) < s_record_count) {
+               s_page++;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1; 
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* */
+       GRID_CREATE(s_grid, FORM_CLASS(MODULE_NAME), 82, 44, 636, 333, 1,
+               "jht.ttf", 20, color, "log-manager.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_grid.grid.readonly = 1;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 482, 388, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 572, 388, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_log_return.cpp b/src/fm_log_return.cpp
new file mode 100644 (file)
index 0000000..98ea00a
--- /dev/null
@@ -0,0 +1,382 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_log_return
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_grid;
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_page = 0;
+static u32 s_data_size = 0;
+static s32 s_record_count = 0;
+static struct log_borrow *s_grid_data = NULL;
+
+static void grid_load_data(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 space_row_start = 0;
+       s32 index;
+       struct log_borrow *p;
+       s32 offset;
+       s32 read_count;
+       struct tm *tmlocal;
+       
+       /* 页数检查 */
+       offset = s_page * object->row;
+       if (!s_grid_data || offset > s_record_count) {
+               return;
+       }
+       
+       read_count = s_record_count - offset;
+       p = s_grid_data + read_count - 1;
+       for (i = 0; i < object->row; ) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%d", s_page * object->row + i + 1);
+                               break;
+                               
+                       case 1: /* column 1 */
+                               //sgi_ncpa2u(object->cells[index].string, p->id,
+                               //      COUNTOF(p->id));
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%05d", p->id);
+                               break;
+                               
+                       case 2: /* column 2 */
+                               sgi_ncp16(object->cells[index].string, p->name,
+                                       COUNTOF(p->name));
+                               break;
+                               
+                       case 3: /* column 3 */
+                               tmlocal = localtime(&p->time);
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%02d/%02d", tmlocal->tm_mon + 1,
+                                       tmlocal->tm_mday);
+                               break;
+                               
+                       case 4: /* column 4 */
+                               sgi_ncp16(object->cells[index].string, p->gun_type,
+                                       COUNTOF(p->gun_type));
+                               break;
+                               
+                       case 5: /* column 5 */
+                               sgi_ncp16(object->cells[index].string, p->gun_code,
+                                       COUNTOF(p->gun_code));
+                               break;
+                               
+                       case 6: /* column 6 */
+                               sgi_sprintf16(object->cells[index].string, 
+                                       L"%d", p->bullets);
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               i++;
+               if (--read_count <= 0) {
+                       break;
+               }
+               p--;                    
+       }
+       
+       printf("space row start: %d\n", i);
+       
+       /* 剩余行清零 */
+       for (; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;                    
+                       memset(object->cells[index].string, 0,
+                               sizeof(object->cells[index].string));
+               }
+       }
+}
+
+static void grid_init(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       s32 y0;
+       const s32 row_offset = 62;
+       const s32 row_h = 26;
+       
+       /* */
+       object->col = 7;
+       object->row = 10;
+       
+       /* */
+       object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+               object->col * object->row);
+               
+       if (!object->cells) {
+               return;
+       }
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * row_h + row_offset;
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 23;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 44;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 68;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 158;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 3: /* column 3 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 249;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 4: /* column 4 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 340;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 89;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 5: /* column 5 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 430;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 6: /* column 6 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 521;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 90;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }       
+}
+
+static void grid_deinit(struct sgi_grid *object)
+{
+       free(object->cells);
+       object->cells = NULL;   
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /* */
+       s_page = 0;
+       s_data_size = 0;
+       
+       /* 初始表格 */
+       grid_init(&s_grid.grid);
+       
+       /* 加载表格数据 */
+       s_grid_data = (struct log_borrow *)sgi_log_open(DBL(back), &s_data_size);
+       s_record_count = s_data_size / sizeof(struct log_borrow);
+       grid_load_data(&s_grid.grid);
+       
+       printf("load data: %d\n", s_record_count);
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       grid_deinit(&s_grid.grid);
+       
+       printf("close data: %d\n", s_data_size);
+       
+       /* 关闭数据 */
+       if (s_grid_data) {
+               close_r(s_grid_data, s_data_size);
+       }       
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_main));        
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       if (s_page > 0) {
+               s_page--;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;         
+       }
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       if (((s_page + 1) * s_grid.grid.row) < s_record_count) {
+               s_page++;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* */
+       GRID_CREATE(s_grid, FORM_CLASS(MODULE_NAME), 82, 44, 636, 333, 1,
+               "jht.ttf", 20, color, "log-return.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_grid.grid.readonly = 1;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 482, 388, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 572, 388, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_log_system.cpp b/src/fm_log_system.cpp
new file mode 100644 (file)
index 0000000..96e3828
--- /dev/null
@@ -0,0 +1,356 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_log_system
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_grid;
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_page = 0;
+static u32 s_data_size = 0;
+static s32 s_record_count = 0;
+static struct log_system *s_grid_data = NULL;
+
+static void grid_load_data(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 space_row_start = 0;
+       s32 index;
+       struct log_system *p;
+       s32 offset;
+       s32 read_count;
+       struct tm *tmlocal;
+       
+       /* 页数检查 */
+       offset = s_page * object->row;
+       if (!s_grid_data || offset > s_record_count) {
+               return;
+       }
+       
+       read_count = s_record_count - offset;
+       p = s_grid_data + read_count - 1;
+       for (i = 0; i < object->row; ) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%d", s_page * object->row + i + 1);
+                               break;
+                               
+                       case 1: /* column 1 */
+                               //sgi_ncpa2u(object->cells[index].string, p->id,
+                               //      COUNTOF(p->id));
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%05d", p->id);
+                               break;
+                               
+                       case 2: /* column 2 */
+                               sgi_ncp16(object->cells[index].string, p->name,
+                                       COUNTOF(p->name));
+                               break;
+                               
+                       case 3: /* column 3 */
+                               tmlocal = localtime(&p->time);
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%02d/%02d", tmlocal->tm_mon + 1,
+                                       tmlocal->tm_mday);
+                               break;                  
+                               
+                       case 4: /* column 4 */
+                               sgi_ncp16(object->cells[index].string, p->content,
+                                       COUNTOF(p->content));
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               i++;
+               if (--read_count <= 0) {
+                       break;
+               }
+               p--;                    
+       }
+       
+       printf("space row start: %d\n", i);
+       
+       /* 剩余行清零 */
+       for (; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;                    
+                       memset(object->cells[index].string, 0,
+                               sizeof(object->cells[index].string));
+               }
+       }
+}
+
+static void grid_init(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       s32 y0;
+       const s32 row_offset = 62;
+       const s32 row_h = 26;
+       
+       /* */
+       object->col = 5;
+       object->row = 10;
+       
+       /* */
+       object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+               object->col * object->row);
+               
+       if (!object->cells) {
+               return;
+       }
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * row_h + row_offset;
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 27;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 44;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 71;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 99;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 170;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 99;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 3: /* column 3 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 270;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 99;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 4: /* column 4 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 369;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 237;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }       
+}
+
+static void grid_deinit(struct sgi_grid *object)
+{
+       free(object->cells);
+       object->cells = NULL;   
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /* */
+       s_page = 0;
+       s_data_size = 0;
+       
+       /* 初始表格 */
+       grid_init(&s_grid.grid);
+       
+       /* 加载表格数据 */
+       s_grid_data = (struct log_system *)sgi_log_open(DBL(syslog), &s_data_size);
+       s_record_count = s_data_size / sizeof(struct log_system);
+       grid_load_data(&s_grid.grid);
+       
+       printf("load data: %d\n", s_record_count);
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       grid_deinit(&s_grid.grid);
+       
+       printf("close data: %d\n", s_data_size);
+       
+       /* 关闭数据 */
+       if (s_grid_data) {
+               close_r(s_grid_data, s_data_size);
+       }       
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_main));        
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       if (s_page > 0) {
+               s_page--;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;         
+       }
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       if (((s_page + 1) * s_grid.grid.row) < s_record_count) {
+               s_page++;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1; 
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* */
+       GRID_CREATE(s_grid, FORM_CLASS(MODULE_NAME), 82, 44, 636, 333, 1,
+               "jht.ttf", 20, color, "log-system.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_grid.grid.readonly = 1;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 482, 388, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 572, 388, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_main.cpp b/src/fm_main.cpp
new file mode 100644 (file)
index 0000000..af9ca5d
--- /dev/null
@@ -0,0 +1,211 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_main
+
+FORM_MODULE(MODULE_NAME);                      /* 领还枪主模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_idt_power;
+static union sgi_object s_idt_net;
+static union sgi_object s_btn_borrow;          /* 领取按钮 */
+static union sgi_object s_btn_return;          /* 归还按钮 */
+static union sgi_object s_btn_chpwd;           /* 修改密码按钮 */
+static union sgi_object s_btn_current;         /* 当前页面指示 */
+static union sgi_object s_btn_menu;            /* 回到主菜单按钮 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       u16 buf[32] = {0};//(u16)L'枪',(u16)L'柜',(u16)L'编',(u16)L'号',(u16)L':'};
+       
+       /* 关闭指纹模块 */
+       //if (fpr_close() != 0) {
+       //      printf("fpr close fail.\n");            
+       //}
+       //power_ctrl(0);
+       /* 打开锁监控 */
+       resume_lock_monitor();  
+       
+       /* */
+       sgi_sprintf16(buf, L"枪柜编号: ");
+       sgi_ncp16(&buf[6], get_box_code(), 16);
+       set_object_text_u(&s_lbl_code.label, buf);      
+}
+
+static void form_exit(struct sgi_form *)
+{
+               
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_borrow_up(struct sgi_button *)
+{
+       /* 打开指纹模块 */
+       //power_ctrl(1);
+       //SDL_Delay(200);
+//     if (fpr_open() != 0) {
+//             printf("fpr open fail.\n");     
+//     }       
+       
+       /* 清零通行记录数据 */
+       memset(&g_passport, 0, sizeof(struct passport_data));
+       
+       sgi_form_show(&FORM_CLASS(fm_borrow_fpr_user)); 
+}
+
+static void btn_return_up(struct sgi_button *)
+{
+       /* 打开指纹模块 */
+       //power_ctrl(1);
+       //SDL_Delay(200);
+       //if (fpr_open() != 0) {
+       //      printf("fpr open fail.\n");     
+       //}
+       
+       /* 清零通行记录数据 */
+       memset(&g_passport, 0, sizeof(struct passport_data));
+       
+       sgi_form_show(&FORM_CLASS(fm_return_fpr_user)); 
+}
+
+static void btn_chpwd_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_chpwd));   
+}
+
+static void btn_menu_up(struct sgi_button *)
+{
+       /* 清零通行记录数据 */
+       memset(&g_passport, 0, sizeof(struct passport_data));
+       
+       /* 调用管理员密码验证窗口 */
+       sgi_form_show(&FORM_CLASS(fm_menu_pwd));        
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       static u32 next_time = 0;
+       s32 status;
+       
+       if (TIME_AFTER(SDL_GetTicks(), next_time)) {
+               status = get_power_status();
+               if (s_idt_power.indicator.state != status) {
+                       s_idt_power.indicator.state = status;
+                       s_idt_power.indicator.redraw = 1;
+               }
+               
+               status = get_net_link_status();         
+               if (s_idt_net.indicator.state != status) {
+                       s_idt_net.indicator.state = status;
+                       s_idt_net.indicator.redraw = 1;
+               }               
+               next_time = SDL_GetTicks() + 1000;
+       }
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       
+       /* */
+       INDICATOR_CREATE(s_idt_power, FORM_CLASS(MODULE_NAME), 698, 429, 35, 35, 1,
+               "ac.png", "battery.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* */
+       INDICATOR_CREATE(s_idt_net, FORM_CLASS(MODULE_NAME), 744, 429, 35, 35, 1,
+               "net-down.png", "net-link.png", IMG_OPTIMIZE | IMG_ALPHA);
+       
+       /* 取枪按钮 */
+       BUTTON_CREATE(s_btn_borrow, FORM_CLASS(MODULE_NAME), 190, 184, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-borrow-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_borrow.button.up = btn_borrow_up;
+       
+       /* 还枪按钮 */
+       BUTTON_CREATE(s_btn_return, FORM_CLASS(MODULE_NAME), 330, 184, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-return-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_return.button.up = btn_return_up;
+       
+       /* 密码修改按钮 */
+       BUTTON_CREATE(s_btn_chpwd, FORM_CLASS(MODULE_NAME), 470, 184, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-chpwd.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_chpwd.button.up = btn_chpwd_up;
+
+       /* 归还枪弹按钮 */
+       BUTTON_CREATE(s_btn_current, FORM_CLASS(MODULE_NAME), 260, 315, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-main.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_current.button.state |= 2;
+       
+       /* 主菜单按钮 */
+       BUTTON_CREATE(s_btn_menu, FORM_CLASS(MODULE_NAME), 407, 315, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-menu.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_menu.button.up = btn_menu_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;     
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_menu.cpp b/src/fm_menu.cpp
new file mode 100644 (file)
index 0000000..7287512
--- /dev/null
@@ -0,0 +1,153 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_menu
+
+FORM_MODULE(MODULE_NAME);                      /* 主菜单模块 */           
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_btn_info;            /* 信息管理按钮 */
+static union sgi_object s_btn_level;           /* 权限管理按钮 */
+static union sgi_object s_btn_box;             /* 枪弹柜管理按钮 */
+static union sgi_object s_btn_log;             /* 使用日志按钮 */
+static union sgi_object s_btn_system;          /* 系统管理按钮 */
+static union sgi_object s_btn_main;            /* 领还枪弹按钮 */
+static union sgi_object s_btn_menu;            /* 回到主菜单按钮 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_info_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_choice));     
+}
+
+static void btn_level_up(struct sgi_button *)
+{      
+       sgi_form_show(&FORM_CLASS(fm_level));   
+}
+
+static void btn_box_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_box_manage));      
+}
+
+static void btn_log_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_main));        
+}
+
+static void btn_system_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_system));  
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       swprintf(buf, sizeof(buf), L"枪弹柜编号: A%03d", 1);
+       set_object_text_w(&s_lbl_code.label, buf);
+       
+       /* 信息管理按钮 */
+       BUTTON_CREATE(s_btn_info, FORM_CLASS(MODULE_NAME), 270, 94, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-info.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_info.button.up = btn_info_up;
+       
+       /* 权限管理按钮 */
+       BUTTON_CREATE(s_btn_level, FORM_CLASS(MODULE_NAME), 410, 94, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-level.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_level.button.up = btn_level_up;
+       
+       /*枪弹柜管理按钮 */
+       BUTTON_CREATE(s_btn_box, FORM_CLASS(MODULE_NAME), 200, 206, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-box.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_box.button.up = btn_box_up;
+       
+       
+       /*使用日志按钮 */
+       BUTTON_CREATE(s_btn_log, FORM_CLASS(MODULE_NAME), 340, 206, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-log.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_log.button.up = btn_log_up;
+       
+       /*系统管理按钮 */
+       BUTTON_CREATE(s_btn_system, FORM_CLASS(MODULE_NAME), 480, 206, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-system.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_system.button.up = btn_system_up;
+
+       /* 领还枪弹按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 260, 315, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-main.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 主菜单按钮 */
+       BUTTON_CREATE(s_btn_menu, FORM_CLASS(MODULE_NAME), 407, 315, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-menu.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_menu.button.state |= 2;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_menu_pwd.cpp b/src/fm_menu_pwd.cpp
new file mode 100644 (file)
index 0000000..fbd45fd
--- /dev/null
@@ -0,0 +1,184 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_menu_pwd
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,警员密码验证 */         
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_uid;             /* 用户编号 */
+static union sgi_object s_edt_pwd;             /* 密码输入框 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_pwd_retries = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {165, 59, 377, 95, {"pwd-2.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       set_object_text_u(&s_edt_uid.edit, NULL);
+       set_object_text_u(&s_edt_pwd.edit, NULL);
+       set_object_focus(&s_edt_uid);
+       
+       s_timer = 60;
+       s_pwd_retries = 0;      
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == ID_INVALID) {
+               set_object_focus(&s_edt_uid);   
+       }
+       else if (user == PWD_INVALID) {
+               set_object_focus(&s_edt_pwd);   
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       s32 r = verify_manager_pwd(&g_passport, s_edt_uid.edit.text, 
+               s_edt_pwd.edit.text);
+       
+       if (r >= 0) {   
+               g_passport.visit &= MGR_PWD_MASK;
+               g_passport.visit |= MGR_PWD_VALID;
+               sgi_form_show(&FORM_CLASS(fm_menu));
+       }
+       else if (r == ID_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户信息不存在!", 
+                       ID_INVALID, callback);          
+       }
+       else if (r == PWD_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码无效!", 
+                       PWD_INVALID, callback); 
+                       
+               if (++s_pwd_retries >= PWD_MAX_RETRIES) {
+                       pwd_alarm();    
+               }       
+       }               
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号输入框 */
+       EDIT_CREATE(s_edt_uid, FORM_CLASS(MODULE_NAME), 346, 86, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /* 密码输入框 */
+       EDIT_CREATE(s_edt_pwd, FORM_CLASS(MODULE_NAME), 346, 126, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_pwd.edit.pwdchar = 1; 
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 556, 106, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_mon_setting.cpp b/src/fm_mon_setting.cpp
new file mode 100644 (file)
index 0000000..110516c
--- /dev/null
@@ -0,0 +1,240 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_mon_setting
+
+FORM_MODULE(MODULE_NAME);                      /*  */          
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_chk_door;
+static union sgi_object s_chk_door_ex;
+static union sgi_object s_chk_lock;
+static union sgi_object s_chk_power;
+static union sgi_object s_chk_borrow;
+static union sgi_object s_chk_pwd;
+static union sgi_object s_lbl_door;            /*  */
+static union sgi_object s_lbl_door_ex;         /*  */
+static union sgi_object s_lbl_lock;            /*  */
+static union sgi_object s_lbl_power;           /*  */
+static union sgi_object s_lbl_borrow;          /*  */
+static union sgi_object s_lbl_pwd;             /*  */
+static union sgi_object s_btn_confirm;         /*  */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {127, 113, 547, 179, {"unlock.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s32 flags;
+       
+       flags = get_alarm_setting();
+       if (flags & ALARM_DOOR_EN) {
+               s_chk_door.check.value = 1;
+       }
+       else {
+               s_chk_door.check.value = 0;
+       }
+       
+       if (flags & ALARM_DOOR_EX_EN) {
+               s_chk_door_ex.check.value = 1;
+       }
+       else {
+               s_chk_door_ex.check.value = 0;
+       }
+       
+       if (flags & ALARM_LOCK_EN) {
+               s_chk_lock.check.value = 1;
+       }
+       else {
+               s_chk_lock.check.value = 0;
+       }
+       
+       if (flags & ALARM_POWER_EN) {
+               s_chk_power.check.value = 1;
+       }
+       else {
+               s_chk_power.check.value = 0;
+       }
+       
+       if (flags & ALARM_BORROW_EN) {
+               s_chk_borrow.check.value = 1;
+       }
+       else {
+               s_chk_borrow.check.value = 0;
+       }
+       
+       if (flags & ALARM_PWD_EN) {
+               s_chk_pwd.check.value = 1;
+       }
+       else {
+               s_chk_pwd.check.value = 0;
+       }
+}
+
+static void form_exit(struct sgi_form *)
+{
+                       
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{      
+       s32 flags = 0;
+       
+       if (s_chk_door.check.value) {
+               flags |= ALARM_DOOR_EN; 
+       }
+       
+       if (s_chk_door_ex.check.value) {
+               flags |= ALARM_DOOR_EX_EN;
+       }
+       
+       if (s_chk_lock.check.value) {
+               flags |= ALARM_LOCK_EN;
+       }
+       
+       if (s_chk_power.check.value) {
+               flags |= ALARM_POWER_EN;
+       }
+       
+       if (s_chk_borrow.check.value) {
+               flags |= ALARM_BORROW_EN;
+       }
+       
+       if (s_chk_pwd.check.value) {
+               flags |= ALARM_PWD_EN;
+       }
+       
+       printf("mon set: 0x%x\n", flags);
+       
+       setup_alarm(flags);
+       
+       s_btn_back.button.up(&s_btn_back.button);       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_system));  
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       LABEL_CREATE(s_lbl_door, FORM_CLASS(MODULE_NAME), 220, 95, 460, 43, 1,
+                "jht.ttf", 26, color);
+       set_object_text_w(&s_lbl_door.label, L"枪柜门锁监控");
+                
+       LABEL_CREATE(s_lbl_door_ex, FORM_CLASS(MODULE_NAME), 480, 95, 200, 43, 1,
+                "jht.ttf", 26, color);
+       set_object_text_w(&s_lbl_door_ex.label, L"柜门辅助监控");
+       
+       LABEL_CREATE(s_lbl_lock, FORM_CLASS(MODULE_NAME), 220, 138, 460, 43, 1,
+                "jht.ttf", 26, color);
+       set_object_text_w(&s_lbl_lock.label, L"枪锁监控");
+                
+       LABEL_CREATE(s_lbl_power, FORM_CLASS(MODULE_NAME), 220, 181, 460, 43, 1,
+                "jht.ttf", 26, color);
+       set_object_text_w(&s_lbl_power.label, L"枪柜断电报警");
+       
+       LABEL_CREATE(s_lbl_borrow, FORM_CLASS(MODULE_NAME), 220, 224, 460, 43, 1,
+                "jht.ttf", 26, color);
+       set_object_text_w(&s_lbl_borrow.label, L"超时还枪报警");
+                
+       LABEL_CREATE(s_lbl_pwd, FORM_CLASS(MODULE_NAME), 220, 267, 460, 43, 1,
+                "jht.ttf", 26, color);
+       set_object_text_w(&s_lbl_pwd.label, L"三次输入错误密码报警");
+       
+       CHECK_CREATE(s_chk_door, FORM_CLASS(MODULE_NAME), 160, 105, 43, 23, 1,
+               "chk-unsel.png", "chk-sel.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       CHECK_CREATE(s_chk_door_ex, FORM_CLASS(MODULE_NAME), 420, 105, 43, 23, 1,
+               "chk-unsel.png", "chk-sel.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       CHECK_CREATE(s_chk_lock, FORM_CLASS(MODULE_NAME), 160, 148, 43, 23, 1,
+               "chk-unsel.png", "chk-sel.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       CHECK_CREATE(s_chk_power, FORM_CLASS(MODULE_NAME), 160, 191, 43, 23, 1,
+               "chk-unsel.png", "chk-sel.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       CHECK_CREATE(s_chk_borrow, FORM_CLASS(MODULE_NAME), 160, 234, 43, 23, 1,
+               "chk-unsel.png", "chk-sel.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       CHECK_CREATE(s_chk_pwd, FORM_CLASS(MODULE_NAME), 160, 277, 43, 23, 1,
+               "chk-unsel.png", "chk-sel.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /*  */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 333, 325, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_box.cpp b/src/fm_reg_box.cpp
new file mode 100644 (file)
index 0000000..1d7c939
--- /dev/null
@@ -0,0 +1,275 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_box
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_cap;             /*  */
+static union sgi_object s_edt_manager;         /*  */
+static union sgi_object s_edt_code;            /*  */
+static union sgi_object s_edt_model;           /*  */
+static union sgi_object s_edt_unit;            /*  */
+static union sgi_object s_rad_gun;             /*  */
+static union sgi_object s_rad_bullet;          /*  */
+static union sgi_object s_btn_save;            /* 返回按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {102, 45, 546, 179, {"box-reg.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void load_data(void)
+{
+       struct box_data *box;
+       size_t size;
+       
+       /* */
+       box = (struct box_data *)open_r(DBD(gun_box), &size);
+       if (!box || size != sizeof(struct box_data)) {
+               set_object_text_u(&s_edt_cap.edit, NULL);
+               set_object_text_u(&s_edt_code.edit, NULL);
+               set_object_text_u(&s_edt_manager.edit, NULL);
+               set_object_text_u(&s_edt_model.edit, NULL);
+               set_object_text_u(&s_edt_unit.edit, NULL);
+               s_rad_gun.radio.value = 0;
+               s_rad_bullet.radio.value = 0;
+       }
+       else {
+               set_object_text_u(&s_edt_code.edit, box->code);
+               set_object_text_u(&s_edt_model.edit, box->model);
+               set_object_text_u(&s_edt_manager.edit, box->manager);
+               set_object_text_u(&s_edt_unit.edit, box->unit);
+               sgi_sprintf16(s_edt_cap.edit.text, L"%d", box->cap);
+               if (box->type == BOX_TYPE_BULLET) {
+                       s_rad_gun.radio.value = 0;
+                       s_rad_bullet.radio.value = 1;
+               }
+               else {
+
+                       s_rad_gun.radio.value = 1;
+                       s_rad_bullet.radio.value = 0;   
+               }       
+       }
+       
+       if (box) {
+               close_r(box, size);     
+       }               
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /*  */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* */
+       load_data();
+       
+       /*  */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_register));   
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_back.button.up(&s_btn_back.button);       
+       }
+       else if (user == REGISTER_FAIL) {
+               set_object_focus(&s_edt_code);  
+       }                       
+}
+
+static void btn_save_up(struct sgi_button *object)
+{
+       s32 r;
+       struct box_data box;
+       
+       /* */
+       memset(&box, 0, sizeof(struct box_data));
+       sgi_cp16(box.code, s_edt_code.edit.text);
+       sgi_cp16(box.model, s_edt_model.edit.text);
+       sgi_cp16(box.manager, s_edt_manager.edit.text);
+       sgi_cp16(box.unit, s_edt_unit.edit.text);
+       box.cap = sgi_utol(s_edt_cap.edit.text, 10);
+       if (s_rad_gun.radio.value) {
+               box.type = BOX_TYPE_GUN;
+       }
+       else {
+               box.type = BOX_TYPE_BULLET;
+       }
+       
+       /* */
+       r = register_box((struct box_data *)&box);
+       if (r == SUCCESS) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"枪/弹柜资料更新成功!", 
+                       SUCCESS, callback);
+                       
+               /* log */
+               record_manager_log(g_passport.mname, L"更新枪/弹柜资料");
+//             struct log_manager manager;
+//             memset(&manager, 0, sizeof(struct log_manager));
+//             manager.id = get_log_no(LOG_MANAGER);
+//             time(&manager.time);
+//             sgi_ncp16(manager.name, g_passport.mname, COUNTOF(manager.name));
+//             sgi_cpw2u(manager.content, L"更新枪/弹柜资料");
+//             sgi_append_log(DBL(manager), &manager, sizeof(struct log_manager));
+       }
+       else {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"枪/弹资料更新失败!", 
+                       REGISTER_FAIL, callback);       
+       }       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_cap, FORM_CLASS(MODULE_NAME), 230, 139, 160, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       s_edt_cap.edit.mask = MSK_DIGIT;
+       s_edt_cap.edit.word_max = 3;
+       
+       /*  */
+       EDIT_CREATE(s_edt_manager, FORM_CLASS(MODULE_NAME), 230, 178, 160, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+               
+       /*  */
+       EDIT_CREATE(s_edt_code, FORM_CLASS(MODULE_NAME), 498, 100, 122, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_model, FORM_CLASS(MODULE_NAME), 498, 139, 122, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_unit, FORM_CLASS(MODULE_NAME), 498, 178, 122, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /* */
+       RADIO_CREATE(s_rad_gun, FORM_CLASS(MODULE_NAME), 224, 98, 33, 23, 1,
+               "rad-sel-u.png", "rad-sel-d.png", IMG_OPTIMIZE | IMG_ALPHA);
+       
+       /* */
+       RADIO_CREATE(s_rad_bullet, FORM_CLASS(MODULE_NAME), 307, 98, 33, 23, 1,
+               "rad-sel-u.png", "rad-sel-d.png", IMG_OPTIMIZE | IMG_ALPHA);
+       
+       /*  */
+       BUTTON_CREATE(s_btn_save, FORM_CLASS(MODULE_NAME), 654, 162, 108, 47, 1,
+               "btn-save-u.png", "btn-save-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_save.button.up = btn_save_up;             
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_bullet.cpp b/src/fm_reg_bullet.cpp
new file mode 100644 (file)
index 0000000..c75271a
--- /dev/null
@@ -0,0 +1,191 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_bullet
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_bullet;          /*  */
+static union sgi_object s_edt_bullet_type;     /*  */
+static union sgi_object s_edt_for_gun;         /*  */
+static union sgi_object s_edt_amount;          /*  */
+static union sgi_object s_edt_batch;           /*  */
+static union sgi_object s_edt_box_no;          /*  */
+static union sgi_object s_edt_unit;            /*  */
+static union sgi_object s_btn_save;            /*  */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {102, 45, 546, 179, {"bullet-reg.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_register));   
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_save_up(struct sgi_button *object)
+{
+       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_bullet, FORM_CLASS(MODULE_NAME), 227, 100, 142, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /*  */
+       EDIT_CREATE(s_edt_bullet_type, FORM_CLASS(MODULE_NAME), 499, 100, 142, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+               
+       /*  */
+       EDIT_CREATE(s_edt_for_gun, FORM_CLASS(MODULE_NAME), 227, 129, 142, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_amount, FORM_CLASS(MODULE_NAME), 499, 129, 142, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_batch, FORM_CLASS(MODULE_NAME), 227, 159, 142, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_box_no, FORM_CLASS(MODULE_NAME), 499, 159, 142, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_unit, FORM_CLASS(MODULE_NAME), 227, 189, 241, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       
+       /*  */
+       BUTTON_CREATE(s_btn_save, FORM_CLASS(MODULE_NAME), 654, 162, 108, 47, 1,
+               "btn-save-u.png", "btn-save-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_save.button.up = btn_save_up;             
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_fpr1_1.cpp b/src/fm_reg_fpr1_1.cpp
new file mode 100644 (file)
index 0000000..e2fba95
--- /dev/null
@@ -0,0 +1,195 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_fpr1_1
+
+FORM_MODULE(MODULE_NAME);                      /*  */  
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_fpr_start = 0;
+static s32 s_fpr_fail = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[5] = {
+       {368, 97, 274, 235, {"fpr.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {108, 120, 234, 129, {"tip-fpr1_1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_lbl_time.label.tag = 60;
+       s_timer = 60;
+       s_fpr_start = 0;
+       s_fpr_fail = 0;
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//     }               
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       sgi_form_show(&FORM_CLASS(fm_reg_person));      
+}
+
+static void callback(s32 user)
+{
+       if (user == FPR_FAIL) {
+               s_fpr_fail = 0; 
+               s_fpr_start = 0;        
+       }                       
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       u32 state = 0;
+       
+       do {
+               if (s_fpr_fail) {
+                       break;
+               }
+               
+               if (!s_fpr_start) {
+                       //if (fpr_check_press_finger(&state) != 0) {
+                       //      printf("check finger press fail.\n");
+                       //      break;
+                       //}
+                       if (fpr_press_detect() != 0) {
+                               break;
+                       }                       
+
+                       fpr_module_trigger(FPR_ENROLL_1);
+                       s_fpr_start = 1;
+                       printf("first enroll.\n");                                                      
+               }
+               
+               if (fpr_get_busy_flag()) {
+                       break;  
+               }       
+               
+               printf("module is not busy.\n");        
+               if (fpr_get_error_flag()) {
+                       s_fpr_fail = 1;
+                       printf("fpr_get_error_flag is true.\n");
+                       msgbox(&FORM_CLASS(MODULE_NAME), L"指纹登记失败!", 
+                               FPR_FAIL, callback);
+               }
+               else {
+                       r = fpr_get_result();
+                       printf("fpr result: %d\n", r);
+                       
+                       g_passport.fpr_id = r;                  
+                       
+                       /*  */
+                       sgi_form_show(&FORM_CLASS(fm_reg_fpr1_2));
+                                       
+               }
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_fpr1_2.cpp b/src/fm_reg_fpr1_2.cpp
new file mode 100644 (file)
index 0000000..d502314
--- /dev/null
@@ -0,0 +1,192 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_fpr1_2
+
+FORM_MODULE(MODULE_NAME);                      /*  */  
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_fpr_start = 0;
+static s32 s_fpr_fail = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[5] = {
+       {368, 97, 274, 235, {"fpr.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {108, 120, 234, 129, {"tip-fpr1_2.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_lbl_time.label.tag = 60;
+       s_timer = 60;
+       s_fpr_start = 0;
+       s_fpr_fail = 0;
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//     }               
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       sgi_form_show(&FORM_CLASS(fm_reg_person));      
+}
+
+static void callback(s32 user)
+{
+       if (user == FPR_FAIL) {
+               s_fpr_fail = 1;         
+       }                       
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       u32 state = 0;
+       
+       do {
+               if (s_fpr_fail) {
+                       break;
+               }
+               
+               if (!s_fpr_start) {
+                       //if (fpr_check_press_finger(&state) != 0) {
+                       //      break;
+                       //}
+                       if (fpr_press_detect() != 0) {
+                               break;
+                       }
+                       
+                       fpr_module_trigger(FPR_ENROLL_2);
+                       s_fpr_start = 1;
+                       printf("second enroll.\n");                                                     
+               }
+               
+               if (fpr_get_busy_flag()) {
+                       break;  
+               }       
+               
+               printf("module is not busy.\n");        
+               if (fpr_get_error_flag()) {
+                       s_fpr_fail = 1;
+                       printf("fpr_get_error_flag is true.\n");
+                       msgbox(&FORM_CLASS(MODULE_NAME), L"指纹登记失败!", 
+                               FPR_FAIL, callback);
+               }
+               else {
+                       r = fpr_get_result();
+                       printf("fpr result: %d\n", r);
+                       
+                       /*  */
+                       sgi_form_show(&FORM_CLASS(fm_reg_fpr1_3));
+                                       
+               }
+               s_fpr_start = 0;
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_fpr1_3.cpp b/src/fm_reg_fpr1_3.cpp
new file mode 100644 (file)
index 0000000..9ea1344
--- /dev/null
@@ -0,0 +1,199 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_fpr1_3
+
+FORM_MODULE(MODULE_NAME);                      /*  */  
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_fpr_start = 0;
+static s32 s_fpr_fail = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[5] = {
+       {368, 97, 274, 235, {"fpr.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {108, 120, 234, 129, {"tip-fpr1_3.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_lbl_time.label.tag = 60;
+       s_timer = 60;
+       s_fpr_start = 0;
+       s_fpr_fail = 0;
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//     }               
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       sgi_form_show(&FORM_CLASS(fm_reg_person));      
+}
+
+static void callback(s32 user)
+{
+       if (user == FPR_FAIL) {
+               sgi_form_show(&FORM_CLASS(fm_reg_person));              
+       }                       
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       u32 state = 0;
+       
+       do {
+               if (s_fpr_fail) {
+                       break;
+               }
+               
+               if (!s_fpr_start) {
+                       //if (fpr_check_press_finger(&state) != 0) {
+                       //      break;  
+                       //}
+                       if (fpr_press_detect() != 0) {
+                               break;
+                       }
+                       
+                       fpr_module_trigger(FPR_ENROLL_3);
+                       s_fpr_start = 1;
+                       printf("third enroll.\n");                      
+               }
+               
+               if (fpr_get_busy_flag()) {
+                       break;  
+               }       
+               
+               printf("module is not busy.\n");        
+               if (fpr_get_error_flag()) {
+                       s_fpr_fail = 1;
+                       printf("fpr_get_error_flag is true.\n");
+                       msgbox(&FORM_CLASS(MODULE_NAME), L"指纹登记失败!", 
+                               FPR_FAIL, callback);
+               }
+               else {
+                       r = fpr_get_result();
+                       printf("fpr result: %d\n", r);
+                       
+                       struct person_data *person = get_person_reg_data();
+                       if (g_passport.fpr_enroll == 1) {
+                               person->fpr1 = g_passport.fpr_id;
+                       }
+                       else if (g_passport.fpr_enroll == 2) {
+                               person->fpr2 = g_passport.fpr_id;       
+                       }
+                       
+                       /*  */
+                       sgi_form_show(&FORM_CLASS(fm_reg_person));
+                                       
+               }
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_gun.cpp b/src/fm_reg_gun.cpp
new file mode 100644 (file)
index 0000000..cd2b518
--- /dev/null
@@ -0,0 +1,384 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_gun
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_gun_code;                /*  */
+static union sgi_object s_edt_lock_code;       /*  */
+static union sgi_object s_edt_model;           /*  */
+static union sgi_object s_edt_caliber;         /*  */
+static union sgi_object s_edt_bullet;          /*  */
+static union sgi_object s_edt_holder;          /*  */
+static union sgi_object s_edt_unit;            /*  */
+static union sgi_object s_edt_stock_date;      /*  */
+static union sgi_object s_rad_good;            /*  */
+static union sgi_object s_rad_fault;           /*  */
+static union sgi_object s_rad_discard;         /*  */
+static union sgi_object s_rad_lost;            /*  */
+static union sgi_object s_btn_save;            /*  */
+static union sgi_object s_btn_del;             /*  */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {103, 46, 546, 179, {"gun-reg.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *object)
+{
+       /* 暂停锁监控 */
+       pause_lock_monitor();
+       
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* */
+       if (g_data_update_state == REG_MODIFY) {
+               s_edt_gun_code.edit.readonly = 1;
+               
+               struct gun_data *p = get_gun_reg_data();
+               set_object_text_u(&s_edt_gun_code.edit, p->code);               
+               set_object_text_u(&s_edt_model.edit, p->model); 
+               set_object_text_u(&s_edt_caliber.edit, p->caliber);     
+               set_object_text_u(&s_edt_bullet.edit, p->bullet);       
+               set_object_text_u(&s_edt_holder.edit, p->holder);       
+               set_object_text_u(&s_edt_unit.edit, p->unit);   
+               set_object_text_u(&s_edt_stock_date.edit, p->stock_date);
+               
+               sgi_sprintf16(s_edt_lock_code.edit.text, L"%d", p->lock_code);
+               if (p->status == 0) {
+                       s_rad_good.radio.value = 1;
+               }
+               else if (p->status == 1) {
+                       s_rad_fault.radio.value = 1;    
+               }
+               else if (p->status == 2) {
+                       s_rad_discard.radio.value = 1;  
+               }
+               else {
+                       s_rad_lost.radio.value = 1;     
+               }
+                               
+               g_data_update_state = REG_UPDATE;
+               
+               s_btn_del.button.state &= ~2;   
+       }
+       else {
+               s_edt_gun_code.edit.readonly = 0;
+               set_object_text_u(&s_edt_gun_code.edit, NULL);  
+               set_object_text_u(&s_edt_lock_code.edit, NULL); 
+               set_object_text_u(&s_edt_model.edit, NULL);     
+               set_object_text_u(&s_edt_caliber.edit, NULL);   
+               set_object_text_u(&s_edt_bullet.edit, NULL);    
+               set_object_text_u(&s_edt_holder.edit, NULL);    
+               set_object_text_u(&s_edt_unit.edit, NULL);      
+               set_object_text_u(&s_edt_stock_date.edit, NULL);        
+               s_rad_good.radio.value = 1;
+               set_object_focus(&s_edt_gun_code);
+               
+               s_btn_del.button.state |= 2;
+               
+               g_data_update_state = REG_NONE;
+       }
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       /* 打开锁监控 */
+       resume_lock_monitor();
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_register));   
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_back.button.up(&s_btn_back.button);       
+       }
+       else if (user == ID_EXIST) {
+               set_object_focus(&s_edt_gun_code);      
+       }
+       else if (user == APPEND_FAIL) {
+               set_object_focus(&s_edt_gun_code);
+       }
+       else if (user == ID_INVALID) {
+               set_object_focus(&s_edt_gun_code);      
+       }                               
+}
+
+static void btn_save_up(struct sgi_button *object)
+{
+       s32 r;
+       struct gun_data gun;
+       
+       /* 校验并保存数据 */
+       if (sgi_len16(s_edt_gun_code.edit.text) == 0) {         
+               msgbox(&FORM_CLASS(MODULE_NAME), L"枪支编号不能为空!", 
+                       ID_INVALID, callback);
+               return;
+       }
+       sgi_cp16(gun.code, s_edt_gun_code.edit.text);
+       sgi_cp16(gun.model, s_edt_model.edit.text);
+       sgi_cp16(gun.caliber, s_edt_caliber.edit.text);
+       sgi_cp16(gun.bullet, s_edt_bullet.edit.text);
+       sgi_cp16(gun.holder, s_edt_holder.edit.text);
+       sgi_cp16(gun.unit, s_edt_unit.edit.text);
+       sgi_cp16(gun.stock_date, s_edt_stock_date.edit.text);
+       gun.lock_code =sgi_utol(s_edt_lock_code.edit.text, 10);
+       if (s_rad_good.radio.value) {
+               gun.status = 0;
+       }
+       else if (s_rad_fault.radio.value) {
+               gun.status = 1; 
+       }
+       else if (s_rad_discard.radio.value) {
+               gun.status = 2; 
+       }
+       else if (s_rad_lost.radio.value) {
+               gun.status = 3; 
+       }
+       else {
+               gun.status = 4;
+       }
+       
+       if (g_data_update_state == REG_UPDATE) {
+               r = update_gun(&gun);
+       }
+       else {
+               r = register_gun(&gun);
+       }
+       
+       if (r == 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"枪支资料更新成功!", 
+                       SUCCESS, callback);
+               
+               /* log */
+               record_manager_log(g_passport.mname, L"更新枪支资料");
+//             struct log_manager manager;
+//             memset(&manager, 0, sizeof(struct log_manager));
+//             manager.id = get_log_no(LOG_MANAGER);
+//             time(&manager.time);
+//             sgi_ncp16(manager.name, g_passport.mname, COUNTOF(manager.name));
+//             sgi_cpw2u(manager.content, L"更新枪支资料");
+//             sgi_append_log(DBL(manager), &manager, sizeof(struct log_manager));     
+       }
+       else if (r == ID_EXIST) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"枪支编号已经存在!", 
+                       ID_EXIST, callback);    
+       }
+       else if (r == APPEND_FAIL) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"枪支资料更新失败!", 
+                       ID_EXIST, callback);
+       }       
+}
+
+
+static void btn_del_up(struct sgi_button *object)
+{
+       if (object->state & 2) { /* disable */
+               return;
+       }
+       
+       struct gun_data *gun = get_gun_reg_data();
+       s32 r = delete_gun(gun);        
+       if (r == 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"枪支资料删除成功!", 
+                       SUCCESS, callback);
+                       
+               /* log */
+               struct log_manager manager;
+               memset(&manager, 0, sizeof(struct log_manager));
+               manager.id = get_log_no(LOG_MANAGER);
+               time(&manager.time);
+               sgi_ncp16(manager.name, g_passport.mname, COUNTOF(manager.name));
+               sgi_cpw2u(manager.content, L"删除枪支资料");
+               sgi_append_log(DBL(manager), &manager, sizeof(struct log_manager));     
+       }
+       else {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"枪支资料删除失败!", 
+                       DEL_FAIL, callback);
+       }       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_gun_code, FORM_CLASS(MODULE_NAME), 214, 91, 122, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_gun_code.edit.word_max = 15;
+       
+       /*  */
+       EDIT_CREATE(s_edt_lock_code, FORM_CLASS(MODULE_NAME), 474, 91, 136, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_lock_code.edit.mask = MSK_DIGIT; 
+       s_edt_lock_code.edit.word_max = 3;
+               
+       /*  */
+       EDIT_CREATE(s_edt_model, FORM_CLASS(MODULE_NAME), 214, 116, 120, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_model.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_caliber, FORM_CLASS(MODULE_NAME), 474, 116, 136, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_caliber.edit.word_max = 7;
+               
+       /*  */
+       EDIT_CREATE(s_edt_bullet, FORM_CLASS(MODULE_NAME), 214, 141, 156, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_bullet.edit.word_max = 7;
+               
+       /*  */
+       EDIT_CREATE(s_edt_holder, FORM_CLASS(MODULE_NAME), 474, 141, 136, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_holder.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_unit, FORM_CLASS(MODULE_NAME), 214, 165, 156, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_unit.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_stock_date, FORM_CLASS(MODULE_NAME), 474, 165, 136, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_stock_date.edit.word_max = 15;
+       
+       /* */
+       RADIO_CREATE(s_rad_good, FORM_CLASS(MODULE_NAME), 208, 192, 33, 23, 1,
+               "rad-sel-u.png", "rad-sel-d.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* */
+       RADIO_CREATE(s_rad_fault, FORM_CLASS(MODULE_NAME), 288, 192, 33, 23, 1,
+               "rad-sel-u.png", "rad-sel-d.png", IMG_OPTIMIZE | IMG_ALPHA);
+       
+       /* */
+       RADIO_CREATE(s_rad_discard, FORM_CLASS(MODULE_NAME), 365, 192, 33, 23, 1,
+               "rad-sel-u.png", "rad-sel-d.png", IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* */
+       RADIO_CREATE(s_rad_lost, FORM_CLASS(MODULE_NAME), 441, 192, 33, 23, 1,
+               "rad-sel-u.png", "rad-sel-d.png", IMG_OPTIMIZE | IMG_ALPHA);    
+       
+       /*  */
+       BUTTON_CREATE(s_btn_save, FORM_CLASS(MODULE_NAME), 654, 176, 110, 45, 1,
+               "btn-save-u.png", "btn-save-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_save.button.up = btn_save_up;
+       
+       BUTTON_CREATE(s_btn_del, FORM_CLASS(MODULE_NAME), 654, 118, 110, 45, 1,
+               "btn-del-u.png", "btn-del-d.png", "btn-del-e.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_del.button.up = btn_del_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_person.cpp b/src/fm_reg_person.cpp
new file mode 100644 (file)
index 0000000..152d985
--- /dev/null
@@ -0,0 +1,431 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_person
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_name;            /*  */
+static union sgi_object s_edt_dept;            /*  */
+static union sgi_object s_edt_gun;             /*  */
+static union sgi_object s_edt_lock_code;       /*  */
+static union sgi_object s_edt_card;            /*  */
+static union sgi_object s_edt_id;              /*  */
+static union sgi_object s_edt_post;            /*  */
+static union sgi_object s_edt_gun_code;                /*  */
+static union sgi_object s_edt_phone;           /*  */
+static union sgi_object s_edt_sex;             /*  */
+static union sgi_object s_edt_age;             /*  */
+static union sgi_object s_btn_photo;           /*  */
+static union sgi_object s_btn_pwd;             /*  */
+static union sgi_object s_btn_fpr1;            /*  */
+static union sgi_object s_btn_fpr2;            /*  */
+static union sgi_object s_btn_save;            /*  */
+static union sgi_object s_btn_del;             /*  */
+static union sgi_object s_chk_ime;             /*  */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {127, 51, 546, 315, {"person-reg.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *object)
+{
+       /* 打开指纹模块电源 */
+       power_ctrl(1);
+       
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* 输入法是否可见 */
+       if (object->ime) {
+               object->ime->hide = s_chk_ime.check.value;
+               printf("check-ime value: %d\n", s_chk_ime.check.value); 
+       }
+       
+       /* */
+       if (g_passport.reg_flag == REG_NEW) {
+               s_edt_id.edit.readonly = 0;
+               set_object_text_u(&s_edt_name.edit, NULL);      
+               set_object_text_u(&s_edt_dept.edit, NULL);      
+               set_object_text_u(&s_edt_gun.edit, NULL);       
+               set_object_text_u(&s_edt_lock_code.edit, NULL);
+               set_object_text_u(&s_edt_card.edit, NULL);      
+               set_object_text_u(&s_edt_id.edit, NULL);        
+               set_object_text_u(&s_edt_post.edit, NULL);      
+               set_object_text_u(&s_edt_gun_code.edit, NULL);  
+               set_object_text_u(&s_edt_phone.edit, NULL);     
+               set_object_text_u(&s_edt_sex.edit, NULL);       
+               set_object_text_u(&s_edt_age.edit, NULL);
+               
+               g_passport.reg_flag = REG_MODIFY;
+               g_data_update_state = REG_NONE;
+               
+               s_btn_del.button.state |= 2;
+       }
+       else if (g_data_update_state == REG_MODIFY) {
+               struct person_data *p = get_person_reg_data();
+               
+               s_edt_id.edit.readonly = 1;
+               set_object_text_u(&s_edt_id.edit, p->uid);
+               set_object_text_u(&s_edt_name.edit, p->name);
+               set_object_text_u(&s_edt_dept.edit, p->dept);   
+               set_object_text_u(&s_edt_gun.edit, p->gun);     
+               set_object_text_u(&s_edt_lock_code.edit, p->uid);                               
+               set_object_text_u(&s_edt_post.edit, p->post);   
+               set_object_text_u(&s_edt_gun_code.edit, p->gun_code);   
+               set_object_text_u(&s_edt_phone.edit, p->phone); 
+               set_object_text_u(&s_edt_sex.edit, p->sex);
+                       
+               sgi_sprintf16(s_edt_age.edit.text, L"%d", p->age);
+               sgi_sprintf16(s_edt_card.edit.text, L"%d", p->idcard);
+               
+               g_data_update_state = REG_UPDATE;
+               
+               s_btn_del.button.state &= ~2;                           
+       }
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       object->ime->hide = 0;  
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_register));   
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void btn_photo_up(struct sgi_button *object)
+{
+       sgi_form_show(&FORM_CLASS(fm_reg_photo));       
+}
+
+static void btn_pwd_up(struct sgi_button *object)
+{
+       sgi_form_show(&FORM_CLASS(fm_reg_pwd));         
+}
+
+static void btn_fpr1_up(struct sgi_button *object)
+{
+       g_passport.fpr_enroll = 1;
+       sgi_form_show(&FORM_CLASS(fm_reg_fpr1_1));
+}
+
+static void btn_fpr2_up(struct sgi_button *object)
+{
+       g_passport.fpr_enroll = 2;
+       sgi_form_show(&FORM_CLASS(fm_reg_fpr1_1));      
+}
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_back.button.up(&s_btn_back.button);       
+       }
+       else if (user == ID_EXIST) {
+               set_object_focus(&s_edt_id);    
+       }
+       else if (user == APPEND_FAIL) {
+               set_object_focus(&s_edt_name);
+       }
+                               
+}
+
+static void btn_save_up(struct sgi_button *object)
+{
+       s32 r;
+       struct person_data *person = get_person_reg_data();
+       
+       /* 校验并保存数据 */
+       sgi_cp16(person->uid, s_edt_id.edit.text);
+       sgi_cp16(person->name, s_edt_name.edit.text);
+       sgi_cp16(person->dept, s_edt_dept.edit.text);
+       sgi_cp16(person->post, s_edt_post.edit.text);
+       sgi_cp16(person->gun, s_edt_gun.edit.text);
+       sgi_cp16(person->gun_code, s_edt_gun_code.edit.text);
+       sgi_cp16(person->phone, s_edt_phone.edit.text);
+       sgi_cp16(person->sex, s_edt_sex.edit.text);     
+       person->age = sgi_utol(s_edt_age.edit.text, 10);
+       person->lock_code = sgi_utol(s_edt_lock_code.edit.text, 10);
+       person->idcard = sgi_utol(s_edt_card.edit.text, 10);
+       
+       if (g_data_update_state == REG_UPDATE) {
+               r = update_person((struct person_data_mem *)person);
+       }
+       else {
+               r = register_person((struct person_data_mem *)person);  
+       }
+       
+       if (r == 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户资料更新成功!", 
+                       SUCCESS, callback);
+                       
+               /* log */
+               record_manager_log(g_passport.mname, L"更新人员资料");
+//             struct log_manager manager;
+//             memset(&manager, 0, sizeof(struct log_manager));
+//             manager.id = get_log_no(LOG_MANAGER);
+//             time(&manager.time);
+//             sgi_ncp16(manager.name, g_passport.mname, COUNTOF(manager.name));
+//             sgi_cpw2u(manager.content, L"更新人员资料");
+//             sgi_append_log(DBL(manager), &manager, sizeof(struct log_manager));     
+       }
+       else if (r == ID_EXIST) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户编号已经存在!", 
+                       ID_EXIST, callback);    
+       }
+       else if (r == APPEND_FAIL) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户资料更新失败!", 
+                       ID_EXIST, callback);
+       }       
+}
+
+static void btn_del_up(struct sgi_button *object)
+{
+       if (object->state & 2) { /* disable */
+               return;
+       }
+       
+       struct person_data *person = get_person_reg_data();
+       s32 r = delete_person((struct person_data_mem *)person);
+       if (r == 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户资料删除成功!", 
+                       SUCCESS, callback);
+                       
+               /* log */
+               struct log_manager manager;
+               memset(&manager, 0, sizeof(struct log_manager));
+               manager.id = get_log_no(LOG_MANAGER);
+               time(&manager.time);
+               sgi_ncp16(manager.name, g_passport.mname, COUNTOF(manager.name));
+               sgi_cpw2u(manager.content, L"删除人员资料");
+               sgi_append_log(DBL(manager), &manager, sizeof(struct log_manager));     
+       }
+       else {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户资料删除失败!", 
+                       DEL_FAIL, callback);
+       }       
+}
+
+static void chk_ime_up(struct sgi_check *object)
+{
+       if (object->parent->ime) {
+               object->parent->ime->hide = object->value;
+               object->parent->redraw = 1;
+               printf("check value: %d\n", object->value);     
+       }       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_name, FORM_CLASS(MODULE_NAME), 212, 101, 122, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_name.edit.word_max = 15;
+       
+       /*  */
+       EDIT_CREATE(s_edt_dept, FORM_CLASS(MODULE_NAME), 212, 126, 122, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       s_edt_dept.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_gun, FORM_CLASS(MODULE_NAME), 246, 152, 142, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_gun.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_lock_code, FORM_CLASS(MODULE_NAME), 246, 178, 142, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_lock_code.edit.mask = MSK_DIGIT;
+       s_edt_lock_code.edit.word_max = 3;
+               
+       /*  */
+       EDIT_CREATE(s_edt_card, FORM_CLASS(MODULE_NAME), 246, 204, 142, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_card.edit.mask = MSK_DIGIT;
+       s_edt_card.edit.word_max = 10;
+               
+       /*  */
+       EDIT_CREATE(s_edt_id, FORM_CLASS(MODULE_NAME), 411, 101, 122, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_id.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_post, FORM_CLASS(MODULE_NAME), 411, 126, 122, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_post.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_gun_code, FORM_CLASS(MODULE_NAME), 493, 152, 142, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_gun_code.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_phone, FORM_CLASS(MODULE_NAME), 493, 178, 142, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_phone.edit.mask = MSK_DIGIT;
+       s_edt_phone.edit.word_max = 15;
+               
+       /*  */
+       EDIT_CREATE(s_edt_sex, FORM_CLASS(MODULE_NAME), 599, 101, 38, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 1);
+       s_edt_sex.edit.align = DT_CENTER;
+       s_edt_sex.edit.word_max = 1;
+               
+       /*  */
+       EDIT_CREATE(s_edt_age, FORM_CLASS(MODULE_NAME), 599, 126, 38, 18, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 2);
+       s_edt_age.edit.align = DT_CENTER;
+       s_edt_age.edit.mask = MSK_DIGIT;
+       s_edt_age.edit.word_max = 3;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_photo, FORM_CLASS(MODULE_NAME), 290, 252, 80, 38, 1,
+               "btn-enter-u.png", "btn-enter-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_photo.button.up = btn_photo_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 501, 252, 80, 38, 1,
+               "btn-enter-u.png", "btn-enter-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_fpr1, FORM_CLASS(MODULE_NAME), 290, 297, 80, 38, 1,
+               "btn-enter-u.png", "btn-enter-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr1.button.up = btn_fpr1_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_fpr2, FORM_CLASS(MODULE_NAME), 501, 297, 80, 38, 1,
+               "btn-enter-u.png", "btn-enter-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr2.button.up = btn_fpr2_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_save, FORM_CLASS(MODULE_NAME), 409, 378, 110, 45, 1,
+               "btn-save-u.png", "btn-save-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_save.button.up = btn_save_up;
+       
+       BUTTON_CREATE(s_btn_del, FORM_CLASS(MODULE_NAME), 272, 378, 110, 45, 1,
+               "btn-del-u.png", "btn-del-d.png", "btn-del-e.png", NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_del.button.up = btn_del_up;
+                       
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* */
+       CHECK_CREATE(s_chk_ime, FORM_CLASS(MODULE_NAME), 673, 138, 92, 38, 1,
+               "chk-ime-u.png", "chk-ime-d.png", IMG_OPTIMIZE | IMG_ALPHA);
+       s_chk_ime.check.up = chk_ime_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_photo.cpp b/src/fm_reg_photo.cpp
new file mode 100644 (file)
index 0000000..dcc2b32
--- /dev/null
@@ -0,0 +1,158 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_photo
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_photo;           /*  */
+static union sgi_object s_btn_save;            /*  */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {251, 47, 298, 256, {"photo-reg.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{      
+       s_timer = 240;  
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_reg_person));      
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_photo_up(struct sgi_button *object)
+{
+       
+}
+
+static void btn_save_up(struct sgi_button *object)
+{
+       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_photo, FORM_CLASS(MODULE_NAME), 282, 313, 108, 47, 1,
+               "btn-photo-u.png", "btn-photo-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_photo.button.up = btn_photo_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_save, FORM_CLASS(MODULE_NAME), 407, 313, 180, 47, 1,
+               "btn-save-u.png", "btn-save-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_save.button.up = btn_save_up;             
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_pwd.cpp b/src/fm_reg_pwd.cpp
new file mode 100644 (file)
index 0000000..828aed5
--- /dev/null
@@ -0,0 +1,191 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_pwd
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_pwd;             /*  */
+static union sgi_object s_edt_confirm_pwd;     /*  */
+static union sgi_object s_btn_confirm;         /*  */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {216, 92, 367, 68, {"pwd-reg.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       s_timer = 240;  
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_reg_person));      
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_back.button.up(&s_btn_back.button);       
+       }
+       else if (user == PWD_NOT_MATCH) {
+               set_object_focus(&s_edt_confirm_pwd);   
+       }
+       else if (user == PWD_SHORTEST) {
+               set_object_focus(&s_edt_pwd);   
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *object)
+{
+       s32 r;
+       struct person_data *person = get_person_reg_data();
+       
+       /* 检查两次所输入新密码是否一致 */
+       if (sgi_ncmp16(s_edt_pwd.edit.text, s_edt_confirm_pwd.edit.text,
+               COUNTOF(s_edt_pwd.edit.text)) != 0) {
+               printf("confirm pwd fail.\n");
+               msgbox(&FORM_CLASS(MODULE_NAME), L"两次输入密码不一致!", 
+                       PWD_NOT_MATCH, callback);
+               return; 
+       }
+       
+       /* 检查密码长度是否符合要求 */
+       if ((r = sgi_len16(s_edt_pwd.edit.text)) < MIN_PWD_LEN) {
+               printf("pwd is shortest.\n");
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码长度应大于6个字符!", 
+                       PWD_SHORTEST, callback);
+               return; 
+       }
+       printf("pwd len: %d\n", r);
+       
+       /* 保存密码并提示 */
+       sgi_cp16(person->pwd, s_edt_pwd.edit.text);
+       msgbox(&FORM_CLASS(MODULE_NAME), L"密码已保存,请牢记您的密码!",
+               SUCCESS, callback);     
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_pwd, FORM_CLASS(MODULE_NAME), 390, 98, 189, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /*  */
+       EDIT_CREATE(s_edt_confirm_pwd, FORM_CLASS(MODULE_NAME), 390, 134, 189, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /*  */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 341, 178, 107, 44, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_reg_unit.cpp b/src/fm_reg_unit.cpp
new file mode 100644 (file)
index 0000000..4753a22
--- /dev/null
@@ -0,0 +1,237 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_reg_unit
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_name;            /*  */
+static union sgi_object s_edt_addr;            /*  */
+static union sgi_object s_edt_dept;            /*  */
+static union sgi_object s_edt_parent;          /*  */
+static union sgi_object s_btn_save;            /*  */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {127, 45, 547, 179, {"unit-reg.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void load_data(void)
+{
+       struct unit_data *unit;
+       size_t size;
+       
+       /* */
+       unit = (struct unit_data *)open_r(DBD(unit), &size);
+       if (!unit || size != sizeof(struct unit_data)) {
+               set_object_text_u(&s_edt_name.edit, NULL);
+               set_object_text_u(&s_edt_addr.edit, NULL);
+               set_object_text_u(&s_edt_dept.edit, NULL);
+               set_object_text_u(&s_edt_parent.edit, NULL);
+       }
+       else {
+               set_object_text_u(&s_edt_name.edit, unit->name);
+               set_object_text_u(&s_edt_addr.edit, unit->addr);
+               set_object_text_u(&s_edt_dept.edit, unit->dept);
+               set_object_text_u(&s_edt_parent.edit, unit->parent);
+       }
+       
+       if (unit) {
+               close_r(unit, size);    
+       }               
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /*  */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* */
+       load_data();
+       
+       /*  */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_register));   
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_back.button.up(&s_btn_back.button);       
+       }
+       else if (user == REGISTER_FAIL) {
+               set_object_focus(&s_edt_name);  
+       }                       
+}
+
+static void btn_save_up(struct sgi_button *object)
+{
+       s32 r;
+       struct unit_data unit;
+       
+       /* */
+       memset(&unit, 0, sizeof(struct unit_data));
+       sgi_cp16(unit.name, s_edt_name.edit.text);
+       sgi_cp16(unit.addr, s_edt_addr.edit.text);
+       sgi_cp16(unit.dept, s_edt_dept.edit.text);
+       sgi_cp16(unit.parent, s_edt_parent.edit.text);
+               
+       r = register_unit((struct unit_data *)&unit);
+       if (r == SUCCESS) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"单位资料更新成功!", 
+                       SUCCESS, callback);
+                       
+               /* log */
+               record_manager_log(g_passport.mname, L"更新单位资料");
+//             struct log_manager manager;
+//             memset(&manager, 0, sizeof(struct log_manager));
+//             manager.id = get_log_no(LOG_MANAGER);
+//             time(&manager.time);
+//             sgi_ncp16(manager.name, g_passport.mname, COUNTOF(manager.name));
+//             sgi_cpw2u(manager.content, L"更新单位资料");
+//             sgi_append_log(DBL(manager), &manager, sizeof(struct log_manager));
+       }
+       else {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"单位资料更新失败!", 
+                       REGISTER_FAIL, callback);       
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_name, FORM_CLASS(MODULE_NAME), 276, 90, 340, 23, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /*  */
+       EDIT_CREATE(s_edt_addr, FORM_CLASS(MODULE_NAME), 276, 121, 340, 23, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+               
+       /*  */
+       EDIT_CREATE(s_edt_dept, FORM_CLASS(MODULE_NAME), 276, 152, 340, 23, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_parent, FORM_CLASS(MODULE_NAME), 276, 183, 340, 23, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       
+       /*  */
+       BUTTON_CREATE(s_btn_save, FORM_CLASS(MODULE_NAME), 679, 183, 84, 36, 1,
+               "btn-save-s-u.png", "btn-save-s-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_save.button.up = btn_save_up;             
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_return_card_manager.cpp b/src/fm_return_card_manager.cpp
new file mode 100644 (file)
index 0000000..03bdca9
--- /dev/null
@@ -0,0 +1,188 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_return_card_manager
+
+FORM_MODULE(MODULE_NAME);                      /* 还枪模块,管理员刷卡验证 */              
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_fpr;             /* 指纹按钮 */
+static union sgi_object s_btn_card;            /* 刷卡按钮 */
+static union sgi_object s_btn_pwd;             /* 密码按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_card_start = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {333, 88, 273, 234, {"card.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {71, 145, 209, 127, {"tip1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_timer = 60;
+       s_card_start = 0;
+       card_start();   
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static void btn_fpr_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_return_fpr_user)); 
+}
+
+static void btn_card_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_return_pwd_user)); 
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       s32 card;
+       
+       do {
+               r = card_state();
+               if (r == -1) {
+                       card_start();   
+               }
+               else if (r == 1) {
+                       card = get_card_id();
+                       r = search_mid(&g_passport, SR_CARD, card);
+                       if (r == 0) {
+                               g_passport.visit &= MGR_CARD_MASK;
+                               g_passport.visit |= MGR_CARD_VALID; 
+                               sgi_form_show(&FORM_CLASS(fm_return_photo_user));
+                       }
+                       else {
+                               msgbox(&FORM_CLASS(MODULE_NAME), L"卡号无对应的用户信息!", 
+                                       0, NULL);
+                               card_start();   
+                       }       
+               }
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-1.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 600, 50, 200, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 指纹按钮 */
+       BUTTON_CREATE(s_btn_fpr, FORM_CLASS(MODULE_NAME), 201, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-fpr.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr.button.up = btn_fpr_up;
+       
+       /* 刷卡按钮 */
+       BUTTON_CREATE(s_btn_card, FORM_CLASS(MODULE_NAME), 340, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-card.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_card.button.state |= 2;
+       s_btn_card.button.up = btn_card_up;
+               
+       /* 密码验证按钮 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 480, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-pwd-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+                       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_return_card_user.cpp b/src/fm_return_card_user.cpp
new file mode 100644 (file)
index 0000000..c0f45f3
--- /dev/null
@@ -0,0 +1,191 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_return_card_user
+
+FORM_MODULE(MODULE_NAME);                      /* 还枪模块,警员刷卡验证 */         
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_fpr;             /* 指纹按钮 */
+static union sgi_object s_btn_card;            /* 刷卡按钮 */
+static union sgi_object s_btn_pwd;             /* 密码按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_card_start = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {288, 18, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {333, 88, 273, 234, {"card.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {71, 145, 209, 127, {"tip1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_timer = 60;
+       s_card_start = 0;
+       card_start();   
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static void btn_fpr_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_return_fpr_user)); 
+}
+
+static void btn_card_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_return_pwd_user)); 
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       s32 card;
+       
+       do {
+               r = card_state();
+               if (r == -1) {
+                       card_start();   
+               }
+               else if (r == 1) {
+                       card = get_card_id();
+                       r = search_uid(&g_passport, SR_CARD, card);
+                       if (r == 0) {
+                               g_passport.visit |= VALID_PASSPORT;
+                               g_passport.visit &= USR_CARD_MASK;
+                               g_passport.visit |= USR_CARD_VALID; 
+                               sgi_form_show(&FORM_CLASS(fm_return_fpr_manager));
+                       }
+                       else {
+                               msgbox(&FORM_CLASS(MODULE_NAME), L"卡号无对应的用户信息!", 
+                                       0, NULL);
+                               card_start();   
+                       }               
+               }
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-1.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 24, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 70, 150, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 指纹按钮 */
+       BUTTON_CREATE(s_btn_fpr, FORM_CLASS(MODULE_NAME), 201, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-fpr.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr.button.up = btn_fpr_up;
+       
+       /* 刷卡按钮 */
+       BUTTON_CREATE(s_btn_card, FORM_CLASS(MODULE_NAME), 340, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-card.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_card.button.state |= 2;
+       s_btn_card.button.up = btn_card_up;
+               
+       /* 密码验证按钮 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 480, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-pwd-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+                       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_return_fpr_manager.cpp b/src/fm_return_fpr_manager.cpp
new file mode 100644 (file)
index 0000000..3df725d
--- /dev/null
@@ -0,0 +1,258 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_return_fpr_manager
+
+FORM_MODULE(MODULE_NAME);                      /* 还枪模块,管理员指纹验证 */
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_fpr;             /* 指纹按钮 */
+static union sgi_object s_btn_card;            /* 刷卡按钮 */
+static union sgi_object s_btn_pwd;             /* 密码按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_fpr_start = 0;
+static s32 s_fpr_fail = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[5] = {
+       {288, 18, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {323, 90, 272, 234, {"fpr.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {71, 145, 209, 127, {"tip2.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_lbl_time.label.tag = 60;
+       s_timer = 60;
+       s_fpr_start = 0;
+       s_fpr_fail = 0;
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//     }               
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+               
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static void btn_fpr_up(struct sgi_button *)
+{
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//             s_timer = 60;
+//     }       
+}
+
+static void btn_card_up(struct sgi_button *)
+{
+       /* 取消指纹识别操作 */
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       
+       sgi_form_show(&FORM_CLASS(fm_return_card_manager));             
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       /* 取消指纹识别操作 */
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       
+       sgi_form_show(&FORM_CLASS(fm_return_pwd_manager));      
+}
+
+static void callback(s32 user)
+{
+       if (user == FPR_FAIL) {
+                       
+       }                       
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       u32 state = 0;
+       
+       do {
+               //if (!s_fpr_start) {
+               //      break;          
+               //}
+               
+               if (s_fpr_fail) {
+                       break;
+               }
+               
+               if (!s_fpr_start) {
+                       //if (fpr_check_press_finger(&state) != 0) {
+                       //      break;  
+                       //}
+                       if (fpr_press_detect() != 0) {
+                               break;
+                       }
+                       
+                       play_effect_fpr();
+                       fpr_module_trigger(FPR_IDENTIFY);
+                       s_fpr_start = 1;
+                       printf("start identify.\n");    
+               }
+               
+               if (fpr_get_busy_flag()) {
+                       break;  
+               }       
+               
+               printf("module is not busy.\n");        
+               if (fpr_get_error_flag()) {
+                       s_fpr_fail = 1;
+                       printf("fpr_get_error_flag is true.\n");
+                       msgbox(&FORM_CLASS(MODULE_NAME), L"指纹无效,请重新采集!", 
+                               FPR_FAIL, callback);
+               }
+               else {
+                       r = fpr_get_result();
+                       r = search_mid(&g_passport, SR_FPR, r);
+                       printf("fpr result: %d\n", r);
+                       if (r == 0) {
+                               g_passport.visit &= MGR_FPR_MASK;
+                               g_passport.visit |= MGR_FPR_VALID; 
+                               sgi_form_show(&FORM_CLASS(fm_return_photo_user));
+                       }
+                       else {
+                               s_fpr_fail = 1;
+                               msgbox(&FORM_CLASS(MODULE_NAME), L"指纹无对应的用户信息!", 
+                                       FPR_FAIL, callback);    
+                       }       
+                                               
+               }
+               s_fpr_start = 0;
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-1.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 24, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 70, 150, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 指纹按钮 */
+       BUTTON_CREATE(s_btn_fpr, FORM_CLASS(MODULE_NAME), 201, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-fpr.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr.button.state |= 2;
+       s_btn_fpr.button.up = btn_fpr_up;
+       
+       /* 刷卡按钮 */
+       BUTTON_CREATE(s_btn_card, FORM_CLASS(MODULE_NAME), 340, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-card.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_card.button.up = btn_card_up;
+               
+       /* 密码验证按钮 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 480, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-pwd-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_return_fpr_user.cpp b/src/fm_return_fpr_user.cpp
new file mode 100644 (file)
index 0000000..ba2006f
--- /dev/null
@@ -0,0 +1,263 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_return_fpr_user
+
+FORM_MODULE(MODULE_NAME);                      /* 还枪模块,警员指纹验证 */ 
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_fpr;             /* 指纹按钮 */
+static union sgi_object s_btn_card;            /* 刷卡按钮 */
+static union sgi_object s_btn_pwd;             /* 密码按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_fpr_start = 0;
+static s32 s_fpr_fail = 0;
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[5] = {
+       {288, 18, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {323, 90, 272, 234, {"fpr.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {71, 145, 209, 127, {"tip0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_lbl_time.label.tag = 60;
+       s_timer = 60;
+       s_fpr_start = 0;
+       s_fpr_fail = 0;
+       
+//     if (fpr_open() != 0) {
+//             printf("fpr open fail.\n");     
+//     }
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//     }               
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static void btn_fpr_up(struct sgi_button *)
+{
+//     if (!s_fpr_start) {
+//             fpr_module_trigger(FPR_IDENTIFY);
+//             s_fpr_start = 1;
+//             s_timer = 60;
+//     }       
+}
+
+static void btn_card_up(struct sgi_button *)
+{
+       /* 取消指纹识别操作 */
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       
+       sgi_form_show(&FORM_CLASS(fm_return_card_user));                
+}
+
+static void btn_pwd_up(struct sgi_button *)
+{
+       /* 取消指纹识别操作 */
+       if (s_fpr_start && fpr_get_busy_flag()) {
+               fpr_set_cancel_flag();
+       }
+       
+       sgi_form_show(&FORM_CLASS(fm_return_pwd_user)); 
+}
+
+static void callback(s32 user)
+{
+       if (user == FPR_FAIL) {
+               s_fpr_fail = 0;         
+       }                       
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       s32 r;
+       u32 state = 0;
+       
+       do {
+               //if (!s_fpr_start) {
+               //      break;          
+               //}
+               
+               if (s_fpr_fail) {
+                       break;
+               }
+               
+               if (!s_fpr_start) {
+                       //if (fpr_check_press_finger(&state) != 0) {
+                       //      break;  
+                       //}
+                       if (fpr_press_detect() != 0) {
+                               break;
+                       }
+                       
+                       play_effect_fpr();
+                       fpr_module_trigger(FPR_IDENTIFY);
+                       s_fpr_start = 1;
+                       printf("start identify.\n");    
+               }
+               
+               if (fpr_get_busy_flag()) {
+                       break;  
+               }       
+               
+               printf("module is not busy.\n");        
+               if (fpr_get_error_flag()) {
+                       s_fpr_fail = 1;
+                       printf("fpr_get_error_flag is true.\n");
+                       msgbox(&FORM_CLASS(MODULE_NAME), L"指纹无效,请重新采集!", 
+                               FPR_FAIL, callback);
+               }
+               else {
+                       r = fpr_get_result();
+                       printf("fpr result: %d\n", r);
+                       r = search_uid(&g_passport, SR_FPR, r);
+                       if (r == 0) {
+                               g_passport.visit |= VALID_PASSPORT;
+                               g_passport.visit &= USR_FPR_MASK;
+                               g_passport.visit |= USR_FPR_VALID; 
+                               time(&g_passport.return_time);
+                               sgi_form_show(&FORM_CLASS(fm_return_fpr_manager));
+                       }
+                       else {
+                               s_fpr_fail = 1;
+                               msgbox(&FORM_CLASS(MODULE_NAME), L"指纹无对应的用户信息!", 
+                                       FPR_FAIL, callback);    
+                       }                       
+               }
+               s_fpr_start = 0;
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-1.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 24, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 70, 150, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 指纹按钮 */
+       BUTTON_CREATE(s_btn_fpr, FORM_CLASS(MODULE_NAME), 201, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-fpr.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_fpr.button.state |= 2;
+       s_btn_fpr.button.up = btn_fpr_up;
+       
+       /* 刷卡按钮 */
+       BUTTON_CREATE(s_btn_card, FORM_CLASS(MODULE_NAME), 340, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-card.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_card.button.up = btn_card_up;
+               
+       /* 密码验证按钮 */
+       BUTTON_CREATE(s_btn_pwd, FORM_CLASS(MODULE_NAME), 480, 336, 134, 105, 1,
+               "btn-l-u.png", "btn-l-d.png", "btn-l-t.png", "btn-pwd-1.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_pwd.button.up = btn_pwd_up;
+               
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_return_photo_user.cpp b/src/fm_return_photo_user.cpp
new file mode 100644 (file)
index 0000000..8f8ef38
--- /dev/null
@@ -0,0 +1,192 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_return_photo_user
+
+FORM_MODULE(MODULE_NAME);                      /* 还枪模块,警员照片比对 */ 
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_lbl_uid;             /* 编号标签 */
+static union sgi_object s_lbl_name;            /* 姓名标签 */
+static union sgi_object s_lbl_dept;            /* 部门标签 */
+static union sgi_object s_lbl_timing;          /* 用时标签 */
+static union sgi_object s_pho_sample;          /* 照片样本 */
+static union sgi_object s_pho_real;            /* 实时照片 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {112, 64, 574, 302, {"photo-3.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       s_timer = 3;
+       
+       /* 获取照片样本 */
+       s_pho_sample.photo.surface = load_photo(&g_passport, PHO_SAMPLE);
+       if (s_pho_sample.photo.surface) {
+               s_pho_sample.photo.redraw = 1;  
+       }
+       
+       /* 获取实时照片 */
+       s_pho_real.photo.surface = load_photo(&g_passport, PHO_REAL);
+       if (s_pho_real.photo.surface) {
+               s_pho_real.photo.redraw = 1;    
+       }
+       printf("load photo end.\n");
+       
+       /* 为人员信息框赋值 */
+       set_object_text_u(&s_lbl_uid.label, g_passport.uid);
+       set_object_text_u(&s_lbl_name.label, g_passport.name);
+       set_object_text_u(&s_lbl_dept.label, g_passport.dept);
+       //set_object_text_u(&s_lbl_dept.label, g_passport.dept);        
+}
+
+static void form_exit(struct sgi_form *)
+{
+       printf("unload photo.\n");
+       unload_photo(&s_pho_sample.photo);
+       unload_photo(&s_pho_real.photo);        
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+                       sgi_form_show(&FORM_CLASS(fm_return_unlock));
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_return_unlock)); 
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       do {
+
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号 */
+       LABEL_CREATE(s_lbl_uid, FORM_CLASS(MODULE_NAME), 546, 92, 120, 25, 1,
+                "jht.ttf", 20, text_cl);
+                
+       /* 姓名 */
+       LABEL_CREATE(s_lbl_name, FORM_CLASS(MODULE_NAME), 546, 134, 120, 25, 1,
+                "jht.ttf", 20, text_cl);
+                
+       /* 部门 */
+       LABEL_CREATE(s_lbl_dept, FORM_CLASS(MODULE_NAME), 546, 176, 120, 25, 1,
+                "jht.ttf", 20, text_cl);
+                
+       /* 用时 */
+       LABEL_CREATE(s_lbl_timing, FORM_CLASS(MODULE_NAME), 588, 220, 35, 40, 1,
+                "jht.ttf", 20, text_cl);
+       s_lbl_timing.label.align = DT_CENTER;
+       //set_object_text_w(&s_lbl_timing.label, L"24");
+       
+       /* 照片样本 */
+       PHOTO_CREATE(s_pho_sample, FORM_CLASS(MODULE_NAME), 135, 87, 158, 178, 1);
+       
+       /* 实时照片 */
+       PHOTO_CREATE(s_pho_real, FORM_CLASS(MODULE_NAME), 307, 87, 158, 178, 1);
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_return_pwd_manager.cpp b/src/fm_return_pwd_manager.cpp
new file mode 100644 (file)
index 0000000..e36ceb6
--- /dev/null
@@ -0,0 +1,183 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_return_pwd_manager
+
+FORM_MODULE(MODULE_NAME);                      /* 还枪模块,管理员密码验证 */              
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_uid;             /* 用户编号 */
+static union sgi_object s_edt_pwd;             /* 密码输入框 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_pwd_retries = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {165, 59, 377, 95, {"pwd-2.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       set_object_text_u(&s_edt_uid.edit, NULL);
+       set_object_text_u(&s_edt_pwd.edit, NULL);
+       set_object_focus(&s_edt_uid);
+       
+       s_timer = 60;   
+       s_pwd_retries = 0;
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == ID_INVALID) {
+               set_object_focus(&s_edt_uid);   
+       }
+       else if (user == PWD_INVALID) {
+               set_object_focus(&s_edt_pwd);   
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       s32 r = verify_manager_pwd(&g_passport, s_edt_uid.edit.text, 
+               s_edt_pwd.edit.text);
+       
+       if (r >= 0) {   
+               g_passport.visit &= MGR_PWD_MASK;
+               g_passport.visit |= MGR_PWD_VALID;
+               sgi_form_show(&FORM_CLASS(fm_return_photo_user));
+       }
+       else if (r == ID_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户信息不存在!", 
+                       ID_INVALID, callback);          
+       }
+       else if (r == PWD_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码无效!", 
+                       PWD_INVALID, callback); 
+               if (++s_pwd_retries >= PWD_MAX_RETRIES) {
+                       pwd_alarm();    
+               }       
+       }               
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号输入框 */
+       EDIT_CREATE(s_edt_uid, FORM_CLASS(MODULE_NAME), 346, 86, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /* 密码输入框 */
+       EDIT_CREATE(s_edt_pwd, FORM_CLASS(MODULE_NAME), 346, 126, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_pwd.edit.pwdchar = 1; 
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 556, 106, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_return_pwd_user.cpp b/src/fm_return_pwd_user.cpp
new file mode 100644 (file)
index 0000000..f6c81af
--- /dev/null
@@ -0,0 +1,185 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_return_pwd_user
+
+FORM_MODULE(MODULE_NAME);                      /* 还枪模块,警员密码验证 */         
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_uid;             /* 用户编号 */
+static union sgi_object s_edt_pwd;             /* 密码输入框 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_pwd_retries = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {188, 58, 353, 106, {"pwd-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       set_object_text_u(&s_edt_uid.edit, NULL);
+       set_object_text_u(&s_edt_pwd.edit, NULL);
+       set_object_focus(&s_edt_uid);
+       
+       s_timer = 60;   
+       s_pwd_retries = 0;
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == ID_INVALID) {
+               set_object_focus(&s_edt_uid);   
+       }
+       else if (user == PWD_INVALID) {
+               set_object_focus(&s_edt_pwd);   
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       s32 r = verify_user_pwd(&g_passport, s_edt_uid.edit.text, 
+               s_edt_pwd.edit.text);
+       
+       if (r >= 0) {
+               g_passport.visit |= VALID_PASSPORT;
+               g_passport.visit &= USR_PWD_MASK;
+               g_passport.visit |= USR_PWD_VALID;
+               sgi_form_show(&FORM_CLASS(fm_return_fpr_manager));
+       }
+       else if (r == ID_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户信息不存在!", 
+                       ID_INVALID, callback);          
+       }
+       else if (r == PWD_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码无效!", 
+                       PWD_INVALID, callback); 
+               
+               if (++s_pwd_retries >= PWD_MAX_RETRIES) {
+                       pwd_alarm();    
+               }       
+       }       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号输入框 */
+       EDIT_CREATE(s_edt_uid, FORM_CLASS(MODULE_NAME), 346, 83, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /* 密码输入框 */
+       EDIT_CREATE(s_edt_pwd, FORM_CLASS(MODULE_NAME), 346, 123, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       s_edt_pwd.edit.pwdchar = 1;
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 556, 106, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_return_unlock.cpp b/src/fm_return_unlock.cpp
new file mode 100644 (file)
index 0000000..4685431
--- /dev/null
@@ -0,0 +1,280 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_return_unlock
+
+FORM_MODULE(MODULE_NAME);                      /* 还枪模块,枪柜开锁 */       
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_box;                 /* 枪柜 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_cell s_box_cell[BOX_NUMS] = {
+       CELL(15,11,61,40),CELL(79,11,61,40),CELL(143,11,61,40),
+       CELL(205,11,61,40),CELL(268,11,61,40),CELL(332,11,61,40),
+       CELL(395,11,61,40),CELL(457,11,61,40),CELL(520,11,61,40),
+       CELL(584,11,61,40),
+       
+       CELL(15,54,61,40),CELL(79,54,61,40),CELL(143,54,61,40),
+       CELL(205,54,61,40),CELL(268,54,61,40),CELL(332,54,61,40),
+       CELL(395,54,61,40),CELL(457,54,61,40),CELL(520,54,61,40),
+       CELL(584,54,61,40),
+       
+       CELL(15,96,61,40),CELL(79,96,61,40),CELL(143,96,61,40),
+       CELL(205,96,61,40),CELL(268,96,61,40),CELL(332,96,61,40),
+       CELL(395,96,61,40),CELL(457,96,61,40),CELL(520,96,61,40),
+       CELL(584,96,61,40),
+       
+       CELL(15,138,102,77),CELL(121,138,102,77),CELL(227,138,102,77),
+       CELL(331,138,102,77),CELL(438,138,102,77),CELL(541,138,102,77),
+       
+       CELL(15,218,102,77),CELL(121,218,102,77),CELL(227,218,102,77),
+       CELL(331,218,102,77),CELL(438,218,102,77),CELL(541,218,102,77), 
+};
+
+static struct sgi_widget s_widget[] = {
+       {69, 55, 658, 308, {"photo-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       u32 i;
+       struct box_info *info = get_box_info();
+
+       /* 暂停锁监控 */
+       pause_lock_monitor();
+       
+       /* */
+       for (i = 0; i < BOX_NUMS; ++i) {
+               s_box.box.cell[i].state = 0;
+               if ((info[i].state & 3) == 1) {
+                       s_box.box.cell[i].tag = 3;
+               }
+               else if ((info[i].state & 3) == 3) {
+                       s_box.box.cell[i].tag = 1;
+               }
+
+               printf("info[%d]: %d\n", i, info[i].state);
+       }
+       
+       /* only show current user's borrow */
+       u8 *user = get_return_info(g_passport.uid);
+       for (i = 0; i < BOX_NUMS; ++i) {
+               printf("user[%d]: %d\n", i, user[i]);
+               if (!user[i] && s_box.box.cell[i].tag == 1) {                   
+                       s_box.box.cell[i].tag = 3;              
+               }               
+       }       
+       
+       s_timer = 600;                  
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_main.button.up(&s_btn_main.button);
+       }               
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       int i;
+       u32 cells[4] = {0};
+       struct box_info *info = get_box_info();
+       
+       int has = 0;
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if (s_box.box.cell[i].state & 1) {
+                       has = 1;
+                       break;
+               }       
+       }
+       
+       if (!has) {
+               return; 
+       }
+       
+       /* 查询借枪信息 */
+       if (!search_borrow_info(&g_passport)) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"无此用户的借枪信息!", 0, NULL);
+               return; 
+       }
+       
+       /* 登记还枪信息 */
+       for (i = 0; i < BOX_NUMS; ++i) {
+               cells[i / 32] |= (s_box.box.cell[i].state & 1) << (i % 32);
+       }
+       if (enroll_return(&g_passport, cells) != 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"登记还枪信息失败!", 0, NULL);
+               return;
+       }
+       
+       /* 记录还枪日志 */
+       //struct log_borrow back;
+       int nums = 0;
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if (s_box.box.cell[i].state & 1) {
+                       record_return_log(&g_passport, &info[i]);
+                       nums++;
+//                     memset(&back, 0, sizeof(struct log_borrow));
+//                     back.id = get_log_no(LOG_RETURN);
+//                     time(&back.time);
+//                     sgi_ncp16(back.name, g_passport.name, 
+//                             COUNTOF(back.name));
+//                     sgi_ncp16(back.gun_type, info[i].gun_model,
+//                             COUNTOF(back.gun_type));
+//                     sgi_ncp16(back.gun_code, info[i].gun_code,
+//                             COUNTOF(back.gun_code));
+//                     sgi_append_log(DBL(back), &back, 
+//                             sizeof(struct log_borrow));
+               }
+       }
+       
+       /* 记录上报数据 */
+       recorcd_return_report(&g_passport, 0, nums);
+       
+       /* 打开枪柜门 */
+       authorize_open_door();
+       
+       /* 打开对应枪锁 */
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if (s_box.box.cell[i].state & 1) {                      
+                       if (i2c_comm_unlock(s_box.box.cell_addr[i]) == 0) {
+                               set_lock_list(s_box.box.cell_addr[i]);
+                               SDL_Delay(2000);        
+                       }
+               }       
+       }
+       
+       msgbox(&FORM_CLASS(MODULE_NAME), L"请在规定的时间内归还枪械并关闭柜门!", 
+               0, callback);   
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       do {
+
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 32, 150, 22, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 枪柜表格 */
+       BOX_CREATE(s_box, FORM_CLASS(MODULE_NAME), 69, 55, 658, 308, 1,
+               "jht.ttf", 20, color, "box-2.png", "box-4.png", "box-0.png", 
+               "box-3.png", IMG_OPTIMIZE | IMG_ALPHA, s_box_cell);
+       s_box.box.cell_addr = g_box_addr;
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 346, 383, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_safecheck.cpp b/src/fm_safecheck.cpp
new file mode 100644 (file)
index 0000000..273725b
--- /dev/null
@@ -0,0 +1,316 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_safecheck
+
+FORM_MODULE(MODULE_NAME);                      /*  */          
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_power;           /*  */
+static union sgi_object s_lbl_door;            /*  */
+static union sgi_object s_lbl_lock;            /*  */
+static union sgi_object s_lbl_fpr;             /*  */
+static union sgi_object s_lbl_net;             /*  */
+
+static struct sgi_widget s_widget[3] = {
+       {134, 22, 332, 262, {"safecheck.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 s_check_step = 0;
+
+static void form_enter(struct sgi_form *)
+{
+       pause_all_monitor();
+       
+       set_object_text_u(&s_lbl_power.label, NULL);
+       set_object_text_u(&s_lbl_door.label, NULL);
+       set_object_text_u(&s_lbl_lock.label, NULL);
+       set_object_text_u(&s_lbl_fpr.label, NULL);
+       set_object_text_u(&s_lbl_net.label, NULL);
+}
+
+static void form_exit(struct sgi_form *)
+{
+       resume_all_monitor();                   
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 power_check(void)
+{
+       static s32 count = 0;
+       static s32 flags = 0;
+       s32 s;
+       
+       s = get_pw_jc();
+       if (s != -1) {
+               flags <<= 1;
+               flags |= (s & 1);       
+       }       
+       count++;
+       
+       if (count >= 3) {
+               if ((flags & 7) == 0) {
+                       set_object_text_w(&s_lbl_power.label, L"备用电源供电");
+                       s_lbl_power.label.redraw = 1;   
+               }
+               else {
+                       set_object_text_w(&s_lbl_power.label, L"市电供电");
+                       s_lbl_power.label.redraw = 1;   
+               }
+               return 1;
+       }
+       
+       return 0;               
+}
+
+static s32 door_check(void)
+{
+       static s32 count = 0;
+       static s32 flags = 0;
+       static s32 qzw1 = 0;
+       static s32 qzw2 = 0;
+       s32 s;
+       
+       s = get_door_fb();
+       if (s != -1) {
+               //flags <<= 1;
+               flags |= (s & 1);       
+       }       
+       
+       s = get_qwz1();
+       if (s != -1) {
+               //qzw1 <<= 1;
+               qzw1 |= (s & 1);
+       }
+       
+       s = get_qwz2();
+       if (s != -1) {
+               //qzw1 <<= 1;
+               qzw2 |= (s & 1);
+       }
+       
+       count++;
+       
+       if (count >= 3) {
+               if ((flags & 1) == 0 || (qzw1 & 1) == 0 || (qzw2 & 1) == 0) {
+                       set_object_text_w(&s_lbl_door.label, L"柜门锁开启");
+                       s_lbl_door.label.redraw = 1;    
+               }
+               else {
+                       set_object_text_w(&s_lbl_door.label, L"柜门锁关闭");
+                       s_lbl_door.label.redraw = 1;    
+               }
+               return 1;
+       }
+       
+       return 0;               
+}
+
+static s32 lock_check(void)
+{
+       s32 i;
+       s32 err = 0;
+       s32 ok = 0;
+       wchar_t buf[64];
+       
+       struct box_info *info = get_box_info();
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if ((info[i].state & 1) == 0) {
+                       continue;
+               }
+               
+               /* */
+               if (i2c_comm_update_state(g_box_addr[i]) != 0) {
+                       err++;  
+               }
+               else {
+                       ok++;
+               }
+               
+               SDL_Delay(200);
+       }
+       
+       swprintf(buf, COUNTOF(buf), L"通讯正常[%d], 通讯失败[%d]", ok, err);
+       
+       set_object_text_w(&s_lbl_lock.label, buf);
+       
+       return 1;               
+}
+
+static s32 fpr_check(void)
+{
+       u32 ver;
+       wchar_t buf[64];
+       
+       if (fpr_get_ver(&ver) != 0) {
+               swprintf(buf, COUNTOF(buf), L"模块自检失败");                             
+       }
+       else {
+               swprintf(buf, COUNTOF(buf), L"模块工作正常,版本: %d", ver);   
+       }       
+       
+       set_object_text_w(&s_lbl_fpr.label, buf);
+       
+       return 1;               
+}
+
+static s32 net_check(void)
+{
+       u32 t = SDL_GetTicks() + 3000;
+       
+       create_heartbeat_packet();
+       
+       do {
+               if (get_net_link_status()) {
+                       break;
+               }
+               SDL_Delay(500);         
+       } while (TIME_BEFORE(SDL_GetTicks(), t));
+       
+       if (get_net_link_status()) {
+               set_object_text_w(&s_lbl_net.label, L"网络已连接");
+       }
+       else {
+               set_object_text_w(&s_lbl_net.label, L"网络未连接");
+       }
+       
+       return 1;               
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       static u32 cycle = 0;
+       
+       /* per 1s check device */
+       if (TIME_AFTER(SDL_GetTicks(), cycle)) {
+       
+               switch (s_check_step) {
+               case 0:
+                       set_object_text_w(&s_lbl_power.label, L"正在检测...");
+                       s_lbl_power.label.redraw = 1;
+                       if (power_check()) {
+                               s_check_step++;
+                       }
+                       break;
+                       
+               case 1:
+                       set_object_text_w(&s_lbl_door.label, L"正在检测...");
+                       s_lbl_door.label.redraw = 1;
+                       if (door_check()) {
+                               s_check_step++;
+                       }
+                       break;
+                       
+               case 2:
+                       set_object_text_w(&s_lbl_lock.label, L"正在检测...");
+                       s_lbl_lock.label.redraw = 1;
+                       if (lock_check()) {
+                               s_check_step++; 
+                       }
+                       break;
+                       
+               case 3:
+                       set_object_text_w(&s_lbl_fpr.label, L"正在检测...");
+                       s_lbl_fpr.label.redraw = 1;
+                       if (fpr_check()) {
+                               s_check_step++; 
+                       }
+                       break;
+                       
+               case 4:
+                       set_object_text_w(&s_lbl_net.label, L"正在检测...");
+                       s_lbl_net.label.redraw = 1;
+                       if (net_check()) {
+                               s_check_step++; 
+                       }
+                       break;
+                       
+               case 5:
+                       SDL_Delay(3000);
+                       s_check_step++;
+                       break;
+                       
+               default:
+                       break;  
+                       
+               }       
+               cycle = SDL_GetTicks() + 1000;  
+       }
+               
+       sgi_form_frame_default(form);
+       
+       if (s_check_step > 5) {
+               sgi_form_show(&FORM_CLASS(fm_main));
+       }
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       LABEL_CREATE(s_lbl_power, FORM_CLASS(MODULE_NAME), 320, 98, 364, 25, 1,
+                "jht.ttf", 24, color);
+                
+       LABEL_CREATE(s_lbl_door, FORM_CLASS(MODULE_NAME), 320, 139, 364, 25, 1,
+                "jht.ttf", 24, color);
+                
+       LABEL_CREATE(s_lbl_lock, FORM_CLASS(MODULE_NAME), 320, 180, 364, 25, 1,
+                "jht.ttf", 24, color);
+                
+       LABEL_CREATE(s_lbl_fpr, FORM_CLASS(MODULE_NAME), 320, 219, 364, 25, 1,
+                "jht.ttf", 24, color);
+                
+       LABEL_CREATE(s_lbl_net, FORM_CLASS(MODULE_NAME), 320, 260, 364, 25, 1,
+                "jht.ttf", 24, color);
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;     
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_stat_box.cpp b/src/fm_stat_box.cpp
new file mode 100644 (file)
index 0000000..0d7b4e0
--- /dev/null
@@ -0,0 +1,191 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_stat_box
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_cap;             /*  */
+static union sgi_object s_edt_manager;         /*  */
+static union sgi_object s_edt_code;            /*  */
+static union sgi_object s_edt_specs;           /*  */
+static union sgi_object s_edt_dept;            /*  */
+static union sgi_object s_rad_gun;             /*  */
+static union sgi_object s_rad_bullet;          /*  */
+static union sgi_object s_btn_edit;            /* 返回按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {127, 100, 547, 179, {"box-info.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       //register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_stat));       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_edit_up(struct sgi_button *object)
+{
+       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_cap, FORM_CLASS(MODULE_NAME), 256, 194, 159, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /*  */
+       EDIT_CREATE(s_edt_manager, FORM_CLASS(MODULE_NAME), 256, 233, 159, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+               
+       /*  */
+       EDIT_CREATE(s_edt_code, FORM_CLASS(MODULE_NAME), 524, 156, 122, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_specs, FORM_CLASS(MODULE_NAME), 524, 194, 122, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_dept, FORM_CLASS(MODULE_NAME), 524, 233, 122, 16, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /* */
+       RADIO_CREATE(s_rad_gun, FORM_CLASS(MODULE_NAME), 250, 153, 33, 23, 1,
+               "rad-sel-u.png", "rad-sel-d.png", IMG_OPTIMIZE | IMG_ALPHA);
+       
+       /* */
+       RADIO_CREATE(s_rad_bullet, FORM_CLASS(MODULE_NAME), 333, 153, 33, 23, 1,
+               "rad-sel-u.png", "rad-sel-d.png", IMG_OPTIMIZE | IMG_ALPHA);
+       
+       /*  */
+       BUTTON_CREATE(s_btn_edit, FORM_CLASS(MODULE_NAME), 367, 290, 80, 38, 1,
+               "btn-edit-u.png", "btn-edit-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_edit.button.up = btn_edit_up;             
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_stat_bullet.cpp b/src/fm_stat_bullet.cpp
new file mode 100644 (file)
index 0000000..d2b90ad
--- /dev/null
@@ -0,0 +1,168 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_stat_bullet
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {74, 43, 654, 333, {"bullet-info.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       //register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_stat));       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 318, 395, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 409, 395, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_stat_gun.cpp b/src/fm_stat_gun.cpp
new file mode 100644 (file)
index 0000000..be0ba4e
--- /dev/null
@@ -0,0 +1,374 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_stat_gun
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_grid;
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_page = 0;
+static u32 s_data_size = 0;
+static s32 s_record_count = 0;
+static struct gun_data *s_grid_data = NULL;
+
+//static struct sgi_widget s_widget[] = {
+//     {74, 43, 654, 333, {"gun-info.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+//     {0, 0, 0, 0, {NULL, 0, NULL}},  
+//};
+static void grid_load_data(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       struct gun_data *p;
+       s32 offset;
+       s32 read_count;
+       
+       /* 页数检查 */
+       offset = s_page * object->row;
+       if (!s_grid_data || offset > s_record_count) {
+               return;
+       }
+       
+       p = s_grid_data + offset;
+       read_count = s_record_count - offset;
+       for (i = 0; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               sgi_ncp16(object->cells[index].string, p->code,
+                                       COUNTOF(p->code));
+                               break;
+                               
+                       case 1: /* column 1 */
+                               sgi_ncp16(object->cells[index].string, p->model,
+                                       COUNTOF(p->model));
+                               break;
+                               
+                       case 2: /* column 2 */
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%d", p->lock_code);
+                               break;
+                               
+                       case 3: /* column 3 */
+                               sgi_ncp16(object->cells[index].string, p->holder,
+                                       COUNTOF(p->holder));
+                               break;
+                               
+                       case 4: /* column 4 */
+                               sgi_ncp16(object->cells[index].string, p->bullet,
+                                       COUNTOF(p->bullet));
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               if (--read_count <= 0) {
+                       break;
+               }
+               p++;                    
+       }
+       
+       /* 剩余行清零 */
+       for (i += 1; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;                    
+                       memset(object->cells[index].string, 0,
+                               sizeof(object->cells[index].string));
+               }
+       }
+}
+
+static void grid_init(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       s32 y0;
+       const s32 row_offset = 62;
+       const s32 row_h = 26;
+       
+       /* */
+       object->col = 6;
+       object->row = 10;
+       
+       /* */
+       object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+               object->col * object->row);
+               
+       if (!object->cells) {
+               return;
+       }
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * row_h + row_offset;
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 40;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 136;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 231;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 3: /* column 3 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 326;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 4: /* column 4 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 423;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 5: /* column 5 */
+                               object->cells[index].type = GRID_BUTTON;
+                               object->cells[index].x = object->x + 519;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }       
+}
+
+static void grid_deinit(struct sgi_grid *object)
+{
+       free(object->cells);
+       object->cells = NULL;   
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /* */
+       s_page = 0;
+       s_data_size = 0;
+       
+       /* 初始表格 */
+       grid_init(&s_grid.grid);
+       
+       /* 加载表格数据 */
+       s_grid_data = (struct gun_data *)open_r(DBD(gun), &s_data_size);
+       s_record_count = s_data_size / sizeof(struct gun_data);
+       grid_load_data(&s_grid.grid);
+       
+       printf("load data: %d\n", s_record_count);
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       grid_deinit(&s_grid.grid);
+       
+       printf("close data: %d\n", s_data_size);
+       
+       /* 关闭数据 */
+       if (s_grid_data) {
+               close_r(s_grid_data, s_data_size);
+       }       
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_stat));       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void edit_button_up(struct sgi_grid *, s32 row)
+{
+       s32 index = s_page * s_grid.grid.row + row;
+       if (index >= s_record_count) {
+               return;
+       }
+       
+       struct gun_data *ps = s_grid_data + index;
+       struct gun_data *pd = get_gun_reg_data();
+       g_data_update_state = REG_MODIFY;
+       memcpy(pd, ps, sizeof(struct gun_data));
+       
+       sgi_form_show(&FORM_CLASS(fm_reg_gun)); 
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       if (s_page > 0) {
+               s_page--;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;         
+       }
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       if (((s_page + 1) * s_grid.grid.row) < s_record_count) {
+               s_page++;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* */
+       GRID_CREATE(s_grid, FORM_CLASS(MODULE_NAME), 74, 43, 654, 333, 1,
+                "jht.ttf", 20, color, "gun-info.png", "grid-edit.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_grid.grid.up = edit_button_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 318, 395, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 409, 395, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_stat_person.cpp b/src/fm_stat_person.cpp
new file mode 100644 (file)
index 0000000..eb1b9cc
--- /dev/null
@@ -0,0 +1,380 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_stat_person
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_grid;
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_page = 0;
+static u32 s_data_size = 0;
+static s32 s_record_count = 0;
+static struct person_data *s_person = NULL;
+
+static void grid_load_data(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       struct person_data *p;
+       s32 offset;
+       s32 read_count;
+       u16 level[5][8] = {
+               {(u16)L'普',(u16)L'通',(u16)L'用',(u16)L'户'},
+               {(u16)L'管',(u16)L'理',(u16)L'员'},
+               {(u16)L'监',(u16)L'督',(u16)L'员',(u16)L'户'},
+               {(u16)L'高',(u16)L'级',(u16)L'监',(u16)L'督',(u16)L'员'},
+               {(u16)L'未',(u16)L'知'},      
+       };
+       
+       /* 页数检查 */
+       offset = s_page * object->row;
+       if (!s_person || offset > s_record_count) {
+               return;
+       }
+       
+       p = s_person + offset;
+       read_count = s_record_count - offset;
+       for (i = 0; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               sgi_ncp16(object->cells[index].string, p->uid,
+                                       COUNTOF(p->uid));
+                               break;
+                               
+                       case 1: /* column 1 */
+                               sgi_ncp16(object->cells[index].string, p->name,
+                                       COUNTOF(p->name));
+                               break;
+                               
+                       case 2: /* column 2 */
+                               sgi_ncp16(object->cells[index].string, p->dept,
+                                       COUNTOF(p->dept));
+                               break;
+                               
+                       case 3: /* column 3 */
+                               sgi_ncp16(object->cells[index].string, p->post,
+                                       COUNTOF(p->post));
+                               break;
+                               
+                       case 4: /* column 4 */
+                               printf("level: %d\n", p->level);
+                               if (p->level < 5) {
+                                       sgi_ncp16(object->cells[index].string, 
+                                       level[p->level], COUNTOF(level[0]));
+                               }
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               if (--read_count <= 0) {
+                       break;
+               }
+               p++;                    
+       }
+       
+       /* 剩余行清零 */
+       for (i += 1; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;                    
+                       memset(object->cells[index].string, 0,
+                               sizeof(object->cells[index].string));
+               }
+       }
+}
+
+static void grid_init(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       s32 y0;
+       const s32 row_offset = 62;
+       const s32 row_h = 26;
+       
+       /* */
+       object->col = 6;
+       object->row = 10;
+       
+       /* */
+       object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+               object->col * object->row);
+               
+       if (!object->cells) {
+               return;
+       }
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * row_h + row_offset;
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 40;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 136;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 231;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 3: /* column 3 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 326;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 4: /* column 4 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 423;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 5: /* column 5 */
+                               object->cells[index].type = GRID_BUTTON;
+                               object->cells[index].x = object->x + 519;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 95;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }       
+}
+
+static void grid_deinit(struct sgi_grid *object)
+{
+       free(object->cells);
+       object->cells = NULL;   
+}
+
+static void form_enter(struct sgi_form *)
+{      
+       /* 初始化所有参数 */
+       s_page = 0;
+       s_data_size = 0;
+       
+       /* 初始表格 */
+       grid_init(&s_grid.grid);
+       
+       /* 加载表格数据 */
+       s_person = (struct person_data *)open_r(DBD(person), &s_data_size);
+       s_record_count = s_data_size / sizeof(struct person_data);
+       grid_load_data(&s_grid.grid);
+       
+       printf("load data: %d\n", s_record_count);      
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       grid_deinit(&s_grid.grid);
+       
+       printf("close data: %d\n", s_data_size);
+       
+       /* 关闭数据 */
+       if (s_person) {
+               close_r(s_person, s_data_size); 
+       }
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_stat));       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void edit_button_up(struct sgi_grid *, s32 row)
+{
+       s32 index = s_page * s_grid.grid.row + row;
+       if (index >= s_record_count) {
+               return;
+       }
+       
+       struct person_data *ps = s_person + index;
+       struct person_data *pd = get_person_reg_data();
+       g_data_update_state = REG_MODIFY;
+       memcpy(pd, ps, sizeof(struct person_data));
+       
+       sgi_form_show(&FORM_CLASS(fm_reg_person));      
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       if (s_page > 0) {
+               s_page--;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;         
+       }
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       if (((s_page + 1) * s_grid.grid.row) < s_record_count) {
+               s_page++;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* */
+       GRID_CREATE(s_grid, FORM_CLASS(MODULE_NAME), 74, 43, 654, 333, 1,
+                "jht.ttf", 20, color, "person-info.png", "grid-edit.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_grid.grid.up = edit_button_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 318, 395, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 409, 395, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_stat_unit.cpp b/src/fm_stat_unit.cpp
new file mode 100644 (file)
index 0000000..be9099c
--- /dev/null
@@ -0,0 +1,176 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_stat_unit
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_name;            /*  */
+static union sgi_object s_edt_addr;            /*  */
+static union sgi_object s_edt_dept;            /*  */
+static union sgi_object s_edt_parent;          /*  */
+static union sgi_object s_btn_edit;            /*  */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {126, 101, 547, 179, {"unit-reg.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       //register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_info_stat));       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_edit_up(struct sgi_button *object)
+{
+       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_name, FORM_CLASS(MODULE_NAME), 279, 147, 340, 19, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /*  */
+       EDIT_CREATE(s_edt_addr, FORM_CLASS(MODULE_NAME), 279, 179, 340, 19, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+               
+       /*  */
+       EDIT_CREATE(s_edt_dept, FORM_CLASS(MODULE_NAME), 279, 209, 340, 19, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+               
+       /*  */
+       EDIT_CREATE(s_edt_parent, FORM_CLASS(MODULE_NAME), 279, 240, 340, 19, 1,
+               "jht.ttf", 18, text_cl, "cursor-1.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       
+       /*  */
+       BUTTON_CREATE(s_btn_edit, FORM_CLASS(MODULE_NAME), 359, 289, 80, 38, 1,
+               "btn-edit-u.png", "btn-edit-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_edit.button.up = btn_edit_up;             
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_system.cpp b/src/fm_system.cpp
new file mode 100644 (file)
index 0000000..8a0ec32
--- /dev/null
@@ -0,0 +1,157 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_system
+
+FORM_MODULE(MODULE_NAME);                      /* 权限管理模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_code;            /* 枪柜编号 */
+static union sgi_object s_btn_db;              /* 数据库设置 */
+static union sgi_object s_btn_box;             /* 枪柜参数设置 */
+static union sgi_object s_btn_sms;             /* 短信功能设置 */
+static union sgi_object s_btn_dt;              /* 系统日期时间设置 */
+static union sgi_object s_btn_remote;          /* 远程控制设置 */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {288, 20, 225, 54, {"title-0.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {211, 454, 380, 16, {"title-1.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_db_up(struct sgi_button *)
+{      
+       sgi_form_show(&FORM_CLASS(fm_download));        
+}
+
+static void btn_box_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_mon_setting));     
+}
+
+static void btn_sms_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_chpwd)); 
+}
+
+static void btn_dt_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_timing));  
+}
+
+static void btn_remote_up(struct sgi_button *)
+{
+       //sgi_form_show(&FORM_CLASS(fm_chpwd)); 
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_menu));    
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 单位编号 */
+       LABEL_CREATE(s_lbl_code, FORM_CLASS(MODULE_NAME), 600, 45, 200, 25, 1,
+                "jht.ttf", 18, color);
+       swprintf(buf, sizeof(buf), L"枪弹柜编号: A%03d", 1);
+       set_object_text_w(&s_lbl_code.label, buf);
+       
+       /* 数据库设置 */
+       BUTTON_CREATE(s_btn_db, FORM_CLASS(MODULE_NAME), 409, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-dbset.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_db.button.up = btn_db_up;
+       
+       /* 枪柜参数设置 */
+       BUTTON_CREATE(s_btn_box, FORM_CLASS(MODULE_NAME), 200, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-boxset.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_box.button.up = btn_box_up;
+       
+       /* 短信功能设置 */
+       BUTTON_CREATE(s_btn_sms, FORM_CLASS(MODULE_NAME), 340, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-smsset.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_sms.button.up = btn_sms_up;
+       
+       /* 系统日期时间设置 */
+       BUTTON_CREATE(s_btn_dt, FORM_CLASS(MODULE_NAME), 480, 245, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-dtset.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_dt.button.up = btn_dt_up;
+       
+       /* 远程控制设置 */
+       BUTTON_CREATE(s_btn_remote, FORM_CLASS(MODULE_NAME), 266, 136, 122, 96, 1,
+               "btn-m-u.png", "btn-m-d.png", "btn-m-t.png", "btn-remote-set.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_remote.button.up = btn_remote_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_timing.cpp b/src/fm_timing.cpp
new file mode 100644 (file)
index 0000000..4c48aef
--- /dev/null
@@ -0,0 +1,327 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_timing
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 时间标签 */
+static union sgi_object s_edt_hour;            /*  */
+static union sgi_object s_edt_minute;          /*  */
+static union sgi_object s_edt_year;            /*  */
+static union sgi_object s_edt_month;           /*  */
+static union sgi_object s_edt_day;             /*  */
+static union sgi_object s_btn_network;         /*  */
+static union sgi_object s_btn_confirm;         /*  */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static struct sgi_widget s_widget[] = {
+       {94, 38, 546, 196, {"timing.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       /* 清空输入框 */
+       set_object_text_u(&s_edt_hour.edit, NULL);
+       set_object_text_u(&s_edt_minute.edit, NULL);
+       set_object_text_u(&s_edt_year.edit, NULL);
+       set_object_text_u(&s_edt_month.edit, NULL);
+       set_object_text_u(&s_edt_day.edit, NULL);
+       set_object_focus(&s_edt_hour);
+       
+       s_timer = 240;  
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       //s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_system));  
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+#define HOUR_INVALID           1
+#define MINUTE_INVALID         2
+#define YEAR_INVALID           3
+#define MONTH_INVALID          4
+#define DAY_INVALID            5
+#define TIME_INVALID           6
+
+static void callback(s32 user)
+{
+       if (user == SUCCESS) {
+               s_btn_back.button.up(&s_btn_back.button);       
+       }
+       else if (user == HOUR_INVALID) {
+               set_object_focus(&s_edt_hour);  
+       }
+       else if (user == MINUTE_INVALID) {
+               set_object_focus(&s_edt_minute);        
+       }
+       else if (user == YEAR_INVALID) {
+               set_object_focus(&s_edt_year);  
+       }
+       else if (user == MONTH_INVALID) {
+               set_object_focus(&s_edt_month); 
+       }
+       else if (user == DAY_INVALID) {
+               set_object_focus(&s_edt_day);   
+       }
+       else if (user == TIME_INVALID) {
+               
+       }                       
+}
+
+static void btn_network_up(struct sgi_button *)
+{
+       u32 t = SDL_GetTicks() + 5000;
+       s32 status;
+       
+       create_time_adjust_packet();
+       do {
+               if ((status = get_time_adjust_status())) {
+                       break;
+               }
+               SDL_Delay(500);         
+       } while (TIME_BEFORE(SDL_GetTicks(), t));
+       
+       if (status) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"校时成功!", 0, NULL);  
+       }
+       else {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"校时失败!", 0, NULL);  
+       }       
+}
+
+static void btn_confirm_up(struct sgi_button *object)
+{
+       s32 r;
+       s32 temp;
+       struct tm mytm;
+       time_t mytime;
+       
+       /* 检查小时 */
+       memset(&mytm, 0, sizeof(struct tm));
+       if (sgi_len16(s_edt_hour.edit.text) == 0) {
+               set_object_focus(&s_edt_hour);          
+       }
+       temp = sgi_utol(s_edt_hour.edit.text, 10);
+       if (temp < 0 || temp > 23) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"小时数据无效(0-23)!",
+                       HOUR_INVALID, callback);
+               return; 
+       }
+       mytm.tm_hour = temp;
+       
+       /* 检查分钟 */
+       if (sgi_len16(s_edt_minute.edit.text) == 0) {
+               set_object_focus(&s_edt_minute);                
+       }
+       temp = sgi_utol(s_edt_minute.edit.text, 10);
+       if (temp < 0 || temp > 59) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"分钟数据无效(0-59)!",
+                       MINUTE_INVALID, callback);
+               return; 
+       }
+       mytm.tm_min = temp;
+       
+       /* 检查年份 */
+       if (sgi_len16(s_edt_year.edit.text) == 0) {
+               set_object_focus(&s_edt_year);          
+       }
+       temp = sgi_utol(s_edt_year.edit.text, 10);
+       if (temp < 1970 || temp > 3000) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"年份数据无效(1970-3000)!",
+                       YEAR_INVALID, callback);
+               return; 
+       }
+       mytm.tm_year = temp - 1900;
+       
+       /* 检查月份 */
+       if (sgi_len16(s_edt_month.edit.text) == 0) {
+               set_object_focus(&s_edt_month);         
+       }
+       temp = sgi_utol(s_edt_month.edit.text, 10);
+       if (temp < 1 || temp > 12) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"月份数据无效(1-12)!",
+                       MONTH_INVALID, callback);
+               return; 
+       }
+       mytm.tm_mon = temp - 1;
+       
+       /* 检查日期 */
+       if (sgi_len16(s_edt_day.edit.text) == 0) {
+               set_object_focus(&s_edt_day);           
+       }
+       temp = sgi_utol(s_edt_day.edit.text, 10);
+       if (temp < 1 || temp > 31) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"月份数据无效(1-31)!",
+                       DAY_INVALID, callback);
+               return; 
+       }
+       mytm.tm_mday = temp;
+       
+       /* 设置日期时间 */
+       mytime = mktime(&mytm);
+       if (mytime == -1) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"校时失败!",
+                       TIME_INVALID, callback);
+               return; 
+       }
+       
+       if (stime(&mytime) != 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"校时失败!",
+                       TIME_INVALID, callback);
+               return; 
+       }
+       
+       /* 写入RTC */
+       system("hwclock --systohc");
+       
+       /* 保存密码并提示 */
+       msgbox(&FORM_CLASS(MODULE_NAME), L"校时成功!",
+               SUCCESS, callback);     
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       //s_lbl_time.label.frame = lbl_time_frame;
+       
+       /*  */
+       EDIT_CREATE(s_edt_hour, FORM_CLASS(MODULE_NAME), 281, 103, 61, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       s_edt_hour.edit.mask = MSK_DIGIT;
+       
+       /*  */
+       EDIT_CREATE(s_edt_minute, FORM_CLASS(MODULE_NAME), 368, 103, 60, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       s_edt_minute.edit.mask = MSK_DIGIT;
+       
+       /*  */
+       EDIT_CREATE(s_edt_year, FORM_CLASS(MODULE_NAME), 280, 164, 79, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_year.edit.mask = MSK_DIGIT;
+               
+       /*  */
+       EDIT_CREATE(s_edt_month, FORM_CLASS(MODULE_NAME), 391, 164, 41, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_month.edit.mask = MSK_DIGIT;
+               
+       /*  */
+       EDIT_CREATE(s_edt_day, FORM_CLASS(MODULE_NAME), 463, 164, 41, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_day.edit.mask = MSK_DIGIT;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_network, FORM_CLASS(MODULE_NAME), 652, 123, 107, 44, 1,
+               "btn-net-u.png", "btn-net-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_network.button.up = btn_network_up;
+               
+       /*  */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 652, 183, 107, 44, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_unlock.cpp b/src/fm_unlock.cpp
new file mode 100644 (file)
index 0000000..7073383
--- /dev/null
@@ -0,0 +1,149 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_unlock
+
+FORM_MODULE(MODULE_NAME);                      /* 权限管理模块 */                
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_btn_unlock;          /*  */
+static union sgi_object s_btn_cancel;          /*  */
+static union sgi_object s_btn_back;            /* 返回 */
+static union sgi_object s_btn_main;            /* 首页 */
+
+static struct sgi_widget s_widget[3] = {
+       {127, 113, 547, 179, {"unlock.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 暂停锁监控 */
+       pause_lock_monitor();   
+}
+
+static void form_exit(struct sgi_form *)
+{
+       //alarm_ctrl(0);                        
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_unlock_up(struct sgi_button *)
+{      
+       int i;
+       
+       // test
+       //alarm_ctrl(1);
+       door_ctrl(DOOR_OPEN);
+       
+       /* unlock all */
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if (i2c_comm_unlock(g_box_addr[i]) == 0) {
+                       SDL_Delay(2000);        
+               }       
+       }
+       
+       /* log */
+//     struct log_alarm log;
+//     memset(&log, 0, sizeof(struct log_alarm));
+//     log.id = get_log_no(LOG_ALARM);
+//     time(&log.time);
+//     sgi_cpw2u(log.content, L"紧急开锁");
+//     sgi_append_log(DBL(alarm), &log, sizeof(struct log_alarm));
+       record_alarm_log(L"紧急开锁");
+       
+       SDL_Delay(100);
+       door_ctrl(DOOR_CLOSE);  
+}
+
+static void btn_cancel_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_menu));    
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_menu));    
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-0.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_unlock, FORM_CLASS(MODULE_NAME), 282, 217, 107, 44, 1,
+               "btn-unlock-u.png", "btn-unlock-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_unlock.button.up = btn_unlock_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_cancel, FORM_CLASS(MODULE_NAME), 408, 217, 107, 44, 1,
+               "btn-cancel-u.png", "btn-cancel-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_cancel.button.up = btn_cancel_up;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 109, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+       
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 611, 350, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_unlock_pwd.cpp b/src/fm_unlock_pwd.cpp
new file mode 100644 (file)
index 0000000..1f48989
--- /dev/null
@@ -0,0 +1,188 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_unlock_pwd
+
+FORM_MODULE(MODULE_NAME);                      /* 取枪模块,警员密码验证 */         
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_edt_uid;             /* 用户编号 */
+static union sgi_object s_edt_pwd;             /* 密码输入框 */
+static union sgi_object s_btn_confirm;         /* 确认按钮 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_pwd_retries = 0;
+
+static struct sgi_widget s_widget[3] = {
+       {165, 59, 377, 95, {"pwd-2.png", IMG_OPTIMIZE | IMG_ALPHA, NULL}},
+       {0, 0, 0, 0, {NULL, 0, NULL}},  
+};
+
+static void form_enter(struct sgi_form *)
+{
+       /* 注册输入法 */
+       register_ime(&FORM_CLASS(MODULE_NAME));
+       
+       set_object_text_u(&s_edt_uid.edit, NULL);
+       set_object_text_u(&s_edt_pwd.edit, NULL);
+       set_object_focus(&s_edt_uid);
+       
+       s_timer = 60;   
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d秒", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void callback(s32 user)
+{
+       if (user == ID_INVALID) {
+               set_object_focus(&s_edt_uid);   
+       }
+       else if (user == PWD_INVALID) {
+               set_object_focus(&s_edt_pwd);   
+       }                       
+}
+
+static void btn_confirm_up(struct sgi_button *)
+{
+       if (sgi_cmp16(g_passport.mid, s_edt_uid.edit.text) == 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"紧急开锁必须由两个管理员开启!",
+                       0, NULL);
+               return; 
+       }
+       sgi_cp16(g_passport.uid, g_passport.mid);
+       
+       s32 r = verify_manager_pwd(&g_passport, s_edt_uid.edit.text, 
+               s_edt_pwd.edit.text);
+       
+       if (r >= 0) {
+               sgi_form_show(&FORM_CLASS(fm_unlock));
+       }
+       else if (r == ID_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"用户信息不存在!", 
+                       ID_INVALID, callback);          
+       }
+       else if (r == PWD_INVALID) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"密码无效!", 
+                       PWD_INVALID, callback);
+                       
+               if (++s_pwd_retries >= PWD_MAX_RETRIES) {
+                       pwd_alarm();    
+               }
+       }               
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, s_widget);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 编号输入框 */
+       EDIT_CREATE(s_edt_uid, FORM_CLASS(MODULE_NAME), 346, 86, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12); 
+       
+       /* 密码输入框 */
+       EDIT_CREATE(s_edt_pwd, FORM_CLASS(MODULE_NAME), 346, 126, 192, 25, 1,
+               "jht.ttf", 20, text_cl, "cursor.png", IMG_OPTIMIZE | IMG_ALPHA, 12);
+       s_edt_pwd.edit.pwdchar = 1;  
+       
+       /* 确认按钮 */
+       BUTTON_CREATE(s_btn_confirm, FORM_CLASS(MODULE_NAME), 556, 106, 108, 45, 1,
+               "btn-confirm-u.png", "btn-confirm-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_confirm.button.up = btn_confirm_up;               
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;             
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/fm_user_level.cpp b/src/fm_user_level.cpp
new file mode 100644 (file)
index 0000000..9c2667e
--- /dev/null
@@ -0,0 +1,485 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_user_level
+
+FORM_MODULE(MODULE_NAME);                      /* 模块 */            
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_grid;
+static union sgi_object s_btn_save;            /* 保存 */
+static union sgi_object s_btn_cancel;          /* 取消 */
+static union sgi_object s_btn_prev;            /* 上一页 */
+static union sgi_object s_btn_next;            /* 下一页 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+static s32 s_page = 0;
+static u32 s_data_size = 0;
+static s32 s_record_count = 0;
+static struct person_data *s_grid_data = NULL;
+
+static void grid_load_data(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 space_row_start = 0;
+       s32 index;
+       struct person_data *p;
+       s32 offset;
+       s32 read_count;
+       struct tm *tmlocal;
+       
+       /* 页数检查 */
+       offset = s_page * object->row;
+       if (!s_grid_data || offset > s_record_count) {
+               return;
+       }
+       
+       p = s_grid_data + offset;
+       read_count = s_record_count - offset;
+       for (i = 0; i < object->row; ) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       object->cells[index].valid = 1;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               sgi_sprintf16(object->cells[index].string,
+                                       L"%d", s_page * object->row + i + 1);
+                               break;
+                               
+                       case 1: /* column 1 */
+                               sgi_ncp16(object->cells[index].string, p->uid,
+                                       COUNTOF(p->uid));
+                               break;
+                               
+                       case 2: /* column 2 */
+                               sgi_ncp16(object->cells[index].string, p->name,
+                                       COUNTOF(p->name));
+                               break;
+                               
+                       case 3: /* column 3 */
+                               if (p->level == LV_USER) {
+                                       object->cells[index].val = 1;
+                               }
+                               else {
+                                       object->cells[index].val = 0;
+                               } 
+                               break;
+                               
+                       case 4: /* column 4 */
+                               if (p->level == LV_MANAGER) {
+                                       object->cells[index].val = 1;
+                               }
+                               else {
+                                       object->cells[index].val = 0;
+                               } 
+                               break;
+                               
+                       case 5: /* column 5 */
+                               if (p->level == LV_ADMIN) {
+                                       object->cells[index].val = 1;
+                               }
+                               else {
+                                       object->cells[index].val = 0;
+                               } 
+                               break;
+                               
+                       case 6: /* column 6 */
+                               if (p->level == LV_SUPER) {
+                                       object->cells[index].val = 1;
+                               }
+                               else {
+                                       object->cells[index].val = 0;
+                               } 
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               i++;
+               if (--read_count <= 0) {
+                       break;
+               }
+               p++;                    
+       }
+       
+       printf("space row start: %d\n", i);
+       
+       /* 剩余行清零 */
+       for (; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       object->cells[index].val = 0;                   
+                       memset(object->cells[index].string, 0,
+                               sizeof(object->cells[index].string));
+               }
+       }
+}
+
+static void grid_init(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index;
+       s32 y0;
+       const s32 row_offset = 67;
+       const s32 row_h = 26;
+       
+       /* */
+       object->col = 7;
+       object->row = 10;
+       
+       /* */
+       object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+               object->col * object->row);
+               
+       if (!object->cells) {
+               return;
+       }
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * row_h + row_offset;
+               for (j = 0; j < object->col; ++j) {
+                       index = i * object->col + j;
+                       
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 27;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 44;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 71;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 89;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               object->cells[index].type = GRID_STRING;
+                               object->cells[index].x = object->x + 161;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 89;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 3: /* column 3 */
+                               object->cells[index].type = GRID_RADIO;
+                               object->cells[index].x = object->x + 251;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 89;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 4: /* column 4 */
+                               object->cells[index].type = GRID_RADIO;
+                               object->cells[index].x = object->x + 340;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 89;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 5: /* column 5 */
+                               object->cells[index].type = GRID_RADIO;
+                               object->cells[index].x = object->x + 430;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 89;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       case 6: /* column 6 */
+                               object->cells[index].type = GRID_RADIO;
+                               object->cells[index].x = object->x + 519;
+                               object->cells[index].y = y0;
+                               object->cells[index].w = 89;
+                               object->cells[index].h = row_h;
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }       
+}
+
+static void grid_deinit(struct sgi_grid *object)
+{
+       free(object->cells);
+       object->cells = NULL;   
+}
+
+static void form_enter(struct sgi_form *)
+{
+       /* */
+       s_page = 0;
+       s_data_size = 0;
+       
+       /* 初始表格 */
+       grid_init(&s_grid.grid);
+       
+       /* 加载表格数据 */
+       s_grid_data = (struct person_data *)open_w(DBD(person), &s_data_size);
+       s_record_count = s_data_size / sizeof(struct person_data);
+       grid_load_data(&s_grid.grid);
+       
+       printf("load data: %d\n", s_record_count);
+       
+       /* 倒计时长 */
+       s_timer = 240;  
+}
+
+static void form_exit(struct sgi_form *object)
+{
+       grid_deinit(&s_grid.grid);
+       
+       printf("close data: %d\n", s_data_size);
+       
+       /* 关闭数据 */
+       if (s_grid_data) {
+               close_w(s_grid_data, s_data_size);
+       }
+       
+       /* 重新加载用户数据 */
+       load_person_data();     
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = localtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+//     static u32 next;
+//     wchar_t buf[64];
+//     
+//     if (SDL_GetTicks() > next) {
+//             s_timer--;
+//             if (s_timer <= 0) {
+//                     //s_btn_main.button.up(&s_btn_main.button);
+//             }
+//             swprintf(buf, sizeof(buf), L"倒计时:%02d秒", s_timer);
+//             set_object_text_w(label, buf);
+//             label->redraw = 1;
+//             
+//             next = SDL_GetTicks() + 1000;   
+//     }
+       
+       return 0;       
+}
+
+static void btn_back_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_log_main));        
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{      
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+static void save_change(void)
+{
+       s32 i;
+       s32 index;
+       struct person_data *p;
+       s32 offset;
+       s32 read_count;
+       
+       /* 页数检查 */
+       offset = s_page * s_grid.grid.row;
+       if (!s_grid_data || offset > s_record_count) {
+               return;
+       }
+       
+       p = s_grid_data + offset;
+       read_count = s_record_count - offset;
+       for (i = 0; i < s_grid.grid.row; ++i) {
+               index = i * s_grid.grid.col;
+               if (s_grid.grid.cells[index + 3].val) {
+                       p->level = 0;
+               }
+               else if (s_grid.grid.cells[index + 4].val) {
+                       p->level = 1;
+               }
+               else if (s_grid.grid.cells[index + 5].val) {
+                       p->level = 2;
+               }
+               else if (s_grid.grid.cells[index + 6].val) {
+                       p->level = 3;
+               }
+               
+               if (--read_count <= 0) {
+                       break;
+               }
+               p++;                    
+       }
+       
+       if (data_flush(s_grid_data, s_data_size) == 0) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"数据保存成功!", 0, NULL);    
+       }       
+}
+
+static void btn_save_up(struct sgi_button *)
+{
+       if (s_grid.grid.changed) {
+               save_change();
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;
+               s_grid.grid.changed = 0;
+       }       
+}
+
+static void btn_cancel_up(struct sgi_button *)
+{
+       if (s_grid.grid.changed) {
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;
+               s_grid.grid.changed = 0;
+       }               
+}
+
+static void callback(s32 user)
+{
+                       
+}
+
+static void btn_prev_up(struct sgi_button *)
+{
+       if (s_grid.grid.changed) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"数据已经改变,请先保存或取消更改!", 
+                       0, NULL);
+               return; 
+       }
+       
+       if (s_page > 0) {
+               s_page--;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;         
+       }
+}
+
+static void btn_next_up(struct sgi_button *)
+{
+       if (s_grid.grid.changed) {
+               msgbox(&FORM_CLASS(MODULE_NAME), L"数据已经改变,请先保存或取消更改!", 
+                       0, NULL);
+               return; 
+       }
+       
+       if (((s_page + 1) * s_grid.grid.row) < s_record_count) {
+               s_page++;
+               grid_load_data(&s_grid.grid);
+               s_grid.grid.redraw = 1;
+       }
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       SDL_Color color = {255,255,255,0};
+       SDL_Color text_cl = {0, 0, 0, 0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "bg-2.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 4, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, FORM_CLASS(MODULE_NAME), 634, 36, 150, 25, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* */
+       GRID_CREATE(s_grid, FORM_CLASS(MODULE_NAME), 82, 44, 636, 333, 1,
+               "jht.ttf", 20, color, "grid-level.png", "grid-sel.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /*  */
+       BUTTON_CREATE(s_btn_save, FORM_CLASS(MODULE_NAME), 153, 388, 85, 35, 1,
+               "btn-save-s-u.png", "btn-save-s-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_save.button.up = btn_save_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_cancel, FORM_CLASS(MODULE_NAME), 251, 388, 85, 35, 1,
+               "btn-cancel-s-u.png", "btn-cancel-s-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_cancel.button.up = btn_cancel_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_prev, FORM_CLASS(MODULE_NAME), 482, 388, 73, 29, 1,
+               "btn-prev-u.png", "btn-prev-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_prev.button.up = btn_prev_up;
+       
+       /*  */
+       BUTTON_CREATE(s_btn_next, FORM_CLASS(MODULE_NAME), 572, 388, 73, 29, 1,
+               "btn-next-u.png", "btn-next-d.png", NULL, NULL,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_next.button.up = btn_next_up;     
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, FORM_CLASS(MODULE_NAME), 32, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-back.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_back.button.up = btn_back_up;
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, FORM_CLASS(MODULE_NAME), 684, 374, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-t.png", "btn-home.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       FORM_CLASS(MODULE_NAME).enter = form_enter;
+       FORM_CLASS(MODULE_NAME).exit = form_exit;
+       FORM_CLASS(MODULE_NAME).frame = form_frame;
+       
+       return 0;
+}
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/src/global_def.h b/src/global_def.h
new file mode 100644 (file)
index 0000000..40644dd
--- /dev/null
@@ -0,0 +1,740 @@
+#ifndef GLOBAL_DEF_H
+#define GLOBAL_DEF_H
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <vector>
+#include <list>
+#include <deque>
+#include "SDL.h"
+#include "SDL_image.h"
+#include "SDL_ttf.h"
+#include "SDL_mixer.h"
+#include "sgi_types.h"
+#include "lock.h"
+
+/* common define */
+#define MAX_PATH               260
+#define IMG_OPTIMIZE           (1 << 0)
+#define IMG_ALPHA              (1 << 1)
+#define X_RES                  800
+#define Y_RES                  480                     
+
+#define DT_LEFT                        0
+#define DT_CENTER              1
+#define DT_RIGHT               2
+
+/* timeout define */
+#define TIMEOUT_IDENT          60
+
+/* fingerprint module define */
+#define FPR_SIGNAL             SIGRTMIN + 1
+
+#define FPR_IDENTIFY           1
+#define FPR_ENROLL_1           2
+#define FPR_ENROLL_2           3
+#define FPR_ENROLL_3           4
+#define FPR_QUIT               15
+
+/* object type define */
+#define SGI_WINDOW             1
+#define SGI_PICTURE            2
+#define SGI_LABEL              3
+#define SGI_EDIT               4
+#define SGI_BUTTON             5
+#define SGI_IME                        6
+#define SGI_GRID               7
+#define SGI_FORM               8
+#define SGI_PHOTO              9
+#define SGI_MSGBOX             10
+#define SGI_RADIO              11
+#define SGI_CHECK              12
+#define SGI_UPDOWN             13
+#define SGI_BOX                        14
+#define SGI_INDICATOR          15
+
+/* grid col type */
+#define GRID_STRING            0
+#define GRID_BUTTON            1
+#define GRID_RADIO             2
+
+/* photo type define */
+#define PHO_SAMPLE             1
+#define PHO_REAL               2
+#define PHOTO_SAMPLE_PATH      "/sdcard/data/photo"
+#define PHOTO_REAL_PATH                "/sdcard/log/photo"
+
+/* text style define */
+#define DEL_CHAR               0x0008
+#define SPACE                  2
+#define EDIT_SPACE             0
+#define RADIO_SPACE            0
+#define CHECK_SPACE            0
+
+#define MSK_DIGIT              (1 << 0)
+#define MSK_ALPHA              (1 << 2)
+#define MSK_CHN                        (1 << 3)
+
+/* ime & box define */
+#define KEY_NUMS               38
+#define SELECTOR_NUMS          10
+#define BOX_NUMS               42
+#define CELL_EMPTY(n)          (((n) & 0x3) == 0)
+#define CELL_VALID(n)          (((n) & 0x3) == 1)
+#define CELL_BORROW(n)         (((n) & 0x3) == 3)
+#define BOX_TYPE_GUN           0
+#define BOX_TYPE_BULLET                1
+
+/* data define */
+#define VALID_PASSPORT         (1u << 31)
+
+#define USR_FPR_MASK           (~(3 << 0))
+#define USR_FPR_VALID          (1 << 0)
+#define USR_FPR_INVALID                (2 << 0)
+#define USR_CARD_MASK          (~(3 << 2))
+#define USR_CARD_VALID         (1 << 2)
+#define USR_CARD_INVALID       (2 << 2)
+#define USR_PWD_MASK           (~(3 << 4))
+#define USR_PWD_VALID          (1 << 4)
+#define USR_PWD_INVALID                (2 << 4)
+
+#define MGR_FPR_MASK           (~(3 << 8))
+#define MGR_FPR_VALID          (1 << 8)
+#define MGR_FPR_INVALID                (2 << 8)
+#define MGR_CARD_MASK          (~(3 << 10))
+#define MGR_CARD_VALID         (1 << 10)
+#define MGR_CARD_INVALID       (2 << 10)
+#define MGR_PWD_MASK           (~(3 << 12))
+#define MGR_PWD_VALID          (1 << 12)
+#define MGR_PWD_INVALID                (2 << 12)
+
+#define MIN_PWD_LEN            6
+
+#define LV_USER                        0
+#define LV_MANAGER             1
+#define LV_ADMIN               2
+#define LV_SUPER               3
+#define LV_SPEC                        4
+
+#define SR_FPR                 1
+#define SR_CARD                        2
+
+#define MSG_TIP                        1
+
+#define REG_NONE               0
+#define REG_NEW                        1
+#define REG_MODIFY             2
+#define REG_UPDATE             3
+
+#define SUCCESS                        0
+#define ID_INVALID             -1
+#define PWD_INVALID            -2
+#define PWD_NOT_MATCH          -3
+#define PWD_SHORTEST           -4
+#define FPR_FAIL               -5
+#define ID_EXIST               -6
+#define CODE_INVALID           -7
+#define APPEND_FAIL            -8
+#define REGISTER_FAIL          -9
+#define ENROLL_FAIL            -10
+#define DEL_FAIL               -11
+
+/* download define */
+#define UDISK_DRV              "/proc/scsi/usb-storage"
+#define UDISK_DEV              "/udisk"
+
+/* monitor define */
+#define LOCK_SCAN_CYCLE                100
+#define REMIT_TIME             30000
+#define POWER_REMIT_TIME       7200000
+#define BORROW_REMIT_TIME      (24 * 3600 * 1000)
+#define AUTHORIZE_TIME         600000
+#define FORCE_OPEN_DOOR                1
+#define FORCE_UNLOCK           2
+#define POWER_LOST             3
+#define BORROW_TIMEOUT         4
+#define PWD_ERROR              5
+
+#define PWD_MAX_RETRIES                3
+
+#define LOCK_MON_COUNT         1
+#define DOOR_MON_COUNT         2
+#define POWER_MON_COUNT                2
+
+#define ALARM_DOOR_EN          (1 << 0)
+#define ALARM_DOOR_EX_EN       (1 << 1)
+#define ALARM_LOCK_EN          (1 << 2)
+#define ALARM_POWER_EN         (1 << 3)
+#define ALARM_BORROW_EN                (1 << 4)
+#define ALARM_PWD_EN           (1 << 5)
+
+#define POWER_AC               0
+#define POWER_BATTERY          1
+
+/* main control board */
+#define MFCARD_MAGIC           'E'
+#define MFCARD_IOCTL_ALARM     _IOW(MFCARD_MAGIC, 1, int)
+#define MFCARD_IOCTL_PW_CTRL   _IOW(MFCARD_MAGIC, 2, int)
+#define MFCARD_IOCTL_DOOR_CTRL _IOW(MFCARD_MAGIC, 3, int)
+#define MFCARD_IOCTL_CARD_START        _IOW(MFCARD_MAGIC, 4, int)
+#define MFCARD_IOCTL_CARD_STATE        _IOR(MFCARD_MAGIC, 5, int)
+#define MFCARD_IOCTL_CARD_READ _IOR(MFCARD_MAGIC, 6, int)
+#define MFCARD_IOCTL_FPR_STATE _IOR(MFCARD_MAGIC, 7, int)
+#define MFCARD_IOCTL_DOOR_FB   _IOR(MFCARD_MAGIC, 8, int)
+#define MFCARD_IOCTL_PW_JC     _IOR(MFCARD_MAGIC, 9, int)
+#define MFCARD_IOCTL_QWZ1      _IOR(MFCARD_MAGIC, 10, int)
+#define MFCARD_IOCTL_QWZ2      _IOR(MFCARD_MAGIC, 11, int)
+
+#define DOOR_CLOSE             0
+#define DOOR_OPEN              1
+
+#define ALARM_ON               1
+#define ALARM_OFF              0
+
+/* message define */
+#define SGI_MOUSEDOWN          0x1001
+#define SGI_MOUSEUP            0x1002
+#define SGI_CHAR               0x1003
+
+/* net define */
+#define SERVER_IP              "192.168.1.8"
+#define SERVER_PORT            6000
+#define NET_MAGIC              0x5AA56699
+
+#define POOL_INIT_NUMS         100
+#define POOL_REALLOC_NUMS      20
+#define POOL_MAX_NUMS          2000
+
+#define CMD_NONE               0
+#define CMD_HEARTBEAT          1
+#define CMD_TIME_ADJUST                2
+#define CMD_DATA_ALARM         3
+#define CMD_DATA_BORROW                4
+#define CMD_DATA_RETURN                5
+#define CMD_DATA_SYSTEM                6
+#define CMD_DATA_MANAGER       7
+#define CMD_DATA_REPORT_BORROW 8
+#define CMD_DATA_REPORT_RETURN 9
+
+#define BOX_CODE_LEN           (16 * sizeof(u16))
+
+#define NET_MONITOR_CYCLE      1000
+#define NET_DOWN_CYCLE         10000
+#define NET_LINK_CYCLE         5000
+#define TIME_ADJUST_CYCLE      3600000
+
+enum sgi_log_type {
+       LOG_MANAGER = 0,
+       LOG_BORROW,
+       LOG_RETURN,
+       LOG_ALARM,
+       LOG_SYSTEM,
+       LOG_MAX,
+};
+
+enum sgi_ime_type {
+       IME_CHAR = 0,
+       IME_SYMBOL,
+       IME_PINYIN,     
+};
+
+struct sgi_msg {
+       u16 type;
+       s16 wparam;
+       s32 lparam;
+};
+
+struct sgi_font {
+       char *name;
+       u32 size;
+       TTF_Font *font;
+};
+
+struct sgi_image {
+       char *name;
+       u32 flags;
+       SDL_Surface *image;
+};
+
+struct sgi_widget {
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       struct sgi_image image;
+};
+
+struct sgi_key {
+       u16 state;
+       s16 index;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+};
+
+struct sgi_cell {
+       u16 state;
+       s16 tag;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+};
+
+struct sgi_ime_caption {
+       u16 text[KEY_NUMS][4];
+};
+
+struct sgi_ime_word {
+       u16 word[KEY_NUMS];
+};
+
+struct sgi_ime_chinese {
+       u16 syllables[8];
+       u16 page;
+       u16 count;
+       wchar_t *chinese;       
+};
+
+struct sgi_window {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       s32 reallocated;
+       
+       struct sgi_image image; 
+       struct sgi_widget *widget;
+
+       int (*init)(struct sgi_window *);
+       void (*deinit)(struct sgi_window *);
+       int (*frame)(struct sgi_window *);
+       void (*render)(struct sgi_window *, SDL_Surface *);
+};
+
+struct sgi_picture {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       
+       u32 state;
+       struct sgi_image image;
+       
+       s32 (*init)(struct sgi_picture *);
+       void (*deinit)(struct sgi_picture *);
+       s32 (*frame)(struct sgi_picture *);
+       void (*render)(struct sgi_picture *, SDL_Surface *);    
+};
+
+struct sgi_photo {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       struct sgi_form *parent;
+       u32 redraw;
+       SDL_Surface *surface;
+       
+       s32 (*init)(struct sgi_photo *);
+       void (*deinit)(struct sgi_photo *);
+       s32 (*frame)(struct sgi_photo *);
+       void (*render)(struct sgi_photo *, SDL_Surface *);
+};
+
+struct sgi_indicator {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;        
+       u32 redraw;
+       
+       s32 state;
+       struct sgi_image image[2];
+       
+       s32 (*init)(struct sgi_indicator *);
+       void (*deinit)(struct sgi_indicator *);
+       s32 (*frame)(struct sgi_indicator *);
+       void (*render)(struct sgi_indicator *, SDL_Surface *);  
+};
+
+struct sgi_label {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       
+       s32 align;
+       SDL_Color fcolor;
+       u32 bcolor;
+       s32 tag;
+       
+       u16 caption[64];
+       struct sgi_font font;
+       
+       s32 (*init)(struct sgi_label *);
+       void (*deinit)(struct sgi_label *);
+       s32 (*frame)(struct sgi_label *);
+       void (*render)(struct sgi_label *, SDL_Surface *);      
+};
+
+struct sgi_edit {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       u32 handle;
+       
+       s32 align;
+       SDL_Color fcolor;
+       u32 bcolor;
+       
+       u16 text[64];
+       struct sgi_font font;
+       struct sgi_image image;
+       
+       u8 readonly;
+       u8 word_max;
+       u8 focus;
+       u8 cursor;
+       u32 cursor_timer;
+       u16 pwdchar;
+       u16 mask;
+       
+       s32 (*init)(struct sgi_edit *);
+       void (*deinit)(struct sgi_edit *);
+       s32 (*frame)(struct sgi_edit *);
+       void (*render)(struct sgi_edit *, SDL_Surface *);
+};
+
+struct sgi_button {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       
+       u32 hide;
+       u32 state;      
+       struct sgi_image back[3];
+       struct sgi_image front; 
+       
+       s32 (*init)(struct sgi_button *);
+       void (*deinit)(struct sgi_button *);
+       s32 (*frame)(struct sgi_button *);
+       void (*render)(struct sgi_button *, SDL_Surface *);
+       
+       void (*down)(struct sgi_button *);
+       void (*up)(struct sgi_button *);
+       void (*click)(struct sgi_button *);
+};
+
+struct sgi_ime {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u16 hide;
+       u16 state;
+       u16 mode;
+       u16 ch; 
+       struct sgi_font font;
+       struct sgi_image back[2];
+       struct sgi_key *key;
+       const struct sgi_ime_word *word;
+       const struct sgi_ime_caption *caption;
+       
+       struct sgi_key *selector;
+       struct sgi_ime_chinese chinese; 
+       
+       u32 redraw;
+       
+       s32 (*init)(struct sgi_ime *);
+       void (*deinit)(struct sgi_ime *);
+       s32 (*frame)(struct sgi_ime *);
+       void (*render)(struct sgi_ime *, SDL_Surface *);
+       
+       void (*down)(struct sgi_ime *);
+       void (*up)(struct sgi_ime *);   
+};
+
+struct sgi_box {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u16 hide;
+       u16 state;
+       struct sgi_font font;   
+       struct sgi_image back[4];
+       struct sgi_cell cell[BOX_NUMS];
+       const u8 *cell_addr;
+       
+       u32 redraw;     
+       
+       s32 (*init)(struct sgi_box *);
+       void (*deinit)(struct sgi_box *);
+       s32 (*frame)(struct sgi_box *);
+       void (*render)(struct sgi_box *, SDL_Surface *);
+       
+       void (*down)(struct sgi_box *);
+       void (*up)(struct sgi_box *);   
+};
+
+struct sgi_msgbox {
+       u16 type;
+       s16 z;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;     
+       struct sgi_font font;
+       struct sgi_image image[4];
+       struct sgi_key button;
+       
+       u16 text[128];
+       s32 style;
+       
+       s32 (*init)(struct sgi_msgbox *);
+       void (*deinit)(struct sgi_msgbox *);
+       s32 (*frame)(struct sgi_msgbox *);
+       void (*render)(struct sgi_msgbox *, SDL_Surface *);
+       
+       u32 user;
+       void (*callback)(s32);
+};     
+
+struct sgi_radio {
+       u16 type;
+       s16 x,y,w,h,z;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       u32 handle;
+       u16 state;
+       s16 value;      
+       struct sgi_image image[2];
+       
+       s32 (*init)(struct sgi_radio *);
+       void (*deinit)(struct sgi_radio *);
+       s32 (*frame)(struct sgi_radio *);
+       void (*render)(struct sgi_radio *, SDL_Surface *);
+       
+       void (*up)(struct sgi_radio *);         
+};
+
+struct sgi_check {
+       u16 type;
+       s16 x,y,w,h,z;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       u32 handle;
+       u16 state;
+       s16 value;      
+       struct sgi_image image[2];
+       
+       s32 (*init)(struct sgi_check *);
+       void (*deinit)(struct sgi_check *);
+       s32 (*frame)(struct sgi_check *);
+       void (*render)(struct sgi_check *, SDL_Surface *);
+       
+       void (*up)(struct sgi_check *);         
+};
+
+struct sgi_updown {
+       u16 type;
+       s16 x,y,w,h,z,tw;
+       
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       u32 handle;
+       u16 state[2];
+       s32 value;      
+       
+       SDL_Color fcolor;
+       struct sgi_font font;
+       struct sgi_image image[2];
+       
+       s32 (*init)(struct sgi_updown *);
+       void (*deinit)(struct sgi_updown *);
+       s32 (*frame)(struct sgi_updown *);
+       void (*render)(struct sgi_updown *, SDL_Surface *);             
+};
+
+struct grid_cell {
+       u16 type;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       u16 state;
+       s16 valid;
+       s16 val;
+       u16 string[32];
+};
+
+struct sgi_grid {
+       u16 type;
+       s16 x,y,w,h,z;
+       
+       s16 row;
+       s16 col;
+       s16 select_index;
+       s16 readonly;
+       s32 changed;
+       struct grid_cell *cells;
+               
+       s32 initialized;
+       struct sgi_form *parent;
+       
+       u32 redraw;
+       u32 handle;
+       SDL_Color fcolor;
+       struct sgi_font font;
+       struct sgi_image back;
+       struct sgi_image action;
+       
+       s32 (*init)(struct sgi_grid *);
+       void (*deinit)(struct sgi_grid *);
+       s32 (*frame)(struct sgi_grid *);
+       void (*render)(struct sgi_grid *, SDL_Surface *);
+       
+       void (*down)(struct sgi_grid *, s32 row);
+       void (*up)(struct sgi_grid *, s32 row);         
+};
+
+union sgi_object {
+       u16 type;
+       struct sgi_window window;
+       struct sgi_picture picture;
+       struct sgi_label label;
+       struct sgi_edit edit;
+       struct sgi_button button;
+       struct sgi_ime ime;
+       struct sgi_grid grid;
+       struct sgi_photo photo;
+       struct sgi_msgbox msgbox;
+       struct sgi_radio radio;
+       struct sgi_check check;
+       struct sgi_updown updown;
+       struct sgi_box box;
+       struct sgi_indicator indicator; 
+};
+
+struct sgi_form {
+       char *name;
+       std::vector <union sgi_object *> form;
+       std::list <struct sgi_msg > msg;
+       struct sgi_window *wnd;
+       struct sgi_ime *ime;
+       struct sgi_msgbox *msgbox;
+       
+       s32 initialized;
+       u16 redraw;
+       u16 dirty;
+       s16 x1,y1,x2,y2;
+       u32 focus_handle;
+               
+       s32 (*init)(struct sgi_form *);
+       void (*deinit)(struct sgi_form *);
+       s32 (*frame)(struct sgi_form *);
+       void (*render)(struct sgi_form *, SDL_Surface *);
+       
+       void (*enter)(struct sgi_form *);
+       void (*exit)(struct sgi_form *);
+       
+       void (*add)(union sgi_object *);
+       void (*del)(union sgi_object *);
+       void (*sort)(s32 order);
+};
+
+struct sgi_form_list {
+       struct sgi_form *form;
+       s32 (*create)(void);
+       void (*destroy)(void);
+       s32 created;
+};     
+
+struct udisk_info {
+       char vendor[32];
+       char product[32];
+       char sn[32];
+       u32 total;
+       u32 avail; 
+};
+
+#endif
diff --git a/src/global_func.h b/src/global_func.h
new file mode 100644 (file)
index 0000000..725ac3c
--- /dev/null
@@ -0,0 +1,447 @@
+#ifndef GLOBAL_FUNC_H
+#define GLOBAL_FUNC_H
+
+#include "global_def.h"
+#include "global_macro.h"
+#include "sgi_string.h"
+#include "sgi_data.h"
+#include "sgi_log.h"
+
+extern const char *get_resource_path(void);
+
+/* global variable declare */
+extern struct passport_data g_passport;
+extern struct alarm_data g_alarm_data;
+extern pthread_t g_fpr_thread;
+extern struct sgi_ime g_sgi_ime;
+extern struct sgi_msgbox g_sgi_msgbox;
+extern const u8 g_box_addr[BOX_NUMS];
+extern s32 g_data_update_state;
+
+/* form declare */
+FORM_DECLARE(fm_main)
+FORM_DECLARE(fm_menu)
+
+FORM_DECLARE(fm_borrow_fpr_user)
+FORM_DECLARE(fm_borrow_card_user)
+FORM_DECLARE(fm_borrow_pwd_user)
+FORM_DECLARE(fm_borrow_fpr_manager)
+FORM_DECLARE(fm_borrow_card_manager)
+FORM_DECLARE(fm_borrow_pwd_manager)
+FORM_DECLARE(fm_borrow_photo_user)
+FORM_DECLARE(fm_borrow_unlock)
+
+FORM_DECLARE(fm_return_fpr_user)
+FORM_DECLARE(fm_return_fpr_manager)
+FORM_DECLARE(fm_return_card_user)
+FORM_DECLARE(fm_return_card_manager)
+FORM_DECLARE(fm_return_pwd_user)
+FORM_DECLARE(fm_return_pwd_manager)
+FORM_DECLARE(fm_return_photo_user)
+FORM_DECLARE(fm_return_unlock)
+FORM_DECLARE(fm_chpwd)
+
+FORM_DECLARE(fm_level)
+FORM_DECLARE(fm_box_manage)
+FORM_DECLARE(fm_log_main)
+FORM_DECLARE(fm_system)
+FORM_DECLARE(fm_info_choice)
+FORM_DECLARE(fm_info_register)
+FORM_DECLARE(fm_reg_person)
+FORM_DECLARE(fm_reg_photo)
+FORM_DECLARE(fm_reg_pwd)
+FORM_DECLARE(fm_reg_fpr1_1)
+FORM_DECLARE(fm_reg_fpr1_2)
+FORM_DECLARE(fm_reg_fpr1_3)
+FORM_DECLARE(fm_reg_gun)
+FORM_DECLARE(fm_reg_bullet)
+FORM_DECLARE(fm_reg_unit)
+FORM_DECLARE(fm_reg_box)
+FORM_DECLARE(fm_info_stat)
+FORM_DECLARE(fm_stat_unit)
+FORM_DECLARE(fm_stat_box)
+FORM_DECLARE(fm_stat_person)
+FORM_DECLARE(fm_stat_bullet)
+FORM_DECLARE(fm_stat_gun)
+FORM_DECLARE(fm_timing)
+FORM_DECLARE(fm_unlock)
+FORM_DECLARE(fm_alarm)
+FORM_DECLARE(fm_log_manager)
+FORM_DECLARE(fm_log_alarm)
+FORM_DECLARE(fm_log_borrow)
+FORM_DECLARE(fm_log_return)
+FORM_DECLARE(fm_log_system)
+FORM_DECLARE(fm_user_level)
+FORM_DECLARE(fm_menu_pwd)
+FORM_DECLARE(fm_alarm_pwd)
+FORM_DECLARE(fm_unlock_pwd)
+FORM_DECLARE(fm_mon_setting)
+FORM_DECLARE(fm_download)
+FORM_DECLARE(fm_safecheck)
+
+#define FORM_LIST_FILL_ALL                     \
+ FORM_LIST_ITEM(fm_main),                      \
+ FORM_LIST_ITEM(fm_menu),                      \
+                                               \
+ FORM_LIST_ITEM(fm_borrow_fpr_user),           \
+ FORM_LIST_ITEM(fm_borrow_card_user),          \
+ FORM_LIST_ITEM(fm_borrow_pwd_user),           \
+ FORM_LIST_ITEM(fm_borrow_fpr_manager),                \
+ FORM_LIST_ITEM(fm_borrow_card_manager),       \
+ FORM_LIST_ITEM(fm_borrow_pwd_manager),                \
+ FORM_LIST_ITEM(fm_borrow_photo_user),         \
+ FORM_LIST_ITEM(fm_borrow_unlock),             \
+                                               \
+ FORM_LIST_ITEM(fm_return_fpr_manager),                \
+ FORM_LIST_ITEM(fm_return_fpr_user),           \
+ FORM_LIST_ITEM(fm_return_card_user),          \
+ FORM_LIST_ITEM(fm_return_card_manager),       \
+ FORM_LIST_ITEM(fm_return_pwd_user),           \
+ FORM_LIST_ITEM(fm_return_pwd_manager),                \
+ FORM_LIST_ITEM(fm_return_photo_user),         \
+ FORM_LIST_ITEM(fm_return_unlock),             \
+                                               \
+ FORM_LIST_ITEM(fm_chpwd),                     \
+                                               \
+ FORM_LIST_ITEM(fm_level),                     \
+ FORM_LIST_ITEM(fm_box_manage),                        \
+ FORM_LIST_ITEM(fm_log_main),                  \
+ FORM_LIST_ITEM(fm_system),                    \
+ FORM_LIST_ITEM(fm_info_choice),               \
+ FORM_LIST_ITEM(fm_info_register),             \
+ FORM_LIST_ITEM(fm_reg_person),                        \
+ FORM_LIST_ITEM(fm_reg_photo),                 \
+ FORM_LIST_ITEM(fm_reg_pwd),                   \
+ FORM_LIST_ITEM(fm_reg_fpr1_1),                        \
+ FORM_LIST_ITEM(fm_reg_fpr1_2),                        \
+ FORM_LIST_ITEM(fm_reg_fpr1_3),                        \
+ FORM_LIST_ITEM(fm_reg_gun),                   \
+ FORM_LIST_ITEM(fm_reg_bullet),                        \
+ FORM_LIST_ITEM(fm_reg_unit),                  \
+ FORM_LIST_ITEM(fm_reg_box),                   \
+ FORM_LIST_ITEM(fm_info_stat),                 \
+ FORM_LIST_ITEM(fm_stat_unit),                 \
+ FORM_LIST_ITEM(fm_stat_box),                  \
+ FORM_LIST_ITEM(fm_stat_person),               \
+ FORM_LIST_ITEM(fm_stat_bullet),               \
+ FORM_LIST_ITEM(fm_stat_gun),                  \
+ FORM_LIST_ITEM(fm_timing),                    \
+ FORM_LIST_ITEM(fm_unlock),                    \
+ FORM_LIST_ITEM(fm_alarm),                     \
+ FORM_LIST_ITEM(fm_log_manager),               \
+ FORM_LIST_ITEM(fm_log_alarm),                 \
+ FORM_LIST_ITEM(fm_log_borrow),                        \
+ FORM_LIST_ITEM(fm_log_return),                        \
+ FORM_LIST_ITEM(fm_log_system),                        \
+ FORM_LIST_ITEM(fm_user_level),                        \
+ FORM_LIST_ITEM(fm_menu_pwd),                  \
+ FORM_LIST_ITEM(fm_alarm_pwd),                 \
+ FORM_LIST_ITEM(fm_unlock_pwd),                        \
+ FORM_LIST_ITEM(fm_mon_setting),               \
+ FORM_LIST_ITEM(fm_download),                  \
+ FORM_LIST_ITEM(fm_safecheck),
+
+/* uart.cpp */
+extern int open_comm(void);
+extern void close_comm(void);
+extern int transfer(u8 *tx, u32 tx_len, u8 *rx, u32 rx_len, u32 timeout);
+extern int uart_receive(u8 *rx, u32 rx_len, u32 timeout);
+extern SDL_Surface *clone_surface(SDL_Surface *image);
+extern void release_clone_surface(SDL_Surface *image);
+
+/* sgi_base.cpp */
+extern u32 request_handle(void);
+extern void strncpy_u2a(char *dst, u16 *src, s32 size);
+extern void strncpy_u(u16 *dst, u16 *src, s32 size);
+extern int strlen_u(u16 *src);
+extern void strncpy_w(u16 *dst, wchar_t *src, s32 size);
+extern s32 strncmp_u(u16 *src1, u16 *src2, s32 size);
+extern void set_object_default_func(struct sgi_form *form);
+extern void set_object_default_func(union sgi_object *object);
+extern void invalidate_rect(struct sgi_form *form, s16 x1, s16 y1, s16 x2, s16 y2);
+extern void set_object_pos(union sgi_object *object, s16 x, s16 y, s16 w, s16 h, s16 z);
+extern void set_object_parent(union sgi_object *object, struct sgi_form *form);
+extern void set_object_image(union sgi_object *object, char *image1, char *image2, 
+       char *image3, char *image4, u32 flags);
+extern void set_object_font(union sgi_object *object, char *name, u32 size, 
+       SDL_Color color);
+extern void form_memset(struct sgi_form *form);
+extern void sgi_edit_insert_text(struct sgi_edit *object, u16 text);
+extern void set_object_text_u(struct sgi_label *object, u16 *text);
+extern void set_object_text_u(struct sgi_edit *object, u16 *text);
+extern void set_object_text_w(struct sgi_label *object, wchar_t *text);
+extern void set_object_text_w(struct sgi_edit *object, wchar_t *text);
+extern void get_object_text_u(struct sgi_label *object, u16 *text);
+extern void get_object_text_u(struct sgi_edit *object, u16 *text);
+extern void set_object_focus(union sgi_object *object);
+extern void register_window(struct sgi_form *form, struct sgi_window *wnd);
+extern void register_ime(struct sgi_form *form);
+extern void msgbox(struct sgi_form *form, w32 *text, s32 user, void (*callback)(s32));
+extern SDL_Surface *load_photo(struct passport_data *pass, s32 type);
+extern void unload_photo(struct sgi_photo *photo);
+
+/* sgi_base_picture.cpp */
+extern s32 sgi_picture_init_default(struct sgi_picture *object);
+extern void sgi_picture_deinit_default(struct sgi_picture *object);
+extern s32 sgi_picture_frame_default(struct sgi_picture *object);
+extern void sgi_picture_render_default(struct sgi_picture *object, 
+       SDL_Surface *screen);
+extern void sgi_photo_render_default(struct sgi_photo *object,
+       SDL_Surface *screen);
+       
+/* sgi_base_indicator.cpp */
+extern s32 sgi_indicator_init_default(struct sgi_indicator *object);
+extern void sgi_indicator_deinit_default(struct sgi_indicator *object);
+extern s32 sgi_indicator_frame_default(struct sgi_indicator *object);
+extern void sgi_indicator_render_default(struct sgi_indicator *object, 
+       SDL_Surface *screen);
+
+/* sgi_base_label.cpp */
+extern s32 sgi_label_init_default(struct sgi_label *object);
+extern void sgi_label_deinit_default(struct sgi_label *object);
+extern s32 sgi_label_frame_default(struct sgi_label *object);
+extern void sgi_label_render_default(struct sgi_label *object, 
+       SDL_Surface *screen);
+
+/* sgi_base_window.cpp */
+extern s32 sgi_window_init_default(struct sgi_window *object);
+extern void sgi_window_deinit_default(struct sgi_window *object);
+extern s32 sgi_window_frame_default(struct sgi_window *object);
+extern void sgi_window_render_default(struct sgi_window *object, 
+       SDL_Surface *screen);
+
+/* sgi_base_edit.cpp */
+extern s32 sgi_edit_init_default(struct sgi_edit *object);
+extern void sgi_edit_deinit_default(struct sgi_edit *object);
+extern s32 sgi_edit_frame_default(struct sgi_edit *object);
+extern void sgi_edit_render_default(struct sgi_edit *object, 
+       SDL_Surface *screen);
+
+/* sgi_base_button.cpp */
+extern s32 sgi_button_init_default(struct sgi_button *object);
+extern void sgi_button_deinit_default(struct sgi_button *object);
+extern s32 sgi_button_frame_default(struct sgi_button *object);
+extern void sgi_button_render_default(struct sgi_button *object, 
+       SDL_Surface *screen);
+extern void sgi_button_down_default(struct sgi_button *object);
+extern void sgi_button_up_default(struct sgi_button *object);
+extern void sgi_button_click_default(struct sgi_button *object);
+
+/* sgi_base_ime.cpp */
+extern void sgi_ime_create(void);
+extern s32 sgi_ime_init_default(struct sgi_ime *object);
+extern void sgi_ime_deinit_default(struct sgi_ime *object);
+extern s32 sgi_ime_frame_default(struct sgi_ime *object);
+extern void sgi_ime_render_default(struct sgi_ime *object, SDL_Surface *screen);
+extern wchar_t *decode_syllables(const u16 *syllables);
+
+/* sgi_base_box.cpp */
+extern s32 sgi_box_init_default(struct sgi_box *object);
+extern void sgi_box_deinit_default(struct sgi_box *object);
+extern s32 sgi_box_frame_default(struct sgi_box *object);
+extern void sgi_box_render_default(struct sgi_box *object, SDL_Surface *screen);
+extern void sgi_box_down_default(struct sgi_box *object);
+extern void sgi_box_up_default(struct sgi_box *object);
+
+/* sgi_base_grid.cpp */
+extern s32 sgi_grid_init_default(struct sgi_grid *object);
+extern void sgi_grid_deinit_default(struct sgi_grid *object);
+extern s32 sgi_grid_frame_default(struct sgi_grid *object);
+extern void sgi_grid_render_default(struct sgi_grid *object, SDL_Surface *screen);
+
+
+/* sgi_base_form.cpp */
+extern s32 sgi_form_init_default(struct sgi_form *form);
+extern void sgi_form_deinit_default(struct sgi_form *form);
+extern s32 sgi_form_frame_default(struct sgi_form *form);
+extern void sgi_form_render_default(struct sgi_form *form, SDL_Surface *screen);
+
+/* sgi_base_msgbox.cpp */
+extern void sgi_msgbox_create(void);
+extern s32 sgi_msgbox_init_default(struct sgi_msgbox *object);
+extern void sgi_msgbox_deinit_default(struct sgi_msgbox *object);
+extern s32 sgi_msgbox_frame_default(struct sgi_msgbox *object);
+extern void sgi_msgbox_render_default(struct sgi_msgbox *object, SDL_Surface *screen);
+
+/* sgi_base_radio.cpp */
+extern s32 sgi_radio_init_default(struct sgi_radio *object);
+extern void sgi_radio_deinit_default(struct sgi_radio *object);
+extern s32 sgi_radio_frame_default(struct sgi_radio *object);
+extern void sgi_radio_render_default(struct sgi_radio *object, 
+       SDL_Surface *screen);
+       
+/* sgi_base_check.cpp */
+extern s32 sgi_check_init_default(struct sgi_check *object);
+extern void sgi_check_deinit_default(struct sgi_check *object);
+extern s32 sgi_check_frame_default(struct sgi_check *object);
+extern void sgi_check_render_default(struct sgi_check *object, 
+       SDL_Surface *screen);
+       
+/* sgi_base_updown.cpp */
+extern s32 sgi_updown_init_default(struct sgi_updown *object);
+extern void sgi_updown_deinit_default(struct sgi_updown *object);
+extern s32 sgi_updown_frame_default(struct sgi_updown *object);
+extern void sgi_updown_render_default(struct sgi_updown *object, 
+       SDL_Surface *screen);
+
+/* sgi_resource.cpp */
+extern int initialize_resource(SDL_Surface *screen);
+extern void destroy_resource(void);
+extern TTF_Font *request_font(char *id, int font_size);
+extern void release_font(void *font);
+extern SDL_Surface *request_image(char *id, int flags);
+extern void release_image(void *image);
+extern Mix_Chunk *request_wav(char *id);
+extern void release_wav(void *wav);
+extern Mix_Music *request_mp3(char *id);
+extern void release_mp3(void *mp3);
+extern void play_effect(void);
+extern void play_effect_fpr(void);
+
+/* fingerprint.cpp */
+extern int fpr_init(void);
+extern void fpr_deinit(void);
+extern int fpr_open(void);
+extern int fpr_close(void);
+extern int fpr_get_ver(u32 *ver);
+extern int fpr_enroll_start(u32 uid);
+extern int fpr_enroll_1(void);
+extern int fpr_enroll_2(void);
+extern int fpr_enroll_3(void);
+extern int fpr_find_free_area(void);
+extern int fpr_delete_user(u32 uid);
+extern int fpr_check_press_finger(u32 *state);
+extern int fpr_identify(u32 *match_id);
+extern int fpr_capture_finger(u32 timeout);
+extern int fpr_capture_cancel(void);
+
+/* finger_intf.cpp */
+extern s32 fpr_get_cancel_flag(void);
+extern void fpr_set_cancel_flag(void);
+extern s32 fpr_get_busy_flag(void);
+extern u32 fpr_get_result(void);
+extern s32 fpr_get_error_flag(void);
+extern s32 fpr_module_init(void);
+extern void fpr_module_deinit(void);
+extern void fpr_module_trigger(s32 ops);
+
+/* sgi_form_manage.cpp */
+extern s32 app_loop(SDL_Surface *screen);
+extern void sgi_form_show(struct sgi_form *form);
+
+/* sgi_data.cpp */
+extern void *open_w(const char *name, size_t *size);
+extern void close_w(void *ptr, size_t size);
+extern void *open_r(const char *name, size_t *size);
+extern void close_r(void *ptr, size_t size);
+extern s32 data_flush(void *ptr, size_t size);
+extern s32 data_open(void);
+extern s32 search_uid(struct passport_data *pass, s32 type, u32 param);
+extern s32 search_mid(struct passport_data *pass, s32 type, u32 param);
+extern s32 verify_user_pwd(struct passport_data *pass, u16 *uid, u16 *pwd);
+extern s32 verify_manager_pwd(struct passport_data *pass, u16 *uid, u16 *pwd);
+extern s32 change_pwd(u16 *uid, u16 *old_pwd, u16 *new_pwd);
+extern struct person_data *get_person_reg_data(void);
+extern void person_reg_data_clear(void);
+extern s32 register_person(struct person_data_mem *person);
+extern s32 register_gun(struct gun_data *gun);
+extern s32 register_box(struct box_data *box);
+extern s32 register_unit(struct unit_data *unit);
+extern struct box_info *get_box_info(void);
+extern struct unit_data *get_unit_info(void);
+extern s32 enroll_borrow(struct passport_data *pass, u32 *cells);
+extern s32 enroll_return(struct passport_data *pass, u32 *cells);
+extern u16 *get_box_code(void);
+extern u32 get_log_no(enum sgi_log_type type);
+extern s32 search_borrow_info(struct passport_data *pass);
+extern s32 load_person_data(void);
+extern u8 *get_return_info(u16 *uid);
+extern s32 get_lock_list(void);
+extern void set_lock_list(s32 addr);
+extern s32 update_person(struct person_data_mem *data);
+extern struct gun_data *get_gun_reg_data(void);
+extern s32 delete_person(struct person_data_mem *data);
+extern s32 update_gun(struct gun_data *gun);
+extern s32 delete_gun(struct gun_data *data);
+extern s32 copy_file(char *out, char *in);
+
+/* sgi_log.cpp */
+extern void record_alarm_log(wchar_t *content);
+extern void record_alarm_log(u16 *content);
+extern void record_manager_log(u16 *name, wchar_t *content);
+extern void record_system_log(u16 *name, wchar_t *content);
+extern void record_borrow_log(struct passport_data *pass, 
+       struct box_info *info);
+extern void record_return_log(struct passport_data *pass, 
+       struct box_info *info);
+extern void recorcd_borrow_report(struct passport_data *pass, int type, 
+       int nums);
+extern void recorcd_return_report(struct passport_data *pass, int type, 
+       int nums);
+extern void mark_to_alarm_file(u32 id);
+extern void mark_to_system_file(u32 id);
+extern void mark_to_manager_file(u32 id);
+extern void mark_to_report_file(u32 id, s32 type);
+extern void mark_to_borrow_file(u32 id, s32 type);
+
+/* i2c comm */
+extern s32 i2c_comm_lock(u8 addr);
+extern s32 i2c_comm_unlock(u8 addr);
+extern s32 i2c_comm_cancel_alarm(u8 addr);
+extern s32 i2c_comm_update_state(u8 addr);
+extern s32 i2c_comm_read_state(u8 addr, u8 *state);
+
+/* control board */
+extern s32 mfcard_module_open(void);
+extern void mfcard_module_close(void);
+extern int alarm_ctrl(int on_off);
+extern int power_ctrl(int on_off);
+extern int fpr_press_detect(void);
+extern int card_start(void);
+extern int card_state(void);
+extern int get_card_id(void);
+extern s32 door_ctrl(s32 flag);
+extern s32 get_door_fb(void);
+extern s32 get_pw_jc(void);
+extern s32 get_qwz1(void);
+extern s32 get_qwz2(void);
+
+/* monitor */
+extern void monitor_init(void);
+extern void monitor(void);
+extern void pause_lock_monitor(void);
+extern void resume_lock_monitor(void);
+extern void pause_all_monitor(void);
+extern void resume_all_monitor(void);
+//extern void cancel_lock_alarm(void);
+extern void cancel_alarm(void);
+extern void authorize_open_door(void);
+extern void borrow_vector_add(struct passport_data *pass);
+extern void borrow_vector_remove(struct passport_data *pass,
+       struct borrow_ctrl *pcont,
+       u32 count);
+extern u16 *get_current_alarm_info(s32 *flash);
+extern void pwd_alarm(void);
+extern void setup_alarm(s32 flags);
+extern s32 get_alarm_setting(void);
+extern s32 get_power_status(void);
+extern s32 get_net_status(void);
+
+/* udisk.cpp */
+extern s32 udisk_remove_detect(void);
+extern s32 udisk_insert_detect(struct udisk_info *udisk);
+
+/* crc.cpp */
+extern u32 crc32_calc(u8 *src, s32 bytes);
+
+/* net.cpp */
+extern s32 net_module_init(void);
+extern void net_module_deinit(void);
+extern s32 get_net_link_status(void);
+extern s32 get_time_adjust_status(void);
+extern void net_monitor(void);
+extern void create_heartbeat_packet(void);
+extern void create_time_adjust_packet(void);
+extern void create_data_packet(u8 cmd, void *data, s32 len);
+
+#endif
\ No newline at end of file
diff --git a/src/global_macro.h b/src/global_macro.h
new file mode 100644 (file)
index 0000000..a27674b
--- /dev/null
@@ -0,0 +1,245 @@
+#ifndef GLOBAL_MACRO_H
+#define GLOBAL_MACRO_H
+
+#define TIME_AFTER(a,b)                ((long)(b) - (long)(a) < 0)
+#define TIME_BEFORE(a,b)       TIME_AFTER(b,a)
+
+#define WINDOW_CREATE(own,m,x,y,w,h,z,p1,pa,wd)                        \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_WINDOW;                                  \
+       own.window.widget = wd;                                 \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, NULL, NULL, NULL, pa);       \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+
+#define PICTURE_CREATE(own,m,x,y,w,h,z,p1,pa)                  \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_WINDOW;                                  \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, NULL, NULL, NULL, pa);       \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+
+#define PHOTO_CREATE(own,m,x,y,w,h,z)                          \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_PHOTO;                                   \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+       
+#define BUTTON_CREATE(own,m,x,y,w,h,z,p1,p2,p3,p4,pa)          \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_BUTTON;                                  \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, p2, p3, p4, pa);             \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)                                                    
+
+#define LABEL_CREATE(own,m,x,y,w,h,z,f,s,c)                    \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_LABEL;                                   \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_font(&own, f, s, c);                         \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+
+#define EDIT_CREATE(own,m,x,y,w,h,z,f,s,c,p1,pa,l)             \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_EDIT;                                    \
+       own.edit.word_max = l;                                  \
+       own.edit.handle = request_handle();                     \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, NULL, NULL, NULL, pa);       \
+       set_object_font(&own, f, s, c);                         \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+
+#define BOX_CREATE(own,m,x,y,w,h,z,f,s,cl,p1,p2,p3,p4,pa,c)    \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_BOX;                                     \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, p2, p3, p4, pa);             \
+       set_object_font(&own, f, s, cl);                        \
+       memcpy(&own.box.cell, &c, sizeof(c));                   \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+
+#define GRID_CREATE(own,m,x,y,w,h,z,f,s,cl,p1,p2,pa)           \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_GRID;                                    \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, p2, NULL, NULL, pa);         \
+       set_object_font(&own, f, s, cl);                        \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+
+#define RADIO_CREATE(own,m,x,y,w,h,z,p1,p2,pa)                         \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_RADIO;                                   \
+       own.radio.handle = request_handle();                    \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, p2, NULL, NULL, pa);         \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0) 
+
+#define CHECK_CREATE(own,m,x,y,w,h,z,p1,p2,pa)                         \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_CHECK;                                   \
+       own.check.handle = request_handle();                    \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, p2, NULL, NULL, pa);         \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0) 
+
+#define UPDOWN_CREATE(own,m,x,y,w,h,z,_tw,f,s,c,p1,p2,pa)      \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_UPDOWN;                                  \
+       own.updown.handle = request_handle();                   \
+       own.updown.tw = _tw;                                    \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, p2, NULL, NULL, pa);         \
+       set_object_font(&own, f, s, c);                         \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+
+
+#define DRAWGRID_CREATE(own,m,x,y,w,h,z,f,s,c,p1,p2,pa)                \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_DRAWGRID;                                \
+       own.check.handle = request_handle();                    \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, p2, NULL, NULL, pa);         \
+       set_object_font(&own, f, s, c);                         \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0)
+
+#define INDICATOR_CREATE(own,m,x,y,w,h,z,p1,p2,pa)             \
+do {                                                           \
+       memset(&own, 0, sizeof(own));                           \
+       own.type = SGI_INDICATOR;                               \
+       set_object_pos(&own, x, y, w, h, z);                    \
+       set_object_parent(&own, &m);                            \
+       set_object_image(&own, p1, p2, NULL, NULL, pa);         \
+       set_object_default_func(&own);                          \
+       m.form.push_back(&own);                                 \
+} while (0) 
+
+#define DRAWGRID_MATRIX(own,r,rh,c,cols)                       \
+do {                                                           \
+       own.row = r;                                            \
+       own.col = c;                                            \
+       own.rowh = rh;                                          \
+       memcpy(own.cols, cols, sizeof(cols));                   \
+} while (0)                            
+
+#define FORM_CREATE(own,w)                                     \
+do {                                                           \
+       own.wnd = &(w.window);                                  \
+       own.redraw = 1;                                         \
+       set_object_default_func(&own);                          \
+} while (0)
+
+#define FORM_MODULE_RAW(name)                                  \
+struct sgi_form g_##name
+
+#define FORM_CLASS_RAW(name)                                   \
+g_##name
+
+#define FORM_NAME_RAW(name)                                    \
+#name
+
+#define FORM_CREATE_FN_RAW(name)                               \
+s32 name##_create(void)
+
+#define FORM_DESTROY_FN_RAW(name)                              \
+void name##_destroy(void)
+
+#define FORM_MODULE(name)                                      \
+FORM_MODULE_RAW(name)
+
+#define FORM_CLASS(name)                                       \
+FORM_CLASS_RAW(name)
+
+#define FORM_NAME(name)                                                \
+FORM_NAME_RAW(name)
+
+#define FORM_CREATE_FN(name)                                   \
+FORM_CREATE_FN_RAW(name)
+
+#define FORM_DESTROY_FN(name)                                  \
+FORM_DESTROY_FN_RAW(name)
+
+#define FORM_LIST_ITEM(name)                                   \
+{&g_##name, name##_create, name##_destroy, 0}  
+
+#define FORM_DECLARE(name)                                     \
+extern FORM_MODULE(name);                                      \
+extern FORM_CREATE_FN(name);                                   \
+extern FORM_DESTROY_FN(name);                  
+
+#define IME_KEY(x,y,w,h)                                       \
+{0,0,x,y,w,h}
+
+#define CELL(x,y,w,h)                                          \
+{0,0,x,y,w,h}
+
+#define REAL_PHOTO(s)                                          \
+"/sdcard/log/photo/"#s".png"
+
+#define DATA_FILE(s)                                           \
+"/sdcard/data/"#s".db"
+
+#define DBD(s)                                                 \
+"/sdcard/data/"#s".db"
+
+#define DBR(s)                                                 \
+"/sdcard/data/"#s".db"
+
+#define DBL(s)                                                 \
+"/sdcard/log/"#s".db"
+
+#define DBT(s)                                                 \
+"/usr/app/"#s".db"
+
+#define DTC(s)                                                 \
+"/sdcard/"#s
+
+#endif
+
diff --git a/src/lock.h b/src/lock.h
new file mode 100644 (file)
index 0000000..78c4f8c
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef LOCK_H
+#define LOCK_H
+
+#include <pthread.h>
+
+class lock_t
+{
+public:
+       lock_t()        
+       {
+               pthread_mutexattr_t attr;
+               
+               pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+               pthread_mutex_init(&m_mutex, &attr);
+       }
+       
+       ~lock_t()       {pthread_mutex_destroy(&m_mutex);}
+       int lock()      {return pthread_mutex_lock(&m_mutex);}
+       int unlock()    {return pthread_mutex_unlock(&m_mutex);}                
+       
+private:
+       pthread_mutex_t m_mutex;        
+       
+};
+
+#endif
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644 (file)
index 0000000..6d39ca4
--- /dev/null
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <signal.h>
+#include "global_func.h"
+
+/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
+static void quit(int rc)
+{
+       SDL_Quit();
+       exit(rc);
+}
+
+int main(int argc, char **argv)
+{
+       SDL_Surface *screen;
+       sigset_t set;
+       
+       /* set system env */
+       putenv("SDL_MOUSEDRV=TSLIB");
+       putenv("SDL_MOUSEDEV=/dev/input/event1");
+       
+       /* mask all signal */
+       sigfillset(&set);
+       if (pthread_sigmask(SIG_SETMASK, &set, NULL) != 0) {
+               printf("pthread_sigmask error!\n");
+       }
+
+       /* Initialize SDL */
+       if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) {
+               fprintf(stderr,
+                       "Couldn't initialize SDL: %s\n", SDL_GetError());
+               return(1);
+       }
+       
+       /* Initialize the display, always use hardware palette */
+       screen = SDL_SetVideoMode(800, 480, 32, SDL_SWSURFACE);
+       if ( screen == NULL ) {
+               fprintf(stderr, "Couldn't set %dx%d video mode: %s\n",
+                       800, 600, SDL_GetError());
+               quit(1);
+       }
+       
+       /* Set the window manager title bar */
+       SDL_ShowCursor(0);
+       SDL_WM_SetCaption("Firearm Manage v1.0", NULL);
+       
+       /* Initialize resource(image,font,sound) */
+       if (initialize_resource(screen) != 0) {
+               destroy_resource();
+               printf("initialize_resource fail.\n");
+               quit(1);        
+       }
+       
+       /* fingerprint module open */
+       if (fpr_module_init() != 0) {
+               printf("fpr_module_init fail.\n");
+               quit(1);        
+       }
+       printf("fpr_module_init ok.\n");
+       
+       mfcard_module_open();
+       
+       /* data module init */
+       if (data_open() != 0) {
+               printf("data init fail.\n");    
+       }
+       
+       /* realtime monitor */
+       monitor_init();
+       
+       /* net */
+       net_module_init();
+       
+       /* main loop */
+       //sgi_form_show(&g_fm_main);
+       sgi_form_show(&g_fm_safecheck);
+       app_loop(screen);       
+
+       /* 程序完蛋 */
+       fpr_module_deinit();
+       net_module_deinit();
+       mfcard_module_close();
+       
+       /* release all resource */
+       destroy_resource();
+       SDL_Quit();
+       
+       printf("all success.\n");
+       
+       return 0;
+}
diff --git a/src/monitor.cpp b/src/monitor.cpp
new file mode 100644 (file)
index 0000000..ca0fa5d
--- /dev/null
@@ -0,0 +1,724 @@
+#include "global_func.h"
+
+static volatile s32 s_lock_monitor_pause = 0;
+static s32 s_lock_monitor_step = 0;
+static u32 s_current_alarm = 0;
+
+struct monitor_control {
+       s32 enable;
+       s32 alarm;
+       u32 cycle;
+       u32 next_time;
+};
+
+struct alarm_control {
+       s16 type;
+       s16 flash;
+       time_t time;
+       u16 content[32];
+       u32 lock_addr;
+       u16 uid[16];
+       time_t return_time;
+};
+
+struct lock_monitor {
+       s32 enable;
+       s32 pause;
+       s32 process;
+       u32 cycle;
+       u32 next_time;
+};
+
+struct door_moinitor {
+       s32 enable;
+       s32 ex_enable;
+       s32 pause;
+       s32 authorize;
+       u32 validity;
+       s32 count;
+       s32 process;
+       u32 cycle;
+       u32 next_time;
+};
+
+struct power_monitor {
+       s32 enable;
+       s32 pause;
+       s32 count;
+       s32 process;
+       u32 cycle;
+       u32 next_time;
+};
+
+struct borrow_monitor {
+       s32 enable;
+       u32 cycle;
+};
+
+struct borrow_detail {
+       s32 process;
+       u32 next_time;
+       u16 uid[16];
+       time_t return_time;     
+};
+
+
+static struct monitor_control s_monitor_control;
+static struct door_moinitor s_door_monitor;
+static struct lock_monitor s_lock_monitor;
+static struct power_monitor s_power_monitor;
+static struct borrow_monitor s_borrow_monitor; 
+
+static s32 s_pwd_monitor_enable = 1;
+
+static s32 s_power_status = POWER_AC;
+
+static std::vector <struct alarm_control > s_alarm_vec;
+static std::vector <struct borrow_detail > s_borrow_vec;
+
+static void monitor_lock(void)
+{
+       s32 i;
+       s32 index = s_lock_monitor_step;
+       s32 found = 0;  
+       u32 current = SDL_GetTicks();
+       
+       if (!s_lock_monitor.enable
+               || s_lock_monitor.pause
+               || TIME_BEFORE(current, s_lock_monitor.cycle)
+               || TIME_BEFORE(current, s_lock_monitor.next_time)
+               || s_lock_monitor.process) {
+               return; 
+       }
+       s_lock_monitor.cycle = SDL_GetTicks() + 1000;
+       
+       struct box_info *info = get_box_info();
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if ((info[index].state & 3) == 1) {
+                       found = 1;
+                       break;                  
+               }
+               index = (index + 1) % BOX_NUMS;                 
+       }
+       
+       s_lock_monitor_step = (index + 1) % BOX_NUMS;
+       
+       if (!found) {           
+               return;         
+       }
+       
+       if (!s_door_monitor.authorize) {
+               s32 lock = get_lock_list();
+               if (lock > 0) {
+                       printf("lock: %d\n", lock);
+                       i2c_comm_lock(lock);
+                       return;                 
+               }       
+       }               
+       
+       /* */
+       if (i2c_comm_update_state(g_box_addr[index]) != 0) {
+               return; 
+       }
+
+       /* */
+       u8 state[4] = {0};
+       SDL_Delay(5);
+       if (i2c_comm_read_state(g_box_addr[index], state) != 0) {
+               return; 
+       }
+       printf("lock state: %d\n", state[0]);
+       
+       if (state[0] & 0x80) { /* force unlock */
+               struct alarm_control data;
+               memset(&data, 0, sizeof(struct alarm_control));
+               data.type = FORCE_UNLOCK;
+               data.flash = 1;
+               data.lock_addr = g_box_addr[index];
+               time(&data.time);
+               sgi_sprintf16(data.content, L"枪锁[%03d]被强行打开!", g_box_addr[index]);
+               s_alarm_vec.push_back(data);
+               
+               /* log */
+               record_alarm_log(data.content);
+               
+               /* */
+               s_current_alarm = s_alarm_vec.size() - 1;
+
+               s_lock_monitor.process = 1;                     
+       }
+       else if ((state[0] & 1) == 0) {
+               if (s_door_monitor.authorize) {
+                       return; 
+               }       
+               
+               struct alarm_control data;
+               memset(&data, 0, sizeof(struct alarm_control));
+               data.type = FORCE_UNLOCK;
+               data.flash = 1;
+               data.lock_addr = g_box_addr[index];
+               time(&data.time);
+               sgi_sprintf16(data.content, L"枪锁[%03d]未锁好!", g_box_addr[index]);
+               s_alarm_vec.push_back(data);
+               
+               /* log */
+               record_alarm_log(data.content);
+               
+               /* */
+               s_current_alarm = s_alarm_vec.size() - 1;
+
+               s_lock_monitor.process = 1;
+       }
+}
+
+static void monitor_door(void)
+{
+       s32 state;
+       s32 qwz = 0;
+       s32 s;
+       u32 current = SDL_GetTicks();
+       
+       if (!s_door_monitor.enable 
+               || TIME_BEFORE(current, s_door_monitor.cycle)) {
+               return; 
+       }
+       s_door_monitor.cycle = SDL_GetTicks() + 1000;
+       
+       state = get_door_fb();
+       if (state == -1) {
+               return;
+       }
+       
+       if (s_door_monitor.pause) {
+               if (state) {
+                       s_door_monitor.next_time = SDL_GetTicks();
+                       s_door_monitor.pause = 0;
+               }
+               else {
+                       if (TIME_BEFORE(current, s_door_monitor.next_time)) {
+                               return;
+                       }
+                       else {
+                               s_door_monitor.next_time = SDL_GetTicks();
+                               s_door_monitor.pause = 0;       
+                       }
+               }       
+       }
+       
+       if (s_door_monitor.authorize) {
+               if (TIME_AFTER(current, s_door_monitor.validity)) {
+                       s_door_monitor.authorize = 0;   
+               }       
+       }
+       
+       if (s_door_monitor.ex_enable) {
+               s = get_qwz2();
+               if (s == -1) {
+                       return;
+               }
+               qwz |= (s & 1) << 1;
+               
+               s = get_qwz1();
+               if (s == -1) {
+                       return;
+               }
+               qwz |= s & 1;
+       }
+       else {
+               qwz = 3;
+       }
+       
+       //printf("authorize2: %d\n", s_door_monitor.authorize);
+       if (!state || (qwz & 3) != 3) {
+               if (!s_door_monitor.authorize && !s_door_monitor.process) {
+                       s_door_monitor.count++;
+                       if (s_door_monitor.count < DOOR_MON_COUNT) {
+                               return; 
+                       }
+                       
+                       struct alarm_control data;
+                       memset(&data, 0, sizeof(struct alarm_control));
+                       data.type = FORCE_OPEN_DOOR;
+                       data.flash = 1;
+                       time(&data.time);
+                       sgi_cpw2u(data.content, L"枪柜门异常开启!");
+                       s_alarm_vec.push_back(data);
+                       
+                       /* log */
+                       record_alarm_log(data.content);
+                       
+                       /* */
+                       s_current_alarm = s_alarm_vec.size() - 1;       
+                       
+                       s_door_monitor.process = 1;                     
+               }       
+       }
+       else {
+               if (s_door_monitor.authorize) {
+                       if (state && (qwz & 3) == 3) {
+                               s_door_monitor.authorize = 0;
+                               s_door_monitor.process = 0;
+                               s_door_monitor.count = 0;
+                       }       
+               }       
+       }               
+#if 0
+       printf("door fb: %d\n", get_door_fb()); 
+       printf("pw jc: %d\n", get_pw_jc());     
+       printf("qwz1: %d\n", get_qwz1());       
+       printf("qwz2: %d\n", get_qwz2());
+#endif 
+}
+
+void monitor_power(void)
+{
+       u32 current = SDL_GetTicks();
+       s32 s;
+       
+       if (!s_power_monitor.enable
+               || TIME_BEFORE(current, s_power_monitor.cycle)) {
+               return;
+       }       
+       s_power_monitor.cycle = SDL_GetTicks() + 1000;
+        
+       s = get_pw_jc();
+       if (s == -1) {
+               return;
+       }
+       
+       /* 取消报警期间监视市电有无恢复 */
+       if (s_power_monitor.pause) {
+               if (s) {
+                       s_power_monitor.pause = 0;
+                       s_power_monitor.next_time = SDL_GetTicks();
+               }
+               else {  
+                       if (TIME_BEFORE(current, s_power_monitor.next_time)) {
+                               return;
+                       }
+                       else {
+                               s_power_monitor.pause = 0;
+                               s_power_monitor.next_time = SDL_GetTicks();
+                       }       
+               }               
+       }
+       
+       if (!s) {
+               s_power_status = POWER_BATTERY;
+               if (!s_power_monitor.process) {
+                       s_power_monitor.count++;
+                       if (s_power_monitor.count < POWER_MON_COUNT) {
+                               return; 
+                       }
+                       
+                       struct alarm_control data;
+                       memset(&data, 0, sizeof(struct alarm_control));
+                       data.type = POWER_LOST;
+                       data.flash = 1;
+                       time(&data.time);
+                       sgi_cpw2u(data.content, L"市电供电异常!");
+                       s_alarm_vec.push_back(data);
+                       
+                       /* log */
+                       record_alarm_log(data.content);
+                       
+                       /* */
+                       s_current_alarm = s_alarm_vec.size() - 1;       
+                       
+                       s_power_monitor.process = 1;
+               }                                               
+       }
+       else {
+               s_power_status = POWER_AC;      
+       }               
+}
+
+static void monitor_borrow(void)
+{
+       u32 current = SDL_GetTicks();
+       u32 i;
+       wchar_t buf[16] = {0};
+       time_t real_time;
+       
+       if (!s_borrow_monitor.enable
+               || TIME_BEFORE(current, s_borrow_monitor.cycle)) {
+               return;
+       }
+       s_borrow_monitor.cycle = SDL_GetTicks() + 60000;
+       
+       time(&real_time);
+       for (i = 0; i < s_borrow_vec.size(); ++i) {
+               if (s_borrow_vec[i].process
+                       || TIME_BEFORE(current, s_borrow_vec[i].next_time)) {
+                       continue;       
+               }
+               
+               if (real_time > s_borrow_vec[i].return_time) {
+                       struct alarm_control data;
+                       memset(&data, 0, sizeof(struct alarm_control));
+                       data.type = BORROW_TIMEOUT;
+                       data.flash = 1;
+                       time(&data.time);
+                       sgi_cpu2w(buf, s_borrow_vec[i].uid);
+                       sgi_sprintf16(data.content, L"用户 [%ls] 用枪超时!", buf);
+                       sgi_cp16(data.uid, s_borrow_vec[i].uid);
+                       data.return_time = s_borrow_vec[i].return_time;
+                       s_alarm_vec.push_back(data);
+                       
+                       /* log */
+                       record_alarm_log(data.content);
+                       
+                       /* */
+                       s_current_alarm = s_alarm_vec.size() - 1;
+                       
+                       s_borrow_vec[i].process = 1;                    
+               }               
+       }               
+}
+
+static void cancel_door_alarm(void)
+{
+       s_door_monitor.next_time = SDL_GetTicks() + REMIT_TIME;
+       s_door_monitor.authorize = 0;
+       s_door_monitor.process = 0;
+       s_door_monitor.count = 0;
+       s_power_monitor.pause = 1;      
+}
+
+static void cancel_power_alarm(void)
+{
+       s_power_monitor.next_time = SDL_GetTicks() + POWER_REMIT_TIME;
+       s_power_monitor.process = 0;
+       s_power_monitor.count = 0;
+       s_power_monitor.pause = 1;      
+}
+
+static void cancel_lock_alarm(u32 addr)
+{
+       i2c_comm_cancel_alarm(addr);
+       s_lock_monitor.next_time = SDL_GetTicks() + REMIT_TIME;
+       s_lock_monitor.process = 0;     
+}
+
+static void cancel_borrow_alarm(void)
+{
+       u32 i;
+       
+       for (i = 0; i < s_borrow_vec.size(); ++i) {
+               if (!s_borrow_vec[i].process) {
+                       continue;
+               }
+               
+               s_borrow_vec[i].next_time = SDL_GetTicks() + BORROW_REMIT_TIME;
+               s_borrow_vec[i].process = 0;
+       }       
+}
+
+static void borrow_vector_init(void)
+{
+       u32 i;
+       u32 size;
+       struct borrow_detail detail;
+
+       /*  */
+       s_borrow_vec.clear();
+       struct borrow_ctrl *pcont;
+       struct borrow_ctrl *p;
+       pcont = (struct borrow_ctrl *)open_r(DBR(borrow), &size);
+       if (pcont == NULL) {
+               return;
+       }
+       
+       p = pcont;
+       for (i = 0; i < size / sizeof(struct borrow_ctrl); ++i) {
+               if (p->cells[0] || p->cells[1] || p->cells[2] || p->cells[3]) {
+                       memset(&detail, 0, sizeof(struct borrow_detail));
+                       sgi_cp16(detail.uid, p->uid);
+                       detail.return_time = p->return_time;
+                       s_borrow_vec.push_back(detail); 
+               }       
+               p++;    
+       }
+       
+       /* 关闭 */
+       close_r(pcont, size);           
+}
+
+void monitor_init(void)
+{
+       memset(&s_monitor_control, 0, sizeof(s_monitor_control));
+       memset(&s_door_monitor, 0, sizeof(s_door_monitor));
+       memset(&s_power_monitor, 0, sizeof(s_power_monitor));
+       memset(&s_borrow_monitor, 0, sizeof(s_borrow_monitor)); 
+       
+       s_monitor_control.enable = 1;
+       s_door_monitor.enable = 1;
+       s_door_monitor.ex_enable = 1;
+       s_power_monitor.enable = 1;
+       s_borrow_monitor.enable = 1;
+       
+       s_alarm_vec.clear();
+       borrow_vector_init();
+}
+
+void monitor(void)
+{
+       if (!s_monitor_control.enable) {
+               return; 
+       }
+       
+       monitor_door();
+       monitor_lock();
+       monitor_power();
+       monitor_borrow();
+       
+       if (s_alarm_vec.size() == 0) {
+               return;                 
+       }
+       
+       if (!s_monitor_control.alarm) {
+               sgi_form_show(&FORM_CLASS(fm_alarm));
+               s_monitor_control.alarm = 1;            
+       }               
+}
+
+void cancel_alarm(void)
+{
+       u32 i;
+       
+       for (i = 0; i < s_alarm_vec.size(); ++i) {
+               switch (s_alarm_vec[i].type) {
+               case FORCE_OPEN_DOOR:
+                       cancel_door_alarm();
+                       break;
+                       
+               case FORCE_UNLOCK:
+                       cancel_lock_alarm(s_alarm_vec[i].lock_addr);
+                       break;
+                       
+               case POWER_LOST:
+                       cancel_power_alarm();
+                       break;                  
+               case BORROW_TIMEOUT:
+                       cancel_borrow_alarm();
+                       break;
+                       
+               default:
+                       break;
+               }               
+       }
+       
+       alarm_ctrl(ALARM_OFF);
+       
+       s_alarm_vec.clear();
+       s_monitor_control.alarm = 0;
+}
+
+void pause_lock_monitor(void)
+{
+       //__sync_lock_test_and_set(&s_lock_monitor_pause, 1);
+       s_lock_monitor.enable = 0;      
+}
+
+void resume_lock_monitor(void)
+{
+       //__sync_lock_test_and_set(&s_lock_monitor_pause, 0);
+       s_lock_monitor.enable = 1;              
+}
+
+void pause_all_monitor(void)
+{
+       s_monitor_control.enable = 0;
+}
+
+void resume_all_monitor(void)
+{
+       s_monitor_control.enable = 1;
+}
+
+void authorize_open_door(void)
+{
+       s_door_monitor.authorize = 1;
+       s_door_monitor.validity = SDL_GetTicks() + AUTHORIZE_TIME;
+       
+       door_ctrl(DOOR_OPEN);
+       SDL_Delay(500);
+       door_ctrl(DOOR_CLOSE);  
+}
+
+void borrow_vector_add(struct passport_data *pass)
+{
+       struct borrow_detail detail;
+               
+       memset(&detail, 0, sizeof(struct borrow_detail));
+       sgi_cp16(detail.uid, pass->uid);
+       detail.return_time = pass->return_time;
+       s_borrow_vec.push_back(detail); 
+}
+
+void borrow_vector_remove(struct passport_data *pass,
+       struct borrow_ctrl *pcont,
+       u32 count)
+{
+       u32 i,j;
+       s32 remove;
+       s32 change = 0;
+       struct borrow_ctrl *p;
+       std::vector <struct borrow_detail > temp_vec;
+
+       /* */
+       temp_vec.clear();
+       for (i = 0; i < s_borrow_vec.size(); ++i) {
+               if (sgi_ncmp16(s_borrow_vec[i].uid, pass->uid,
+                       COUNTOF(pass->uid)) != 0) {
+                       continue;
+               }
+               
+               p = pcont;
+               remove = 0;
+               for (j = 0; j < count; ++j) {
+                       if (sgi_ncmp16(s_borrow_vec[i].uid, p->uid,
+                               COUNTOF(pass->uid)) == 0
+                               && s_borrow_vec[i].return_time == p->return_time
+                               && p->cells[0] == 0
+                               && p->cells[1] == 0
+                               && p->cells[2] == 0
+                               && p->cells[3] == 0) {
+                               
+                               /* remove this */
+                               remove = 1;
+                               change = 0;
+                       }
+                       p++;                            
+               }
+               
+               if (!remove) {
+                       temp_vec.push_back(s_borrow_vec[i]);
+               }       
+       }
+       
+       if (change) {
+               s_borrow_vec.clear();
+               s_borrow_vec = temp_vec;
+               temp_vec.clear();
+       }
+}
+
+u16 *get_current_alarm_info(s32 *flash)
+{
+       u16 *content;
+       
+       if (s_alarm_vec.empty()) {
+               return NULL;
+       }
+       
+       s_current_alarm %= s_alarm_vec.size();
+       printf("alarm: %d, %d, %d\n", s_alarm_vec.size(), s_current_alarm, 
+               s_alarm_vec[s_current_alarm].type);
+       
+       *flash = s_alarm_vec[s_current_alarm].flash;
+       content = s_alarm_vec[s_current_alarm].content;
+       s_current_alarm++;
+       
+       return content; 
+}
+
+void pwd_alarm(void)
+{
+       if (!s_pwd_monitor_enable) {
+               return;
+       }
+       
+       struct alarm_control data;
+       memset(&data, 0, sizeof(struct alarm_control));
+       data.type = PWD_ERROR;
+       time(&data.time);
+       sgi_cpw2u(data.content, L"连续三次输入错误密码!");
+       s_alarm_vec.push_back(data);    
+}
+
+void setup_alarm(s32 flags)
+{
+       if (flags & ALARM_DOOR_EN) {
+               s_door_monitor.enable = 1;              
+       }
+       else {
+               s_door_monitor.enable = 0;      
+       }
+       
+       if (flags & ALARM_DOOR_EX_EN) {
+               s_door_monitor.ex_enable = 1;   
+       }
+       else {
+               s_door_monitor.ex_enable = 0;
+       }
+       
+       if (flags & ALARM_LOCK_EN) {
+               s_lock_monitor.pause = 0;
+       }
+       else {
+               s_lock_monitor.pause = 1;
+       }
+       
+       if (flags & ALARM_POWER_EN) {
+               s_power_monitor.enable = 1;     
+       }
+       else {
+               s_power_monitor.enable = 0;
+       }
+       
+       if (flags & ALARM_BORROW_EN) {
+               s_borrow_monitor.enable = 1;    
+       }
+       else {
+               s_borrow_monitor.enable = 0;
+       }
+       
+       if (flags & ALARM_PWD_EN) {
+               s_pwd_monitor_enable = 1;       
+       }
+       else {
+               s_pwd_monitor_enable = 0;
+       }               
+}
+
+s32 get_alarm_setting(void)
+{
+       s32 flags = 0;
+       
+       if (s_door_monitor.enable) {
+               flags |= ALARM_DOOR_EN;
+       }
+       
+       if (s_door_monitor.ex_enable) {
+               flags |= ALARM_DOOR_EX_EN;
+       }
+       
+       if (!s_lock_monitor.pause) {
+               flags |= ALARM_LOCK_EN;
+       }
+       
+       if (s_power_monitor.enable) {
+               flags |= ALARM_POWER_EN;
+       }
+       
+       if (s_borrow_monitor.enable) {
+               flags |= ALARM_BORROW_EN;
+       }
+       
+       if (s_pwd_monitor_enable) {
+               flags |= ALARM_PWD_EN;
+       }
+       
+       return flags;   
+}
+
+s32 get_power_status(void)
+{
+       return get_pw_jc() ? POWER_AC : POWER_BATTERY;  
+}
+
+s32 get_net_status(void)
+{
+       return 0;       
+}
\ No newline at end of file
diff --git a/src/net.cpp b/src/net.cpp
new file mode 100644 (file)
index 0000000..e22ead4
--- /dev/null
@@ -0,0 +1,800 @@
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include "global_func.h"
+
+#define SKIP_WS(s)                     \
+do {                                   \
+       while (isspace(*s) && s++);     \
+} while (0)
+
+#define FIND_QT(s)                     \
+do {                                   \
+       while (*s != '=' && s++);       \
+       s++;                            \
+} while (0)    
+
+struct packet_head_t {
+       u32 magic;
+       u32 crc;
+       u8 cmd;
+       u8 sp[3];
+       u32 params;
+       u16 len;
+       u16 checksum;
+       u8 data[0];
+};
+
+union packet_t {
+       struct packet_head_t head;
+       u8 data[512];
+};
+
+static std::deque <packet_t *> s_idle_deq;
+static std::deque <packet_t *> s_work_deq;
+static u32 s_pool_total_nums = 0;
+static lock_t s_pool_lock;
+static pthread_t s_work_thread;
+static pthread_t s_test_thread;
+static char s_server_ip[32] = SERVER_IP;
+static int s_server_port = SERVER_PORT;
+
+static u32 s_net_monitor_cycle = 0;
+static u32 s_net_link_cycle = 0;
+static u32 s_time_adjust_cycle = 0;
+static volatile u32 s_net_down_cycle = 0;
+static volatile s32 s_net_link_status = 0;
+static volatile s32 s_time_adjust_status = 0;
+static volatile s32 s_thread_exit = 0;
+
+void get_net_config(void)
+{
+       char buf[1024];
+       
+       FILE *fp = fopen(DTC(net-cfg.txt), "r");
+       if (fp == NULL) {
+               return;
+       }
+       
+       while (fgets(buf, sizeof(buf), fp)) {
+               char *p = buf;
+               
+               SKIP_WS(p);
+               if (strncmp(p, "ip", 2) == 0) {
+                       FIND_QT(p);
+                       SKIP_WS(p);
+                       char *p1 = strtok(p, "\n");
+                       strncpy(s_server_ip, p1, sizeof(s_server_ip));                  
+               }
+               else if (strncmp(p, "port", 4) == 0) {
+                       FIND_QT(p);
+                       SKIP_WS(p);
+                       char *p1 = strtok(p, "\n");
+                       s_server_port = atoi(p1);       
+               }               
+       }
+       
+       fclose(fp);             
+}
+
+void net_pool_init(void)
+{
+       s32 i;
+       union packet_t *p;
+       
+       s_pool_total_nums = 0;
+       s_idle_deq.clear();
+       s_work_deq.clear();
+       
+       /* */
+       for (i = 0; i < POOL_INIT_NUMS; ++i) {
+               p = (union packet_t *)calloc(1, sizeof(union packet_t));
+               if (!p) {
+                       return; 
+               }
+               
+               s_pool_total_nums++;
+               s_idle_deq.push_back(p);        
+       }       
+}
+
+void net_pool_deinit(void)
+{
+       u32 i;
+       
+       for (i = 0; i < s_work_deq.size(); ++i) {
+               free(s_work_deq[i]);    
+       }
+       
+       for (i = 0; i < s_idle_deq.size(); ++i) {
+               free(s_idle_deq[i]);
+       }
+       
+       s_work_deq.clear();
+       s_idle_deq.clear();     
+}
+
+void net_pool_realloc(void)
+{
+       s32 i;
+       union packet_t *p;
+       
+       if (s_pool_total_nums > POOL_MAX_NUMS) {
+               return;
+       }
+       
+       for (i = 0; i < POOL_REALLOC_NUMS; ++i) {
+               p = (union packet_t *)calloc(1, sizeof(union packet_t));
+               if (!p) {
+                       return; 
+               }
+               
+               s_pool_total_nums++;
+               s_idle_deq.push_back(p);        
+       }               
+}
+
+void insert_to_idle_deque(union packet_t *packet)
+{
+       s_pool_lock.lock();
+       s_idle_deq.push_back(packet);
+       s_pool_lock.unlock();           
+}
+
+void insert_to_work_deque(union packet_t *packet)
+{
+       s_pool_lock.lock();
+       s_work_deq.push_back(packet);
+       s_pool_lock.unlock();
+}
+
+void push_top_to_work_deque(union packet_t *packet)
+{
+       s_pool_lock.lock();
+       s_work_deq.push_front(packet);
+       s_pool_lock.unlock();
+}
+
+union packet_t *get_from_idle_deque(void)
+{
+       union packet_t *p = NULL;
+       
+       s_pool_lock.lock();
+       if (s_idle_deq.empty()) {
+               net_pool_realloc();             
+       }
+       
+       if (!s_idle_deq.empty()) {
+               p = s_idle_deq.front();
+               s_idle_deq.pop_front();
+       };
+       s_pool_lock.unlock();
+       
+       return p;       
+}
+
+union packet_t *get_from_work_deque(void)
+{
+       union packet_t *p = NULL;
+       
+       s_pool_lock.lock();
+       if (!s_work_deq.empty()) {
+               p = s_work_deq.front();
+               s_work_deq.pop_front();
+       };
+       s_pool_lock.unlock();
+       
+       return p;       
+}
+
+u32 get_work_deque_count(void)
+{
+       u32 t;
+       
+       s_pool_lock.lock();
+       t = s_work_deq.size();
+       s_pool_lock.unlock();
+       
+       return t;                       
+}
+
+void fill_random(u8 *dst, int len)
+{
+       while (len-- > 0) {
+               *dst++ = rand() & 0xff;
+       }
+}
+
+u16 calc_cks(const u8 *src, int len)
+{
+       u16 cks = 0;
+       
+       while (len-- > 0) {
+               cks += *src++;
+       }
+       
+       return cks;     
+}
+
+void mark_to_file(union packet_t *packet)
+{
+       u32 id;
+       
+       switch (packet->head.cmd) {
+       case CMD_DATA_ALARM:
+               id = ((struct log_alarm *)(packet->data))->id;
+               mark_to_alarm_file(id);         
+               break;
+               
+       case CMD_DATA_REPORT_BORROW:
+               id = ((struct log_report *)(packet->data))->id;         
+               mark_to_report_file(id, CMD_DATA_REPORT_BORROW);                        
+               break;
+               
+       case CMD_DATA_REPORT_RETURN:
+               id = ((struct log_report *)(packet->data))->id;
+               mark_to_report_file(id, CMD_DATA_REPORT_RETURN);        
+               break;
+               
+       case CMD_DATA_BORROW:
+               id = ((struct log_borrow *)(packet->data))->id;         
+               mark_to_borrow_file(id, CMD_DATA_BORROW);                               
+               break;
+               
+       case CMD_DATA_RETURN:
+               id = ((struct log_borrow *)(packet->data))->id;
+               mark_to_borrow_file(id, CMD_DATA_RETURN);               
+               break;
+               
+       case CMD_DATA_SYSTEM:
+               id = ((struct log_system *)(packet->data))->id;         
+               mark_to_system_file(id);                        
+               break;
+               
+       case CMD_DATA_MANAGER:
+               id = ((struct log_manager *)(packet->data))->id;                
+               mark_to_system_file(id);                                
+               break;
+               
+       default:
+               break;
+       }                       
+}
+
+s32 apply_packet(union packet_t *packet)
+{
+       switch (packet->head.cmd) {
+       case CMD_TIME_ADJUST:
+               struct tm *remote;
+               
+               remote = localtime((time_t *)&packet->head.params);
+               printf("%d-%02d-%02d %02d:%02d:%02d\n", 
+                       remote->tm_year + 1900, remote->tm_mon + 1, 
+                       remote->tm_mday, remote->tm_hour, remote->tm_min,
+                       remote->tm_sec);
+               
+               /* adjust time */       
+               if (stime((time_t *)&(packet->head.params)) == 0) {
+                       /* 写入RTC */
+                       system("hwclock --systohc");
+                       
+                       __sync_lock_test_and_set(&s_time_adjust_status, 1);
+               }       
+               break;
+               
+       case CMD_HEARTBEAT:
+               __sync_lock_test_and_set(&s_net_link_status, 1);
+               __sync_lock_test_and_set(&s_net_down_cycle, SDL_GetTicks());
+               break;
+               
+       default:
+               //mark_to_file(packet);
+               break;
+       }
+       
+       return 0;       
+}
+
+SOCKET async_connect(const char *ip, int port)
+{
+       struct sockaddr_in server;
+       int flags;
+       struct timeval tv = {5, 0};
+       SOCKET s = -1;
+
+       s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+       if(s == -1) {
+               goto err;
+       }
+       
+       /* 将连接设置为异步模式 */
+       if ((flags = fcntl(s, F_GETFL, 0)) < 0) {
+               goto err;
+       }
+       if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
+               goto err;
+       }
+
+       /* 服务器参数 */
+       memset(&server, 0, sizeof(server));
+       server.sin_family = AF_INET;
+       server.sin_port = htons(port);
+       server.sin_addr.s_addr = inet_addr(ip);
+
+       /* 连接至服务器 */        
+       if (connect(s, (struct sockaddr*)&server, sizeof(server))) {
+               //printf("errno: %d, %d\n", s, errno);
+               if (errno != EINPROGRESS) {
+                       goto err;
+               }
+               
+               /* 连接超时检测 */
+               fd_set rfds;
+               fd_set wfds;
+               FD_ZERO(&rfds);
+               FD_ZERO(&wfds);
+               FD_SET(s, &rfds);
+               FD_SET(s, &wfds);
+               if (select(s + 1, &rfds,&wfds, NULL, &tv) <= 0) {
+                       //printf("-----timeout-----\n");
+                       goto err;
+               }
+               
+               if (FD_ISSET(s, &rfds) && FD_ISSET(s, &wfds)) {
+                       printf("connect fail\n");
+                       goto err;
+               }
+                
+               if (!FD_ISSET(s, &wfds)) {
+                       printf("invalid socket: %d\n", s);
+                       goto err;
+               }                                               
+       }       
+       
+       /* 将连接设置为同步模式 */
+       if ((flags = fcntl(s, F_GETFL, 0)) < 0) {
+               goto err;
+       }
+       if (fcntl(s, F_SETFL, flags & ~O_NONBLOCK) < 0) {
+               goto err;
+       }
+
+       /* 设定发送及接收超时时间 */
+       tv.tv_sec = 2;
+       setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
+       setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
+  
+       return s;
+       
+err:
+       if (s != -1) {
+               close(s);
+       }
+       
+       return -1;
+}
+
+int transmit(union packet_t *tx, union packet_t *rx)
+{
+       SOCKET s;
+       s32 len;
+       
+       if ((s = async_connect(s_server_ip, s_server_port)) == -1) {
+               return -1;
+       }
+       //printf("async connect: %d\n", s);
+       
+       len = sizeof(struct packet_head_t) + tx->head.len;
+       if (send(s, (char *)tx, len, MSG_NOSIGNAL) < len) {
+               close(s);
+               return -1;
+       }
+
+       len = sizeof(struct packet_head_t);
+       if (recv(s, (char *)rx, len, MSG_NOSIGNAL) < len) {
+               close(s);
+               perror("recv fail: ");
+               return -1;
+       }
+       
+       u16 cks = calc_cks(rx->data, len - sizeof(u16));
+       if (rx->head.magic != NET_MAGIC || cks != rx->head.checksum) {
+               close(s);
+               printf("invalid response packet\n");
+               return -1;
+       } 
+       
+       printf("rx type: %d, 0x%x\n", rx->head.cmd, rx->head.magic);
+       
+       apply_packet(rx);
+
+       close(s);   
+       
+       return 0;
+
+}
+
+static void *work_proc(void *arg)
+{
+       union packet_t *tx;
+       union packet_t rx;
+       int err = 0;
+       
+       for (;__sync_fetch_and_or(&s_thread_exit, 0) == 0;) {
+               tx = get_from_work_deque();
+               if (tx) {
+                       bzero(&rx, sizeof(union packet_t));
+                       if (transmit(tx, &rx) == 0) {
+                               insert_to_idle_deque(tx);
+                               err = 0;        
+                       }
+                       else {
+                               switch (tx->head.cmd) {
+                               case CMD_HEARTBEAT:
+                               case CMD_TIME_ADJUST:
+                                       insert_to_idle_deque(tx);
+                                       break;
+                                       
+                               default:
+                                       insert_to_work_deque(tx);
+                                       break;
+                               }
+                               
+                               err++;
+                               if (err == 3) {
+                                       __sync_lock_release(&s_net_link_status);        
+                               }       
+                       }                       
+               }
+       
+               SDL_Delay(1000);        
+       }
+       
+       return NULL;    
+}
+
+void create_data_packet(u8 cmd, void *data, s32 len)
+{
+       union packet_t *p;
+       u16 *code;
+       
+       if (len > (s32)(sizeof(union packet_t) 
+               - sizeof(struct packet_head_t)
+               - BOX_CODE_LEN)) {
+               return;
+       }
+       
+       p = get_from_idle_deque();
+       if (!p) {
+               return;
+       }
+       
+       code = get_box_code();
+       
+       bzero(p, sizeof(union packet_t));
+       p->head.magic = NET_MAGIC;
+       p->head.cmd = cmd;
+       p->head.len = len;
+       memcpy(p->head.data, data, p->head.len);
+       memcpy(p->head.data + p->head.len, code, BOX_CODE_LEN);
+       p->head.len += BOX_CODE_LEN;
+       p->head.crc = crc32_calc(p->head.data, p->head.len);    
+       p->head.checksum = calc_cks((u8 *)p, sizeof(struct packet_head_t) 
+               - sizeof(u16));
+       
+       insert_to_work_deque(p);                
+}
+
+static void create_cmd_packet(u8 cmd)
+{
+       union packet_t *p;
+       
+       p = get_from_idle_deque();
+       if (!p) {
+               return;
+       }
+       
+       bzero(p, sizeof(union packet_t));
+       p->head.magic = NET_MAGIC;
+       p->head.cmd = cmd;      
+       p->head.checksum = calc_cks((u8 *)p, sizeof(struct packet_head_t) 
+               - sizeof(u16));
+       
+       //insert_to_work_deque(p);
+       push_top_to_work_deque(p);      
+}
+
+void create_heartbeat_packet(void)
+{
+       create_cmd_packet(CMD_HEARTBEAT);       
+}
+
+void create_time_adjust_packet(void)
+{      
+       __sync_lock_release(&s_time_adjust_status);
+       create_cmd_packet(CMD_TIME_ADJUST);     
+}
+
+#if 0
+static void *test_proc(void *arg)
+{
+       union packet_t *p;
+       int count;
+       
+       for (;;) {
+               if ((count = get_work_deque_count()) < 5) {
+                       p = get_from_idle_deque();
+                       if (!p) {
+                               continue;
+                       }
+                       
+                       #if 1
+                       //printf("fill work deque: %d\n", count);
+                       bzero(p, sizeof(union packet_t));
+                       p->head.magic = NET_MAGIC;
+                       if ((rand() % 10) == 0) {
+                               p->head.cmd = CMD_TIME_ADJUST;  
+                       }
+                       else
+                               p->head.cmd = 1;
+                       
+                       //p->head.len = rand() % (sizeof(union packet_t) - sizeof(struct packet_head_t));
+                       //fill_random(p->head.data, p->head.len);
+                       //p->head.crc = crc32_calc(p->head.data, (int)p->head.len);
+                       //p->head.params = 0;
+                       p->head.checksum = calc_cks((u8 *)p, sizeof(struct packet_head_t) - 2);
+                       
+                       insert_to_work_deque(p);
+                       #endif
+                       //create_heartbeat_packet();            
+               }
+               
+               usleep(10000);  
+       }       
+}
+#endif
+
+static void collect_from_file(void)
+{
+       u32 i;
+       size_t size;
+       void *pcont;
+       
+       /* alarm */
+       pcont = sgi_log_open(DBL(alarm), &size);
+       if (pcont) {
+               struct log_alarm *p = (struct log_alarm *)pcont;
+               for (i = 0; i < size / sizeof(struct log_alarm); ++i) {
+                       if (p->up) {
+                               continue;
+                       }
+                       
+                       create_data_packet(CMD_DATA_ALARM, p, 
+                               sizeof(struct log_alarm)); 
+                       
+                       p++;    
+               }
+               
+               sgi_log_close(pcont, size);             
+       }
+       
+       /* report borrow */
+       pcont = sgi_log_open(DBL(report-borrow), &size);
+       if (pcont) {
+               struct log_report *p = (struct log_report *)pcont;
+               for (i = 0; i < size / sizeof(struct log_report); ++i) {
+                       if (p->up) {
+                               continue;
+                       }
+                       
+                       create_data_packet(CMD_DATA_REPORT_BORROW, p, 
+                               sizeof(struct log_report)); 
+                       
+                       p++;    
+               }
+               
+               sgi_log_close(pcont, size);             
+       }
+       
+       /* report return */
+       pcont = sgi_log_open(DBL(report-back), &size);
+       if (pcont) {
+               struct log_report *p = (struct log_report *)pcont;
+               for (i = 0; i < size / sizeof(struct log_report); ++i) {
+                       if (p->up) {
+                               continue;
+                       }
+                       
+                       create_data_packet(CMD_DATA_REPORT_RETURN, p, 
+                               sizeof(struct log_report)); 
+                       
+                       p++;    
+               }
+               
+               sgi_log_close(pcont, size);             
+       }       
+       
+       /* borrow */
+       pcont = sgi_log_open(DBL(borrow), &size);
+       if (pcont) {
+               struct log_borrow *p = (struct log_borrow *)pcont;
+               for (i = 0; i < size / sizeof(struct log_borrow); ++i) {
+                       if (p->up) {
+                               continue;
+                       }
+                       
+                       create_data_packet(CMD_DATA_BORROW, p, 
+                               sizeof(struct log_borrow)); 
+                       
+                       p++;    
+               }
+               
+               sgi_log_close(pcont, size);             
+       }
+       
+       /* return */
+       pcont = sgi_log_open(DBL(back), &size);
+       if (pcont) {
+               struct log_borrow *p = (struct log_borrow *)pcont;
+               for (i = 0; i < size / sizeof(struct log_borrow); ++i) {
+                       if (p->up) {
+                               continue;
+                       }
+                       
+                       create_data_packet(CMD_DATA_RETURN, p, 
+                               sizeof(struct log_borrow)); 
+                       
+                       p++;    
+               }
+               
+               sgi_log_close(pcont, size);             
+       }
+       
+       /* system */
+       pcont = sgi_log_open(DBL(syslog), &size);
+       if (pcont) {
+               struct log_system *p = (struct log_system *)pcont;
+               for (i = 0; i < size / sizeof(struct log_system); ++i) {
+                       if (p->up) {
+                               continue;
+                       }
+                       
+                       create_data_packet(CMD_DATA_SYSTEM, p, 
+                               sizeof(struct log_system)); 
+                       
+                       p++;    
+               }
+               
+               sgi_log_close(pcont, size);             
+       }
+       
+       /* manager */
+       pcont = sgi_log_open(DBL(manager), &size);
+       if (pcont) {
+               struct log_manager *p = (struct log_manager *)pcont;
+               for (i = 0; i < size / sizeof(struct log_manager); ++i) {
+                       if (p->up) {
+                               continue;
+                       }
+                       
+                       create_data_packet(CMD_DATA_SYSTEM, p, 
+                               sizeof(struct log_manager)); 
+                       
+                       p++;    
+               }
+               
+               sgi_log_close(pcont, size);             
+       }       
+}
+
+s32 net_module_init(void)
+{
+       s32 ret;
+       
+       get_net_config();
+       
+       printf("ip: %s, port: %d\n", s_server_ip, s_server_port);
+       
+       net_pool_init();
+       
+       collect_from_file();
+       
+       printf("work deque: %d\n", get_work_deque_count());
+       
+       ret = pthread_create(&s_work_thread, NULL, work_proc, NULL);
+       if (ret) {
+               return -1;
+       }
+       
+#if 0
+       ret = pthread_create(&s_test_thread, NULL, test_proc, NULL);
+       if (ret) {
+               return -1;
+       }
+#endif
+       
+       return 0;       
+}
+
+void net_module_deinit(void)
+{
+       __sync_lock_test_and_set(&s_thread_exit, 1);
+       pthread_join(s_work_thread, NULL);
+       //pthread_join(s_test_thread, NULL);    
+}
+
+void net_monitor(void)
+{
+       u32 current = SDL_GetTicks();
+       
+       if (TIME_BEFORE(current, s_net_monitor_cycle)) {
+               return;
+       }
+       s_net_monitor_cycle = SDL_GetTicks() + NET_MONITOR_CYCLE;
+       
+       /* */
+       u32 cycle = __sync_fetch_and_or(&s_net_down_cycle, 0) + NET_DOWN_CYCLE; 
+       if (TIME_AFTER(current, cycle)) {
+               __sync_lock_release(&s_net_link_status);                
+       }
+        
+       /* */
+       if (TIME_AFTER(current, s_net_link_cycle)) {
+               s_net_link_cycle = SDL_GetTicks() + NET_LINK_CYCLE;
+               create_heartbeat_packet();
+       }
+
+       /* */
+       if (TIME_AFTER(current, s_time_adjust_cycle)) {
+               s_time_adjust_cycle = SDL_GetTicks() + TIME_ADJUST_CYCLE;
+               create_time_adjust_packet();    
+       }               
+}
+
+s32 get_net_link_status(void)
+{
+       return __sync_fetch_and_or(&s_net_link_status, 0);
+}
+
+s32 get_time_adjust_status(void)
+{
+       return __sync_fetch_and_or(&s_time_adjust_status, 0);
+}
+
+
+#if 0
+ #include <signal.h>
+int main(int argc, char **argv)
+{
+       s32 success = 0;
+       s32 err = 0;
+       
+       sigset_t set;
+       sigfillset(&set);
+       if (pthread_sigmask(SIG_SETMASK, &set, NULL) != 0) {
+               printf("pthread_sigmask error!\n");
+       }
+       
+       if (net_module_init() == 0) {
+               printf("net module setup success\n");
+       }
+       else {
+               printf("net module setup fail\n");
+       }
+       for(;;) {
+               //create_heartbeat_packet();
+               SDL_Delay(1000);
+       }
+       
+       net_module_deinit();
+       
+       return 0;       
+}
+#endif
+
diff --git a/src/pinyin.cpp b/src/pinyin.cpp
new file mode 100755 (executable)
index 0000000..805b084
--- /dev/null
@@ -0,0 +1,1079 @@
+#include "global_func.h"       
+
+struct _PyIndexType {
+       wchar_t *syllables;
+       u16 *final;
+}; 
+
+/* code table */
+wchar_t _PyMa_a    [] = L"阿啊呵爱安";
+wchar_t _PyMa_ai   [] = L"哎爱唉碍哀埃挨矮蔼皑癌艾隘暧呆";
+wchar_t _PyMa_an   [] = L"安按暗岸案氨鞍俺胺";
+wchar_t _PyMa_aang [] = L"肮昂盎";
+wchar_t _PyMa_aao  [] = L"奥澳傲懊熬袄凹敖翱";
+                        
+wchar_t _PyMa_b    [] = L"不把吧爸必";
+wchar_t _PyMa_ba   [] = L"八吧把爸罢扒拔霸巴叭芭疤捌笆跋靶坝";
+wchar_t _PyMa_bai  [] = L"白百佰柏摆败拜稗";
+wchar_t _PyMa_ban  [] = L"扳班办半般搬板伴拌绊版斑扮颁瓣";
+wchar_t _PyMa_bang [] = L"邦帮梆绑榜膀蚌傍棒谤磅镑";
+wchar_t _PyMa_bao  [] = L"包宝饱报抱保苞胞褒雹堡豹鲍暴爆剥薄瀑";
+wchar_t _PyMa_bei  [] = L"被北倍杯备背卑悲碑贝狈钡惫焙辈";
+wchar_t _PyMa_ben  [] = L"本奔苯笨夯";
+wchar_t _PyMa_beng [] = L"崩绷甭迸蹦泵";
+wchar_t _PyMa_bi   [] = L"必毕闭鼻比彼笔币避鄙逼庇毖陛毙敝痹蓖弊碧蔽壁臂";
+wchar_t _PyMa_bian [] = L"边编鞭贬扁卞便变遍辨辩辫";
+wchar_t _PyMa_biao [] = L"彪标膘表";
+wchar_t _PyMa_bie  [] = L"憋鳖别瘪";
+wchar_t _PyMa_bin  [] = L"宾斌彬滨鬓濒摈";
+wchar_t _PyMa_bing [] = L"冰丙并病秉柄炳饼兵";
+wchar_t _PyMa_bo   [] = L"拨波玻钵脖菠播伯驳帛泊勃铂舶博渤搏箔膊卜";
+wchar_t _PyMa_bu   [] = L"不补哺捕布步怖部埠簿";
+                        
+wchar_t _PyMa_c    [] = L"才吃此差错";
+wchar_t _PyMa_ca   [] = L"擦嚓";
+wchar_t _PyMa_cai  [] = L"猜才菜蔡财材裁采彩睬踩";
+wchar_t _PyMa_can  [] = L"参餐残蚕惭惨灿";
+wchar_t _PyMa_cang [] = L"仓沧苍舱藏";
+wchar_t _PyMa_cao  [] = L"曹操草嘈槽糙";
+wchar_t _PyMa_ce   [] = L"侧厕测策册恻";
+wchar_t _PyMa_ceng [] = L"层蹭曾";
+wchar_t _PyMa_ci   [] = L"此次词辞刺慈磁瓷伺祠雌赐疵茨糍";
+wchar_t _PyMa_cong [] = L"囱从匆葱聪丛";
+wchar_t _PyMa_cou  [] = L"凑";
+wchar_t _PyMa_cu   [] = L"粗促醋簇";
+wchar_t _PyMa_cuan [] = L"蹿窜篡";
+wchar_t _PyMa_cui  [] = L"崔催摧脆淬瘁粹翠";
+wchar_t _PyMa_cun  [] = L"寸村存";
+wchar_t _PyMa_cuo  [] = L"错搓磋撮挫措鹾";
+                        
+wchar_t _PyMa_d    [] = L"的地得第多";
+wchar_t _PyMa_da   [] = L"大打搭达答瘩";
+wchar_t _PyMa_dai  [] = L"呆歹傣代带待怠殆贷袋逮戴";
+wchar_t _PyMa_dan  [] = L"但单担淡耽蛋旦丹弹胆掸诞惮郸氮";
+wchar_t _PyMa_dang [] = L"当挡党荡档";
+wchar_t _PyMa_dao  [] = L"道到倒导盗刀岛捣稻蹈悼祷";
+wchar_t _PyMa_de   [] = L"的地得德";
+wchar_t _PyMa_deng [] = L"灯等登蹬邓凳瞪";
+wchar_t _PyMa_di   [] = L"第地弟低底抵堤滴狄迪敌涤笛嫡帝递缔蒂";
+wchar_t _PyMa_dian [] = L"点电店典掂惦甸垫淀奠颠碘佃殿滇靛";
+wchar_t _PyMa_diao [] = L"掉钓刁叼凋碉雕吊";
+wchar_t _PyMa_die  [] = L"爹跌叠蝶谍碟迭";
+wchar_t _PyMa_ding [] = L"顶定订丁钉叮盯鼎锭";
+wchar_t _PyMa_diu  [] = L"丢";
+wchar_t _PyMa_dong [] = L"动东冬懂冻洞董侗恫栋";
+wchar_t _PyMa_dou  [] = L"都豆斗抖陡逗兜痘";
+wchar_t _PyMa_du   [] = L"杜读独肚度督毒犊堵赌睹妒渡镀";
+wchar_t _PyMa_duan [] = L"端短段断缎锻";
+wchar_t _PyMa_dui  [] = L"对堆队兑";
+wchar_t _PyMa_dun  [] = L"吨敦墩蹲盾钝顿遁";
+wchar_t _PyMa_duo  [] = L"多哆夺掇朵垛躲剁堕舵惰跺";
+
+wchar_t _PyMa_e    [] = L"二饿鹅恶额俄讹娥峨蛾遏厄扼鄂";
+wchar_t _PyMa_en   [] = L"恩嗯";
+wchar_t _PyMa_er   [] = L"二儿而尔耳洱饵贰";
+
+wchar_t _PyMa_f    [] = L"发否方放法";
+wchar_t _PyMa_fa   [] = L"法发乏罚伐阀筏珐";
+wchar_t _PyMa_fan  [] = L"反饭翻烦返繁帆番藩凡矾钒樊犯泛范贩";
+wchar_t _PyMa_fang [] = L"方放坊芳防妨房肪仿访纺";
+wchar_t _PyMa_fei  [] = L"飞非啡菲费肥匪诽吠废沸肺";
+wchar_t _PyMa_fen  [] = L"分份吩纷奋愤芬氛酚坟汾焚粉忿粪";
+wchar_t _PyMa_feng [] = L"峰锋丰风枫封疯烽蜂冯逢缝讽凤奉";
+wchar_t _PyMa_fo   [] = L"佛";
+wchar_t _PyMa_fou  [] = L"否";
+wchar_t _PyMa_fu   [] = L"服复幅付夫妇赴副肤父符府附咐伏扶福敷弗拂俘氟浮涪袱辐抚甫斧俯釜辅腑腐讣负阜傅孵富赋缚腹覆";
+
+wchar_t _PyMa_g    [] = L"给该个广郭";
+wchar_t _PyMa_ga   [] = L"嘎噶尬";
+wchar_t _PyMa_gai  [] = L"该改概盖钙溉";
+wchar_t _PyMa_gan  [] = L"干甘杆柑肝赶敢感赣竿秆尴";
+wchar_t _PyMa_gang [] = L"冈刚岗纲肛缸钢港杠";
+wchar_t _PyMa_gao  [] = L"皋羔高膏篙糕搞稿镐告";
+wchar_t _PyMa_ge   [] = L"个各格哥咯胳鸽割歌革葛阁搁隔戈疙铬";
+wchar_t _PyMa_gei  [] = L"给";
+wchar_t _PyMa_gen  [] = L"根跟";
+wchar_t _PyMa_geng [] = L"更庚耕羹埂耿梗";
+wchar_t _PyMa_gong [] = L"公共工弓功攻供宫恭躬龚巩汞拱贡";
+wchar_t _PyMa_gou  [] = L"勾沟购够构钩狗苟垢";
+wchar_t _PyMa_gu   [] = L"故顾估姑古菇固咕孤沽辜箍谷股骨蛊鼓雇";
+wchar_t _PyMa_gua  [] = L"挂瓜刮剐寡褂";
+wchar_t _PyMa_guai [] = L"怪乖拐";
+wchar_t _PyMa_guan [] = L"关惯观管馆官冠棺贯灌罐";
+wchar_t _PyMa_guang[] = L"光广逛";
+wchar_t _PyMa_gui  [] = L"归规桂贵瑰闺诡跪轨癸硅龟鬼刽圭柜";
+wchar_t _PyMa_gun  [] = L"辊滚棍";
+wchar_t _PyMa_guo  [] = L"国过郭锅果裹";
+
+wchar_t _PyMa_h    [] = L"哈呵嘿和好";
+wchar_t _PyMa_ha   [] = L"哈蛤";
+wchar_t _PyMa_hai  [] = L"孩海害亥骇氦骸";
+wchar_t _PyMa_han  [] = L"汉汗韩含寒函涵捍憾撼罕喊酣憨旱悍焊翰邯";
+wchar_t _PyMa_hang [] = L"杭航行";
+wchar_t _PyMa_hao  [] = L"好号毫豪嚎壕郝浩耗";
+wchar_t _PyMa_he   [] = L"和何河喝合盒呵核贺禾阂荷涸菏褐赫鹤";
+wchar_t _PyMa_hei  [] = L"黑嘿";
+wchar_t _PyMa_hen  [] = L"很狠恨痕";
+wchar_t _PyMa_heng [] = L"哼横亨恒衡";
+wchar_t _PyMa_hong [] = L"红哄洪烘宏鸿轰虹弘";
+wchar_t _PyMa_hou  [] = L"后厚候喉猴吼侯";
+wchar_t _PyMa_hu   [] = L"乎呼忽胡护弧狐壶湖葫瑚糊蝴虎唬互户沪";
+wchar_t _PyMa_hua  [] = L"花话华化哗滑猾划画";
+wchar_t _PyMa_huai [] = L"怀坏淮徊槐";
+wchar_t _PyMa_huan [] = L"欢还环患换缓幻焕痪唤涣宦桓豢";
+wchar_t _PyMa_huang[] = L"黄荒慌皇凰惶煌蝗磺簧恍晃谎幌";
+wchar_t _PyMa_hui  [] = L"会恢回灰慧挥辉徽汇悔诲绘卉烩贿晦讳蛔秽惠毁";
+wchar_t _PyMa_hun  [] = L"昏婚混荤浑魂";
+wchar_t _PyMa_huo  [] = L"或货活火伙获祸惑霍豁";
+
+wchar_t _PyMa_j    [] = L"九今及几家";
+wchar_t _PyMa_ji   [] = L"己计记极基纪技际积继几及击急寂既寄讥饥圾机肌鸡迹姬绩缉畸箕稽激吉汲级即疾棘集嫉辑籍挤脊伎妓忌剂季济悸祭蓟冀藉";
+wchar_t _PyMa_jia  [] = L"家加夹价驾佳假嘉颊甲贾钾架嫁枷稼荚挟";
+wchar_t _PyMa_jian [] = L"见件间建简渐减奸尖坚歼肩艰兼监缄煎拣俭柬茧捡剪检硷碱饯剑荐贱健涧舰溅践笺鉴键箭";
+wchar_t _PyMa_jiang[] = L"江将浆姜讲奖降蒋匠疆桨僵酱";
+wchar_t _PyMa_jiao [] = L"交觉叫郊较教饺娇浇骄胶椒角焦蕉礁狡绞矫脚铰搅剿缴轿窖酵嚼";
+wchar_t _PyMa_jie  [] = L"阶借姐街介结节解界接皆届揭劫杰洁捷睫截竭戒秸芥疥诫";
+wchar_t _PyMa_jin  [] = L"今近进斤紧仅尽巾劲津金筋襟谨锦晋浸烬禁靳";
+wchar_t _PyMa_jing [] = L"京经净警景惊精睛竞竟敬井晶境静镜颈径痉茎靖兢鲸粳荆";
+wchar_t _PyMa_jiong[] = L"炯窘";
+wchar_t _PyMa_jiu  [] = L"九就久酒旧究舅纠救揪咎疚灸玖韭臼厩";
+wchar_t _PyMa_ju   [] = L"据句局拒距巨聚具桔菊拘剧驹居举鞠咀沮矩炬俱惧锯踞狙疽";
+wchar_t _PyMa_juan [] = L"娟捐鹃卷倦绢眷";
+wchar_t _PyMa_jue  [] = L"绝觉决抉诀倔掘爵撅攫";
+wchar_t _PyMa_jun  [] = L"军君均钧竣俊峻骏菌郡浚";
+
+wchar_t _PyMa_k    [] = L"开可快看况";
+wchar_t _PyMa_ka   [] = L"卡咖喀咔";
+wchar_t _PyMa_kai  [] = L"开揩凯慨楷忾";
+wchar_t _PyMa_kan  [] = L"看砍刊坎勘堪槛侃瞰";
+wchar_t _PyMa_kang [] = L"康慷糠扛亢抗炕伉";
+wchar_t _PyMa_kao  [] = L"靠考拷烤犒";
+wchar_t _PyMa_ke   [] = L"客科可克刻渴课棵颗壳恪咳坷苛珂柯嗑磕瞌";
+wchar_t _PyMa_ken  [] = L"肯垦恳啃";
+wchar_t _PyMa_keng [] = L"吭坑铿";
+wchar_t _PyMa_kong [] = L"空孔恐控崆倥";
+wchar_t _PyMa_kou  [] = L"口扣抠寇叩";
+wchar_t _PyMa_ku   [] = L"哭库苦裤酷枯窟骷绔";
+wchar_t _PyMa_kua  [] = L"夸垮挎胯跨";
+wchar_t _PyMa_kuai [] = L"块快侩筷会脍";
+wchar_t _PyMa_kuan [] = L"宽款";
+wchar_t _PyMa_kuang[] = L"框况狂邝矿筐旷眶诳诓匡";
+wchar_t _PyMa_kui  [] = L"亏馈窥愧盔溃奎葵魁傀岿";
+wchar_t _PyMa_kun  [] = L"坤昆捆困琨";
+wchar_t _PyMa_kuo  [] = L"扩括阔廓";
+
+wchar_t _PyMa_l    [] = L"了来拉老六";
+wchar_t _PyMa_la   [] = L"啦拉垃喇腊蜡辣";
+wchar_t _PyMa_lai  [] = L"来莱赖";
+wchar_t _PyMa_lan  [] = L"兰篮蓝懒拦栏览揽烂婪阑谰澜缆滥";
+wchar_t _PyMa_lang [] = L"郎狼廊琅榔朗浪";
+wchar_t _PyMa_lao  [] = L"老捞劳牢佬姥涝烙酪";
+wchar_t _PyMa_le   [] = L"了乐勒";
+wchar_t _PyMa_lei  [] = L"类泪累雷蕾镭磊擂肋垒儡";
+wchar_t _PyMa_leng [] = L"棱楞冷";
+wchar_t _PyMa_li   [] = L"李理里立利丽例离力莉梨粒厘漓璃黎篱礼哩鲤历厉吏励沥隶俐荔栗砾犁傈痢狸";
+wchar_t _PyMa_lian [] = L"连联脸怜练恋炼帘涟莲廉镰敛链";
+wchar_t _PyMa_liang[] = L"两俩良凉梁量亮辆谅粮粱晾";
+wchar_t _PyMa_liao [] = L"了潦辽廖疗聊僚寥撩燎镣料撂";
+wchar_t _PyMa_lie  [] = L"列劣烈猎裂咧";
+wchar_t _PyMa_lin  [] = L"林临邻淋琳霖赁凛吝拎磷鳞";
+wchar_t _PyMa_ling [] = L"另令零龄领铃伶灵岭凌菱玲陵羚";
+wchar_t _PyMa_liu  [] = L"六刘流留溜柳榴硫馏瘤琉";
+wchar_t _PyMa_long [] = L"龙笼隆聋垄窿陇拢咙";
+wchar_t _PyMa_lou  [] = L"搂楼篓陋娄漏髅";
+wchar_t _PyMa_lu   [] = L"卢录鲁陆露路庐炉颅芦鹿卤赂虏掳禄碌戮潞麓";
+wchar_t _PyMa_luan [] = L"乱孪峦挛滦卵";
+wchar_t _PyMa_lue  [] = L"略掠";
+wchar_t _PyMa_lun  [] = L"抡论轮仑伦沦纶";
+wchar_t _PyMa_luo  [] = L"罗萝洛络锣箩落骡螺逻裸骆";
+wchar_t _PyMa_lv   [] = L"率吕侣绿旅律虑滤驴铝屡缕履氯";
+
+wchar_t _PyMa_m    [] = L"妈吗嘛没们";
+wchar_t _PyMa_ma   [] = L"妈吗嘛麻马玛码蚂骂";
+wchar_t _PyMa_mai  [] = L"买卖迈麦埋脉";
+wchar_t _PyMa_man  [] = L"蛮馒瞒满曼谩慢漫蔓";
+wchar_t _PyMa_mang [] = L"忙芒盲茫莽氓";
+wchar_t _PyMa_mao  [] = L"猫毛矛茅锚卯铆茂冒贸帽貌";
+wchar_t _PyMa_me   [] = L"么";
+wchar_t _PyMa_mei  [] = L"没每妹美枚玫眉梅媒煤酶霉镁昧媚寐";
+wchar_t _PyMa_men  [] = L"们门闷懑";
+wchar_t _PyMa_meng [] = L"梦猛萌孟盟檬蒙锰";
+wchar_t _PyMa_mi   [] = L"秘密蜜米迷谜觅泌糜靡眯醚弥幂";
+wchar_t _PyMa_mian [] = L"面免勉眠绵棉娩冕缅";
+wchar_t _PyMa_miao [] = L"妙秒描苗瞄庙渺藐";
+wchar_t _PyMa_mie  [] = L"灭乜蔑";
+wchar_t _PyMa_min  [] = L"民敏皿抿闽悯玟";
+wchar_t _PyMa_ming [] = L"明名命鸣铭螟冥";
+wchar_t _PyMa_miu  [] = L"谬缪";
+wchar_t _PyMa_mo   [] = L"莫摸模默抹摩磨蘑魔寞末膜貉墨摹沫陌漠";
+wchar_t _PyMa_mou  [] = L"牟谋某眸";
+wchar_t _PyMa_mu   [] = L"母木目牡亩幕睦慕牧姆拇募墓暮穆";
+
+wchar_t _PyMa_n    [] = L"你哪那能年";
+wchar_t _PyMa_na   [] = L"哪那拿纳娜钠呐";
+wchar_t _PyMa_nai  [] = L"乃奶奈耐氖";
+wchar_t _PyMa_nan  [] = L"男南难喃楠";
+wchar_t _PyMa_nang [] = L"囊";
+wchar_t _PyMa_nao  [] = L"挠恼脑闹淖";
+wchar_t _PyMa_ne   [] = L"呢";
+wchar_t _PyMa_nei  [] = L"内那馁";
+wchar_t _PyMa_nen  [] = L"嫩恁";
+wchar_t _PyMa_neng [] = L"能";
+wchar_t _PyMa_ni   [] = L"你拟妮尼泥倪霓逆匿溺腻";
+wchar_t _PyMa_nian [] = L"年念捻拈撵碾蔫";
+wchar_t _PyMa_niang[] = L"娘酿";
+wchar_t _PyMa_niao [] = L"鸟尿";
+wchar_t _PyMa_nie  [] = L"捏聂镊涅啮镍孽";
+wchar_t _PyMa_nin  [] = L"您";
+wchar_t _PyMa_ning [] = L"宁拧狞凝柠泞";
+wchar_t _PyMa_niu  [] = L"牛扭纽钮";
+wchar_t _PyMa_nong [] = L"弄农浓脓";
+wchar_t _PyMa_nu   [] = L"怒努奴弩";
+wchar_t _PyMa_nuan [] = L"暖";
+wchar_t _PyMa_nue  [] = L"疟虐谑";
+wchar_t _PyMa_nuo  [] = L"挪诺懦糯";
+wchar_t _PyMa_nv   [] = L"女";
+
+wchar_t _PyMa_o    [] = L"哦噢";
+wchar_t _PyMa_ou   [] = L"欧殴鸥呕偶藕沤区";
+
+wchar_t _PyMa_p    [] = L"怕拼彭潘朋";
+wchar_t _PyMa_pa   [] = L"怕趴啪爬耙琶帕";
+wchar_t _PyMa_pai  [] = L"拍徘排牌派湃";
+wchar_t _PyMa_pan  [] = L"潘攀盘磐判叛盼畔";
+wchar_t _PyMa_pang [] = L"乓庞旁耪胖";
+wchar_t _PyMa_pao  [] = L"抛刨咆炮袍跑泡";
+wchar_t _PyMa_pei  [] = L"胚陪培赔佩配裴沛呸";
+wchar_t _PyMa_pen  [] = L"喷盆";
+wchar_t _PyMa_peng [] = L"彭抨朋碰砰鹏烹棚硼蓬澎篷膨捧";
+wchar_t _PyMa_pi   [] = L"皮批啤披脾疲劈霹僻譬毗琵匹辟坯痞屁砒";
+wchar_t _PyMa_pian [] = L"片偏篇骗";
+wchar_t _PyMa_piao [] = L"漂飘瓢票";
+wchar_t _PyMa_pie  [] = L"撇瞥";
+wchar_t _PyMa_pin  [] = L"拼贫频品聘";
+wchar_t _PyMa_ping [] = L"乒平评凭坪苹屏瓶萍";
+wchar_t _PyMa_po   [] = L"坡泼颇婆迫破粕魄";
+wchar_t _PyMa_pou  [] = L"剖";
+wchar_t _PyMa_pu   [] = L"扑铺仆普谱葡莆菩脯蒲朴圃埔浦曝";
+
+wchar_t _PyMa_q    [] = L"七其请去却";
+wchar_t _PyMa_qi   [] = L"七其齐气起妻企骑器岂期欺棋旗柒凄栖戚漆祁奇歧祈脐崎畦沏乞启讫迄弃汽泣契砌";
+wchar_t _PyMa_qia  [] = L"掐恰洽";
+wchar_t _PyMa_qian [] = L"千前钱欠谦签潜浅嵌歉仟扦迁钎牵铅钳乾黔遣谴堑";
+wchar_t _PyMa_qiang[] = L"强墙抢枪蔷羌腔呛";
+wchar_t _PyMa_qiao [] = L"巧悄敲瞧桥窍翘橇乔侨俏峭锹撬鞘";
+wchar_t _PyMa_qie  [] = L"切茄且怯窃";
+wchar_t _PyMa_qin  [] = L"亲侵钦芹秦琴禽勤擒寝沁";
+wchar_t _PyMa_qing [] = L"请青清情晴轻倾庆卿氰擎顷氢";
+wchar_t _PyMa_qiong[] = L"穷琼";
+wchar_t _PyMa_qiu  [] = L"求球邱秋囚泅酋丘";
+wchar_t _PyMa_qu   [] = L"去区趣取曲躯趋娶驱屈蛆渠龋";
+wchar_t _PyMa_quan [] = L"全权圈劝泉拳痊醛颧犬券";
+wchar_t _PyMa_que  [] = L"却确缺雀鹊瘸炔榷";
+wchar_t _PyMa_qun  [] = L"裙群";
+
+wchar_t _PyMa_r    [] = L"然人日如让";
+wchar_t _PyMa_ran  [] = L"然燃冉染";
+wchar_t _PyMa_rang [] = L"让嚷瓤壤攘";
+wchar_t _PyMa_rao  [] = L"饶扰绕";
+wchar_t _PyMa_re   [] = L"惹热";
+wchar_t _PyMa_ren  [] = L"人认任仁壬忍刃纫妊韧";
+wchar_t _PyMa_reng [] = L"扔仍";
+wchar_t _PyMa_ri   [] = L"日";
+wchar_t _PyMa_rong [] = L"荣容溶蓉融熔戎绒茸冗";
+wchar_t _PyMa_rou  [] = L"柔揉肉";
+wchar_t _PyMa_ru   [] = L"如入茹乳辱褥儒孺蠕汝";
+wchar_t _PyMa_ruan [] = L"软阮";
+wchar_t _PyMa_rui  [] = L"锐瑞蕊";
+wchar_t _PyMa_run  [] = L"闰润";
+wchar_t _PyMa_ruo  [] = L"若弱";
+
+wchar_t _PyMa_s    [] = L"是上三什谁";
+wchar_t _PyMa_sa   [] = L"撒洒萨";
+wchar_t _PyMa_sai  [] = L"塞腮鳃赛";
+wchar_t _PyMa_san  [] = L"三叁伞散";
+wchar_t _PyMa_sang [] = L"桑嗓丧";
+wchar_t _PyMa_sao  [] = L"搔骚扫嫂臊";
+wchar_t _PyMa_se   [] = L"色涩啬瑟";
+wchar_t _PyMa_sen  [] = L"森";
+wchar_t _PyMa_seng [] = L"僧";
+wchar_t _PyMa_si   [] = L"四司私思斯丝嘶撕死巳寺伺饲嗣肆";
+wchar_t _PyMa_song [] = L"送松怂耸讼宋诵颂嵩";
+wchar_t _PyMa_sou  [] = L"嗽搜艘擞";
+wchar_t _PyMa_su   [] = L"速诉苏酥俗肃素粟塑溯僳";
+wchar_t _PyMa_suan [] = L"酸蒜算";
+wchar_t _PyMa_sui  [] = L"虽岁随碎穗遂髓绥隋祟隧";
+wchar_t _PyMa_sun  [] = L"孙损笋";
+wchar_t _PyMa_suo  [] = L"所锁缩索唆琐梭蓑";
+
+wchar_t _PyMa_t    [] = L"她他它天太";
+wchar_t _PyMa_ta   [] = L"她他它塌塔獭挞踏蹋";
+wchar_t _PyMa_tai  [] = L"太胎台抬态泰苔汰酞";
+wchar_t _PyMa_tan  [] = L"叹探谈谭摊滩瘫贪炭毯坛坍痰潭檀坦袒碳";
+wchar_t _PyMa_tang [] = L"倘趟糖汤唐堂棠塘搪膛淌躺烫";
+wchar_t _PyMa_tao  [] = L"讨萄涛桃绦套掏滔逃陶淘";
+wchar_t _PyMa_te   [] = L"特";
+wchar_t _PyMa_teng [] = L"疼腾誊藤";
+wchar_t _PyMa_ti   [] = L"剔梯锑踢啼提题蹄体屉剃涕惕替嚏";
+wchar_t _PyMa_tian [] = L"天添田恬甜填腆舔";
+wchar_t _PyMa_tiao [] = L"调挑条迢眺跳";
+wchar_t _PyMa_tie  [] = L"贴铁帖";
+wchar_t _PyMa_ting [] = L"厅汀听烃廷亭庭停挺艇";
+wchar_t _PyMa_tong [] = L"通同彤桐铜童酮瞳统捅桶筒痛";
+wchar_t _PyMa_tou  [] = L"偷头投透";
+wchar_t _PyMa_tu   [] = L"凸秃突图徒涂途屠土吐兔";
+wchar_t _PyMa_tuan [] = L"湍团";
+wchar_t _PyMa_tui  [] = L"推颓腿退蜕褪";
+wchar_t _PyMa_tun  [] = L"囤吞屯臀";
+wchar_t _PyMa_tuo  [] = L"托拖脱驮陀驼鸵妥椭拓唾";
+
+wchar_t _PyMa_w    [] = L"我五无吴为";
+wchar_t _PyMa_wa   [] = L"哇娃挖洼蛙瓦袜";
+wchar_t _PyMa_wai  [] = L"外歪";
+wchar_t _PyMa_wan  [] = L"弯湾豌丸完玩顽烷宛挽晚婉惋皖碗万腕纨";
+wchar_t _PyMa_wang [] = L"往王网望忘汪亡枉妄旺";
+wchar_t _PyMa_wei  [] = L"为危位喂威伟唯委维味韦围谓微违魏潍慰伪尾纬苇萎卫未畏胃尉渭惟桅蔚巍韪";
+wchar_t _PyMa_wen  [] = L"文温闻问稳吻纹蚊紊瘟";
+wchar_t _PyMa_weng [] = L"翁嗡瓮";
+wchar_t _PyMa_wo   [] = L"我卧握挝涡窝蜗沃斡龌";
+wchar_t _PyMa_wu   [] = L"五午吴误无务晤武侮巫屋污诬钨毋吾芜梧伍呜乌坞捂舞勿戊物悟雾";
+
+wchar_t _PyMa_x    [] = L"下象想兴小";
+wchar_t _PyMa_xi   [] = L"西细系息熄席牺惜吸悉戏洗习喜隙媳希昔溪夕汐析矽烯硒晰犀稀嘻膝袭锡熙檄";
+wchar_t _PyMa_xia  [] = L"下吓夏虾瞎匣侠峡狭暇辖霞";
+wchar_t _PyMa_xian [] = L"现先县线限献显险鲜嫌咸纤掀锨闲弦贤涎舷衔宪陷馅仙羡腺铣";
+wchar_t _PyMa_xiang[] = L"想象相项箱向像香响乡详祥厢巷翔湘享镶橡襄";
+wchar_t _PyMa_xiao [] = L"小笑效肖消校销宵晓萧硝霄孝哮啸嚣淆";
+wchar_t _PyMa_xie  [] = L"些写谢歇械斜携鞋协卸邪胁谐泄泻屑蝎懈蟹楔";
+wchar_t _PyMa_xin  [] = L"心新薪信辛欣芯锌衅忻";
+wchar_t _PyMa_xing [] = L"行兴姓性形型刑幸星醒杏惺猩腥邢";
+wchar_t _PyMa_xiong[] = L"凶兄匈汹胸雄熊";
+wchar_t _PyMa_xiu  [] = L"休修秀绣袖羞朽锈嗅宿";
+wchar_t _PyMa_xu   [] = L"徐许须需续虚婿嘘吁绪旭序叙戌墟恤酗絮蓄";
+wchar_t _PyMa_xuan [] = L"选宣喧旋玄轩悬绚癣眩";
+wchar_t _PyMa_xue  [] = L"学雪血削穴薛靴";
+wchar_t _PyMa_xun  [] = L"讯迅寻巡旬循勋熏驯询训汛逊殉";
+
+wchar_t _PyMa_y    [] = L"一已呀也与";
+wchar_t _PyMa_ya   [] = L"亚呀压牙涯哑雅讶押崖丫鸦鸭芽蚜衙";
+wchar_t _PyMa_yan  [] = L"验言烟眼沿严掩颜淹咽燕研延岩宴艳演厌盐炎阎蜒奄彦砚唁谚焰雁衍焉堰阉";
+wchar_t _PyMa_yang [] = L"样阳杨央洋仰养秧漾扬羊佯氧痒鸯疡殃";
+wchar_t _PyMa_yao  [] = L"要钥姚摇遥药耀腰邀咬谣侥妖尧窑瑶舀";
+wchar_t _PyMa_ye   [] = L"也爷页夜冶液野业叶噎椰曳掖腋耶";
+wchar_t _PyMa_yi   [] = L"一以已亿医益谊亦依译伊衣铱壹揖仪夷沂宜姨胰移遗颐疑彝乙矣蚁倚椅义亿忆艺议亦屹异役抑译邑易绎诣疫益谊翌逸意溢肄裔毅翼臆";
+wchar_t _PyMa_yin  [] = L"因音姻银引饮阴茵印吟尹隐荫殷淫寅";
+wchar_t _PyMa_ying [] = L"应硬迎英影营映鹰盈荧莹樱婴蝇萤缨赢颖";
+wchar_t _PyMa_yo   [] = L"哟";
+wchar_t _PyMa_yong [] = L"用永拥勇咏佣泳涌恿雍臃蛹踊庸痈";
+wchar_t _PyMa_you  [] = L"又有优由邮忧幽悠右友诱犹油游酉幼佑尤釉铀";
+wchar_t _PyMa_yu   [] = L"与于欲语羽雨玉遇预鱼愈喻寓予余榆誉俞娱渔隅愉逾愚虞舆宇屿禹驭芋育郁狱峪浴域盂淤渝御裕迂豫";
+wchar_t _PyMa_yuan [] = L"元员园远圆愿原院袁冤渊援缘源怨垣猿辕苑鸳";
+wchar_t _PyMa_yue  [] = L"约月岳越阅悦跃粤曰";
+wchar_t _PyMa_yun  [] = L"云匀郧耘允陨孕运晕酝韵蕴";
+
+wchar_t _PyMa_z    [] = L"在再怎知则";
+wchar_t _PyMa_za   [] = L"匝杂砸咋";
+wchar_t _PyMa_zai  [] = L"再在灾载仔栽宰哉";
+wchar_t _PyMa_zan  [] = L"咱攒暂赞";
+wchar_t _PyMa_zang [] = L"赃脏葬藏";
+wchar_t _PyMa_zao  [] = L"早造噪燥躁澡藻遭糟皂凿枣蚤灶";
+wchar_t _PyMa_ze   [] = L"则择泽责";
+wchar_t _PyMa_zei  [] = L"贼";
+wchar_t _PyMa_zen  [] = L"怎";
+wchar_t _PyMa_zeng [] = L"增赠憎";
+wchar_t _PyMa_zi   [] = L"子自字资紫咨姿孜兹滋渍籽淄滓";
+wchar_t _PyMa_zong [] = L"总纵宗踪综棕鬃";
+wchar_t _PyMa_zou  [] = L"走邹奏揍";
+wchar_t _PyMa_zu   [] = L"足组祖租阻族卒诅";
+wchar_t _PyMa_zuan [] = L"钻赚纂";
+wchar_t _PyMa_zui  [] = L"最嘴罪醉";
+wchar_t _PyMa_zun  [] = L"尊遵";
+wchar_t _PyMa_zuo  [] = L"昨做左佐作坐座";
+wchar_t _PyMa_zz   [] = L",。!?、;:“”‘’()…#¥%【】《》『』~◎×-+÷=§";
+                        
+wchar_t _PyMa_cha   [] = L"插察查茶差叉茬搽碴岔诧刹";
+wchar_t _PyMa_chai  [] = L"拆柴差豺";
+wchar_t _PyMa_chan  [] = L"产缠掺搀谗馋蝉铲阐婵颤";
+wchar_t _PyMa_chang [] = L"长常唱厂场昌尝偿猖肠敞畅倡";
+wchar_t _PyMa_chao  [] = L"抄钞吵炒超巢朝嘲潮绰";
+wchar_t _PyMa_che   [] = L"车扯彻掣撤澈";
+wchar_t _PyMa_chen  [] = L"郴尘臣忱沉辰陈晨衬趁";
+wchar_t _PyMa_cheng [] = L"称撑成呈承诚城乘惩程澄橙逞骋秤";
+wchar_t _PyMa_chi   [] = L"吃痴弛池驰迟持尺侈齿耻斥赤炽翅";
+wchar_t _PyMa_chong [] = L"重充冲虫崇宠铳";
+wchar_t _PyMa_chou  [] = L"抽仇绸畴愁稠筹酬踌丑瞅臭";
+wchar_t _PyMa_chu   [] = L"处出初除厨楚触锄础雏橱躇储搐矗畜滁";
+wchar_t _PyMa_chuai [] = L"揣踹";
+wchar_t _PyMa_chuan [] = L"穿传串船川椽喘";
+wchar_t _PyMa_chuang[] = L"闯窗床创疮";
+wchar_t _PyMa_chui  [] = L"吹炊垂捶锤陲";
+wchar_t _PyMa_chun  [] = L"春椿纯唇淳醇蠢";
+wchar_t _PyMa_chuo  [] = L"戳绰辍";
+wchar_t _PyMa_sha   [] = L"杀沙纱砂莎傻啥煞厦";
+wchar_t _PyMa_shai  [] = L"筛晒";
+wchar_t _PyMa_shan  [] = L"山衫闪陕删杉珊煽汕苫扇善缮擅膳赡栅";
+wchar_t _PyMa_shang [] = L"上尚伤商墒裳晌赏";
+wchar_t _PyMa_shao  [] = L"少捎梢烧稍勺芍韶邵绍哨";
+wchar_t _PyMa_she   [] = L"设社舌蛇舍射涉奢赊赦慑摄";
+wchar_t _PyMa_shen  [] = L"什深神申伸身婶肾甚呻绅娠砷沈审渗慎";
+wchar_t _PyMa_sheng [] = L"生升省声胜盛剩牲甥绳圣";
+wchar_t _PyMa_shi   [] = L"是十时似事式试实使示始市失释视适驶室师识史诗匙石拾世仕侍虱施狮湿蚀食矢屎士氏势饰恃拭尸柿逝嗜誓噬";
+wchar_t _PyMa_shou  [] = L"收手守首寿受兽售授瘦";
+wchar_t _PyMa_shu   [] = L"书数熟暑树束输术述抒叔舒枢殊属梳恕竖淑疏蔬孰赎黍署鼠蜀薯曙戍庶墅漱";
+wchar_t _PyMa_shua  [] = L"刷耍唰";
+wchar_t _PyMa_shuai [] = L"摔帅率衰甩";
+wchar_t _PyMa_shuan [] = L"拴栓涮";
+wchar_t _PyMa_shuang[] = L"双霜爽孀";
+wchar_t _PyMa_shui  [] = L"谁水税睡说";
+wchar_t _PyMa_shun  [] = L"吮顺舜瞬";
+wchar_t _PyMa_shuo  [] = L"说烁朔硕";
+wchar_t _PyMa_zha   [] = L"诈炸榨扎喳渣札眨轧闸铡乍柞";
+wchar_t _PyMa_zhai  [] = L"摘宅债寨斋翟窄";
+wchar_t _PyMa_zhan  [] = L"展站战沾绽湛粘毡盏斩崭辗占栈詹瞻蘸";
+wchar_t _PyMa_zhang [] = L"长张章彰漳樟涨掌丈仗帐杖胀账障瘴";
+wchar_t _PyMa_zhao  [] = L"招昭找沼召兆赵照罩肇爪";
+wchar_t _PyMa_zhe   [] = L"这者着浙遮哲折蛰辙锗蔗";
+wchar_t _PyMa_zhen  [] = L"真针阵振镇诊侦珍枕帧斟震贞疹砧甄臻";
+wchar_t _PyMa_zheng [] = L"正政整争证郑征挣睁拯蒸怔症狰";
+wchar_t _PyMa_zhi   [] = L"之知支只止址至志直值置质智汁芝吱枝织肢脂蜘执侄职植殖旨纸指趾制帜治炙峙挚秩致掷痔窒滞稚";
+wchar_t _PyMa_zhong [] = L"中众重钟忠衷终种肿仲盅";
+wchar_t _PyMa_zhou  [] = L"州周皱粥洲昼轴肘帚咒宙诌舟骤";
+wchar_t _PyMa_zhu   [] = L"住助⒅熳V髦碇胫裰曛橹鹬钪蛑糁笾鲋踔ぶ镏�";
+wchar_t _PyMa_zhua  [] = L"抓";
+wchar_t _PyMa_zhuai [] = L"拽";
+wchar_t _PyMa_zhuan [] = L"专砖转撰篆";
+wchar_t _PyMa_zhuang[] = L"妆庄桩装壮状幢撞";
+wchar_t _PyMa_zhui  [] = L"追椎锥坠缀赘";
+wchar_t _PyMa_zhun  [] = L"谆准";
+wchar_t _PyMa_zhuo  [] = L"捉桌浊卓拙灼茁酌啄琢";
+
+u16 _YunMu_none[4] = {0};
+u16 _YunMu_a   [4] = {'a'};
+u16 _YunMu_o   [4] = {'o'};
+u16 _YunMu_e   [4] = {'e'};
+u16 _YunMu_ai  [4] = {'a','i'};
+u16 _YunMu_ou  [4] = {'o','u'};
+u16 _YunMu_ei  [4] = {'e','i'};
+u16 _YunMu_ao  [4] = {'a','o'};
+u16 _YunMu_an  [4] = {'a','n'};
+u16 _YunMu_en  [4] = {'e','n'};
+u16 _YunMu_ang [4] = {'a','n','g'};
+u16 _YunMu_eng [4] = {'e','n','g'};
+u16 _YunMu_ong [4] = {'o','n','g'};
+u16 _YunMu_i   [4] = {'i'};
+u16 _YunMu_ia  [4] = {'i','a'};
+u16 _YunMu_ie  [4] = {'i','e'};
+u16 _YunMu_iao [4] = {'i','a','o'};
+u16 _YunMu_iu  [4] = {'i','u'};
+u16 _YunMu_ian [4] = {'i','a','n'};
+u16 _YunMu_in  [4] = {'i','n'};
+u16 _YunMu_iang[4] = {'i','a','n','g'};
+u16 _YunMu_ing [4] = {'i','n','g'};
+u16 _YunMu_iong[4] = {'i','o','n','g'};
+u16 _YunMu_u   [4] = {'u'};
+u16 _YunMu_ua  [4] = {'u','a'};
+u16 _YunMu_ue  [4] = {'u','e'};
+u16 _YunMu_uo  [4] = {'u','o'};
+u16 _YunMu_uai [4] = {'u','a','i'};
+u16 _YunMu_ui  [4] = {'u','i'};
+u16 _YunMu_uan [4] = {'u','a','n'};
+u16 _YunMu_uang[4] = {'u','a','n','g'};
+u16 _YunMu_un  [4] = {'u','n'};
+u16 _YunMu_r   [4] = {'r'};
+u16 _YunMu_v   [4] = {'v'};
+u16 _YunMu_n   [4] = {'n'};
+u16 _YunMu_ng  [4] = {'n','g'};
+u16 _YunMu_z   [4] = {'z'};
+
+struct _PyIndexType PyIndex_a[] = {                                                  
+        {_PyMa_a    ,_YunMu_none},
+        {_PyMa_ai   ,_YunMu_i   },
+        {_PyMa_an   ,_YunMu_n   },
+        {_PyMa_aang ,_YunMu_ang },
+        {_PyMa_aao  ,_YunMu_ao  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_b[] = {
+        {_PyMa_b    ,_YunMu_none},
+        {_PyMa_ba   ,_YunMu_a   },
+        {_PyMa_bai  ,_YunMu_ai  },
+        {_PyMa_ban  ,_YunMu_an  },
+        {_PyMa_bang ,_YunMu_ang },
+        {_PyMa_bao  ,_YunMu_ao  },
+        {_PyMa_bei  ,_YunMu_ei  },
+        {_PyMa_ben  ,_YunMu_en  },
+        {_PyMa_beng ,_YunMu_eng },
+        {_PyMa_bi   ,_YunMu_i   },
+        {_PyMa_bian ,_YunMu_ian },
+        {_PyMa_biao ,_YunMu_iao },
+        {_PyMa_bie  ,_YunMu_ie  },
+        {_PyMa_bin  ,_YunMu_in  },
+        {_PyMa_bing ,_YunMu_ing },
+        {_PyMa_bo   ,_YunMu_o   },
+        {_PyMa_bu   ,_YunMu_u   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_c[] = {
+        {_PyMa_c    ,_YunMu_none},
+        {_PyMa_ca   ,_YunMu_a   },
+        {_PyMa_cai  ,_YunMu_ai  },
+        {_PyMa_can  ,_YunMu_an  },
+        {_PyMa_cang ,_YunMu_ang },
+        {_PyMa_cao  ,_YunMu_ao  },
+        {_PyMa_ce   ,_YunMu_e   },
+        {_PyMa_ceng ,_YunMu_eng },
+        {_PyMa_ci   ,_YunMu_i   },
+        {_PyMa_cong ,_YunMu_ong },
+        {_PyMa_cou  ,_YunMu_ou  },
+        {_PyMa_cu   ,_YunMu_u   },
+        {_PyMa_cuan ,_YunMu_uan },
+        {_PyMa_cui  ,_YunMu_ui  },
+        {_PyMa_cun  ,_YunMu_un  },
+        {_PyMa_cuo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_d[] = {
+        {_PyMa_d    ,_YunMu_none},
+        {_PyMa_da   ,_YunMu_a   },
+        {_PyMa_dai  ,_YunMu_ai  },
+        {_PyMa_dan  ,_YunMu_an  },
+        {_PyMa_dang ,_YunMu_ang },
+        {_PyMa_dao  ,_YunMu_ao  },
+        {_PyMa_de   ,_YunMu_e   },
+        {_PyMa_deng ,_YunMu_eng },
+        {_PyMa_di   ,_YunMu_i   },
+        {_PyMa_dian ,_YunMu_ian },
+        {_PyMa_diao ,_YunMu_iao },
+        {_PyMa_die  ,_YunMu_ie  },
+        {_PyMa_ding ,_YunMu_ing },
+        {_PyMa_diu  ,_YunMu_iu  },
+        {_PyMa_dong ,_YunMu_ong },
+        {_PyMa_dou  ,_YunMu_ou  },
+        {_PyMa_du   ,_YunMu_u   },
+        {_PyMa_duan ,_YunMu_uan },
+        {_PyMa_dui  ,_YunMu_ui  },
+        {_PyMa_dun  ,_YunMu_un  },
+        {_PyMa_duo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_e[] = {
+        {_PyMa_e    ,_YunMu_none},
+        {_PyMa_en   ,_YunMu_n   },
+        {_PyMa_er   ,_YunMu_r   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_f[] = {
+        {_PyMa_f    ,_YunMu_none},
+        {_PyMa_fa   ,_YunMu_a   },
+        {_PyMa_fan  ,_YunMu_an  },
+        {_PyMa_fang ,_YunMu_ang },
+        {_PyMa_fei  ,_YunMu_ei  },
+        {_PyMa_fen  ,_YunMu_en  },
+        {_PyMa_feng ,_YunMu_eng },
+        {_PyMa_fo   ,_YunMu_o   },
+        {_PyMa_fou  ,_YunMu_ou  },
+        {_PyMa_fu   ,_YunMu_u   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_g[] = {
+        {_PyMa_g    ,_YunMu_none},
+        {_PyMa_ga   ,_YunMu_a   },
+        {_PyMa_gai  ,_YunMu_ai  },
+        {_PyMa_gan  ,_YunMu_an  },
+        {_PyMa_gang ,_YunMu_ang },
+        {_PyMa_gao  ,_YunMu_ao  },
+        {_PyMa_ge   ,_YunMu_e   },
+        {_PyMa_gei  ,_YunMu_ei  },
+        {_PyMa_gen  ,_YunMu_en  },
+        {_PyMa_geng ,_YunMu_eng },
+        {_PyMa_gong ,_YunMu_ong },
+        {_PyMa_gou  ,_YunMu_ou  },
+        {_PyMa_gu   ,_YunMu_u   },
+        {_PyMa_gua  ,_YunMu_ua  },
+        {_PyMa_guai ,_YunMu_uai },
+        {_PyMa_guan ,_YunMu_uan },
+        {_PyMa_guang,_YunMu_uang},
+        {_PyMa_gui  ,_YunMu_ui  },
+        {_PyMa_gun  ,_YunMu_un  },
+        {_PyMa_guo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_h[] = {
+        {_PyMa_h    ,_YunMu_none},
+        {_PyMa_ha   ,_YunMu_a   },
+        {_PyMa_hai  ,_YunMu_ai  },
+        {_PyMa_han  ,_YunMu_an  },
+        {_PyMa_hang ,_YunMu_ang },
+        {_PyMa_hao  ,_YunMu_ao  },
+        {_PyMa_he   ,_YunMu_e   },
+        {_PyMa_hei  ,_YunMu_ei  },
+        {_PyMa_hen  ,_YunMu_en  },
+        {_PyMa_heng ,_YunMu_eng },
+        {_PyMa_hong ,_YunMu_ong },
+        {_PyMa_hou  ,_YunMu_ou  },
+        {_PyMa_hu   ,_YunMu_u   },
+        {_PyMa_hua  ,_YunMu_ua  },
+        {_PyMa_huai ,_YunMu_uai },
+        {_PyMa_huan ,_YunMu_uan },
+        {_PyMa_huang,_YunMu_uang},
+        {_PyMa_hui  ,_YunMu_ui  },
+        {_PyMa_hun  ,_YunMu_un  },
+        {_PyMa_huo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_j[] = {
+        {_PyMa_j    ,_YunMu_none},
+        {_PyMa_ji   ,_YunMu_i   },
+        {_PyMa_jia  ,_YunMu_ia  },
+        {_PyMa_jian ,_YunMu_ian },
+        {_PyMa_jiang,_YunMu_iang},
+        {_PyMa_jiao ,_YunMu_iao },
+        {_PyMa_jie  ,_YunMu_ie  },
+        {_PyMa_jin  ,_YunMu_in  },
+        {_PyMa_jing ,_YunMu_ing },
+        {_PyMa_jiong,_YunMu_iong},
+        {_PyMa_jiu  ,_YunMu_iu  },
+        {_PyMa_ju   ,_YunMu_u   },
+        {_PyMa_juan ,_YunMu_uan },
+        {_PyMa_jue  ,_YunMu_ue  },
+        {_PyMa_jun  ,_YunMu_un  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_k[] = {
+        {_PyMa_k    ,_YunMu_none},
+        {_PyMa_ka   ,_YunMu_a   },
+        {_PyMa_kai  ,_YunMu_ai  },
+        {_PyMa_kan  ,_YunMu_an  },
+        {_PyMa_kang ,_YunMu_ang },
+        {_PyMa_kao  ,_YunMu_ao  },
+        {_PyMa_ke   ,_YunMu_e   },
+        {_PyMa_ken  ,_YunMu_en  },
+        {_PyMa_keng ,_YunMu_eng },
+        {_PyMa_kong ,_YunMu_ong },
+        {_PyMa_kou  ,_YunMu_ou  },
+        {_PyMa_ku   ,_YunMu_u   },
+        {_PyMa_kua  ,_YunMu_ua  },
+        {_PyMa_kuai ,_YunMu_uai },
+        {_PyMa_kuan ,_YunMu_uan },
+        {_PyMa_kuang,_YunMu_uang},
+        {_PyMa_kui  ,_YunMu_ui  },
+        {_PyMa_kun  ,_YunMu_un  },
+        {_PyMa_kuo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_l[] = {
+        {_PyMa_l    ,_YunMu_none},
+        {_PyMa_la   ,_YunMu_a   },
+        {_PyMa_lai  ,_YunMu_ai  },
+        {_PyMa_lan  ,_YunMu_an  },
+        {_PyMa_lang ,_YunMu_ang },
+        {_PyMa_lao  ,_YunMu_ao  },
+        {_PyMa_le   ,_YunMu_e   },
+        {_PyMa_lei  ,_YunMu_ei  },
+        {_PyMa_leng ,_YunMu_eng },
+        {_PyMa_li   ,_YunMu_i   },
+        {_PyMa_lian ,_YunMu_ian },
+        {_PyMa_liang,_YunMu_iang},
+        {_PyMa_liao ,_YunMu_iao },
+        {_PyMa_lie  ,_YunMu_ie  },
+        {_PyMa_lin  ,_YunMu_in  },
+        {_PyMa_ling ,_YunMu_ing },
+        {_PyMa_liu  ,_YunMu_iu  },
+        {_PyMa_long ,_YunMu_ong },
+        {_PyMa_lou  ,_YunMu_ou  },
+        {_PyMa_lu   ,_YunMu_u   },
+        {_PyMa_luan ,_YunMu_uan },
+        {_PyMa_lue  ,_YunMu_ue  },
+        {_PyMa_lun  ,_YunMu_un  },
+        {_PyMa_luo  ,_YunMu_uo  },
+        {_PyMa_lv   ,_YunMu_v   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_m[] = {
+        {_PyMa_m    ,_YunMu_none},
+        {_PyMa_ma   ,_YunMu_a   },
+        {_PyMa_mai  ,_YunMu_ai  },
+        {_PyMa_man  ,_YunMu_an  },
+        {_PyMa_mang ,_YunMu_ang },
+        {_PyMa_mao  ,_YunMu_ao  },
+        {_PyMa_me   ,_YunMu_e   },
+        {_PyMa_mei  ,_YunMu_ei  },
+        {_PyMa_men  ,_YunMu_en  },
+        {_PyMa_meng ,_YunMu_eng },
+        {_PyMa_mi   ,_YunMu_i   },
+        {_PyMa_mian ,_YunMu_ian },
+        {_PyMa_miao ,_YunMu_iao },
+        {_PyMa_mie  ,_YunMu_ie  },
+        {_PyMa_min  ,_YunMu_in  },
+        {_PyMa_ming ,_YunMu_ing },
+        {_PyMa_miu  ,_YunMu_iu  },
+        {_PyMa_mo   ,_YunMu_o   },
+        {_PyMa_mou  ,_YunMu_ou  },
+        {_PyMa_mu   ,_YunMu_u   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_n[] = {
+        {_PyMa_n    ,_YunMu_none},
+        {_PyMa_na   ,_YunMu_a   },
+        {_PyMa_nai  ,_YunMu_ai  },
+        {_PyMa_nan  ,_YunMu_an  },
+        {_PyMa_nang ,_YunMu_ang },
+        {_PyMa_nao  ,_YunMu_ao  },
+        {_PyMa_ne   ,_YunMu_e   },
+        {_PyMa_nei  ,_YunMu_ei  },
+        {_PyMa_nen  ,_YunMu_en  },
+        {_PyMa_neng ,_YunMu_eng },
+        {_PyMa_ni   ,_YunMu_i   },
+        {_PyMa_nian ,_YunMu_ian },
+        {_PyMa_niang,_YunMu_iang},
+        {_PyMa_niao ,_YunMu_iao },
+        {_PyMa_nie  ,_YunMu_ie  },
+        {_PyMa_nin  ,_YunMu_in  },
+        {_PyMa_ning ,_YunMu_ing },
+        {_PyMa_niu  ,_YunMu_iu  },
+        {_PyMa_nong ,_YunMu_ong },
+        {_PyMa_nu   ,_YunMu_u   },
+        {_PyMa_nuan ,_YunMu_uan },
+        {_PyMa_nue  ,_YunMu_ue  },
+        {_PyMa_nuo  ,_YunMu_uo  },
+        {_PyMa_nv   ,_YunMu_v   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_o[] = {
+        {_PyMa_o    ,_YunMu_none},
+        {_PyMa_ou   ,_YunMu_u   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_p[] = {
+        {_PyMa_p    ,_YunMu_none},
+        {_PyMa_pa   ,_YunMu_a   },
+        {_PyMa_pai  ,_YunMu_ai  },
+        {_PyMa_pan  ,_YunMu_an  },
+        {_PyMa_pang ,_YunMu_ang },
+        {_PyMa_pao  ,_YunMu_ao  },
+        {_PyMa_pei  ,_YunMu_ei  },
+        {_PyMa_pen  ,_YunMu_en  },
+        {_PyMa_peng ,_YunMu_eng },
+        {_PyMa_pi   ,_YunMu_i   },
+        {_PyMa_pian ,_YunMu_ian },
+        {_PyMa_piao ,_YunMu_iao },
+        {_PyMa_pie  ,_YunMu_ie  },
+        {_PyMa_pin  ,_YunMu_in  },
+        {_PyMa_ping ,_YunMu_ing },
+        {_PyMa_po   ,_YunMu_o   },
+        {_PyMa_pou  ,_YunMu_ou  },
+        {_PyMa_pu   ,_YunMu_u   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_q[] = {
+        {_PyMa_q    ,_YunMu_none},
+        {_PyMa_qi   ,_YunMu_i   },
+        {_PyMa_qia  ,_YunMu_ia  },
+        {_PyMa_qian ,_YunMu_ian },
+        {_PyMa_qiang,_YunMu_iang},
+        {_PyMa_qiao ,_YunMu_iao },
+        {_PyMa_qie  ,_YunMu_ie  },
+        {_PyMa_qin  ,_YunMu_in  },
+        {_PyMa_qing ,_YunMu_ing },
+        {_PyMa_qiong,_YunMu_iong},
+        {_PyMa_qiu  ,_YunMu_iu  },
+        {_PyMa_qu   ,_YunMu_u   },
+        {_PyMa_quan ,_YunMu_uan },
+        {_PyMa_que  ,_YunMu_ue  },
+        {_PyMa_qun  ,_YunMu_un  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_r[] = {
+        {_PyMa_r    ,_YunMu_none},
+        {_PyMa_ran  ,_YunMu_an  },
+        {_PyMa_rang ,_YunMu_ang },
+        {_PyMa_rao  ,_YunMu_ao  },
+        {_PyMa_re   ,_YunMu_e   },
+        {_PyMa_ren  ,_YunMu_en  },
+        {_PyMa_reng ,_YunMu_eng },
+        {_PyMa_ri   ,_YunMu_i   },
+        {_PyMa_rong ,_YunMu_ong },
+        {_PyMa_rou  ,_YunMu_ou  },
+        {_PyMa_ru   ,_YunMu_u   },
+        {_PyMa_ruan ,_YunMu_uan },
+        {_PyMa_rui  ,_YunMu_ui  },
+        {_PyMa_run  ,_YunMu_un  },
+        {_PyMa_ruo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_s[] = {
+        {_PyMa_s    ,_YunMu_none},
+        {_PyMa_sa   ,_YunMu_a   },
+        {_PyMa_sai  ,_YunMu_ai  },
+        {_PyMa_san  ,_YunMu_an  },
+        {_PyMa_sang ,_YunMu_ang },
+        {_PyMa_sao  ,_YunMu_ao  },
+        {_PyMa_se   ,_YunMu_e   },
+        {_PyMa_sen  ,_YunMu_en  },
+        {_PyMa_seng ,_YunMu_eng },
+        {_PyMa_si   ,_YunMu_i   },
+        {_PyMa_song ,_YunMu_ong },
+        {_PyMa_sou  ,_YunMu_ou  },
+        {_PyMa_su   ,_YunMu_u   },
+        {_PyMa_suan ,_YunMu_uan },
+        {_PyMa_sui  ,_YunMu_ui  },
+        {_PyMa_sun  ,_YunMu_un  },
+        {_PyMa_suo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_t[] = {
+        {_PyMa_t    ,_YunMu_none},
+        {_PyMa_ta   ,_YunMu_a   },
+        {_PyMa_tai  ,_YunMu_ai  },
+        {_PyMa_tan  ,_YunMu_an  },
+        {_PyMa_tang ,_YunMu_ang },
+        {_PyMa_tao  ,_YunMu_ao  },
+        {_PyMa_te   ,_YunMu_e   },
+        {_PyMa_teng ,_YunMu_eng },
+        {_PyMa_ti   ,_YunMu_i   },
+        {_PyMa_tian ,_YunMu_ian },
+        {_PyMa_tiao ,_YunMu_iao },
+        {_PyMa_tie  ,_YunMu_ie  },
+        {_PyMa_ting ,_YunMu_ing },
+        {_PyMa_tong ,_YunMu_ong },
+        {_PyMa_tou  ,_YunMu_ou  },
+        {_PyMa_tu   ,_YunMu_u   },
+        {_PyMa_tuan ,_YunMu_uan },
+        {_PyMa_tui  ,_YunMu_ui  },
+        {_PyMa_tun  ,_YunMu_un  },
+        {_PyMa_tuo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_w[] = {
+        {_PyMa_w    ,_YunMu_none},
+        {_PyMa_wa   ,_YunMu_a   },
+        {_PyMa_wai  ,_YunMu_ai  },
+        {_PyMa_wan  ,_YunMu_an  },
+        {_PyMa_wang ,_YunMu_ang },
+        {_PyMa_wei  ,_YunMu_ei  },
+        {_PyMa_wen  ,_YunMu_en  },
+        {_PyMa_weng ,_YunMu_eng },
+        {_PyMa_wo   ,_YunMu_o   },
+        {_PyMa_wu   ,_YunMu_u   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_x[] = {
+        {_PyMa_x    ,_YunMu_none},
+        {_PyMa_xi   ,_YunMu_i   },
+        {_PyMa_xia  ,_YunMu_ia  },
+        {_PyMa_xian ,_YunMu_ian },
+        {_PyMa_xiang,_YunMu_iang},
+        {_PyMa_xiao ,_YunMu_iao },
+        {_PyMa_xie  ,_YunMu_ie  },
+        {_PyMa_xin  ,_YunMu_in  },
+        {_PyMa_xing ,_YunMu_ing },
+        {_PyMa_xiong,_YunMu_iong},
+        {_PyMa_xiu  ,_YunMu_iu  },
+        {_PyMa_xu   ,_YunMu_u   },
+        {_PyMa_xuan ,_YunMu_uan },
+        {_PyMa_xue  ,_YunMu_ue  },
+        {_PyMa_xun  ,_YunMu_un  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_y[] = {
+        {_PyMa_y    ,_YunMu_none},
+        {_PyMa_ya   ,_YunMu_a   },
+        {_PyMa_yan  ,_YunMu_an  },
+        {_PyMa_yang ,_YunMu_ang },
+        {_PyMa_yao  ,_YunMu_ao  },
+        {_PyMa_ye   ,_YunMu_e   },
+        {_PyMa_yi   ,_YunMu_i   },
+        {_PyMa_yin  ,_YunMu_in  },
+        {_PyMa_ying ,_YunMu_ing },
+        {_PyMa_yo   ,_YunMu_o   },
+        {_PyMa_yong ,_YunMu_ong },
+        {_PyMa_you  ,_YunMu_ou  },
+        {_PyMa_yu   ,_YunMu_u   },
+        {_PyMa_yuan ,_YunMu_uan },
+        {_PyMa_yue  ,_YunMu_ue  },
+        {_PyMa_yun  ,_YunMu_un  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_z[] = {
+        {_PyMa_z    ,_YunMu_none},
+        {_PyMa_za   ,_YunMu_a   },
+        {_PyMa_zai  ,_YunMu_ai  },
+        {_PyMa_zan  ,_YunMu_an  },
+        {_PyMa_zang ,_YunMu_ang },
+        {_PyMa_zao  ,_YunMu_ao  },
+        {_PyMa_ze   ,_YunMu_e   },
+        {_PyMa_zei  ,_YunMu_ei  },
+        {_PyMa_zen  ,_YunMu_en  },
+        {_PyMa_zeng ,_YunMu_eng },
+        {_PyMa_zi   ,_YunMu_i   },
+        {_PyMa_zong ,_YunMu_ong },
+        {_PyMa_zou  ,_YunMu_ou  },
+        {_PyMa_zu   ,_YunMu_u   },
+        {_PyMa_zuan ,_YunMu_uan },
+        {_PyMa_zui  ,_YunMu_ui  },
+        {_PyMa_zun  ,_YunMu_un  },
+        {_PyMa_zuo  ,_YunMu_uo  },
+        {_PyMa_zz   ,_YunMu_z   },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_ch[] = {
+        {_PyMa_cha   ,_YunMu_a   },
+        {_PyMa_chai  ,_YunMu_ai  },
+        {_PyMa_chan  ,_YunMu_an  },
+        {_PyMa_chang ,_YunMu_ang },
+        {_PyMa_chao  ,_YunMu_ao  },
+        {_PyMa_che   ,_YunMu_e   },
+        {_PyMa_chen  ,_YunMu_en  },
+        {_PyMa_cheng ,_YunMu_eng },
+        {_PyMa_chi   ,_YunMu_i   },
+        {_PyMa_chong ,_YunMu_ong },
+        {_PyMa_chou  ,_YunMu_ou  },
+        {_PyMa_chu   ,_YunMu_u   },
+        {_PyMa_chuai ,_YunMu_uai },
+        {_PyMa_chuan ,_YunMu_uan },
+        {_PyMa_chuang,_YunMu_uang},
+        {_PyMa_chui  ,_YunMu_ui  },
+        {_PyMa_chun  ,_YunMu_un  },
+        {_PyMa_chuo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_sh[] = {
+        {_PyMa_sha   ,_YunMu_a   },
+        {_PyMa_shai  ,_YunMu_ai  },
+        {_PyMa_shan  ,_YunMu_an  },
+        {_PyMa_shang ,_YunMu_ang },
+        {_PyMa_shao  ,_YunMu_ao  },
+        {_PyMa_she   ,_YunMu_e   },
+        {_PyMa_shen  ,_YunMu_en  },
+        {_PyMa_sheng ,_YunMu_eng },
+        {_PyMa_shi   ,_YunMu_i   },
+        {_PyMa_shou  ,_YunMu_ou  },
+        {_PyMa_shu   ,_YunMu_u   },
+        {_PyMa_shua  ,_YunMu_ua  },
+        {_PyMa_shuai ,_YunMu_uai },
+        {_PyMa_shuan ,_YunMu_uan },
+        {_PyMa_shuang,_YunMu_uang},
+        {_PyMa_shui  ,_YunMu_ui  },
+        {_PyMa_shun  ,_YunMu_un  },
+        {_PyMa_shuo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType PyIndex_zh[] = {
+        {_PyMa_zha   ,_YunMu_a   },
+        {_PyMa_zhai  ,_YunMu_ai  },
+        {_PyMa_zhan  ,_YunMu_an  },
+        {_PyMa_zhang ,_YunMu_ang },
+        {_PyMa_zhao  ,_YunMu_ao  },
+        {_PyMa_zhe   ,_YunMu_e   },
+        {_PyMa_zhen  ,_YunMu_en  },
+        {_PyMa_zheng ,_YunMu_eng },
+        {_PyMa_zhi   ,_YunMu_i   },
+        {_PyMa_zhong ,_YunMu_ong },
+        {_PyMa_zhou  ,_YunMu_ou  },
+        {_PyMa_zhu   ,_YunMu_u   },
+        {_PyMa_zhua  ,_YunMu_ua  },
+        {_PyMa_zhuai ,_YunMu_uai },
+        {_PyMa_zhuan ,_YunMu_uan },
+        {_PyMa_zhuang,_YunMu_uang},
+        {_PyMa_zhui  ,_YunMu_ui  },
+        {_PyMa_zhun  ,_YunMu_un  },
+        {_PyMa_zhuo  ,_YunMu_uo  },
+        {NULL        ,NULL}
+};
+
+struct _PyIndexType *PyIndexPointer[] = {
+               PyIndex_a,
+        PyIndex_b,
+        PyIndex_c,
+        PyIndex_d,
+        PyIndex_e,
+        PyIndex_f,
+        PyIndex_g,
+        PyIndex_h,
+        NULL,
+        PyIndex_j,
+        PyIndex_k,
+        PyIndex_l,
+        PyIndex_m,
+        PyIndex_n,
+        PyIndex_o,
+        PyIndex_p,
+        PyIndex_q,
+        PyIndex_r,
+        PyIndex_s,
+        PyIndex_t,
+        NULL,
+        NULL,
+        PyIndex_w,
+        PyIndex_x,
+        PyIndex_y,
+        PyIndex_z,
+};
+
+wchar_t *decode_syllables(const u16 *syllables)
+{
+       struct _PyIndexType *p1 = NULL;
+       const u16 *p2 = syllables;
+       s32 s = 0;
+
+       if (syllables == NULL) {
+               return NULL;
+       }
+
+       if (p2[1] == 'h') {
+               if (p2[0] == 'z') {
+                       p1 = PyIndex_zh;        
+               }
+               else if (p2[0] == 'c') {
+                       p1 = PyIndex_ch;
+               }
+               else if (p2[0] == 's') {
+                       p1 = PyIndex_sh;
+               }
+               p2 += 2;
+               s = 3 * sizeof(u16);
+       }
+       else {
+               p1 = PyIndexPointer[p2[0] - 'a'];
+               p2++;
+               s = 4 * sizeof(u16);
+       }
+
+       if (p1 == NULL) {
+               return NULL;
+       }
+
+       while (p1->syllables && p1->final) {
+               if (memcmp(p1->final, p2, s) == 0) {
+                       return p1->syllables;
+               }
+               p1++;
+       }
+       
+       return NULL;
+}
diff --git a/src/raw_i2c.cpp b/src/raw_i2c.cpp
new file mode 100644 (file)
index 0000000..20522f9
--- /dev/null
@@ -0,0 +1,215 @@
+#include <stdio.h>
+#include <linux/types.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include "sgi_types.h"
+
+#define CMD_UNLOCK     0xC0
+#define CMD_LOCK       0xC1
+#define CMD_STATE      0xC2
+#define CMD_CANCEL     0xC3
+
+static int i2c_comm_send(u8 addr, u8 *buf, int len)
+{
+       int fd = -1;
+       int r = 0;
+       struct i2c_msg msg[1];
+       struct i2c_rdwr_ioctl_data e2prom_data;
+       
+       /* 打开I2C设备 */
+       fd = open("/dev/i2c/0", O_RDWR);
+       if (fd < 0) {
+               printf("open i2c device fail.\n");
+               goto err;
+       }
+       
+       /* 设定超时时间,以10ms为单位 */
+       ioctl(fd, I2C_TIMEOUT, 1);
+       
+       /* 设定重复次数 */
+        ioctl(fd, I2C_RETRIES, 2);
+       
+       /* 准备写入数据 */
+       e2prom_data.nmsgs = 1;
+       e2prom_data.msgs = msg;
+       e2prom_data.msgs[0].buf = buf; 
+       e2prom_data.msgs[0].len = len;
+       e2prom_data.msgs[0].flags = 0; /* 写入 */
+       e2prom_data.msgs[0].addr = addr;
+
+       /* 执行I2C总线操作 */
+       r = ioctl(fd, I2C_RDWR, (unsigned long)&e2prom_data);
+       if (r < 0) {
+               //printf("send ioctl to i2c device fail.\n");
+               goto err;
+       }
+       
+       /* 操作成功,返回实际数据长度 */
+       r = 0;  
+       
+err:
+       if (fd != -1) {
+               close(fd);      
+       }
+       
+       return r;       
+}
+
+static int i2c_comm_recv(u8 addr, u8 *buf, int len)
+{
+       int fd = -1;
+       int r = 0;
+       struct i2c_msg msg[1];
+       struct i2c_rdwr_ioctl_data e2prom_data;
+       
+       /* 打开I2C设备 */
+       fd = open("/dev/i2c/0", O_RDWR);
+       if (fd < 0) {
+               printf("open i2c device fail.\n");
+               goto err;
+       }
+       
+       /* 设定超时时间,以10ms为单位 */
+       ioctl(fd, I2C_TIMEOUT, 1);
+       
+       /* 设定重复次数 */
+        ioctl(fd, I2C_RETRIES, 2);
+       
+       /* 准备写入数据 */
+       e2prom_data.nmsgs = 1;
+       e2prom_data.msgs = msg;
+       e2prom_data.msgs[0].buf = buf; 
+       e2prom_data.msgs[0].len = len;
+       e2prom_data.msgs[0].flags = I2C_M_RD; /* 读取 */
+       e2prom_data.msgs[0].addr = addr;
+
+       /* 执行I2C总线操作 */
+       r = ioctl(fd, I2C_RDWR, (unsigned long)&e2prom_data);
+       if (r < 0) {
+               //printf("send ioctl to i2c device fail.\n");
+               goto err;
+       }
+       
+       /* 操作成功,返回实际数据长度 */
+       r = 0;  
+       
+err:
+       if (fd != -1) {
+               close(fd);      
+       }
+       
+       return r;       
+}
+
+static u8 calc_cks(u8 *data, int len)
+{
+       u8 t = 0;
+       
+       while (len-- > 0) {
+               t += *data++;
+       }
+       
+       return t;       
+}
+
+s32 i2c_comm_unlock(u8 addr)
+{
+       u8 buf[8] = {0};
+       
+       printf("i2c comm, addr: %d\n", addr);
+       buf[0] = 0x5A;
+       buf[1] = 0xA5;
+       buf[2] = CMD_UNLOCK;
+       buf[7] = calc_cks(buf, 7);
+       if (i2c_comm_send(addr, buf, sizeof(buf)) != 0) {
+               printf("i2c comm unlock fail.\n");
+               return -1;              
+       }
+       printf("i2c comm unlock ok.\n");
+       
+       return 0;       
+}
+
+s32 i2c_comm_lock(u8 addr)
+{
+       u8 buf[8] = {0};
+       
+       buf[0] = 0x5A;
+       buf[1] = 0xA5;
+       buf[2] = CMD_LOCK;
+       buf[7] = calc_cks(buf, 7);
+       if (i2c_comm_send(addr, buf, sizeof(buf)) != 0) {
+               printf("i2c comm unlock fail.\n");
+               return -1;              
+       }
+       //printf("i2c comm unlock ok.\n");
+       
+       return 0;               
+}
+
+s32 i2c_comm_cancel_alarm(u8 addr)
+{
+       u8 buf[8] = {0};
+       
+       printf("i2c comm, addr: %d\n", addr);
+       buf[0] = 0x5A;
+       buf[1] = 0xA5;
+       buf[2] = CMD_CANCEL;
+       buf[7] = calc_cks(buf, 7);
+       if (i2c_comm_send(addr, buf, sizeof(buf)) != 0) {
+               printf("i2c comm cancel alarm fail.\n");
+               return -1;              
+       }
+       printf("i2c comm cancel alarm ok.\n");
+       
+       return 0;       
+}
+
+s32 i2c_comm_update_state(u8 addr)
+{
+       u8 buf[8] = {0};
+       
+       printf("i2c comm, addr: %d\n", addr);
+       buf[0] = 0x5A;
+       buf[1] = 0xA5;
+       buf[2] = CMD_STATE;
+       buf[7] = calc_cks(buf, 7);
+       if (i2c_comm_send(addr, buf, sizeof(buf)) != 0) {
+               printf("i2c comm update state fail.\n");
+               return -1;              
+       }
+       //printf("i2c comm update state ok.\n");
+       
+       return 0;       
+}
+
+s32 i2c_comm_read_state(u8 addr, u8 *state)
+{
+       u8 buf[8] = {0};
+               
+       if (i2c_comm_recv(addr, buf, sizeof(buf)) != 0) {
+               //printf("i2c comm read state fail.\n");
+               return -1;              
+       }
+       
+       /* */
+       if (buf[0] != 0x66 || buf[1] != 0x99) {
+               printf("i2c comm read head error.\n");
+               return -1;      
+       }
+       
+       if (buf[7] !=  calc_cks(buf, 7)) {
+               printf("i2c comm read cks error.\n");
+               return -1;      
+       }
+       
+       memcpy(state, &buf[3], 4);      
+       
+       return 0;
+}
\ No newline at end of file
diff --git a/src/sgi_base.cpp b/src/sgi_base.cpp
new file mode 100755 (executable)
index 0000000..d90e020
--- /dev/null
@@ -0,0 +1,1052 @@
+#include "global_func.h"
+
+/* global variable define */
+static u32 kernel_handle_id = 1024;
+struct passport_data g_passport;
+struct alarm_data g_alarm_data;
+
+static s32 s_mfcard_fd = -1;
+
+const u8 g_box_addr[BOX_NUMS] = {
+       0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
+       0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
+       0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
+       0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
+       0x6a,0x6b,      
+};
+
+u32 request_handle(void)
+{
+       return kernel_handle_id++;      
+}
+
+SDL_Surface *clone_surface(SDL_Surface *image)
+{
+       SDL_Surface *surface;
+       Uint32 rmask, gmask, bmask, amask;
+       
+       assert(image);
+
+       rmask = image->format->Rmask;
+       gmask = image->format->Gmask;
+       bmask = image->format->Bmask;
+       amask = image->format->Amask;
+       
+       surface = SDL_CreateRGBSurface(SDL_SWSURFACE, image->w, image->h, 32,
+               rmask, gmask, bmask, amask);
+       if (surface) {
+               SDL_BlitSurface(image, NULL, surface, NULL);
+               return surface; 
+       }
+       
+       return NULL;    
+}
+
+void release_clone_surface(SDL_Surface *image)
+{
+       if (image) {
+               SDL_FreeSurface(image); 
+       }
+}
+
+void sgi_edit_insert_text(struct sgi_edit *object, u16 text)
+{
+       u32 r;
+       
+       r = sgi_len16(object->text);
+       
+       if (text == DEL_CHAR) {
+               object->text[r - 1] = 0;                
+       }
+       else {
+               if (object->mask == MSK_DIGIT) {
+                       if (!iswdigit(text)) {
+                               return;
+                       }       
+               }
+                       
+               if (r >= object->word_max) {
+                       return;
+               }
+       
+               if (r < sizeof(object->text) / sizeof(u16) - 2) {
+                       object->text[r] = text;
+                       object->text[r + 1] = 0;                                
+               }
+       }
+}
+
+
+void set_object_default_func(struct sgi_form *form)
+{
+       if (!form->init) {
+               form->init = sgi_form_init_default;
+       }
+       if (!form->deinit) {
+               form->deinit = sgi_form_deinit_default;
+       }
+       if (!form->frame) {
+               form->frame = sgi_form_frame_default;
+       }
+       if (!form->render) {
+               form->render = sgi_form_render_default; 
+       }       
+}
+
+void set_object_default_func(union sgi_object *object)
+{
+       switch (object->type) {
+       case SGI_WINDOW:
+               if (!object->window.init) {
+                       object->window.init = sgi_window_init_default;
+               }
+               if (!object->window.deinit) {
+                       object->window.deinit = sgi_window_deinit_default;
+               }
+               if (!object->window.frame) {
+                       object->window.frame = sgi_window_frame_default;
+               }
+               if (!object->window.render) {
+                       object->window.render = sgi_window_render_default;      
+               }
+               break;
+               
+       case SGI_PICTURE:
+               if (!object->picture.init) {
+                       object->picture.init = sgi_picture_init_default;
+               }
+               if (!object->picture.deinit) {
+                       object->picture.deinit = sgi_picture_deinit_default;
+               }
+               if (!object->picture.frame) {
+                       object->picture.frame = sgi_picture_frame_default;
+               }
+               if (!object->picture.render) {
+                       object->picture.render = sgi_picture_render_default;    
+               }
+               break;
+               
+       case SGI_LABEL:
+               if (!object->label.init) {
+                       object->label.init = sgi_label_init_default;
+               }
+               if (!object->label.deinit) {
+                       object->label.deinit = sgi_label_deinit_default;
+               }
+               if (!object->label.frame) {
+                       object->label.frame = sgi_label_frame_default;
+               }
+               if (!object->label.render) {
+                       object->label.render = sgi_label_render_default;        
+               }
+               break;  
+               
+       case SGI_EDIT:
+               if (!object->edit.init) {
+                       object->edit.init = sgi_edit_init_default;
+               }
+               if (!object->edit.deinit) {
+                       object->edit.deinit = sgi_edit_deinit_default;
+               }
+               if (!object->edit.frame) {
+                       object->edit.frame = sgi_edit_frame_default;
+               }
+               if (!object->edit.render) {
+                       object->edit.render = sgi_edit_render_default;  
+               }
+               break;  
+               
+       case SGI_BUTTON:
+               if (!object->button.init) {
+                       object->button.init = sgi_button_init_default;
+               }
+               if (!object->button.deinit) {
+                       object->button.deinit = sgi_button_deinit_default;
+               }
+               if (!object->button.frame) {
+                       object->button.frame = sgi_button_frame_default;
+               }
+               if (!object->button.render) {
+                       object->button.render = sgi_button_render_default;      
+               }
+               if (!object->button.down) {
+                       object->button.down = sgi_button_down_default;  
+               }
+               if (!object->button.up) {
+                       object->button.up = sgi_button_up_default;      
+               }
+               if (!object->button.click) {
+                       object->button.click = sgi_button_click_default;        
+               }
+               break;
+               
+       case SGI_IME:
+               if (!object->ime.init) {
+                       object->ime.init = sgi_ime_init_default;
+               }
+               if (!object->ime.deinit) {
+                       object->ime.deinit = sgi_ime_deinit_default;
+               }
+               if (!object->ime.frame) {
+                       object->ime.frame = sgi_ime_frame_default;
+               }
+               if (!object->ime.render) {
+                       object->ime.render = sgi_ime_render_default;    
+               }
+//             if (!object->ime.down) {
+//                     object->ime.down = sgi_ime_down_default;        
+//             }
+//             if (!object->ime.up) {
+//                     object->ime.up = sgi_ime_up_default;    
+//             }
+               break;
+       
+       case SGI_BOX:
+               if (!object->box.init) {
+                       object->box.init = sgi_box_init_default;
+               }
+               if (!object->box.deinit) {
+                       object->box.deinit = sgi_box_deinit_default;
+               }
+               if (!object->box.frame) {
+                       object->box.frame = sgi_box_frame_default;
+               }
+               if (!object->box.render) {
+                       object->box.render = sgi_box_render_default;    
+               }
+               if (!object->box.down) {
+                       object->box.down = sgi_box_down_default;        
+               }
+               if (!object->box.up) {
+                       object->box.up = sgi_box_up_default;    
+               }
+               break;
+               
+       case SGI_GRID:
+               if (!object->grid.init) {
+                       object->grid.init = sgi_grid_init_default;
+               }
+               if (!object->grid.deinit) {
+                       object->grid.deinit = sgi_grid_deinit_default;
+               }
+               if (!object->grid.frame) {
+                       object->grid.frame = sgi_grid_frame_default;
+               }
+               if (!object->grid.render) {
+                       object->grid.render = sgi_grid_render_default;  
+               }
+               break;
+               
+       case SGI_PHOTO:
+               if (!object->photo.render) {
+                       object->photo.render = sgi_photo_render_default;        
+               }
+               break;
+               
+       case SGI_MSGBOX:
+               if (!object->msgbox.init) {
+                       object->msgbox.init = sgi_msgbox_init_default;
+               }
+               if (!object->msgbox.deinit) {
+                       object->msgbox.deinit = sgi_msgbox_deinit_default;
+               }
+               if (!object->msgbox.frame) {
+                       object->msgbox.frame = sgi_msgbox_frame_default;
+               }
+               if (!object->msgbox.render) {
+                       object->msgbox.render = sgi_msgbox_render_default;      
+               }
+               break;
+               
+       case SGI_RADIO:
+               if (!object->radio.init) {
+                       object->radio.init = sgi_radio_init_default;
+               }
+               if (!object->radio.deinit) {
+                       object->radio.deinit = sgi_radio_deinit_default;
+               }
+               if (!object->radio.frame) {
+                       object->radio.frame = sgi_radio_frame_default;
+               }
+               if (!object->radio.render) {
+                       object->radio.render = sgi_radio_render_default;        
+               }
+               break;
+               
+       case SGI_CHECK:
+               if (!object->check.init) {
+                       object->check.init = sgi_check_init_default;
+               }
+               if (!object->check.deinit) {
+                       object->check.deinit = sgi_check_deinit_default;
+               }
+               if (!object->check.frame) {
+                       object->check.frame = sgi_check_frame_default;
+               }
+               if (!object->check.render) {
+                       object->check.render = sgi_check_render_default;        
+               }
+               break;
+               
+       case SGI_UPDOWN:
+               if (!object->updown.init) {
+                       object->updown.init = sgi_updown_init_default;
+               }
+               if (!object->updown.deinit) {
+                       object->updown.deinit = sgi_updown_deinit_default;
+               }
+               if (!object->updown.frame) {
+                       object->updown.frame = sgi_updown_frame_default;
+               }
+               if (!object->updown.render) {
+                       object->updown.render = sgi_updown_render_default;      
+               }
+               break;
+               
+       case SGI_INDICATOR:
+               if (!object->indicator.init) {
+                       object->indicator.init = sgi_indicator_init_default;
+               }
+               if (!object->indicator.deinit) {
+                       object->indicator.deinit = sgi_indicator_deinit_default;
+               }
+               if (!object->indicator.frame) {
+                       object->indicator.frame = sgi_indicator_frame_default;
+               }
+               if (!object->indicator.render) {
+                       object->indicator.render = sgi_indicator_render_default;        
+               }
+               break;
+               
+       default:
+               break;          
+       }
+}
+
+void invalidate_rect(struct sgi_form *form, s16 x1, s16 y1, s16 x2, s16 y2)
+{
+       form->dirty = 1;
+       
+       if (form->x1 > x1) {
+               form->x1 = x1;
+       }
+       
+       if (form->y1 > y1) {
+               form->y1 = y1;
+       }
+       
+       if (form->x2 < x2) {
+               form->x2 = x2;
+       }
+       
+       if (form->y2 < y2) {
+               form->y2 = y2;
+       }       
+}
+
+void set_object_pos(union sgi_object *object, s16 x, s16 y, s16 w, s16 h, s16 z)
+{
+       switch (object->type) {
+       case SGI_WINDOW:
+               object->window.x = x;
+               object->window.y = y;
+               object->window.w = w;
+               object->window.h = h;
+               object->window.z = z;
+               break;
+               
+       case SGI_PICTURE:
+               object->picture.x = x;
+               object->picture.y = y;
+               object->picture.w = w;
+               object->picture.h = h;
+               object->picture.z = z;
+               break;
+               
+       case SGI_LABEL:
+               object->label.x = x;
+               object->label.y = y;
+               object->label.w = w;
+               object->label.h = h;
+               object->label.z = z;
+               break;  
+               
+       case SGI_EDIT:
+               object->edit.x = x;
+               object->edit.y = y;
+               object->edit.w = w;
+               object->edit.h = h;
+               object->edit.z = z;
+               break;  
+               
+       case SGI_BUTTON:
+               object->button.x = x;
+               object->button.y = y;
+               object->button.w = w;
+               object->button.h = h;
+               object->button.z = z;
+               break;
+               
+       case SGI_IME:
+               object->ime.x = x;
+               object->ime.y = y;
+               object->ime.w = w;
+               object->ime.h = h;
+               object->ime.z = z;
+               break;
+               
+       case SGI_BOX:
+               object->box.x = x;
+               object->box.y = y;
+               object->box.w = w;
+               object->box.h = h;
+               object->box.z = z;
+               break;
+               
+       case SGI_GRID:
+               object->grid.x = x;
+               object->grid.y = y;
+               object->grid.w = w;
+               object->grid.h = h;
+               object->grid.z = z;
+               break;
+               
+       case SGI_PHOTO:
+               object->photo.x = x;
+               object->photo.y = y;
+               object->photo.w = w;
+               object->photo.h = h;
+               object->photo.z = z;
+               break;
+               
+       case SGI_RADIO:
+               object->radio.x = x;
+               object->radio.y = y;
+               object->radio.w = w;
+               object->radio.h = h;
+               object->radio.z = z;
+               break;
+               
+       case SGI_CHECK:
+               object->check.x = x;
+               object->check.y = y;
+               object->check.w = w;
+               object->check.h = h;
+               object->check.z = z;
+               break;
+               
+       case SGI_UPDOWN:
+               object->updown.x = x;
+               object->updown.y = y;
+               object->updown.w = w;
+               object->updown.h = h;
+               object->updown.z = z;
+               break;
+               
+       case SGI_INDICATOR:
+               object->indicator.x = x;
+               object->indicator.y = y;
+               object->indicator.w = w;
+               object->indicator.h = h;
+               object->indicator.z = z;
+               break;
+               
+       default:
+               break;          
+       }               
+}
+
+void set_object_text_u(struct sgi_label *object, u16 *text)
+{
+       if (text == NULL) {
+               memset(object->caption, 0, sizeof(object->caption));    
+       }
+       else {
+               sgi_ncp16(object->caption, text, COUNTOF(object->caption));
+       }
+}
+
+void set_object_text_u(struct sgi_edit *object, u16 *text)
+{
+       if (text == NULL) {
+               memset(object->text, 0, sizeof(object->text));  
+       }
+       else {
+               sgi_ncp16(object->text, text, COUNTOF(object->text));   
+       }
+}
+
+void set_object_text_w(struct sgi_label *object, w32 *text)
+{
+       if (text == NULL) {
+               memset(object->caption, 0, sizeof(object->caption));    
+       }
+       else {
+               sgi_ncpw2u(object->caption, text, COUNTOF(object->caption));
+       }
+}
+       
+void set_object_text_w(struct sgi_edit *object, w32 *text)     
+{
+       if (text == NULL) {
+               memset(object->text, 0, sizeof(object->text));  
+       }
+       else {
+               sgi_ncpw2u(object->text, text, COUNTOF(object->text));
+       }
+}
+
+void get_object_text_u(struct sgi_label *object, u16 *text)
+{
+       sgi_ncp16(text, object->caption, COUNTOF(object->caption));
+}
+
+void get_object_text_u(struct sgi_edit *object, u16 *text)
+{
+       sgi_ncp16(text, object->text, COUNTOF(object->text));   
+}
+
+void set_object_focus(union sgi_object *object)
+{
+       if (object->type == SGI_EDIT) {
+               object->edit.parent->focus_handle = object->edit.handle;                        
+       }       
+}
+
+void set_object_parent(union sgi_object *object, struct sgi_form *form)
+{
+       switch (object->type) {
+       case SGI_WINDOW:
+               object->window.parent = form;
+               break;
+               
+       case SGI_PICTURE:
+               object->picture.parent = form;
+               break;
+               
+       case SGI_LABEL:
+               object->label.parent = form;
+               break;  
+               
+       case SGI_EDIT:
+               object->edit.parent = form;
+               break;  
+               
+       case SGI_BUTTON:
+               object->button.parent = form;
+               break;
+               
+       case SGI_IME:
+               object->ime.parent = form;
+               break;
+               
+       case SGI_BOX:
+               object->box.parent = form;
+               break;
+               
+       case SGI_GRID:
+               object->grid.parent = form;
+               break;
+               
+       case SGI_PHOTO:
+               object->photo.parent = form;
+               break;
+               
+       case SGI_MSGBOX:
+               object->msgbox.parent = form;
+               break;
+               
+       case SGI_RADIO:
+               object->radio.parent = form;
+               break;
+               
+       case SGI_CHECK:
+               object->check.parent = form;
+               break;
+               
+       case SGI_UPDOWN:
+               object->updown.parent = form;
+               break;
+               
+       case SGI_INDICATOR:
+               object->indicator.parent = form;
+               break;                          
+               
+       default:
+               break;          
+       }               
+}
+
+void set_object_image(union sgi_object *object, char *image1, char *image2, 
+       char *image3, char *image4, u32 flags)
+{
+       switch (object->type) {
+       case SGI_WINDOW:
+               object->window.image.name = image1;
+               object->window.image.flags = flags;
+               break;
+               
+       case SGI_PICTURE:
+               object->picture.image.name = image1;
+               object->picture.image.flags = flags;
+               break;
+               
+       case SGI_LABEL:
+               break;  
+               
+       case SGI_EDIT:
+               object->edit.image.name = image1;
+               object->edit.image.flags = flags;
+               break;  
+               
+       case SGI_BUTTON:
+               object->button.back[0].name = image1;
+               object->button.back[1].name = image2;
+               object->button.back[2].name = image3;
+               object->button.front.name = image4;
+               object->button.back[0].flags = flags;
+               object->button.back[1].flags = flags;
+               object->button.back[2].flags = flags;
+               object->button.front.flags = flags;             
+               break;
+               
+       case SGI_IME:
+               object->ime.back[0].name = image1;
+               object->ime.back[1].name = image2;
+               object->ime.back[0].flags = flags;
+               object->ime.back[1].flags = flags;
+               break;
+               
+       case SGI_BOX:
+               object->box.back[0].name = image1;
+               object->box.back[1].name = image2;
+               object->box.back[2].name = image3;
+               object->box.back[3].name = image4;
+               object->box.back[0].flags = flags;
+               object->box.back[1].flags = flags;
+               object->box.back[2].flags = flags;
+               object->box.back[3].flags = flags;
+               break;
+               
+       case SGI_GRID:
+               object->grid.back.name = image1;
+               object->grid.action.name = image2;
+               object->grid.back.flags = flags;
+               object->grid.action.flags = flags;
+               break;
+               
+       case SGI_MSGBOX:
+               object->msgbox.image[0].name = image1;
+               object->msgbox.image[1].name = image2;
+               object->msgbox.image[2].name = image3;
+               object->msgbox.image[3].name = image4;
+               object->msgbox.image[0].flags = flags;
+               object->msgbox.image[1].flags = flags;
+               object->msgbox.image[2].flags = flags;
+               object->msgbox.image[3].flags = flags;
+               break;
+               
+       case SGI_RADIO:
+               object->radio.image[0].name = image1;
+               object->radio.image[1].name = image2;
+               object->radio.image[0].flags = flags;
+               object->radio.image[1].flags = flags;
+               break;
+               
+       case SGI_CHECK:
+               object->check.image[0].name = image1;
+               object->check.image[1].name = image2;
+               object->check.image[0].flags = flags;
+               object->check.image[1].flags = flags;
+               break;
+               
+       case SGI_UPDOWN:
+               object->updown.image[0].name = image1;
+               object->updown.image[1].name = image2;
+               object->updown.image[0].flags = flags;
+               object->updown.image[1].flags = flags;
+               break;
+               
+       case SGI_INDICATOR:
+               object->indicator.image[0].name = image1;
+               object->indicator.image[1].name = image2;
+               object->indicator.image[0].flags = flags;
+               object->indicator.image[1].flags = flags;
+               break;
+               
+       default:
+               break;          
+       }               
+}
+
+void set_object_font(union sgi_object *object, char *name, u32 size, SDL_Color color)
+{
+       switch (object->type) {
+       case SGI_WINDOW:
+               break;
+               
+       case SGI_LABEL:
+               object->label.font.name = name;
+               object->label.font.size = size;
+               object->label.fcolor = color;
+               break;  
+               
+       case SGI_EDIT:
+               object->edit.font.name = name;
+               object->edit.font.size = size;
+               object->edit.fcolor = color;
+               break;  
+               
+       case SGI_BUTTON:
+               break;
+               
+       case SGI_IME:
+               object->ime.font.name = name;
+               object->ime.font.size = size;
+               break;
+               
+       case SGI_BOX:
+               object->box.font.name = name;
+               object->box.font.size = size;
+               break;
+               
+       case SGI_GRID:
+               object->grid.font.name = name;
+               object->grid.font.size = size;
+               break;
+               
+       case SGI_MSGBOX:
+               object->msgbox.font.name = name;
+               object->msgbox.font.size = size;
+               break;
+               
+       case SGI_UPDOWN:
+               object->updown.font.name = name;
+               object->updown.font.size = size;
+               object->updown.fcolor = color;
+               break;
+               
+       case SGI_INDICATOR:
+               break;
+               
+       default:
+               break;          
+       }               
+}
+
+void register_window(struct sgi_form *form, struct sgi_window *wnd)
+{
+       assert(form != NULL && wnd != NULL);
+       form->wnd = wnd;        
+}
+
+void register_ime(struct sgi_form *form)
+{
+       s32 r = 0;
+       assert(form != NULL);
+
+       sgi_ime_create();
+       
+       if (!g_sgi_ime.initialized) {
+               r = g_sgi_ime.init(&g_sgi_ime);
+               printf("init ime module: %d\n", r);     
+       }
+       
+       if (r == 0) {
+               form->ime = &g_sgi_ime;
+               g_sgi_ime.parent = form;
+               printf("register ime success.\n");
+       }       
+}
+
+void msgbox(struct sgi_form *form, w32 *text, s32 user, void (*callback)(s32))
+{
+       assert(form != NULL);
+       
+       s32 r = 0;
+       sgi_msgbox_create();
+       
+       if (!g_sgi_msgbox.initialized) {
+               r = g_sgi_msgbox.init(&g_sgi_msgbox);
+               printf("sgi_msgbox init.\n");   
+       }
+       
+       if (r == 0) {
+               sgi_ncpw2u(g_sgi_msgbox.text, text, COUNTOF(g_sgi_msgbox.text));
+               form->msgbox = &g_sgi_msgbox;
+               g_sgi_msgbox.parent = form;
+               g_sgi_msgbox.x = form->wnd->x + (form->wnd->w - g_sgi_msgbox.w) / 2;
+               g_sgi_msgbox.y = form->wnd->y + (form->wnd->h - g_sgi_msgbox.h) / 2;
+               g_sgi_msgbox.redraw = 1;
+               g_sgi_msgbox.user = user;
+               g_sgi_msgbox.callback = callback;
+       }       
+}
+
+SDL_Surface *load_photo(struct passport_data *pass, s32 type)
+{
+       char file[MAX_PATH] = {0};
+       char name[sizeof(pass->uid)];
+       SDL_Surface *surface;
+       
+       if ((pass->visit & VALID_PASSPORT) != VALID_PASSPORT) {
+               return NULL;    
+       }
+       
+       if (type == PHO_SAMPLE) {
+               sgi_ncpu2a(name, pass->uid, COUNTOF(pass->uid));
+               sprintf(file, "%s/%s.jpg", PHOTO_SAMPLE_PATH, name);            
+       }
+       else if (type == PHO_REAL) {
+               sprintf(file, "%s/%s.jpg", PHOTO_REAL_PATH, pass->photo);                       
+       }
+       
+       /*  */
+       printf("photo: %s\n", file);
+       surface = IMG_Load(file);
+       printf("surface: %p\n", surface);
+       
+       return surface; 
+}
+
+void unload_photo(struct sgi_photo *photo)
+{
+       if (photo->surface) {
+               SDL_FreeSurface(photo->surface);        
+       }       
+}
+
+int alarm_ctrl(int on_off)
+{
+//     int fd;
+       int stat = -1;
+//     
+//     /*  */
+//     fd = open("/dev/mfcard", O_RDWR);
+//     if (fd == -1) {
+//             printf("Open /dev/mfcard fail.\n");
+//             goto end;
+//     }
+       
+       /*  */
+       stat = ioctl(s_mfcard_fd, MFCARD_IOCTL_ALARM, &on_off); 
+//     
+//end:
+//     /*  */
+//     close(fd);
+       
+       return stat;
+}
+
+int power_ctrl(int on_off)
+{
+//     int fd;
+       int stat = -1;
+//     
+//     /*  */
+//     fd = open("/dev/mfcard", O_RDWR);
+//     if (fd == -1) {
+//             printf("Open /dev/mfcard fail.\n");
+//             goto end;
+//     }
+       
+       /*  */
+       stat = ioctl(s_mfcard_fd, MFCARD_IOCTL_PW_CTRL, &on_off);       
+//     
+//end:
+//     /*  */
+//     close(fd);
+       
+       return stat;
+}
+
+int fpr_press_detect(void)
+{
+//     int fd;
+       int stat = 0;
+//     
+//     /*  */
+//     fd = open("/dev/mfcard", O_RDWR);
+//     if (fd == -1) {
+//             printf("Open /dev/mfcard fail.\n");
+//             goto end;
+//     }
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_FPR_STATE, &stat) < 0) {
+               printf("MFCARD_IOCTL_FPR_STATE fail.\n");
+               stat = 0;
+       }
+//     printf("fpr state: %d\n", stat);
+//             
+//end:
+//     /*  */
+//     close(fd);
+       
+       return stat;
+}
+
+int card_start(void)
+{
+//     int fd;
+       int stat = 0;
+//     
+//     /*  */
+//     fd = open("/dev/mfcard", O_RDWR);
+//     if (fd == -1) {
+//             printf("Open /dev/mfcard fail.\n");
+//             goto end;
+//     }
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_CARD_START, &stat) < 0) {
+               printf("MFCARD_IOCTL_CARD_START fail.\n");
+               stat = 0;
+       }
+//     printf("card start: %d\n", stat);
+//             
+//end:
+//     /*  */
+//     close(fd);
+       
+       return stat;
+}
+
+int card_state(void)
+{
+//     int fd;
+       int stat = 0;
+//     
+//     /*  */
+//     fd = open("/dev/mfcard", O_RDWR);
+//     if (fd == -1) {
+//             printf("Open /dev/mfcard fail.\n");
+//             goto end;
+//     }
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_CARD_STATE, &stat) < 0) {
+               printf("MFCARD_IOCTL_CARD_STATE fail.\n");
+               stat = 0;
+       }
+//     printf("card state: %d\n", stat);
+//             
+//end:
+//     /*  */
+//     close(fd);
+       
+       return stat;
+}
+
+int get_card_id(void)
+{
+//     int fd;
+       int stat = 0;
+//     
+//     /*  */
+//     fd = open("/dev/mfcard", O_RDWR);
+//     if (fd == -1) {
+//             printf("Open /dev/mfcard fail.\n");
+//             goto end;
+//     }
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_CARD_READ, &stat) < 0) {
+               printf("MFCARD_IOCTL_CARD_READ fail.\n");
+               stat = -1;
+       }
+       printf("card id: 0x%x\n", stat);
+//             
+//end:
+//     /*  */
+//     close(fd);
+       
+       return stat;
+}
+
+s32 door_ctrl(s32 flag)
+{
+       int stat = 0;
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_DOOR_CTRL, &flag) < 0) {
+               printf("MFCARD_IOCTL_CARD_READ fail.\n");
+               stat = -1;
+       }
+       
+       return stat;            
+}
+
+s32 get_door_fb(void)
+{
+       int stat = 0;
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_DOOR_FB, &stat) < 0) {
+               printf("MFCARD_IOCTL_DOOR_FB fail.\n");
+               stat = -1;
+       }
+       
+       return stat;    
+}
+
+s32 get_pw_jc(void)
+{
+       int stat = 0;
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_PW_JC, &stat) < 0) {
+               printf("MFCARD_IOCTL_PW_JC fail.\n");
+               stat = -1;
+       }
+       
+       return stat;    
+}
+
+s32 get_qwz1(void)
+{
+       int stat = 0;
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_QWZ1, &stat) < 0) {
+               printf("MFCARD_IOCTL_QWZ1 fail.\n");
+               stat = -1;
+       }
+       
+       return stat;    
+}
+
+s32 get_qwz2(void)
+{
+       int stat = 0;
+       
+       /*  */
+       if (ioctl(s_mfcard_fd, MFCARD_IOCTL_QWZ2, &stat) < 0) {
+               printf("MFCARD_IOCTL_QWZ2 fail.\n");
+               stat = -1;
+       }
+       
+       return stat;    
+}
+
+s32 mfcard_module_open(void)
+{              
+       /*  */
+       s_mfcard_fd = open("/dev/mfcard", O_RDWR);
+       if (s_mfcard_fd == -1) {
+               printf("Open /dev/mfcard fail.\n");
+       }
+       printf("Open /dev/mfcard ok.\n");
+       
+       return 0;       
+}
+
+void mfcard_module_close(void)
+{
+       if (s_mfcard_fd != -1) {
+               close(s_mfcard_fd);
+       }       
+}
+
+
+
diff --git a/src/sgi_base_box.cpp b/src/sgi_base_box.cpp
new file mode 100644 (file)
index 0000000..39e74fa
--- /dev/null
@@ -0,0 +1,224 @@
+#include "global_func.h"
+
+/* sgi-box default subroutine */
+s32 sgi_box_init_default(struct sgi_box *object)
+{
+       u32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+
+       /* 加载背景图片 */
+       for (i = 0; i < 4; ++i) {
+               object->back[i].image = request_image(object->back[i].name, 
+                       IMG_OPTIMIZE | IMG_ALPHA);
+               if (!object->back[i].image) {
+                       return FAIL;
+               }
+       }
+
+       /* 加载字体 */
+       object->font.font = request_font(object->font.name, object->font.size);
+       if (!object->font.font) {
+               return FAIL;    
+       }
+
+       /* 置初始化标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_box_deinit_default(struct sgi_box *object)
+{
+       u32 i;
+       
+       /* 释放背景图片 */
+       for (i = 0; i < 4; ++i) {
+               release_image(object->back[i].image);
+               object->back[i].image = NULL;   
+       }
+       
+       /* 释放字体 */
+       release_font(object->font.font);
+       object->font.font = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_box_frame_default(struct sgi_box *object)
+{
+       u32 i;
+       s32 index;
+       s16 x,y;
+       struct sgi_msg msg;
+       
+       /* 查看消息队列 */
+       if (object->parent->msg.empty()) {
+               return 0;
+       }
+       
+       msg = object->parent->msg.front();
+       if (msg.type != SGI_MOUSEDOWN) {
+               return 0;
+       }
+       
+       /* 判断那个按键被按下 */
+       x = msg.lparam & 0xffff;
+       y = msg.lparam >> 16;
+       index = -1;
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if ((x > object->x + object->cell[i].x + SPACE) 
+                       && (x < object->x + object->cell[i].x + object->cell[i].w - SPACE)
+                       && (y > object->y + object->cell[i].y + SPACE) 
+                       && (y < object->y + object->cell[i].y + object->cell[i].h - SPACE)) {
+                       index = i;
+                       break;          
+               }       
+       }
+       
+       /* 无按键被按下,退出处理 */
+       if (index == -1) {
+               return 0;
+       }
+       
+       if (CELL_VALID(object->cell[index].tag)) {
+               object->cell[index].state = 1 - object->cell[index].state;
+       }
+       if (object->down) {
+               object->down(object);
+       }
+       
+       /* 移除已经处理的消息 */
+       object->parent->msg.pop_front();
+       
+       /* 置重绘标志 */
+       object->redraw = 1;
+       
+       return 0;       
+}
+
+static void draw_cell_text(SDL_Surface *screen, SDL_Rect *rect, TTF_Font *font,
+       u16 *text)
+{
+       int x1 = 0;
+       int y1 = 0;
+       SDL_Surface *surface;
+       SDL_Color color = {255,255,255,0};
+       
+       /* 字体图形生成 */
+       surface = TTF_RenderUNICODE_Blended(font, text, color); 
+       
+       if (!surface) {
+               return;
+       }
+       
+       /* 对齐处理 */
+       if (rect->w > surface->w) {
+               x1 = (rect->w - surface->w) / 2;        
+       }
+       rect->x = rect->x + x1;
+       if (rect->h > surface->h) {
+               y1 = (rect->h - surface->h) / 2;                
+       }
+       rect->y = rect->y + y1;
+       rect->w = rect->w > surface->w ? surface->w : rect->w;
+       rect->h = surface->h;
+       
+       /* 将字体图形渲染到目标 */
+       SDL_BlitSurface(surface, NULL, screen, rect);   
+       
+       /* 释放字体图形资源 */
+       SDL_FreeSurface(surface);
+}
+
+void sgi_box_render_default(struct sgi_box *object, SDL_Surface *screen)
+{
+       u32 i;
+       SDL_Rect dst;
+       SDL_Rect src;
+       
+       /* 是否隐藏显示 */
+       if (!(object->parent->redraw || object->redraw) || object->hide) {
+               return;
+       }
+       
+       /* 重绘背景图片 */
+       dst.x = object->x;
+       dst.y = object->y;
+       dst.w = object->w;
+       dst.h = object->h;      
+       SDL_BlitSurface(object->back[0].image, NULL, screen, &dst);
+       
+       /* 重绘cell */
+       for (i = 0; i < BOX_NUMS; ++i) {
+               if (CELL_EMPTY(object->cell[i].tag)) {
+                       src.x = object->cell[i].x;
+                       src.y = object->cell[i].y;
+                       src.w = object->cell[i].w;
+                       src.h = object->cell[i].h;
+                       
+                       dst.x = object->x + src.x;
+                       dst.y = object->y + src.y;
+                       dst.w = src.w;
+                       dst.h = src.h;
+                       SDL_BlitSurface(object->back[3].image, &src, screen, &dst);     
+               }
+               else if (CELL_BORROW(object->cell[i].tag)) {
+                       src.x = object->cell[i].x;
+                       src.y = object->cell[i].y;
+                       src.w = object->cell[i].w;
+                       src.h = object->cell[i].h;
+                       
+                       dst.x = object->x + src.x;
+                       dst.y = object->y + src.y;
+                       dst.w = src.w;
+                       dst.h = src.h;
+                       SDL_BlitSurface(object->back[2].image, &src, screen, &dst);     
+               }
+               else if (object->cell[i].state) {
+                       src.x = object->cell[i].x;
+                       src.y = object->cell[i].y;
+                       src.w = object->cell[i].w;
+                       src.h = object->cell[i].h;
+                       
+                       dst.x = object->x + src.x;
+                       dst.y = object->y + src.y;
+                       dst.w = src.w;
+                       dst.h = src.h;
+                       SDL_BlitSurface(object->back[1].image, &src, screen, &dst);
+               }
+       }
+       
+       /* 重绘枪锁地址 */
+       if (object->cell_addr) {
+               u16 buf[8] = {0};
+               for (i = 0; i < BOX_NUMS; ++i) {                        
+                       dst.x = object->x + object->cell[i].x;
+                       dst.y = object->y + object->cell[i].y;
+                       dst.w = object->cell[i].w;
+                       dst.h = object->cell[i].h;      
+                       
+                       sgi_sprintf16(buf, L"%03d", object->cell_addr[i]);
+                       draw_cell_text(screen, &dst, object->font.font, buf);
+               }               
+       }
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;                     
+}
+
+void sgi_box_down_default(struct sgi_box *object)
+{
+
+}
+
+void sgi_box_up_default(struct sgi_box *object)
+{
+
+}
diff --git a/src/sgi_base_button.cpp b/src/sgi_base_button.cpp
new file mode 100644 (file)
index 0000000..8d87a88
--- /dev/null
@@ -0,0 +1,175 @@
+#include "global_func.h"
+
+/* sgi-button default subroutine */
+s32 sgi_button_init_default(struct sgi_button *object)
+{
+       u32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 加载背景图片 */
+       for (i = 0; i < 3; ++i) {
+               if (!object->back[i].name) {
+                       continue;
+               }
+               object->back[i].image = request_image(object->back[i].name, 
+                       IMG_OPTIMIZE | IMG_ALPHA);
+               if (!object->back[i].image) {
+                       return FAIL;
+               }
+       }
+       
+       /* 加载前景图片 */
+       if (object->front.name) {
+               object->front.image = request_image(object->front.name, 
+                       IMG_OPTIMIZE | IMG_ALPHA);
+               if (!object->front.image) {
+                       return FAIL;
+               }
+       }
+       
+       /* 置初始化标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_button_deinit_default(struct sgi_button *object)
+{
+       u32 i;
+       
+       /* 释放背景图片 */
+       for (i = 0; i < 3; ++i) {
+               release_image(object->back[i].image);
+               object->back[i].image = NULL;   
+       }
+       
+       /* 释放前景图片 */
+       release_image(object->front.image);
+       object->front.image = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_button_frame_default(struct sgi_button *object)
+{
+       s16 x,y;
+       s32 keypress = 0;
+       
+       /* 查看消息队列 */
+       if (object->parent->msg.empty()) {
+               return 0;
+       }
+
+       struct sgi_msg &msg = object->parent->msg.front();      
+       if (msg.type != SGI_MOUSEDOWN && msg.type != SGI_MOUSEUP) {
+               return 0;
+       }
+       
+       // test 
+       //printf("button has a msg.\n");
+       
+       /* 判断按键是否被按下 */
+       x = msg.lparam & 0xffff;
+       y = msg.lparam >> 16;
+       if ((x > object->x + SPACE) && (x < object->x + object->w - SPACE)
+               && (y > object->y + SPACE) && (y < object->y + object->h - SPACE)) {
+               keypress = 1;           
+       }
+               
+       if (!keypress) {
+               /* 如果按键收到弹起消息,不管坐标是否在按键之内,都要取消被按下状态 */
+               if (msg.type == SGI_MOUSEUP) {
+                       object->state &= ~1;
+                       object->redraw = 1;     
+               }
+               
+               return 0;
+       }
+       
+       switch (msg.type) {
+       case SGI_MOUSEDOWN:
+               printf("sgi_mousedown.\n");
+               if ((object->state & 2) == 0) {
+                       play_effect();
+               }
+               object->state |= 1;
+               object->redraw = 1;
+               if (object->down) {
+                       object->down(object);
+               }
+               break;
+               
+       case SGI_MOUSEUP:
+               printf("sgi_mouseup.\n");
+               if (object->up && object->state) {
+                       object->up(object);
+               }
+                       
+               object->state &= ~1;
+               object->redraw = 1;
+               break;
+               
+       default:
+               break;
+       }
+       
+       /* 移除已经处理的消息 */
+       object->parent->msg.pop_front();
+       
+       return 0;       
+}
+
+void sgi_button_render_default(struct sgi_button *object, SDL_Surface *screen)
+{
+       SDL_Rect rect;
+       s32 index;
+       
+       if (!(object->parent->redraw || object->redraw) || object->hide) {
+               return;
+       }
+       
+       /* 重绘背景图片 */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;
+       if (object->state & 2) {
+               index = 2;      
+       }
+       else {
+               index = object->state & 1;
+       }
+       if (object->back[index].image) {        
+               SDL_BlitSurface(object->back[index].image, NULL, screen, &rect);
+       }
+       
+       /* 重绘前景图片 */
+       if (object->front.image) {
+               SDL_BlitSurface(object->front.image, NULL, screen, &rect);
+       }
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;             
+}
+
+void sgi_button_down_default(struct sgi_button *object)
+{
+       
+}
+
+void sgi_button_up_default(struct sgi_button *object)
+{
+
+}
+
+void sgi_button_click_default(struct sgi_button *object)
+{
+
+}
diff --git a/src/sgi_base_check.cpp b/src/sgi_base_check.cpp
new file mode 100644 (file)
index 0000000..be4ff3e
--- /dev/null
@@ -0,0 +1,129 @@
+#include "global_func.h"
+
+/* sgi-check default subroutine */
+s32 sgi_check_init_default(struct sgi_check *object)
+{
+       u32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /*  */
+       for (i = 0; i < 2; ++i) {
+               object->image[i].image = request_image(object->image[i].name, 
+                       IMG_OPTIMIZE | IMG_ALPHA);
+               if (!object->image[i].image) {
+                       return FAIL;
+               }
+       }
+       
+       /* 置初始化标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_check_deinit_default(struct sgi_check *object)
+{
+       u32 i;
+       
+       /* 释放背景图片 */
+       for (i = 0; i < 2; ++i) {
+               release_image(object->image[i].image);
+               object->image[i].image = NULL;  
+       }
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_check_frame_default(struct sgi_check *object)
+{
+       s16 x,y;
+       s32 keypress = 0;
+       
+       /* 查看消息队列 */
+       if (object->parent->msg.empty()) {
+               return 0;
+       }
+
+       struct sgi_msg &msg = object->parent->msg.front();      
+       if (msg.type != SGI_MOUSEDOWN && msg.type != SGI_MOUSEUP) {
+               return 0;
+       }
+       
+       /* 判断按键是否被按下 */
+       x = msg.lparam & 0xffff;
+       y = msg.lparam >> 16;
+       if ((x > object->x + RADIO_SPACE) 
+               && (x < object->x + object->w - RADIO_SPACE)
+               && (y > object->y + RADIO_SPACE) 
+               && (y < object->y + object->h - RADIO_SPACE)) {
+               keypress = 1;           
+       }
+               
+       if (!keypress) {                
+               return 0;
+       }
+       
+       switch (msg.type) {
+       case SGI_MOUSEDOWN:
+               printf("check mousedown.\n");
+               play_effect();
+               object->state |= 1;
+               object->redraw = 1;
+               break;
+               
+       case SGI_MOUSEUP:
+               printf("check mouseup.\n");
+               if (object->state) {                    
+                       object->value = 1 - object->value;
+                       object->redraw = 1;
+                       
+                       if (object->up) {
+                               object->up(object);     
+                       }
+               }
+                       
+               object->state &= ~1;            
+               break;
+               
+       default:
+               break;
+       }
+       
+       /* 移除已经处理的消息 */
+       object->parent->msg.pop_front();
+       
+       return 0;       
+}
+
+void sgi_check_render_default(struct sgi_check *object, SDL_Surface *screen)
+{
+       SDL_Rect rect;
+       s32 index = 0;
+       
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       /* 重绘背景图片 */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;
+       if (object->value) {
+               index = 1;      
+       }
+
+       if (object->image[index].image) {       
+               SDL_BlitSurface(object->image[index].image, NULL, screen, &rect);
+       }
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;             
+}
diff --git a/src/sgi_base_edit.cpp b/src/sgi_base_edit.cpp
new file mode 100644 (file)
index 0000000..b756770
--- /dev/null
@@ -0,0 +1,213 @@
+#include "global_func.h"
+
+/* sgi-edit default subroutine */
+s32 sgi_edit_init_default(struct sgi_edit *object)
+{
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 申请光标资源 */
+       object->image.image = request_image(object->image.name, object->image.flags);
+       if (!object->image.image) {
+               return FAIL;
+       }
+       
+       /* 申请字体资源 */
+       object->font.font = request_font(object->font.name, object->font.size);
+       if (!object->font.font) {
+               return FAIL;    
+       }
+       
+       /* 置初始标志 */
+       object->initialized = 1;
+       
+       return 0;               
+}
+
+void sgi_edit_deinit_default(struct sgi_edit *object)
+{
+       /* 释放光标资源 */
+       release_image(object->image.image);
+       object->image.image = NULL;
+       
+       /* 释放字体资源 */
+       release_font(object->font.font);
+       object->font.font = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_edit_frame_default(struct sgi_edit *object)
+{
+       s16 x,y;
+       s32 keypress = 0;
+       
+       /* 判断控件是否拥有焦点 */
+       if (object->parent->focus_handle == object->handle) {
+               /* 光标闪烁 */
+               if (SDL_GetTicks() > object->cursor_timer) {
+                       object->cursor = 1 - object->cursor;
+                       object->redraw = 1;
+                       object->cursor_timer = SDL_GetTicks() + 500;            
+               }
+               
+               /* 查看消息队列 */
+               if (object->parent->msg.empty()) {
+                       return 0;
+               }
+               
+               /* 输入内容处理 */
+               struct sgi_msg &char_msg = object->parent->msg.front();
+               if (char_msg.type == SGI_CHAR) {
+                       if (!object->readonly) {
+                               sgi_edit_insert_text(object, char_msg.lparam);
+                       }
+                       
+                       /* 移除已经处理的消息 */
+                       object->parent->msg.pop_front();
+                       
+                       object->redraw = 1;
+                                       
+               }
+       }
+       else {
+               /* 无焦点不能拥有光标 */
+               if (object->cursor) {
+                       object->cursor = 0;
+                       object->redraw = 1;     
+               }               
+       }
+
+       /* 查看消息队列是否有按下消息 */
+       if (object->parent->msg.empty()) {
+               return 0;
+       }
+       
+       struct sgi_msg &msg = object->parent->msg.front();      
+       if (msg.type == SGI_MOUSEDOWN) {                
+               /* 判断按键是否被按下 */
+               x = msg.lparam & 0xffff;
+               y = msg.lparam >> 16;
+               if ((x > object->x + EDIT_SPACE) 
+                       && (x < object->x + object->w - EDIT_SPACE) 
+                       && (y > object->y + EDIT_SPACE) 
+                       && (y < object->y + object->h - EDIT_SPACE)) {
+                       keypress = 1;           
+               }
+               
+               if (keypress) {
+                       //printf("edit: sgi_mousedown.\n");
+                       object->parent->focus_handle = object->handle;
+                       
+                       /* 移除已经处理的消息 */
+                       object->parent->msg.pop_front();
+               }                               
+       }
+               
+       return 0;       
+}
+
+void sgi_edit_render_default(struct sgi_edit *object, SDL_Surface *screen)
+{
+       int x1 = 0;
+       int y1 = 0;
+       int y2 = 0;
+       SDL_Rect rect;
+       SDL_Rect rect_cur;
+       SDL_Surface *surface;
+       
+       assert(object->font.font != NULL);
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       /* 用背景图像刷新文字范围 */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;
+       SDL_BlitSurface(object->parent->wnd->image.image, &rect, screen, &rect);
+       
+       /* 无内容且不重绘文本层 */
+       if (object->text[0] != 0) {
+               if (object->pwdchar) {
+                       u32 i;
+                       u32 len;
+                       u16 text[64];
+                       
+                       len = sgi_len16(object->text);
+                       for (i = 0; i < len - 1; ++i) {
+                               text[i] = (u16)L'*';
+                       }
+                       text[i] = object->text[i];
+                       text[i + 1] = 0;
+                       
+                       surface = TTF_RenderUNICODE_Blended(object->font.font, 
+                               text, object->fcolor);                  
+               }
+               else {          
+                       /* 字体图形生成 */
+                       surface = TTF_RenderUNICODE_Blended(object->font.font, 
+                               object->text, object->fcolor);
+               }
+               
+               if (!surface) {
+                       return;
+               }
+                       
+               /* 对齐处理 */
+               if (object->w > surface->w) {
+                       if (object->align == DT_CENTER) {
+                               x1 = (object->w - surface->w) / 2;      
+                       }
+                       else if (object->align == DT_RIGHT) {
+                               x1 = (object->w - surface->w);
+                       }               
+               }
+               rect.x = object->x + x1;
+               if (object->h > surface->h) {
+                       y1 = (object->h - surface->h) / 2;              
+               }
+               rect.y = object->y + y1;
+               rect.w = object->w > surface->w ? surface->w : object->w;
+               rect.h = surface->h;
+               
+               /* 将字体图形渲染到目标 */
+               SDL_BlitSurface(surface, NULL, screen, &rect);
+               
+               /* 释放字体图形资源 */
+               SDL_FreeSurface(surface);
+               
+               /* 记录字体长度以便重绘光标使用 */
+               x1 = surface->w;
+       }
+       else {
+               x1 = 0; 
+       }
+       
+       /* 是否需要重绘光标 */
+       if (object->cursor) {
+               if (object->h > object->image.image->h) {
+                       y1 = (object->h - object->image.image->h) / 2;  
+                       y2 = object->image.image->h;
+               }
+               else {
+                       y1 = -2;
+                       y2 = object->image.image->h - 2;
+                       
+               }
+               rect_cur.x = object->x + x1;
+               rect_cur.y = object->y + y1;
+               rect_cur.w = object->image.image->w;
+               rect_cur.h = y2;        
+               SDL_BlitSurface( object->image.image, NULL, screen, &rect_cur);
+       }       
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;             
+}
diff --git a/src/sgi_base_form.cpp b/src/sgi_base_form.cpp
new file mode 100644 (file)
index 0000000..a84e879
--- /dev/null
@@ -0,0 +1,407 @@
+#include "global_func.h"
+
+s32 sgi_form_init_default(struct sgi_form *form)
+{
+       u32 i,r;
+       
+       if (form->initialized) {
+               return 0;
+       }
+       
+       for (i = 0; i < form->form.size(); ++i) {
+               switch (form->form[i]->type) {
+               case SGI_WINDOW:
+                       r = form->form[i]->window.init(&form->form[i]->window);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+//             case SGI_PICTURE
+//                     form->form[i].picture.init(form->form[i].window);
+//                     break;
+                       
+               case SGI_LABEL:
+                       r = form->form[i]->label.init(&form->form[i]->label);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_EDIT:
+                       r = form->form[i]->edit.init(&form->form[i]->edit);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_BUTTON:
+                       r = form->form[i]->button.init(&form->form[i]->button);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_IME:
+                       r = form->form[i]->ime.init(&form->form[i]->ime);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_BOX:
+                       r = form->form[i]->box.init(&form->form[i]->box);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_GRID:
+                       r = form->form[i]->grid.init(&form->form[i]->grid);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_RADIO:
+                       r = form->form[i]->radio.init(&form->form[i]->radio);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_CHECK:
+                       r = form->form[i]->check.init(&form->form[i]->check);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_UPDOWN:
+                       r = form->form[i]->updown.init(&form->form[i]->updown);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                       
+               case SGI_INDICATOR:
+                       r = form->form[i]->indicator.init(&form->form[i]->indicator);
+                       if (r != 0) {
+                               return FAIL;
+                       }
+                       break;
+                               
+               default:
+                       break;                  
+               }       
+       }
+       
+       form->initialized = 1;
+       
+       return 0;       
+}
+
+void sgi_form_deinit_default(struct sgi_form *form)
+{
+       u32 i;
+       
+       if (!form->initialized) {
+               return;
+       }
+       
+       for (i = 0; i < form->form.size(); ++i) {
+               switch (form->form[i]->type) {
+               case SGI_WINDOW:
+                       form->form[i]->window.deinit(&form->form[i]->window);
+                       break;
+                       
+//             case SGI_PICTURE
+//                     form->form[i].picture.init(form->form[i].window);
+//                     break;
+                       
+               case SGI_LABEL:
+                       form->form[i]->label.deinit(&form->form[i]->label);
+                       break;
+                       
+               case SGI_EDIT:
+                       form->form[i]->edit.deinit(&form->form[i]->edit);
+                       break;
+                       
+               case SGI_BUTTON:
+                       form->form[i]->button.deinit(&form->form[i]->button);
+                       break;
+                       
+               case SGI_IME:
+                       form->form[i]->ime.deinit(&form->form[i]->ime);
+                       break;
+                       
+               case SGI_BOX:
+                       form->form[i]->box.deinit(&form->form[i]->box);
+                       break;
+                       
+               case SGI_GRID:
+                       form->form[i]->grid.deinit(&form->form[i]->grid);
+                       break;
+                       
+               case SGI_RADIO:
+                       form->form[i]->radio.deinit(&form->form[i]->radio);
+                       break;
+                       
+               case SGI_CHECK:
+                       form->form[i]->check.deinit(&form->form[i]->check);
+                       break;
+                       
+               case SGI_UPDOWN:
+                       form->form[i]->updown.deinit(&form->form[i]->updown);
+                       break;
+                       
+               case SGI_INDICATOR:
+                       form->form[i]->indicator.deinit(&form->form[i]->indicator);
+                       break;
+                       
+               default:
+                       break;                  
+               }       
+       }       
+}
+
+s32 sgi_form_frame_default(struct sgi_form *form)
+{
+       u32 i;
+       
+       if (!form->initialized) {
+               return 0;
+       }
+       
+       /* 对话框处理 */
+       if (form->msgbox) {
+               form->msgbox->frame(form->msgbox);      
+       }
+       
+       /* 输入法处理 */
+       if (form->ime) {
+               form->ime->frame(form->ime);
+       }
+       
+       /* 其他控件处理 */
+       for (i = 0; i < form->form.size(); ++i) {
+               switch (form->form[i]->type) {
+               case SGI_WINDOW:
+                       if (form->form[i]->window.frame) {
+                               form->form[i]->window.frame(&form->form[i]->window);
+                       }
+                       break;
+                       
+//             case SGI_PICTURE
+//                     form->form[i].picture.init(form->form[i].window);
+//                     break;
+                       
+               case SGI_LABEL:
+                       if (form->form[i]->label.frame) {
+                               form->form[i]->label.frame(&form->form[i]->label);
+                       }
+                       break;
+                       
+               case SGI_EDIT:
+                       if (form->form[i]->edit.frame) {
+                               form->form[i]->edit.frame(&form->form[i]->edit);
+                       }
+                       break;
+                       
+               case SGI_BUTTON:
+                       form->form[i]->button.frame(&form->form[i]->button);
+                       break;
+                       
+               case SGI_IME:
+                       if (form->form[i]->ime.frame) {
+                               form->form[i]->ime.frame(&form->form[i]->ime);
+                       }
+                       break;
+               
+               case SGI_BOX:
+                       if (form->form[i]->box.frame) {
+                               form->form[i]->box.frame(&form->form[i]->box);
+                       }
+                       break;
+                               
+               case SGI_GRID:
+                       if (form->form[i]->grid.frame) {
+                               form->form[i]->grid.frame(&form->form[i]->grid);
+                       }
+                       break;
+                       
+               case SGI_RADIO:
+                       if (form->form[i]->radio.frame) {
+                               form->form[i]->radio.frame(&form->form[i]->radio);
+                       }
+                       break;
+                       
+               case SGI_CHECK:
+                       if (form->form[i]->check.frame) {
+                               form->form[i]->check.frame(&form->form[i]->check);
+                       }
+                       break;
+                       
+               case SGI_UPDOWN:
+                       if (form->form[i]->updown.frame) {
+                               form->form[i]->updown.frame(&form->form[i]->updown);
+                       }
+                       break;
+                       
+               case SGI_INDICATOR:
+                       if (form->form[i]->indicator.frame) {
+                               form->form[i]->indicator.frame(&form->form[i]->indicator);
+                       }
+                       break;
+                       
+               default:
+                       break;                  
+               }       
+       }
+       
+       return 0;               
+}
+
+void sgi_form_render_default(struct sgi_form *form, SDL_Surface *screen)
+{
+       u32 i;
+       
+       if (!form->initialized) {
+               return;
+       }
+       
+       for (i = 0; i < form->form.size(); ++i) {
+               switch (form->form[i]->type) {
+               case SGI_WINDOW:
+                       if (form->form[i]->window.render) {
+                               form->form[i]->window.render(&form->form[i]->window, screen);
+                       }
+                       break;
+                       
+               case SGI_PHOTO:
+                       if (form->form[i]->photo.render) {
+                               form->form[i]->photo.render(&form->form[i]->photo, screen);
+                       }
+                       break;
+                       
+               case SGI_LABEL:
+                       if (form->form[i]->label.render) {
+                               form->form[i]->label.render(&form->form[i]->label, screen);
+                       }
+                       break;
+                       
+               case SGI_EDIT:
+                       if (form->form[i]->edit.render) {
+                               form->form[i]->edit.render(&form->form[i]->edit, screen);
+                       }
+                       break;
+                       
+               case SGI_BUTTON:
+                       if (form->form[i]->button.render) {
+                               form->form[i]->button.render(&form->form[i]->button, screen);
+                       }
+                       break;
+                       
+               case SGI_IME:
+                       if (form->form[i]->ime.render) {
+                               form->form[i]->ime.render(&form->form[i]->ime, screen);
+                       }
+                       break;
+                       
+               case SGI_BOX:
+                       if (form->form[i]->box.render) {
+                               form->form[i]->box.render(&form->form[i]->box, screen);
+                       }
+                       break;
+                       
+               case SGI_GRID:
+                       if (form->form[i]->grid.render) {
+                               form->form[i]->grid.render(&form->form[i]->grid, screen);
+                       }
+                       break;
+                       
+               case SGI_RADIO:
+                       if (form->form[i]->radio.render) {
+                               form->form[i]->radio.render(&form->form[i]->radio, screen);
+                       }
+                       break;
+                       
+               case SGI_CHECK:
+                       if (form->form[i]->check.render) {
+                               form->form[i]->check.render(&form->form[i]->check, screen);
+                       }
+                       break;
+                       
+               case SGI_UPDOWN:
+                       if (form->form[i]->updown.render) {
+                               form->form[i]->updown.render(&form->form[i]->updown, screen);
+                       }
+                       break;
+                       
+               case SGI_INDICATOR:
+                       if (form->form[i]->indicator.render) {
+                               form->form[i]->indicator.render(&form->form[i]->indicator, screen);     
+                       }
+                       break;
+                       
+               default:
+                       break;                  
+               }       
+       }
+       
+       /* 输入法模块处理 */
+       if (form->ime) {
+               form->ime->render(form->ime, screen);
+       }
+       
+       /* 对话框显示 */
+       if (form->msgbox) {
+               if (form->dirty) {
+                       form->msgbox->redraw = 1;
+               }
+               form->msgbox->render(form->msgbox, screen);     
+       }
+       
+       /* 更新显示 */
+       if (form->dirty) {
+               SDL_UpdateRect(screen, form->x1, form->y1, 
+                       form->x2 - form->x1, form->y2 - form->y1);
+               
+               form->dirty = 0;
+               form->redraw = 0;
+               form->x1 = X_RES;
+               form->y1 = Y_RES;
+               form->x2 = 0;
+               form->y2 = 0;           
+       }       
+}
+
+void form_memset(struct sgi_form *form)
+{
+       form->name = NULL;
+       form->form.clear();
+       form->msg.clear();
+       form->wnd = NULL;
+       form->ime = NULL;
+       form->msgbox = NULL;
+       
+       form->initialized = 0;
+       form->redraw = 0;
+       form->dirty = 0;
+       form->x1 = 0;
+       form->x2 = 0;
+       form->y1 = 0;
+       form->y2 = 0;
+       
+       form->init = NULL;
+       form->deinit = NULL;
+       form->frame = NULL;
+       form->render = NULL;
+       
+       form->enter = NULL;
+       form->exit = NULL;
+       
+       form->add = NULL;
+       form->del = NULL;
+       form->sort = NULL;      
+}
diff --git a/src/sgi_base_grid.cpp b/src/sgi_base_grid.cpp
new file mode 100644 (file)
index 0000000..09b9db7
--- /dev/null
@@ -0,0 +1,267 @@
+#include "global_func.h"
+
+/* sgi-grid default subroutine */
+s32 sgi_grid_init_default(struct sgi_grid *object)
+{
+       u32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 加载图片 */      
+       object->back.image = request_image(object->back.name, 
+               IMG_OPTIMIZE | IMG_ALPHA);
+       if (!object->back.image) {
+               return FAIL;
+       }
+       
+       object->action.image = request_image(object->action.name,
+               IMG_OPTIMIZE | IMG_ALPHA);
+       
+       /* 加载字体 */
+       object->font.font = request_font(object->font.name, object->font.size);
+       if (!object->font.font) {
+               return FAIL;    
+       }
+       
+       /* 置初始化标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_grid_deinit_default(struct sgi_grid *object)
+{
+       u32 i;
+       
+       /* 释放图片 */
+       release_image(object->back.image);
+       object->back.image = NULL;
+       release_image(object->action.image);
+       object->action.image = NULL;    
+       
+       /* 释放字体 */
+       release_font(object->font.font);
+       object->font.font = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+static void grid_radio_handle(struct sgi_grid *object, s32 index)
+{
+       s32 pos;
+       s32 i;
+       s32 old_val = object->cells[index].val;
+       
+       pos = index / object->col * object->col;
+       printf("pos: %d, index: %d\n", pos, index);
+       for (i = pos; i < pos + object->col; ++i) {
+               if (object->cells[i].type == GRID_RADIO) {
+                       if (i != index) {
+                               object->cells[i].val = 0;       
+                       }
+                       else {
+                               object->cells[i].val = 1;       
+                       }       
+               }       
+       }
+       
+       if (object->cells[index].val != old_val) {
+               object->changed = 1;
+       }       
+}
+
+static void grid_button_handle(struct sgi_grid *object, s32 index)
+{
+       s32 row = index / object->col;
+       
+       if (object->up) {
+               printf("grid row (2): %d\n", row);
+               object->up(object, row);
+       }       
+}
+
+s32 sgi_grid_frame_default(struct sgi_grid *object)
+{
+       s32 i,j;
+       s32 index,pos;
+       s16 x,y;
+       struct sgi_msg msg;
+       
+       /* 只读表格不响应按键动作 */
+       if (object->readonly) {
+               return 0;
+       }
+       
+       /* 查看消息队列 */
+       if (object->parent->msg.empty()) {
+               return 0;
+       }
+       
+       msg = object->parent->msg.front();
+       if (msg.type != SGI_MOUSEDOWN && msg.type != SGI_MOUSEUP) {
+               return 0;
+       }
+       
+       /* 判断那个按键被按下 */
+       x = msg.lparam & 0xffff;
+       y = msg.lparam >> 16;
+       index = -1;
+       for (i = 0; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       pos = i * object->col + j;
+                       if ((x > object->cells[pos].x)
+                               && (x < object->cells[pos].x + object->cells[pos].w)
+                               && (y > object->cells[pos].y)
+                               && (y < object->cells[pos].y + object->cells[pos].h)) {
+                               index = pos;
+                               break;
+                       }                       
+               }
+       }
+       
+       /* 无按键被按下,退出处理 */
+       if (index == -1) {
+               if (msg.type == SGI_MOUSEUP) {
+                       for (i = 0; i < object->col * object->row; ++i) {
+                               object->cells[i].state &= ~1;
+                       }
+               }
+               
+               return 0;
+       }
+       
+       /* */
+       if (object->cells[index].type == GRID_STRING) {
+               return 0;
+       }
+       
+       if (msg.type == SGI_MOUSEDOWN) {
+               object->cells[index].state |= 1;        
+       }
+       else {
+               if (object->cells[index].state) {
+                       if (object->cells[index].type == GRID_RADIO) {
+                               grid_radio_handle(object, index);       
+                       }
+                       else if (object->cells[index].type == GRID_BUTTON) {
+                               grid_button_handle(object, index);      
+                       }
+               }
+               
+               for (i = 0; i < object->col * object->row; ++i) {
+                       object->cells[i].state &= ~1;
+               }       
+       }
+       
+       /* 置重绘标志 */
+       object->redraw = 1;
+       
+       return 0;       
+}
+
+static void draw_cell_text(SDL_Surface *screen, SDL_Rect *rect, TTF_Font *font,
+       u16 *text)
+{
+       int x1 = 0;
+       int y1 = 0;
+       SDL_Surface *surface;
+       SDL_Color color = {0,0,0,0};
+       
+       if (!text || text[0] == 0) {
+               return;
+       }
+       
+       /* 字体图形生成 */
+       surface = TTF_RenderUNICODE_Blended(font, text, color); 
+       
+       if (!surface) {
+               return;
+       }
+       
+       /* 对齐处理 */
+       if (rect->w > surface->w) {
+               x1 = (rect->w - surface->w) / 2;        
+       }
+       rect->x = rect->x + x1;
+       if (rect->h > surface->h) {
+               y1 = (rect->h - surface->h + 1) / 2;            
+       }
+       rect->y = rect->y + y1;
+       rect->w = rect->w > surface->w ? surface->w : rect->w;
+       rect->h = surface->h;
+       printf("surface->h: %d, y1: %d\n", surface->h, y1);
+       
+       /* 将字体图形渲染到目标 */
+       SDL_BlitSurface(surface, NULL, screen, rect);   
+       
+       /* 释放字体图形资源 */
+       SDL_FreeSurface(surface);
+}
+
+void sgi_grid_render_default(struct sgi_grid *object, SDL_Surface *screen)
+{
+       s32 i;
+       SDL_Rect dst;
+       SDL_Rect src;
+       
+       /* 是否隐藏显示 */
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       /* 重绘背景图片 */
+       dst.x = object->x;
+       dst.y = object->y;
+       dst.w = object->w;
+       dst.h = object->h;      
+       SDL_BlitSurface(object->back.image, NULL, screen, &dst);
+       
+       /* 重绘cell */
+       for (i = 0; i < object->col * object->row; ++i) {
+               switch (object->cells[i].type) {
+               case GRID_STRING:
+                       dst.x = object->cells[i].x;
+                       dst.y = object->cells[i].y;
+                       dst.w = object->cells[i].w;
+                       dst.h = object->cells[i].h;
+                       draw_cell_text(screen, &dst, object->font.font,
+                               object->cells[i].string);               
+                       break;
+               
+               case GRID_RADIO:
+                       if (object->cells[i].val) {
+                               dst.x = object->cells[i].x;
+                               dst.y = object->cells[i].y;
+                               dst.w = object->cells[i].w;
+                               dst.h = object->cells[i].h;
+                               SDL_BlitSurface(object->action.image, NULL,
+                                       screen, &dst);  
+                       }
+                       break;
+                       
+               case GRID_BUTTON:
+                       if (object->cells[i].state & 1) {
+                               dst.x = object->cells[i].x;
+                               dst.y = object->cells[i].y;
+                               dst.w = object->cells[i].w;
+                               dst.h = object->cells[i].h;
+                               SDL_BlitSurface(object->action.image, NULL,
+                                       screen, &dst);  
+                       }
+                       break;
+                       
+               default:
+                       break;
+               }
+       }
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;                     
+}
+
diff --git a/src/sgi_base_ime.cpp b/src/sgi_base_ime.cpp
new file mode 100644 (file)
index 0000000..e829baf
--- /dev/null
@@ -0,0 +1,452 @@
+#include "global_func.h"
+
+/* sgi-ime default subroutine */
+s32 sgi_ime_init_default(struct sgi_ime *object)
+{
+       u32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 加载背景图片 */
+       for (i = 0; i < 2; ++i) {
+               object->back[i].image = request_image(object->back[i].name, 
+                       IMG_OPTIMIZE | IMG_ALPHA);
+               if (!object->back[i].image) {
+                       return FAIL;
+               }
+       }
+       
+       /* 加载字体 */
+       object->font.font = request_font(object->font.name, object->font.size);
+       if (!object->font.font) {
+               return FAIL;    
+       }
+       
+       /* 置初始化标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_ime_deinit_default(struct sgi_ime *object)
+{
+       u32 i;
+       
+       /* 释放背景图片 */
+       for (i = 0; i < 2; ++i) {
+               release_image(object->back[i].image);
+               object->back[i].image = NULL;   
+       }
+       
+       /* 释放字体 */
+       release_font(object->font.font);
+       object->font.font = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_ime_frame_default(struct sgi_ime *object)
+{
+       u32 i;
+       s32 index,pos;
+       s16 x,y;
+       u16 ch;
+       
+       /* 查看消息队列 */
+       if (object->hide || object->parent->msg.empty()) {
+               return 0;
+       }
+       
+       struct sgi_msg &msg = object->parent->msg.front();
+       if (msg.type != SGI_MOUSEDOWN && msg.type != SGI_MOUSEUP) {
+               return 0;
+       }
+       
+       /* 判断那个按键被按下 */
+       x = msg.lparam & 0xffff;
+       y = msg.lparam >> 16;
+       
+       /* 在中文模式下扫描文字选择区 */
+       do {
+               if (object->mode != IME_PINYIN) {
+                       break;
+               }
+               
+               index = -1;
+               for (i = 0; i < SELECTOR_NUMS; ++i) {
+                       if ((x > object->x + object->selector[i].x)
+                               && (x < object->x + object->selector[i].x + object->selector[i].w)
+                               && (y > object->y + object->selector[i].y)
+                               && (y < object->y + object->selector[i].y + object->selector[i].h)) {
+                               index = i;
+                       }       
+               }
+               
+               //printf("selector: %d\n", index);
+               
+               if (index == -1) {
+                       break;
+               }
+               
+               if (msg.type == SGI_MOUSEUP) {
+                       for (i = 0; i < SELECTOR_NUMS; ++i) {
+                               object->selector[i].state &= ~1;        
+                       }
+               }
+               else {
+                       switch (index) {
+                       case 0: /* 上一页 */
+                               if (object->chinese.page > 0) {
+                                       object->chinese.page--; 
+                               }
+                               else {
+                                       object->chinese.page = 0;
+                               }
+                               object->selector[index].state |= 1;
+                               break;
+                               
+                       case 1: /*拼音显示区 */
+                               break;
+                               
+                       case 2: /* 选字区 */
+                       case 3:
+                       case 4:
+                       case 5:
+                       case 6:
+                       case 7:
+                       case 8:
+                               pos = object->chinese.page * 7 + (index - 2);
+                               if (pos < object->chinese.count) {
+                                       struct sgi_msg m;
+                                       m.type = SGI_CHAR;
+                                       m.wparam = 0;
+                                       m.lparam = (u16)object->chinese.chinese[pos];
+                                       object->parent->msg.push_back(m);
+                                       
+                                       /* 清除选择面板 */
+                                       memset(&object->chinese, 0, sizeof(struct sgi_ime_chinese));    
+                               }
+                               object->selector[index].state |= 1;
+                               break;
+                               
+                       case 9: /* 下一页 */
+                               if (object->chinese.page < object->chinese.count / 7) { /* 7个选字框 */
+                                       object->chinese.page++; 
+                               }
+                               else {
+                                       object->chinese.page = object->chinese.count / 7;
+                               }
+                               object->selector[index].state |= 1;
+                               break;  
+                       
+                       default:
+                               break;                          
+                       }       
+               }
+               
+               goto finished; 
+               
+       } while (0);
+       
+       /* 扫描普通按键区 */
+       index = -1;
+       for (i = 0; i < KEY_NUMS; ++i) {
+               if ((x > object->key[i].x + object->x + SPACE) 
+                       && (x < object->x + object->key[i].x + object->key[i].w - SPACE)
+                       && (y > object->y + object->key[i].y + SPACE) 
+                       && (y < object->y + object->key[i].y + object->key[i].h - SPACE)) {
+                       index = i;
+                       //printf("key press: %d\n", index);
+                       break;          
+               }       
+       }
+       
+       /* 无按键被按下,退出处理 */
+       if (index == -1) {
+               /* 如果按键收到弹起消息,不管坐标是否在按键之内,都要取消被按下状态 */
+               if (msg.type == SGI_MOUSEUP) {
+                       for (i = 0; i < KEY_NUMS; ++i) {
+                               object->key[i].state &= ~1;
+                               object->redraw = 1;
+                       }       
+               }
+               
+               /* 如果坐标落在输入法框范围内, 则移除按键消息,防止后面程序响应 */
+               if (x > object->x + 78 && x < object->x + object->w - 78
+                       && y > object->y && y < object->y + object->h) {
+                       object->parent->msg.pop_front();                
+               }
+               
+               return 0;
+       }
+       
+       switch (msg.type) {
+       case SGI_MOUSEDOWN:
+               play_effect();
+               object->state |= 1;
+               object->key[index].state |= 1;
+               if (object->mode == IME_PINYIN) {
+                       ch = object->word[object->mode].word[index];
+                       if (ch == 0x0008) { /* del */
+                               if (object->chinese.syllables[0] == 0) {
+                                       struct sgi_msg m;
+                                       m.type = SGI_CHAR;
+                                       m.wparam = 0;
+                                       m.lparam = 0x0008;
+                                       object->parent->msg.push_back(m);       
+                               }
+                               else {
+                                       sgi_rdel16(object->chinese.syllables, 
+                                               COUNTOF(object->chinese.syllables));
+                               }       
+                       }
+                       else if (ch != 0x001b) {
+                               //char buf[8] = {0};
+                               //printf("syllables ch: %x\n", ch);
+                               if (ch >= 'a' && ch <= 'z') {                   
+                                       sgi_ncat16(object->chinese.syllables, ch, 6);
+                               }
+                               //printf("syllables: %s\n", sgi_cpu2a(buf, object->chinese.syllables)); 
+                       }
+                       
+                       if (object->chinese.syllables[0] == 0) { /* 无拼音输入 */
+                               memset(&object->chinese, 0, sizeof(struct sgi_ime_chinese));    
+                       }
+                       else {
+                               object->chinese.chinese = decode_syllables(object->chinese.syllables);
+                               if (object->chinese.chinese) {
+                                       object->chinese.count = wcslen(object->chinese.chinese);
+                               }
+                               else {
+                                       object->chinese.count = 0;
+                               }
+                               object->chinese.page = 0;                               
+                       }               
+               }
+               else {
+                       if  (object->word[object->mode].word[index] != 0x001B){
+                               struct sgi_msg m;
+                               m.type = SGI_CHAR;
+                               m.wparam = 0;
+                               m.lparam = object->word[object->mode].word[index];
+                               object->parent->msg.push_back(m);
+                       }                       
+               }
+               
+               if (object->down) {
+                       object->down(object);
+               }
+               break;
+               
+       case SGI_MOUSEUP:
+               object->state &= ~1;
+               object->key[index].state &= ~1;
+               
+               /* 判断是否切换输入法按键 */
+               if (object->word[object->mode].word[index] == 0x001B) {
+                       object->mode++;
+                       if (object->mode == IME_PINYIN) {
+                               /* 清零中文输入法缓冲区 */
+                               memset(&object->chinese, 0, sizeof(struct sgi_ime_chinese));    
+                       }
+                       if (object->mode > IME_PINYIN) {
+                               object->mode = IME_CHAR;        
+                       }       
+               }
+               
+               if (object->up) {
+                       object->up(object);
+               }
+               break;
+               
+       default:
+               break;
+       }
+       
+finished:
+       
+       /* 移除已经处理的消息 */
+       object->parent->msg.pop_front();
+       
+       /* 置重绘标志 */
+       object->redraw = 1;
+       
+       return 0;       
+}
+
+static void draw_key_text(SDL_Surface *screen, SDL_Rect *rect, TTF_Font *font,
+       const u16 *text)
+{
+       int x1 = 0;
+       int y1 = 0;
+       SDL_Surface *surface;
+       SDL_Color color = {0,0,0,0};
+       
+       /* 字体图形生成 */
+       surface = TTF_RenderUNICODE_Blended(font, text, color); 
+       
+       if (!surface) {
+               return;
+       }
+       
+       /* 对齐处理 */
+       if (rect->w > surface->w) {
+               x1 = (rect->w - surface->w) / 2;        
+       }
+       rect->x = rect->x + x1;
+       if (rect->h > surface->h) {
+               y1 = (rect->h - surface->h) / 2;                
+       }
+       rect->y = rect->y + y1;
+       rect->w = rect->w > surface->w ? surface->w : rect->w;
+       rect->h = surface->h;
+       
+       /* 将字体图形渲染到目标 */
+       SDL_BlitSurface(surface, NULL, screen, rect);   
+       
+       /* 释放字体图形资源 */
+       SDL_FreeSurface(surface);
+}
+
+void sgi_ime_render_default(struct sgi_ime *object, SDL_Surface *screen)
+{
+       u32 i;
+       s32 index;
+       SDL_Rect rect;
+       SDL_Rect dest;
+       
+       /* 是否隐藏显示 */
+       if (!(object->parent->redraw || object->redraw) || object->hide) {
+               return;
+       }
+       
+       /* 重绘背景图片 */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;     
+       SDL_BlitSurface(object->back[0].image, NULL, screen, &rect); 
+       
+       if (object->mode == IME_PINYIN) {
+               index = -1;
+               for (i = 0; i < SELECTOR_NUMS; ++i) {
+                       if (object->selector[i].state & 1) {
+                               index = i;
+                               break;
+                       }
+               }
+               
+               //printf("render py: %d\n", index);
+               if (index != -1) {
+                       rect.x = object->selector[index].x;
+                       rect.y = object->selector[index].y;
+                       rect.w = object->selector[index].w;
+                       rect.h = object->selector[index].h;
+                       
+                       dest.x = object->x + rect.x;
+                       dest.y = object->y + rect.y;
+                       dest.w = rect.w;
+                       dest.h = rect.h;
+                       
+                       i = SDL_BlitSurface(object->back[1].image, &rect, screen, &dest);
+                       if (i != 0) {
+                               printf("draw err: %s\n",  SDL_GetError() );
+                       }       
+               }               
+
+               /* 重绘选择区文字 */
+               u16 buf[4];
+               s32 pos;                
+               
+               /* 重绘 << */
+               buf[0] = '<';
+               buf[1] = '<';
+               buf[2] = 0;
+               rect.x = object->x + object->selector[0].x;
+               rect.y = object->y + object->selector[0].y;
+               rect.w = object->selector[0].w;
+               rect.h = object->selector[0].h;
+               draw_key_text(screen, &rect, object->font.font, buf);
+               
+               /* 重绘 >> */
+               buf[0] = '>';
+               buf[1] = '>';
+               buf[2] = 0;
+               rect.x = object->x + object->selector[9].x;
+               rect.y = object->y + object->selector[9].y;
+               rect.w = object->selector[9].w;
+               rect.h = object->selector[9].h;
+               draw_key_text(screen, &rect, object->font.font, buf);
+               
+               /* 重绘音节 */
+               rect.x = object->x + object->selector[1].x;
+               rect.y = object->y + object->selector[1].y;
+               rect.w = object->selector[1].w;
+               rect.h = object->selector[1].h;
+               draw_key_text(screen, &rect, object->font.font, object->chinese.syllables);
+               
+               /* 重绘拼音汉字 */
+               for (i = 0; i < 7; ++i) {
+                       pos = object->chinese.page * 7 + i;
+                       if (pos > object->chinese.count - 1) {
+                               break;
+                       }
+                       
+                       buf[0] = (u16)object->chinese.chinese[pos];
+                       buf[1] = 0;
+                       rect.x = object->x + object->selector[i + 2].x;
+                       rect.y = object->y + object->selector[1 + 2].y;
+                       rect.w = object->selector[i + 2].w;
+                       rect.h = object->selector[i + 2].h;
+                       draw_key_text(screen, &rect, object->font.font, buf);                   
+               }               
+       }
+       
+       /* 重绘被按下按键 */
+       if (object->state & 1) {        
+               index = -1;
+               for (i = 0; i < KEY_NUMS; ++i) {
+                       if (object->key[i].state & 1) {
+                               index = i;
+                               //printf("key redraw: %d\n", index);
+                               break;  
+                       }       
+               }
+               if (index != -1) {
+                       rect.x = object->key[index].x;
+                       rect.y = object->key[index].y;
+                       rect.w = object->key[index].w;
+                       rect.h = object->key[index].h;
+                       
+                       dest.x = object->x + object->key[index].x;
+                       dest.y = object->y + object->key[index].y;
+                       dest.w = object->key[index].w;
+                       dest.h = object->key[index].h;
+                       
+                       i = SDL_BlitSurface(object->back[1].image, &rect, screen, &dest);
+                       if (i != 0) {
+                               printf("draw err: %s\n",  SDL_GetError() );
+                       }
+               }
+       }
+       
+       /* 重绘按键文字 */
+       for (i = 0; i < KEY_NUMS; ++i) {
+               rect.x = object->x + object->key[i].x;
+               rect.y = object->y + object->key[i].y;
+               rect.w = object->key[i].w;
+               rect.h = object->key[i].h;
+               draw_key_text(screen, &rect, object->font.font, 
+                       object->caption[object->mode].text[i]);
+       }
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;                     
+}
+
diff --git a/src/sgi_base_indicator.cpp b/src/sgi_base_indicator.cpp
new file mode 100644 (file)
index 0000000..3f6bd12
--- /dev/null
@@ -0,0 +1,65 @@
+#include "global_func.h"
+
+/* sgi-picture default subroutine */
+s32 sgi_indicator_init_default(struct sgi_indicator *object)
+{
+       u32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 申请资源 */
+       for (i = 0; i < 2; ++i) {
+               object->image[i].image = request_image(object->image[i].name, 
+                       object->image[i].flags);
+       }
+       
+       /* 置初始标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_indicator_deinit_default(struct sgi_indicator *object)
+{
+       u32 i;
+       
+       /* 释放资源 */
+       for (i = 0; i < 2; ++i) {
+               release_image(object->image[i].image);
+               object->image[i].image = NULL;
+       }
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_indicator_frame_default(struct sgi_indicator *object)
+{
+       return 0;       
+}
+
+void sgi_indicator_render_default(struct sgi_indicator *object, SDL_Surface *screen)
+{
+       SDL_Rect rect;
+       
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;
+       if (object->image[object->state & 1].image) {   
+               SDL_BlitSurface(object->image[object->state & 1].image, NULL, 
+                       screen, &rect);
+       }
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;     
+}
diff --git a/src/sgi_base_label.cpp b/src/sgi_base_label.cpp
new file mode 100644 (file)
index 0000000..0c7675c
--- /dev/null
@@ -0,0 +1,95 @@
+#include "global_func.h"
+
+/* sgi-label default subroutine */
+s32 sgi_label_init_default(struct sgi_label *object)
+{
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 申请资源 */
+       object->font.font = request_font(object->font.name, object->font.size);
+       if (!object->font.font) {
+               return FAIL;    
+       }
+       
+       /* 置初始标志 */
+       object->initialized = 1;
+       
+       return 0;       
+}
+
+void sgi_label_deinit_default(struct sgi_label *object)
+{
+       /* 释放资源 */
+       release_font(object->font.font);
+       object->font.font = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;                
+}
+
+s32 sgi_label_frame_default(struct sgi_label *object)
+{
+       return 0;       
+}
+
+void sgi_label_render_default(struct sgi_label *object, SDL_Surface *screen)
+{
+       int x1 = 0;
+       int y1 = 0;
+       SDL_Rect rect;
+       SDL_Surface *surface;
+       
+       assert(object->font.font != NULL);
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       if (object->caption[0] == 0) { /* Caption为空 */
+               return;
+       }       
+       
+       /* 字体图形生成 */
+       surface = TTF_RenderUNICODE_Blended(object->font.font, object->caption, 
+                               object->fcolor);
+       if (!surface) {
+               return;
+       }
+       
+       /* 用背景图像刷新文字范围 */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;
+       SDL_BlitSurface(object->parent->wnd->image.image, &rect, screen, &rect);
+       
+       /* 对齐处理 */
+       if (object->w > surface->w) {
+               if (object->align == DT_CENTER) {
+                       x1 = (object->w - surface->w) / 2;      
+               }
+               else if (object->align == DT_RIGHT) {
+                       x1 = (object->w - surface->w);
+               }               
+       }
+       rect.x = object->x + x1;
+       if (object->h > surface->h) {
+               y1 = (object->h - surface->h) / 2;              
+       }
+       rect.y = object->y + y1;
+       rect.w = object->w > surface->w ? surface->w : object->w;
+       rect.h = surface->h;
+       
+       /* 将字体图形渲染到目标 */
+       SDL_BlitSurface(surface, NULL, screen, &rect);  
+       
+       /* 释放字体图形资源 */
+       SDL_FreeSurface(surface);
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;     
+}
diff --git a/src/sgi_base_msgbox.cpp b/src/sgi_base_msgbox.cpp
new file mode 100644 (file)
index 0000000..738c150
--- /dev/null
@@ -0,0 +1,231 @@
+#include "global_func.h"
+
+/* sgi-label default subroutine */
+static void release_msgbox(struct sgi_msgbox *object)
+{
+       object->parent->redraw = 1;
+       object->parent->msgbox = NULL;  
+       
+       if (object->callback) {
+               object->callback(object->user);
+       }
+}
+
+s32 sgi_msgbox_init_default(struct sgi_msgbox *object)
+{
+       s32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 加载背景和提示图片 */
+       for (i = 0; i < 4; ++i) {
+               object->image[i].image = request_image(object->image[i].name, 
+                       IMG_OPTIMIZE | IMG_ALPHA);
+       }
+       if (!object->image[0].image || !object->image[2].image
+               || !object->image[3].image) { /* 背景图片不能为空 */
+               return FAIL;
+       }
+       
+       printf("msgbox request font.\n");
+       /* 加载字体 */
+       object->font.font = request_font(object->font.name, object->font.size);
+       if (!object->font.font) {
+               return FAIL;    
+       }       
+       
+       /* 根据背景图片设置尺寸 */
+       object->w = object->image[0].image->w;
+       object->h = object->image[0].image->h;
+       object->button.w = object->image[2].image->w;
+       object->button.h = object->image[2].image->h;
+       
+       /* 置初始标志 */
+       object->initialized = 1;
+       
+       return 0;       
+}
+
+void sgi_msgbox_deinit_default(struct sgi_msgbox *object)
+{
+       u32 i;
+       
+       /* 释放背景图片 */
+       for (i = 0; i < 2; ++i) {
+               release_image(object->image[i].image);
+               object->image[i].image = NULL;  
+       }
+       
+       /* 释放字体 */
+       release_font(object->font.font);
+       object->font.font = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;                
+}
+
+s32 sgi_msgbox_frame_default(struct sgi_msgbox *object)
+{
+       s16 x,y;
+       s32 keypress = 0;
+       
+       /* 查看消息队列 */
+       if (object->parent->msg.empty()) {
+               return 0;
+       }
+
+       struct sgi_msg &msg = object->parent->msg.front();      
+       if (msg.type != SGI_MOUSEDOWN && msg.type != SGI_MOUSEUP) {
+               object->parent->msg.pop_front();
+               return 0;
+       }
+       
+       /* 判断按键是否被按下 */
+       x = msg.lparam & 0xffff;
+       y = msg.lparam >> 16;
+       if (x > object->x + object->button.x 
+               && x < object->x + object->button.x + object->button.w
+               && y > object->y + object->button.y
+               && y < object->y + object->button.y + object->button.h) {               
+               keypress = 1;           
+       }
+       
+       if (!keypress) {
+               /* 如果按键收到弹起消息,不管坐标是否在按键之内,都要取消被按下状态 */
+               if (msg.type == SGI_MOUSEUP) {
+                       object->button.state &= ~1;
+                       object->redraw = 1;     
+               }
+               
+               object->parent->msg.pop_front();
+               return 0;
+       }
+       
+       switch (msg.type) {
+       case SGI_MOUSEDOWN:
+               play_effect();
+               object->button.state |= 1;
+               object->redraw = 1;
+               
+               object->parent->msg.pop_front();
+               break;
+               
+       case SGI_MOUSEUP:
+               object->button.state &= ~1;
+               object->redraw = 1;
+               
+               /* 清空消息队列 */
+               object->parent->msg.clear();                            
+               release_msgbox(object);
+               break;
+               
+       default:
+               break;
+       }
+       
+#if 0
+       s16 x,y;
+       
+       /* 查看消息队列 */        
+       while (!object->parent->msg.empty()) {
+               struct sgi_msg &msg = object->parent->msg.front();
+               if (msg.type == SGI_MOUSEDOWN) {
+                       x = msg.lparam & 0xffff;
+                       y = msg.lparam >> 16;
+                       if (x > object->x + object->button->x 
+                               && x < object->x + object-button->w
+                               && y > object->y + object->button->y
+                               && y < object->y + object-button->h) {
+                               
+                               /* 清空消息队列 */
+                               object->parent->msg.clear();
+                               
+                               release_msgbox(object);
+                               break;          
+                       }
+               }
+               
+               object->parent->msg.pop_front();                
+       }
+#endif
+       
+       
+       return 0;       
+}
+
+void sgi_msgbox_render_default(struct sgi_msgbox *object, SDL_Surface *screen)
+{
+       int x1 = 0;
+       int y1 = 0;
+       SDL_Rect rect;
+       SDL_Rect src;
+       SDL_Color color = {0, 0, 0, 0};
+       SDL_Surface *surface;
+       
+       assert(object->font.font != NULL);
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       if (object->text == NULL) { /* Caption为空 */
+               return;
+       }       
+       
+       /* 字体图形生成 */
+       surface = TTF_RenderUNICODE_Blended(object->font.font, object->text, color);
+       if (!surface) {
+               return;
+       }
+       
+       /* 用背景图像刷新文字范围 */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;
+       SDL_BlitSurface(object->image[0].image, NULL, screen, &rect);
+       
+       /* 按键图像 */
+       rect.x = object->x + object->button.x;
+       rect.y = object->y + object->button.y;
+       rect.w = object->button.w;
+       rect.h = object->button.h;
+       if (object->button.state & 1) {
+               SDL_BlitSurface(object->image[3].image, NULL, screen, &rect);   
+       }
+       else {
+               SDL_BlitSurface(object->image[2].image, NULL, screen, &rect);   
+       }
+       
+       /* 对齐处理 */
+       if (object->w > surface->w) {
+               x1 = (object->w - surface->w) / 2;              
+       }
+       
+       if (object->h > surface->h) {
+               y1 = (object->h - surface->h - 70) / 2;         
+       }
+       
+       rect.x = object->x + x1;
+       rect.y = object->y + y1;
+       rect.w = object->w > surface->w ? surface->w : object->w;
+       rect.h = surface->h;
+       
+       src.x = 0;
+       src.y = 0;
+       src.w = rect.w;
+       src.h = rect.h;
+       
+       /* 将字体图形渲染到目标 */
+       SDL_BlitSurface(surface, &src, screen, &rect);  
+       
+       /* 释放字体图形资源 */
+       SDL_FreeSurface(surface);
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;     
+}
diff --git a/src/sgi_base_picture.cpp b/src/sgi_base_picture.cpp
new file mode 100644 (file)
index 0000000..3f4e755
--- /dev/null
@@ -0,0 +1,82 @@
+#include "global_func.h"
+
+/* sgi-picture default subroutine */
+s32 sgi_picture_init_default(struct sgi_picture *object)
+{
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 申请资源 */
+       object->image.image = request_image(object->image.name, object->image.flags);
+       if (!object->image.image) {
+               return FAIL;
+       }
+       
+       /* 置初始标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_picture_deinit_default(struct sgi_picture *object)
+{
+       /* 释放资源 */
+       release_image(object->image.image);
+       object->image.image = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_picture_frame_default(struct sgi_picture *object)
+{
+       return 0;       
+}
+
+void sgi_picture_render_default(struct sgi_picture *object, SDL_Surface *screen)
+{
+       SDL_Rect rect;
+       
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;     
+       SDL_BlitSurface(object->image.image, NULL, screen, &rect);
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;     
+}
+
+void sgi_photo_render_default(struct sgi_photo *object, SDL_Surface *screen)
+{
+       SDL_Rect dst;
+       SDL_Rect src;
+       
+       if (!(object->parent->redraw || object->redraw) || !object->surface) {
+               return;
+       }
+       
+       printf("photo redraw.\n");
+       dst.x = object->x;
+       dst.y = object->y;
+       dst.w = object->w;
+       dst.h = object->h;
+       src.x = 0;
+       src.y = 0;
+       src.w = dst.w;
+       src.h = dst.h;  
+       SDL_BlitSurface(object->surface, &src, screen, &dst);
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;     
+}
diff --git a/src/sgi_base_radio.cpp b/src/sgi_base_radio.cpp
new file mode 100644 (file)
index 0000000..bc1cdd7
--- /dev/null
@@ -0,0 +1,146 @@
+#include "global_func.h"
+
+/* sgi-check default subroutine */
+s32 sgi_radio_init_default(struct sgi_radio *object)
+{
+       u32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /*  */
+       for (i = 0; i < 2; ++i) {
+               object->image[i].image = request_image(object->image[i].name, 
+                       IMG_OPTIMIZE | IMG_ALPHA);
+               if (!object->image[i].image) {
+                       return FAIL;
+               }
+       }
+       
+       /* 置初始化标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_radio_deinit_default(struct sgi_radio *object)
+{
+       u32 i;
+       
+       /* 释放背景图片 */
+       for (i = 0; i < 2; ++i) {
+               release_image(object->image[i].image);
+               object->image[i].image = NULL;  
+       }
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+static void radio_up(struct sgi_radio *object)
+{
+       u32 i;
+       
+       for (i = 0; i < object->parent->form.size(); ++i) {
+               if (object->parent->form[i]->type != SGI_RADIO) {
+                       continue;       
+               }       
+               
+               if (object->parent->form[i]->radio.handle != object->handle) {
+                       object->parent->form[i]->radio.value = 0;       
+               }
+               else {
+                       object->parent->form[i]->radio.value = 1;       
+               }
+               object->parent->form[i]->radio.redraw = 1;
+       }
+}
+
+s32 sgi_radio_frame_default(struct sgi_radio *object)
+{
+       s16 x,y;
+       s32 keypress = 0;
+       
+       /* 查看消息队列 */
+       if (object->parent->msg.empty()) {
+               return 0;
+       }
+
+       struct sgi_msg &msg = object->parent->msg.front();      
+       if (msg.type != SGI_MOUSEDOWN && msg.type != SGI_MOUSEUP) {
+               return 0;
+       }
+       
+       /* 判断按键是否被按下 */
+       x = msg.lparam & 0xffff;
+       y = msg.lparam >> 16;
+       if ((x > object->x + RADIO_SPACE) 
+               && (x < object->x + object->w - RADIO_SPACE)
+               && (y > object->y + RADIO_SPACE) 
+               && (y < object->y + object->h - RADIO_SPACE)) {
+               keypress = 1;           
+       }
+               
+       if (!keypress) {                
+               return 0;
+       }
+       
+       switch (msg.type) {
+       case SGI_MOUSEDOWN:
+               printf("radio mousedown.\n");
+               object->state |= 1;
+               break;
+               
+       case SGI_MOUSEUP:
+               printf("radio mouseup.\n");
+               if (object->state) {                    
+                       radio_up(object);
+                       object->redraw = 1;
+                       
+                       if (object->up) {
+                               object->up(object);     
+                       }
+               }
+                       
+               object->state &= ~1;            
+               break;
+               
+       default:
+               break;
+       }
+       
+       /* 移除已经处理的消息 */
+       object->parent->msg.pop_front();
+       
+       return 0;       
+}
+
+void sgi_radio_render_default(struct sgi_radio *object, SDL_Surface *screen)
+{
+       SDL_Rect rect;
+       s32 index = 0;
+       
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       /* 重绘背景图片 */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;
+       if (object->value) {
+               index = 1;      
+       }
+
+       if (object->image[index].image) {       
+               SDL_BlitSurface(object->image[index].image, NULL, screen, &rect);
+       }
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;             
+}
diff --git a/src/sgi_base_updown.cpp b/src/sgi_base_updown.cpp
new file mode 100644 (file)
index 0000000..6778034
--- /dev/null
@@ -0,0 +1,229 @@
+#include "global_func.h"
+
+/* sgi-updown default subroutine */
+s32 sgi_updown_init_default(struct sgi_updown *object)
+{
+       u32 i;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* image */
+       for (i = 0; i < 2; ++i) {
+               object->image[i].image = request_image(object->image[i].name, 
+                       IMG_OPTIMIZE | IMG_ALPHA);
+               if (!object->image[i].image) {
+                       return FAIL;
+               }
+       }
+       
+       /* font */
+       object->font.font = request_font(object->font.name, object->font.size);
+       if (!object->font.font) {
+               return FAIL;    
+       }
+       
+       /* 置初始化标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_updown_deinit_default(struct sgi_updown *object)
+{
+       u32 i;
+       
+       /* image */
+       for (i = 0; i < 2; ++i) {
+               release_image(object->image[i].image);
+               object->image[i].image = NULL;  
+       }
+       
+       /* font */
+       release_font(object->font.font);
+       object->font.font = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_updown_frame_default(struct sgi_updown *object)
+{
+       s16 x,y;
+       s32 keypress = 0;
+       
+       /* 查看消息队列 */
+       if (object->parent->msg.empty()) {
+               return 0;
+       }
+
+       struct sgi_msg &msg = object->parent->msg.front();      
+       if (msg.type != SGI_MOUSEDOWN && msg.type != SGI_MOUSEUP) {
+               return 0;
+       }
+       
+       /* 判断按键是否被按下 */
+       x = msg.lparam & 0xffff;
+       y = msg.lparam >> 16;
+       if ((x > object->x) 
+               && (x < object->x + (object->w - object->tw)  / 2)
+               && (y > object->y) 
+               && (y < object->y + object->h)) {
+               keypress = 1;           
+       }
+       else if ((x > object->x + (object->w + object->tw) / 2)
+               && (x < object->x + object->w)
+               && (y > object->y)
+               && (y < object->y + object->h)) {
+               keypress = 2;
+       }
+               
+       if (!keypress) {
+               /* 如果按键收到弹起消息,不管坐标是否在按键之内,都要取消被按下状态 */
+               if (msg.type == SGI_MOUSEUP) {
+                       object->state[0] &= ~1;
+                       object->state[1] &= ~1;
+                       object->redraw = 1;     
+               }               
+               return 0;
+       }
+       
+       switch (msg.type) {
+       case SGI_MOUSEDOWN:
+               printf("updown mousedown.\n");
+               object->state[keypress - 1] |= 1;
+               object->redraw = 1;
+               break;
+               
+       case SGI_MOUSEUP:
+               printf("updown mouseup.\n");
+               if (object->state[0]) {
+                       object->value--;
+               }
+               else if (object->state[1]) {
+                       object->value++;
+               }
+               object->redraw = 1;
+               object->state[0] &= ~1;
+               object->state[1] &= ~1; 
+               break;
+               
+       default:
+               break;
+       }
+       
+       /* 移除已经处理的消息 */
+       object->parent->msg.pop_front();
+       
+       return 0;       
+}
+
+static void draw_text(SDL_Surface *screen, SDL_Rect *rect, TTF_Font *font,
+       u16 *text)
+{
+       int x1 = 0;
+       int y1 = 0;
+       SDL_Surface *surface;
+       SDL_Color color = {0,0,0,0};
+       
+       /* 字体图形生成 */
+       surface = TTF_RenderUNICODE_Blended(font, text, color); 
+       
+       if (!surface) {
+               return;
+       }
+       
+       /* 对齐处理 */
+       if (rect->w > surface->w) {
+               x1 = (rect->w - surface->w) / 2;        
+       }
+       rect->x = rect->x + x1;
+       if (rect->h > surface->h) {
+               y1 = (rect->h - surface->h) / 2;                
+       }
+       rect->y = rect->y + y1;
+       rect->w = rect->w > surface->w ? surface->w : rect->w;
+       rect->h = surface->h;
+       
+       /* 将字体图形渲染到目标 */
+       SDL_BlitSurface(surface, NULL, screen, rect);   
+       
+       /* 释放字体图形资源 */
+       SDL_FreeSurface(surface);
+}
+
+void sgi_updown_render_default(struct sgi_updown *object, SDL_Surface *screen)
+{
+       SDL_Rect rect;
+       SDL_Rect src;
+       u16 text[16];
+       
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       /*  */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;
+       if (object->image[0].image) {
+               SDL_BlitSurface(object->image[0].image, NULL, screen, &rect);
+       }
+       
+       /* */
+       if (object->state[0]) {
+               rect.x = object->x;
+               rect.y = object->y;
+               rect.w = (object->w - object->tw) / 2;
+               rect.h = object->h;
+               src.x = 0;
+               src.y = 0;
+               src.w = rect.w;
+               src.h = rect.h; 
+       }
+       else if (object->state[1]) {
+               rect.x = object->x + (object->w + object->tw) / 2;
+               rect.y = object->y;
+               rect.w = (object->w - object->tw ) / 2;
+               rect.h = object->h;
+               src.x = (object->w + object->tw) / 2;
+               src.y = 0;
+               src.w = rect.w;
+               src.h = rect.h; 
+       }
+       if (object->image[1].image) {           
+               SDL_BlitSurface(object->image[1].image, &src, screen, &rect);
+       }
+       
+       /* draw font */
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = (object->w - object->tw) / 2;
+       rect.h = object->h;
+       text[0] = (u16)L'-';
+       text[1] = 0;
+       draw_text(screen, &rect, object->font.font, text);
+       
+       rect.x = object->x + (object->w + object->tw) / 2;
+       rect.y = object->y;
+       rect.w = (object->w - object->tw ) / 2;
+       rect.h = object->h;
+       text[0] = (u16)L'+';
+       text[1] = 0;
+       draw_text(screen, &rect, object->font.font, text);
+       
+       rect.x = object->x + (object->w - object->tw) / 2;
+       rect.y = object->y;
+       rect.w = object->tw;
+       rect.h = object->h;
+       sgi_sprintf16(text, L"%d", object->value);
+       draw_text(screen, &rect, object->font.font, text);      
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;             
+}
diff --git a/src/sgi_base_window.cpp b/src/sgi_base_window.cpp
new file mode 100644 (file)
index 0000000..6c52839
--- /dev/null
@@ -0,0 +1,104 @@
+#include "global_func.h"
+
+/* sgi-window default subroutine */
+s32 sgi_window_init_default(struct sgi_window *object)
+{
+       struct sgi_widget *p;
+       SDL_Rect rect;
+       SDL_Surface *surface;
+       
+       /* 是否已经初始过 */
+       if (object->initialized) {
+               return 0;
+       }
+       
+       /* 申请主背景资源 */
+       surface = request_image(object->image.name, object->image.flags);
+       if (!surface) {
+               return FAIL;
+       }
+       
+       /* 申请widget资源(如果有) */
+       p = object->widget;
+       if (p) {
+               object->image.image = clone_surface(surface);
+               
+               /* 释放原来的主背景资源 */
+               release_image(surface);
+               
+               if (!object->image.image) {
+                       printf("clone surface fail.\n");        
+                       return FAIL;    
+               }               
+               object->reallocated = 1;                        
+       }
+       else {
+               object->image.image = surface;  
+       }
+       
+       /* 组合widget */
+       while (p) {
+               if (!p->image.name) {
+                       break;  
+               }
+               
+               p->image.image = request_image(p->image.name, p->image.flags);
+               if (p->image.image) {
+                       rect.x = p->x;
+                       rect.y = p->y;
+                       rect.w = p->w;
+                       rect.h = p->h;
+                       SDL_BlitSurface(p->image.image, NULL, 
+                               object->image.image, &rect);
+                       release_image(p->image.image);
+                       p->image.image = NULL;  
+               }
+               p++;    
+       }
+       
+       /* 置初始标志 */
+       object->initialized = 1;
+
+       return 0;       
+}
+
+void sgi_window_deinit_default(struct sgi_window *object)
+{
+       /* 释放资源 */
+       if (object->reallocated) {
+               release_clone_surface(object->image.image);
+               object->reallocated = 0;        
+       }
+       else {
+               release_image(object->image.image);
+       }
+       object->image.image = NULL;
+       
+       /* 重置初始标志 */
+       object->initialized = 0;        
+}
+
+s32 sgi_window_frame_default(struct sgi_window *object)
+{
+       return 0;       
+}
+
+void sgi_window_render_default(struct sgi_window *object, SDL_Surface *screen)
+{
+       SDL_Rect rect;
+       
+       if (!(object->parent->redraw || object->redraw)) {
+               return;
+       }
+       
+       rect.x = object->x;
+       rect.y = object->y;
+       rect.w = object->w;
+       rect.h = object->h;     
+       SDL_BlitSurface(object->image.image, NULL, screen, &rect);
+       
+       /* 提交重绘区域 */
+       invalidate_rect(object->parent, object->x, object->y, 
+               object->x + object->w, object->y + object->h);
+       object->redraw = 0;     
+}
diff --git a/src/sgi_data.cpp b/src/sgi_data.cpp
new file mode 100644 (file)
index 0000000..70c0b4c
--- /dev/null
@@ -0,0 +1,1243 @@
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "global_func.h"
+
+static std::vector <struct person_data_mem > s_person_vec;
+static std::vector <struct gun_data > s_gun_vec;
+static std::list <s32 >s_lock_list;
+static struct box_data s_gun_box;
+static struct unit_data s_unit;
+static struct person_data_mem s_person_reg_data;
+static struct box_info s_box_info[BOX_NUMS];
+static u32 s_log_no[LOG_MAX] = {0};
+
+//struct person_data g_person_modify;
+static struct gun_data s_gun_reg_data;
+s32 g_data_update_state;
+
+s32 copy_file(char *out, char *in)
+{
+       FILE *fi = fopen(in, "rb");
+       if (fi == NULL) {
+               return -1;
+       }
+       
+       FILE *fo = fopen(out, "wb");
+       if (fo == NULL) {
+               fclose(fi);
+               return -1;
+       }
+       
+       fseek(fi, 0, SEEK_END);
+       size_t size = ftell(fi);
+       fseek(fi, 0, SEEK_SET);
+       
+       void *buf = malloc(size);
+       if (buf == NULL) {
+               fclose(fi);
+               fclose(fo);
+               return -1;
+       }
+       
+       fread(buf, 1, size, fi);
+       fwrite(buf, 1, size, fo);
+       
+       free(buf);
+       
+       fclose(fi);
+       fclose(fo);
+       
+       return 0;       
+}
+
+void *open_w(const char *name, size_t *size)
+{
+       int fd;
+       void *ptr;
+       
+       /* 打开文件 */
+       if ((fd = open(name, O_RDWR)) < 0) {
+               return NULL;
+       }
+       
+       *size = lseek(fd, 0, SEEK_END);
+       ptr = mmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       
+       /* 关闭文件 */
+       close(fd);
+       
+       return ptr;     
+}
+
+s32 data_flush(void *ptr, size_t size)
+{
+       return msync(ptr, size, MS_SYNC);       
+}
+
+void close_w(void *ptr, size_t size)
+{
+       if (ptr) {
+               munmap(ptr, size);
+       }       
+}
+
+void *open_r(const char *name, size_t *size)
+{
+       int fd;
+       void *ptr;
+       
+       /* 打开文件 */
+       if ((fd = open(name, O_RDONLY)) < 0) {
+               return NULL;
+       }
+       
+       *size = lseek(fd, 0, SEEK_END);
+       ptr = mmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0);
+       
+       /* 关闭文件 */
+       close(fd);
+       
+       return ptr;     
+}
+
+void close_r(void *ptr, size_t size)
+{
+       if (ptr) {
+               munmap(ptr, size);
+       }       
+}
+       
+static s32 open_person_db(char *dbname, s32 spec)
+{
+       u32 i;
+       u32 count;
+       struct person_data_mem person;
+       FILE *fp;
+       
+       /* 打开数据文件 */
+       fp = fopen(dbname, "rb");
+       if (fp == NULL) {
+               return 0;
+       }
+       
+       /* 获取记录数 */
+       fseek(fp, 0, SEEK_END);
+       count = ftell(fp) / sizeof(struct person_data);
+       fseek(fp, 0, SEEK_SET);
+       
+       /* 限定最大用户数不能超过65536 */
+       count &= 0xffff;
+       
+       /* 读取人员数据 */
+       for (i = 0; i < count; ++i) {
+               fread(&person, 1, sizeof(struct person_data), fp);
+               if (spec) {
+                       person.index = (1 << 30) | i; /* super user flag */
+               }
+               else {
+                       person.index = i;
+               }
+               s_person_vec.push_back(person);
+       }
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+       
+       return count;   
+}
+
+static s32 load_gun_data(const char *dbname)
+{
+       u32 i;
+       u32 count;
+       struct gun_data gun;
+       FILE *fp;
+       
+       /* 清空枪支记录数据 */
+       s_gun_vec.clear();
+       
+       /* 打开数据文件 */
+       fp = fopen(dbname, "rb");
+       if (fp == NULL) {
+               return 0;
+       }
+       
+       /* 获取记录数 */
+       fseek(fp, 0, SEEK_END);
+       count = ftell(fp) / sizeof(struct gun_data);
+       fseek(fp, 0, SEEK_SET);
+       
+       /* 读取人员数据 */
+       for (i = 0; i < count; ++i) {
+               fread(&gun, 1, sizeof(struct gun_data), fp);
+               s_gun_vec.push_back(gun);
+       }
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+       
+       return count;   
+}
+
+static s32 open_gun_box_db(const char *dbname)
+{
+       FILE *fp;
+       
+       /* 打开数据文件 */
+       fp = fopen(dbname, "rb");
+       if (fp == NULL) {
+               return 0;
+       }
+       
+       /* 读取数据 */
+       fread(&s_gun_box, 1, sizeof(struct box_data), fp);
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+       
+       return 1;       
+}
+
+static s32 open_unit_db(const char *dbname)
+{
+       FILE *fp;
+       
+       /* 打开数据文件 */
+       fp = fopen(dbname, "rb");
+       if (fp == NULL) {
+               return 0;
+       }
+       
+       /* 读取数据 */
+       fread(&s_unit, 1, sizeof(struct unit_data), fp);
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+       
+       return 1;       
+}
+
+static void borrow_update_box_info(u32 *cells)
+{
+       /* box max cap 128 */
+       u32 i,j;
+       s32 index = 0;
+       
+       for (i = 0; i < 4; ++i) {
+               for (j = 0; j < 32; ++j) {
+                       if ((cells[i] & (1 << j)) != 0) {
+                               s_box_info[index].state |= 2;
+                       }               
+
+                       if (++index >= BOX_NUMS) {
+                               break;
+                       }
+               }
+       }       
+}
+
+static void return_update_box_info(u32 *cells)
+{
+       /* box max cap 128 */
+       u32 i,j;
+       s32 index = 0;
+       
+       for (i = 0; i < 4; ++i) {
+               for (j = 0; j < 32; ++j) {
+                       if ((cells[i] & (1 << j)) != 0) {
+                               s_box_info[index].state &= ~2;
+                       }               
+                       
+                       if (++index >= BOX_NUMS) {
+                               break;
+                       }
+               }
+       }       
+}
+
+#if 0
+static void update_box_info(u32 *cells)
+{
+       /* box max cap 128 */
+       u32 i,j;
+       s32 index = 0;
+       
+       for (i = 0; i < 4; ++i) {
+               for (j = 0; j < 32; ++j) {
+                       if ((cells[i] & (1 << j)) != 0) {
+                               s_box_info[index].state |= 2;
+                       }
+                       else {
+                               s_box_info[index].state &= ~2;  
+                       }               
+                       index++;
+               }
+       }                       
+}
+#endif
+
+void load_gun_box_info(void)
+{
+       u32 i;
+       u32 size;
+       
+       memset(&s_box_info, 0, sizeof(s_box_info));
+       
+       /* 用枪支登记信息初始枪柜 */
+       //printf("gun vector size: %d\n", s_gun_vec.size());
+       for (i = 0; i < s_gun_vec.size(); ++i) {
+               if (s_gun_vec[i].lock_code < 1 
+                       || s_gun_vec[i].lock_code > BOX_NUMS) {
+                       continue;
+               }
+               
+               //printf("gun vector lock code: %d\n", s_gun_vec[i].lock_code);
+               s_box_info[s_gun_vec[i].lock_code - 1].state = 1;
+               sgi_ncp16(s_box_info[s_gun_vec[i].lock_code].gun_code,
+                       s_gun_vec[i].code, 
+                       COUNTOF(s_box_info[s_gun_vec[i].lock_code].gun_code));
+               sgi_ncp16(s_box_info[s_gun_vec[i].lock_code].gun_model,
+                       s_gun_vec[i].model, 
+                       COUNTOF(s_box_info[s_gun_vec[i].lock_code].gun_model));
+               sgi_ncp16(s_box_info[s_gun_vec[i].lock_code].holder,
+                       s_gun_vec[i].holder, 
+                       COUNTOF(s_box_info[s_gun_vec[i].lock_code].holder));                    
+       }
+       
+       /* 用枪支借出信息初始枪柜 */
+       struct borrow_ctrl *pcont;
+       struct borrow_ctrl *p;
+       pcont = (struct borrow_ctrl *)open_r(DBR(borrow), &size);
+       if (pcont == NULL) {
+               return;
+       }
+       
+       p = pcont;
+       for (i = 0; i < size / sizeof(struct borrow_ctrl); ++i) {
+               borrow_update_box_info(p->cells);       
+               p++;    
+       }
+       
+       for (i = 0; i < BOX_NUMS; ++i) {
+               printf("box-info[%d]: %d\n", i, s_box_info[i].state);
+                       
+       }
+       
+       /* 关闭 */
+       close_r(pcont, size);   
+}
+
+static void load_log_no(void)
+{
+       size_t size;
+       void *p;
+       
+       /* manager log no. */
+       p = open_r(DBL(manager), &size);
+       if (p) {
+               struct log_manager *m = (struct log_manager *)((u8 *)p + size 
+                       - sizeof(struct log_manager));
+               s_log_no[LOG_MANAGER] = m->id & 0xffff;
+               close_r(p, size);               
+       }
+       
+       /*  */
+       p = open_r(DBL(borrow), &size);
+       if (p) {
+               struct log_borrow *b = (struct log_borrow *)((u8 *)p + size 
+                       - sizeof(struct log_borrow));
+               s_log_no[LOG_BORROW] = b->id & 0xffff;
+               close_r(p, size);               
+       }
+       
+       /*  */
+       p = open_r(DBL(back), &size);
+       if (p) {
+               struct log_borrow *r = (struct log_borrow *)((u8 *)p + size 
+                       - sizeof(struct log_borrow));
+               s_log_no[LOG_RETURN] = r->id & 0xffff;  
+               close_r(p, size);       
+       }
+       
+       /*  */
+       p = open_r(DBL(alarm), &size);
+       if (p) {
+               struct log_alarm *a = (struct log_alarm *)((u8 *)p + size 
+                       - sizeof(struct log_alarm));
+               s_log_no[LOG_ALARM] = a->id & 0xffff;
+               close_r(p, size);               
+       }
+       
+       /*  */
+       p = open_r(DBL(syslog), &size);
+       if (p) {
+               struct log_system *s = (struct log_system *)((u8 *)p + size 
+                       - sizeof(struct log_system));
+               s_log_no[LOG_SYSTEM] = s->id & 0xffff;
+               close_r(p, size);               
+       }       
+}
+
+s32 load_person_data(void)
+{
+       u32 count = 0;
+       
+       /* 清空人员记录数据 */
+       s_person_vec.clear();
+       
+       /* 加载特殊权限人员数据 */
+       count += open_person_db(DBD(super), 1);
+       
+       /* 加载普通人员数据 */
+       count += open_person_db(DBD(person), 0);
+       
+       return count;   
+}
+       
+s32 data_open(void)
+{
+       u32 count = 0;
+       
+       /* 清空人员记录数据 */
+       //s_person_vec.clear();
+       s_lock_list.clear();
+       
+       /* 清空枪支记录数据 */
+       //s_gun_vec.clear();
+       
+       /* 清空枪柜记录 */
+       memset(&s_gun_box, 0, sizeof(struct box_data));
+       
+       /* 清空单位信息 */
+       memset(&s_unit, 0, sizeof(struct unit_data));
+       
+       /* 加载特殊权限人员数据 */
+       //count += open_person_db(DBD(super), 1);
+       
+       /* 加载普通人员数据 */
+       //count += open_person_db(DBD(person), 0);
+       count = load_person_data();
+       
+       /* 加载枪支信息 */
+       load_gun_data(DBD(gun));
+       
+       /* 加载枪柜信息 */
+       open_gun_box_db(DBD(gun_box));
+       
+       /* 加载单位信息 */
+       open_unit_db(DBD(unit));
+       
+       /* 加载枪柜与枪支影射信息 */
+       load_gun_box_info();
+       
+       /* 加载日志编号 */
+       load_log_no();
+                       
+       return count > 0 ? 0 : -1;
+}
+
+void data_close(void)
+{
+       s_person_vec.clear();
+       s_gun_vec.clear();      
+}
+
+s32 search_uid(struct passport_data *pass, s32 type, u32 param)
+{
+       assert(pass != NULL);
+       
+       u32 i;
+       s32 found = 0;
+       
+       if (type == SR_FPR) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].person.level == LV_USER
+                               && (s_person_vec[i].person.fpr1 == param ||
+                               s_person_vec[i].person.fpr2 == param)) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->dept, s_person_vec[i].person.dept,
+                                       COUNTOF(s_person_vec[i].person.dept));
+                               sgi_ncp16(pass->post, s_person_vec[i].person.post,
+                                       COUNTOF(s_person_vec[i].person.post));
+                               found = 1;
+                               break;          
+                       }       
+               }               
+       }
+       else if (type == SR_CARD) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].person.level == LV_USER
+                               && s_person_vec[i].person.idcard == param) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->dept, s_person_vec[i].person.dept,
+                                       COUNTOF(s_person_vec[i].person.dept));
+                               sgi_ncp16(pass->post, s_person_vec[i].person.post,
+                                       COUNTOF(s_person_vec[i].person.post));
+                               found = 1;
+                               break;          
+                       }       
+               }       
+       }
+       
+       if (!found) {
+               return FAIL;
+       }
+               
+       return 0;
+}
+
+s32 search_mid(struct passport_data *pass, s32 type, u32 param)
+{
+       assert(pass != NULL);
+       
+       u32 i;
+       s32 found = 0;
+       
+       if (type == SR_FPR) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].person.level == LV_MANAGER
+                               && (s_person_vec[i].person.fpr1 == param ||
+                               s_person_vec[i].person.fpr2 == param)) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->mdept, s_person_vec[i].person.dept,
+                                       COUNTOF(s_person_vec[i].person.dept));
+                               found = 1;
+                               break;          
+                       }       
+               }               
+       }
+       else if (type == SR_CARD) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].person.level == LV_MANAGER
+                               && s_person_vec[i].person.idcard == param) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->mdept, s_person_vec[i].person.dept,
+                                       COUNTOF(s_person_vec[i].person.dept));
+                               found = 1;
+                               break;          
+                       }       
+               }       
+       }
+       
+       if (!found) {
+               return FAIL;
+       }
+               
+       return 0;
+}
+
+s32 verify_user_pwd(struct passport_data *pass, u16 *uid, u16 *pwd)
+{
+       assert(uid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (s_person_vec[i].person.level != LV_USER
+                       || (sgi_ncmp16(s_person_vec[i].person.uid, uid, 
+                       COUNTOF(s_person_vec[i].person.uid)) != 0)) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].person.pwd, pwd,
+                       COUNTOF(s_person_vec[i].person.pwd)) == 0) {
+                       if (pass) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->post, s_person_vec[i].person.post,
+                                       COUNTOF(s_person_vec[i].person.post));
+                       }
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+s32 verify_manager_pwd(struct passport_data *pass, u16 *mid, u16 *pwd)
+{
+       assert(mid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (s_person_vec[i].person.level != LV_MANAGER
+                       || (sgi_ncmp16(s_person_vec[i].person.uid, mid, 
+                       COUNTOF(s_person_vec[i].person.uid)) != 0)) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].person.pwd, pwd,
+                       COUNTOF(s_person_vec[i].person.pwd)) == 0) {
+                       if (pass) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                       }
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+static s32 verify_all_user_pwd(u16 *uid, u16 *pwd)
+{
+       assert(uid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (sgi_ncmp16(s_person_vec[i].person.uid, uid, 
+                       COUNTOF(s_person_vec[i].person.uid)) != 0) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].person.pwd, pwd,
+                       COUNTOF(s_person_vec[i].person.pwd)) == 0) {
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+static s32 search_all_user(u16 *uid)
+{
+       assert(uid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (sgi_ncmp16(s_person_vec[i].person.uid, uid, 
+                       COUNTOF(s_person_vec[i].person.uid)) == 0) {
+                       r = i;
+                       break;
+               }               
+       }
+       
+       return r;               
+}
+
+static s32 sync_pwd(struct person_data_mem *person, u16 *new_pwd)
+{
+       s32 r = FAIL;
+       u32 index;
+       size_t size;
+       struct person_data *ptr = NULL;
+       
+       /* 打开数据文件 */
+       if (person->index & (1 << 30)) { /* super user */       
+               ptr = (struct person_data *)open_w(DBD(super), &size);                          
+       }       
+       else {
+               ptr = (struct person_data *)open_w(DBD(person), &size); 
+       }
+       
+       if (ptr == NULL) {
+               goto err;
+       }
+       
+       /* 修改内容 */
+       index = person->index & 0xffff;
+       if (index > size / sizeof(struct person_data)) {
+               goto err;
+       }       
+       sgi_ncp16(ptr[index].pwd, new_pwd, COUNTOF(ptr[index].pwd));
+       
+       /* 更新到文件 */
+       if (msync(ptr, size, MS_SYNC) != 0) {
+               goto err;       
+       }       
+       
+       r = 0;
+       
+err:
+       /* 关闭文件 */
+       close_w(ptr, size);
+       
+       return r;               
+}
+
+s32 change_pwd(u16 *uid, u16 *old_pwd, u16 *new_pwd)
+{
+       assert(uid != NULL || old_pwd != NULL || new_pwd != NULL);
+       
+       s32 r;
+       
+       /* 校验旧密码是否有效 */
+       r = verify_all_user_pwd(uid, old_pwd);
+       if (r < 0) {
+               return r;
+       }
+       
+       /* 修改为新密码 */
+       if (sync_pwd(&s_person_vec[r], new_pwd) != 0) {
+               return FAIL;
+       }
+       
+       sgi_ncp16(s_person_vec[r].person.pwd, new_pwd, 
+               COUNTOF(s_person_vec[r].person.pwd));
+       
+       return 0;
+}
+
+static s32 sgi_append_data(const char *name, void *data, size_t size)
+{
+       FILE *fp;
+       
+       /* 打开日志文件 */
+       if (access(name, R_OK | W_OK) == 0) {
+               fp = fopen(name, "ab");         
+       }
+       else {
+               fp = fopen(name, "wb"); 
+       }       
+       if (fp == NULL) {
+               printf("sgi_append_data open fail\n");
+               return FAIL;
+       }
+       
+       /* 追加数据 */
+       if (fwrite(data, 1, size, fp) < size) {
+               fclose(fp);
+               printf("sgi_append_data write fail\n");
+               return FAIL;
+       }
+       
+       /* 关闭文件 */
+       fclose(fp);
+       
+       return 0;       
+}
+
+s32 register_person(struct person_data_mem *person)
+{
+       u32 i;
+       s32 index = 0;
+       
+       if (search_all_user(person->person.uid) != ID_INVALID)  {
+               /* user exist */
+               return ID_EXIST;        
+       }
+       
+       if (sgi_append_data(DBD(person), person, 
+               sizeof(struct person_data)) != 0) {
+               return APPEND_FAIL;
+       }
+       
+       /* 追加到列表 */
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               if ((s_person_vec[i].index & (1 << 30)) == 0) { /* normal user */
+                       index++;
+               }
+       }
+       person->index = index;
+       s_person_vec.push_back(*person);
+       
+       return SUCCESS;
+}
+
+s32 delete_person(struct person_data_mem *data)
+{
+       u32 i;
+       
+       FILE *fp = fopen(DBT(person-tmp), "wb");
+       if (fp == NULL) {
+               return -1;
+       }
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               if ((s_person_vec[i].index & (1 << 30)) != 0) { /* super user */
+                       continue;
+               }
+               
+               if (sgi_ncmp16(data->person.uid, s_person_vec[i].person.uid,
+                       COUNTOF(data->person.uid)) == 0) {
+                       continue;
+               }
+               
+               fwrite(&s_person_vec[i].person, 1, sizeof(struct person_data), fp);
+       }
+       
+       fclose(fp);
+       
+       if (copy_file(DBD(person-bak), DBD(person)) != 0) {
+               return -1;      
+       }
+       
+       if (copy_file(DBD(person), DBT(person-tmp)) != 0) {
+               copy_file(DBD(person), DBD(person-bak));
+               return -1;      
+       }
+       
+       /* */
+       load_person_data();     
+       
+       return 0;                       
+}
+
+s32 update_person(struct person_data_mem *data)
+{
+       u32 i;
+       u32 size;
+       s32 found = 0;
+       s32 result = APPEND_FAIL;
+       struct person_data *p,*pcont;
+       const char *dbname = DBD(person);
+       
+       pcont = (struct person_data *)open_w(dbname, &size);
+       if (pcont == NULL) {
+               goto end;
+       }
+       
+       p = pcont;
+       for (i = 0; i < size / sizeof(struct person_data); ++i) {
+               if (sgi_ncmp16(p->uid, data->person.uid, COUNTOF(p->uid)) == 0) {
+                       found = 1;
+                       break;                          
+               }
+               p++;    
+       }
+       
+       if (found) {
+               memcpy(p, data, sizeof(struct person_data));            
+               
+               /* 更新到文件 */
+               if (msync(pcont, size, MS_SYNC) != 0) {
+                       goto end;       
+               }
+               
+               /* */
+               load_person_data();     
+               
+               result = 0;
+       }       
+
+end:   
+       if (pcont) {
+               close_w(pcont, size);
+       }
+       
+       return result;          
+}
+
+static s32 search_gun(u16 *code)
+{
+       assert(code != NULL);
+       
+       u32 i;
+       s32 r = CODE_INVALID;
+       
+       for (i = 0; i < s_gun_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (sgi_ncmp16(s_gun_vec[i].code, code, 
+                       COUNTOF(s_gun_vec[i].code)) == 0) {
+                       r = i;
+                       break;
+               }               
+       }
+       
+       return r;               
+}
+
+s32 register_gun(struct gun_data *gun)
+{
+       if (search_gun(gun->code) != CODE_INVALID) { /* gun exist */
+               return ID_EXIST;
+       }
+       
+       if (sgi_append_data(DBD(gun), gun, 
+               sizeof(struct gun_data)) != 0) {
+               return APPEND_FAIL;
+       }
+       
+       /* 追加到列表 */
+       s_gun_vec.push_back(*gun);
+       
+       /* 更新槍柜影射信息 */
+       load_gun_box_info();
+       
+       return SUCCESS;                 
+}
+
+s32 update_gun(struct gun_data *data)
+{
+       u32 i;
+       u32 size;
+       s32 found = 0;
+       s32 result = APPEND_FAIL;
+       struct gun_data *p,*pcont;
+       const char *dbname = DBD(gun);
+       
+       pcont = (struct gun_data *)open_w(dbname, &size);
+       if (pcont == NULL) {
+               goto end;
+       }
+       
+       p = pcont;
+       for (i = 0; i < size / sizeof(struct gun_data); ++i) {
+               if (sgi_ncmp16(p->code, data->code, COUNTOF(p->code)) == 0) {
+                       found = 1;
+                       break;                          
+               }
+               p++;    
+       }
+       
+       if (found) {
+               memcpy(p, data, sizeof(struct gun_data));               
+               
+               /* 更新到文件 */
+               if (msync(pcont, size, MS_SYNC) != 0) {
+                       goto end;       
+               }
+               
+               /* 重新加载到内存影射表 */
+               load_gun_data(DBD(gun));
+               
+               /* 更新槍柜影射信息 */
+               load_gun_box_info();    
+               
+               result = 0;
+       }       
+
+end:   
+       if (pcont) {
+               close_w(pcont, size);
+       }
+       
+       return result;          
+}
+
+s32 delete_gun(struct gun_data *data)
+{
+       u32 i;
+       
+       FILE *fp = fopen(DBT(gun-tmp), "wb");
+       if (fp == NULL) {
+               return -1;
+       }
+       
+       for (i = 0; i < s_gun_vec.size(); ++i) {
+               if (sgi_ncmp16(data->code, s_gun_vec[i].code,
+                       COUNTOF(data->code)) == 0) {
+                       continue;
+               }
+               
+               fwrite(&s_gun_vec[i], 1, sizeof(struct gun_data), fp);
+       }
+       
+       fclose(fp);
+       
+       if (copy_file(DBD(gun-bak), DBD(gun)) != 0) {
+               return -1;      
+       }
+       
+       if (copy_file(DBD(gun), DBT(gun-tmp)) != 0) {
+               copy_file(DBD(gun), DBD(gun-bak));
+               return -1;      
+       }
+       
+       /* 重新加载到内存影射表 */
+       load_gun_data(DBD(gun));
+       
+       /* 更新槍柜影射信息 */
+       load_gun_box_info();    
+       
+       return 0;
+                       
+}
+
+s32 register_box(struct box_data *box)
+{
+       FILE *fp;
+       const char *name = DBD(gun_box);
+       
+       /* 打开文件 */
+       fp = fopen(name, "wb");         
+       if (fp == NULL) {
+               return FAIL;
+       }
+       
+       /* 写入数据 */
+       if (fwrite(box, 1, sizeof(struct box_data), fp) < sizeof(struct box_data)) {
+               fclose(fp);
+               return FAIL;
+       }
+       
+       /* 关闭文件 */
+       fclose(fp);
+       
+       /* */
+       memcpy(&s_gun_box, box, sizeof(struct box_data));       
+       
+       return 0;               
+}
+
+s32 register_unit(struct unit_data *unit)
+{
+       FILE *fp;
+       const char *name = DBD(unit);
+       
+       /* 打开文件 */
+       fp = fopen(name, "wb");         
+       if (fp == NULL) {
+               return REGISTER_FAIL;
+       }
+       
+       /* 写入数据 */
+       if (fwrite(unit, 1, sizeof(struct unit_data), fp) < sizeof(struct unit_data)) {
+               fclose(fp);
+               return REGISTER_FAIL;
+       }
+       
+       /* 关闭文件 */
+       fclose(fp);
+       
+       /* */
+       memcpy(&s_unit, unit, sizeof(struct unit_data));        
+       
+       return SUCCESS;         
+}
+
+struct box_info *get_box_info(void)
+{
+       return s_box_info;      
+}
+
+u16 *get_box_code(void)
+{
+       return s_gun_box.code;  
+}
+
+struct unit_data *get_unit_info(void)
+{
+       return &s_unit; 
+}
+
+s32 enroll_borrow(struct passport_data *pass, u32 *cells)
+{
+       ///* 4 x sizeof(u32) x 8 = 128 bit = box-cap */
+       struct borrow_ctrl content;
+       const char *dbname = DBR(borrow);
+       
+       memset(&content, 0, sizeof(struct borrow_ctrl));
+       sgi_cp16(content.uid, pass->uid);
+       content.borrow_time = pass->borrow_time;
+       content.return_time = pass->return_time;
+       memcpy(content.cells, cells, sizeof(content.cells));
+       
+       if (sgi_append_log(dbname, &content, sizeof(struct borrow_ctrl)) != 0) {
+               return ENROLL_FAIL;     
+       }
+       
+       /* 更新枪柜实时记录 */
+       borrow_update_box_info(cells);
+       
+       /* 更新借还枪超时监控 */
+       borrow_vector_add(pass);        
+       
+       return 0;
+}
+
+s32 search_borrow_info(struct passport_data *pass)
+{
+       u32 i;
+       u32 size;
+       s32 found = 0;
+       struct borrow_ctrl *p,*pcont;
+       const char *dbname = DBR(borrow);
+       
+       pcont = (struct borrow_ctrl *)open_w(dbname, &size);
+       if (pcont == NULL) {
+               goto end;
+       }
+       
+       p = pcont;
+       for (i = 0; i < size / sizeof(struct borrow_ctrl); ++i) {
+               if (sgi_ncmp16(p->uid, pass->uid, COUNTOF(p->uid)) == 0) {
+                       if (p->cells[0] != 0 || p->cells[1] != 0
+                               || p->cells[2] != 0 || p->cells[3] != 0) {
+                               found = 1;
+                               break;
+                       }                               
+               }
+               p++;    
+       }
+
+end:   
+       if (pcont) {
+               close_w(pcont, size);
+       }
+       
+       return found;   
+}
+
+s32 enroll_return(struct passport_data *pass, u32 *cells)
+{
+       ///* 4 x sizeof(u32) x 8 = 128 bit = box-cap */
+       u32 i;
+       u32 size;
+       s32 r = FAIL;
+       struct borrow_ctrl *p,*pcont;
+       const char *dbname = DBR(borrow);
+       
+       pcont = (struct borrow_ctrl *)open_w(dbname, &size);
+       if (pcont == NULL) {
+               goto err;
+       }
+       
+       p = pcont;
+       for (i = 0; i < size / sizeof(struct borrow_ctrl); ++i) {
+               if (sgi_ncmp16(p->uid, pass->uid, COUNTOF(p->uid)) == 0) {
+                       p->cells[0] &= ~cells[0];
+                       p->cells[1] &= ~cells[1];
+                       p->cells[2] &= ~cells[2];
+                       p->cells[3] &= ~cells[3];                               
+               }
+               p++;    
+       }
+       
+       /* 更新到文件 */
+       if (msync(pcont, size, MS_SYNC) != 0) {
+               goto err;       
+       }
+       
+       /* 更新枪柜实时记录 */
+       return_update_box_info(cells);
+       
+       /* 更新借还枪超时监控 */
+       borrow_vector_remove(pass, pcont,  size / sizeof(struct borrow_ctrl));  
+               
+       r = 0;
+err:
+       if (pcont) {
+               close_w(pcont, size);
+       }
+       
+       return r;
+}
+
+struct person_data *get_person_reg_data(void)
+{
+       return (struct person_data *)&s_person_reg_data;        
+}
+
+struct gun_data *get_gun_reg_data(void)
+{
+       return (struct gun_data *)&s_gun_reg_data;
+}
+
+void person_reg_data_clear(void)
+{
+       memset(&s_person_reg_data, 0, sizeof(struct person_data_mem));  
+}
+
+u32 get_log_no(enum sgi_log_type type)
+{
+       return (++s_log_no[type] & 0xffff);     
+}
+
+u8 *get_return_info(u16 *uid)
+{
+       static u8 info[BOX_NUMS];
+       u32 i,j,k;
+       u32 size;
+       
+       /* */
+       memset(info, 0, sizeof(info));
+       
+       /*  */
+       struct borrow_ctrl *pcont;
+       struct borrow_ctrl *p;
+       pcont = (struct borrow_ctrl *)open_r(DBR(borrow), &size);
+       if (pcont == NULL) {
+               return info;
+       }
+       
+       p = pcont;
+       for (i = 0; i < size / sizeof(struct borrow_ctrl); ++i,p++) {
+               if (sgi_ncmp16(uid, p->uid, COUNTOF(p->uid)) != 0) {
+                       continue;
+               }
+               
+               s32 exit = 0;
+               for (j = 0; j < 4; ++j) {
+                       for (k = 0; k < 32; ++k) {
+                               if (j * 32 + k > BOX_NUMS) {
+                                       exit = 1;
+                                       break;
+                               }
+                                       
+                               if ((p->cells[j] & (1 << k)) != 0) {
+                                       info[j * 32 + k] |= 1;
+                               }                               
+                       }
+                       
+                       if (exit) {
+                               break;
+                       }                                       
+               }                       
+       }
+       
+       /* 关闭 */
+       close_r(pcont, size);
+       
+       return info;    
+}
+
+s32 get_lock_list(void)
+{
+       s32 addr;
+       
+       if (s_lock_list.empty()) {
+               return -1;
+       }
+       
+       addr = s_lock_list.front();
+       s_lock_list.pop_front();
+       
+       return addr;            
+}
+
+void set_lock_list(s32 addr)
+{
+       s_lock_list.push_back(addr);    
+}
diff --git a/src/sgi_data.h b/src/sgi_data.h
new file mode 100644 (file)
index 0000000..d5f4f87
--- /dev/null
@@ -0,0 +1,113 @@
+#ifndef SGI_DATA_H
+#define SGI_DATA_H
+
+#include <time.h>
+#include "sgi_types.h"
+
+struct person_data {
+       u16 uid[16];
+       u16 name[16];
+       u16 sex[2];
+       u32 age;
+       u16 dept[16];
+       u16 post[16];
+       u16 gun[16];
+       u16 gun_code[16];
+       u16 lock_code;
+       u16 level;
+       u16 fpr1;
+       u16 fpr2;
+       u32 idcard;
+       u16 pwd[16];
+       u16 phone[16];  
+};
+
+struct person_data_mem {
+       struct person_data person;
+       s32 index;
+};
+
+struct gun_data {
+       u16 code[16];
+       u16 model[16];
+       u16 caliber[8];
+       u16 bullet[8];
+       u16 holder[16];
+       u16 unit[16];
+       u16 stock_date[16];
+       u16 lock_code;
+       u16 status;
+};
+
+struct sgi_bullet {
+       u16 name[16];
+       u16 model[16];
+       u16 for_gun[16];
+       u16 amount;
+       u16 lock_code;
+       u16 batch[16];
+       u16 unit[16];   
+};
+
+struct box_data {
+       u16 type;
+       u16 cap;
+       u16 code[16];
+       u16 model[16];
+       u16 manager[16];
+       u16 unit[16];   
+};
+
+struct unit_data {
+       u16 name[16];
+       u16 addr[32];
+       u16 dept[16];
+       u16 parent[16]; 
+};
+
+struct passport_data {
+       u32 visit;
+       u16 uid[16];
+       u16 name[16];
+       u16 dept[16];
+       u16 post[16];
+       u16 mid[16];
+       u16 mname[16];
+       u16 mdept[16];
+       char photo[64];
+       time_t borrow_time;
+       time_t return_time;
+       s16 fpr_enroll;
+       s16 fpr_id;
+       s32 reg_flag;
+};
+
+struct borrow_ctrl {
+       u16 uid[16];
+       time_t borrow_time;
+       time_t return_time;
+       u32 cells[4];   
+};
+
+struct box_info {
+       s32 state;
+       u16 gun_code[16];
+       u16 gun_model[16];
+       u16 holder[16];
+};
+
+#if 0
+struct alarm_data {
+       s16 type;
+       u16 lock_addr;
+       time_t time;
+       u16 content[32];
+};
+#endif
+struct alarm_data {
+       u16 cabinet_id[16];
+       time_t time;
+       u16 content[32];
+};
+
+#endif
diff --git a/src/sgi_form_manage.cpp b/src/sgi_form_manage.cpp
new file mode 100644 (file)
index 0000000..5afeaa3
--- /dev/null
@@ -0,0 +1,166 @@
+#include "global_func.h"
+
+static s32 s_app_quit = 0;
+static struct sgi_form *s_active_form = NULL;
+static struct sgi_form *s_old_form = NULL;
+static struct sgi_form *s_next_form = NULL;
+
+static struct sgi_form_list s_form_list[] = {
+       FORM_LIST_FILL_ALL
+};
+
+s32 app_loop(SDL_Surface *screen)
+{
+       SDL_Event event;
+       struct sgi_msg msg;
+       
+       s_active_form->msg.clear();     
+       
+       while (!s_app_quit) {
+               
+               assert(s_active_form != NULL);
+
+               /* monitor */
+               monitor();
+               
+               /* network realtime monitor */
+               net_monitor();
+               
+               if (SDL_PollEvent(&event)) {
+                       /* message push */
+                       if (event.type == SDL_MOUSEBUTTONDOWN) {
+#if 0
+                               if (event.button.x > 700 &&
+                                       event.button.y < 80) {
+                                       printf("app quit.\n");
+                                       s_app_quit = 1;
+                                       continue;
+                               }
+#endif
+                               msg.type = SGI_MOUSEDOWN;
+                               msg.wparam = 0;
+                               msg.lparam = (event.button.y << 16) | (event.button.x & 0xffff);
+                               s_active_form->msg.push_back(msg);
+                       }
+                       else if (event.type == SDL_MOUSEBUTTONUP) {
+                               msg.type = SGI_MOUSEUP;
+                               msg.wparam = 0;
+                               msg.lparam = (event.button.y << 16) | (event.button.x & 0xffff);                                
+                               s_active_form->msg.push_back(msg);      
+                       }                       
+               }
+               
+               /* 置消息列表头标志 */
+               if (!s_active_form->msg.empty()) {
+                       struct sgi_msg &t = s_active_form->msg.front();
+                       t.wparam |= 0x8000;     
+               }
+
+               /* 进行消息循环 */
+               s_active_form->frame(s_active_form);
+               s_active_form->render(s_active_form, screen);
+               
+               /* 移除已处理的消息 */
+               if (!s_active_form->msg.empty()) {
+                       struct sgi_msg &t = s_active_form->msg.front();
+                       if ((t.wparam & 0x8000) == 0x8000) {
+                               s_active_form->msg.pop_front();
+                       }
+               }
+               
+               /* 是否需要进行form切换 */
+               if (s_next_form != NULL) {
+                       /* 执行前页面的退出动作 */
+                       if (s_active_form->exit) {
+                               s_active_form->exit(s_active_form);
+                       }
+                       s_active_form->msgbox = NULL;
+               
+                       /* 清除前页面消息队列 */
+                       s_active_form->msg.clear();
+                       
+                       /* 切换form */        
+                       s_old_form = s_active_form;
+                       s_active_form = s_next_form;
+                       s_active_form->redraw = 1;
+                       s_next_form = NULL;
+                       
+                       /* 如果form未初始,先执行初始化 */
+                       if (!s_active_form->initialized) {
+                               printf("active form init.\n");
+                               if (s_active_form->init(s_active_form) != 0) {
+                                       printf("form init fail: %s\n", s_active_form->name);
+                                       return FAIL;
+                               }                               
+                       }
+                       
+                       /* 执行新页面的初始动作 */
+                       if (s_active_form->enter) {
+                               s_active_form->enter(s_active_form);
+                       }
+                       s_active_form->msgbox = NULL;
+               }
+               
+               /* 如果队列中有消息,立即处理 */
+               if (!s_active_form->msg.empty()) {
+                       continue;                       
+               }
+               
+               SDL_Delay(10);                                          
+       }
+       
+       /* 清除form资源 */
+       u32 i;
+       for (i = 0; i < sizeof(s_form_list) / sizeof(struct sgi_form_list); ++i) {
+               if (s_form_list[i].created) {                           
+                       s_form_list[i].destroy();
+                       s_form_list[i].created = 0;
+                       printf("destroy form: %s\n", s_form_list[i].form->name);
+               }               
+       }
+       
+       return 0;
+}
+
+void sgi_form_show(struct sgi_form *form)
+{
+       u32 i;
+       
+       assert(form != NULL);
+       
+       /* 检查form是否已经创建 */
+       for (i = 0; i < sizeof(s_form_list) / sizeof(struct sgi_form_list); ++i) {
+               if (form == s_form_list[i].form) {
+                       if (!s_form_list[i].created) {                          
+                               s_form_list[i].create();
+                               s_form_list[i].created = 1;
+                       }
+                       break;
+               }               
+       }
+       
+       if (s_active_form == NULL) {            
+               /* 页面切换 */
+               s_active_form = form;
+               
+               /* 如果form未初始,先执行初始化 */
+               if (!s_active_form->initialized) {
+                       printf("active form init.\n");
+                       if (s_active_form->init(s_active_form) != 0) {
+                               printf("form init fail: %s\n", s_active_form->name);
+                               return;
+                       }                               
+               }
+       
+               /* 执行新页面的进入动作 */
+               if (s_active_form->enter) {
+                       s_active_form->enter(s_active_form);
+               }       
+       }
+       else {
+               s_next_form = form;     
+       }
+       
+       printf("form name: %s\n", s_active_form->name); 
+}
+
diff --git a/src/sgi_ime.cpp b/src/sgi_ime.cpp
new file mode 100644 (file)
index 0000000..7afa721
--- /dev/null
@@ -0,0 +1,156 @@
+#include "global_func.h"
+
+static struct sgi_key s_ime_key[KEY_NUMS] = {
+       IME_KEY(0,42,62,44),IME_KEY(61,42,62,44),IME_KEY(122,42,62,44),
+       IME_KEY(183,42,62,44),IME_KEY(244,42,62,44),IME_KEY(304,42,62,44),
+       IME_KEY(365,42,62,44),IME_KEY(426,42,62,44),IME_KEY(486,42,62,44),
+       IME_KEY(547,42,62,44),IME_KEY(608,42,84,44),
+       
+       IME_KEY(40,85,62,44),IME_KEY(102,85,62,44),IME_KEY(164,85,62,44),
+       IME_KEY(225,85,62,44),IME_KEY(285,85,62,44),IME_KEY(346,85,62,44),
+       IME_KEY(407,85,62,44),IME_KEY(468,85,62,44),IME_KEY(529,85,62,44),
+       IME_KEY(589,85,62,44),
+       
+       IME_KEY(73,127,62,44),IME_KEY(133,127,62,44),IME_KEY(194,127,62,44),
+       IME_KEY(255,127,62,44),IME_KEY(316,127,62,44),IME_KEY(376,127,62,44),
+       IME_KEY(437,127,62,44),IME_KEY(498,127,62,44),IME_KEY(559,127,62,44),
+       
+       IME_KEY(91,170,62,44),IME_KEY(152,170,62,44),IME_KEY(213,170,62,44),
+       IME_KEY(274,170,62,44),IME_KEY(334,170,62,44),IME_KEY(395,170,62,44),
+       IME_KEY(456,170,62,44),IME_KEY(517,170,84,44),  
+};
+
+static struct sgi_key s_ime_selector[10] = {
+       IME_KEY(0,0,84,42),IME_KEY(84,0,99,42),IME_KEY(183,0,61,42),
+       IME_KEY(244,0,61,42),IME_KEY(305,0,61,42),IME_KEY(366,0,61,42),
+       IME_KEY(426,0,61,42),IME_KEY(487,0,61,42),IME_KEY(548,0,61,42),
+       IME_KEY(608,0,84,42),
+};
+
+static const struct sgi_ime_caption s_ime_caption[3] = {
+       {{
+               {(u16)L'1'},{(u16)L'2'},{(u16)L'3'},{(u16)L'4'},{(u16)L'5'},
+               {(u16)L'6'},{(u16)L'7'},{(u16)L'8'},{(u16)L'9'},{(u16)L'0'},
+               {(u16)L'删',(u16)L'除'},
+               
+               {(u16)L'Q'},{(u16)L'W'},{(u16)L'E'},{(u16)L'R'},{(u16)L'T'},
+               {(u16)L'Y'},{(u16)L'U'},{(u16)L'I'},{(u16)L'O'},{(u16)L'P'},
+               
+               {(u16)L'A'},{(u16)L'S'},{(u16)L'D'},{(u16)L'F'},{(u16)L'G'},
+               {(u16)L'H'},{(u16)L'J'},{(u16)L'K'},{(u16)L'L'},
+               
+               {(u16)L'Z'},{(u16)L'X'},{(u16)L'C'},{(u16)L'V'},{(u16)L'B'},
+               {(u16)L'N'},{(u16)L'M'},{(u16)L'英',(u16)L'文'},
+       }},
+       
+       {{
+               {(u16)L'~'},{(u16)L'!'},{(u16)L'@'},{(u16)L'#'},{(u16)L'$'},
+               {(u16)L'%'},{(u16)L'.'},{(u16)L'&'},{(u16)L'*'},{(u16)L'_'},
+               {(u16)L'删',(u16)L'除'},
+               
+               {(u16)L'q'},{(u16)L'w'},{(u16)L'e'},{(u16)L'r'},{(u16)L't'},
+               {(u16)L'y'},{(u16)L'u'},{(u16)L'i'},{(u16)L'o'},{(u16)L'p'},
+               
+               {(u16)L'a'},{(u16)L's'},{(u16)L'd'},{(u16)L'f'},{(u16)L'g'},
+               {(u16)L'h'},{(u16)L'j'},{(u16)L'k'},{(u16)L'l'},
+               
+               {(u16)L'z'},{(u16)L'x'},{(u16)L'c'},{(u16)L'v'},{(u16)L'b'},
+               {(u16)L'n'},{(u16)L'm'},{(u16)L'符',(u16)L'号'},      
+       }},
+       
+       {{
+               {(u16)L'1'},{(u16)L'2'},{(u16)L'3'},{(u16)L'4'},{(u16)L'5'},
+               {(u16)L'6'},{(u16)L'7'},{(u16)L'8'},{(u16)L'9'},{(u16)L'0'},
+               {(u16)L'删',(u16)L'除'},
+               
+               {(u16)L'Q'},{(u16)L'W'},{(u16)L'E'},{(u16)L'R'},{(u16)L'T'},
+               {(u16)L'Y'},{(u16)L'U'},{(u16)L'I'},{(u16)L'O'},{(u16)L'P'},
+               
+               {(u16)L'A'},{(u16)L'S'},{(u16)L'D'},{(u16)L'F'},{(u16)L'G'},
+               {(u16)L'H'},{(u16)L'J'},{(u16)L'K'},{(u16)L'L'},
+               
+               {(u16)L'Z'},{(u16)L'X'},{(u16)L'C'},{(u16)L'V'},{(u16)L'B'},
+               {(u16)L'N'},{(u16)L'M'},{(u16)L'拼',(u16)L'音'},      
+       }},             
+};
+
+static const struct sgi_ime_word s_ime_word[3] = {
+       {
+               (u16)L'1',(u16)L'2',(u16)L'3',(u16)L'4',(u16)L'5',
+               (u16)L'6',(u16)L'7',(u16)L'8',(u16)L'9',(u16)L'0',
+               0x08,
+               
+               (u16)L'Q',(u16)L'W',(u16)L'E',(u16)L'R',(u16)L'T',
+               (u16)L'Y',(u16)L'U',(u16)L'I',(u16)L'O',(u16)L'P',
+               
+               (u16)L'A',(u16)L'S',(u16)L'D',(u16)L'F',(u16)L'G',
+               (u16)L'H',(u16)L'J',(u16)L'K',(u16)L'L',
+               
+               (u16)L'Z',(u16)L'X',(u16)L'C',(u16)L'V',(u16)L'B',
+               (u16)L'N',(u16)L'M',0x1b,
+       },
+       
+       {
+               (u16)L'~',(u16)L'!',(u16)L'@',(u16)L'#',(u16)L'$',
+               (u16)L'%',(u16)L'.',(u16)L'&',(u16)L'*',(u16)L'_',
+               0x08,
+               
+               (u16)L'q',(u16)L'w',(u16)L'e',(u16)L'r',(u16)L't',
+               (u16)L'y',(u16)L'u',(u16)L'i',(u16)L'o',(u16)L'p',
+               
+               (u16)L'a',(u16)L's',(u16)L'd',(u16)L'f',(u16)L'g',
+               (u16)L'h',(u16)L'j',(u16)L'k',(u16)L'l',
+               
+               (u16)L'z',(u16)L'x',(u16)L'c',(u16)L'v',(u16)L'b',
+               (u16)L'n',(u16)L'm',0x1b,       
+       },
+       
+       {
+               (u16)L'1',(u16)L'2',(u16)L'3',(u16)L'4',(u16)L'5',
+               (u16)L'6',(u16)L'7',(u16)L'8',(u16)L'9',(u16)L'0',
+               0x08,
+               
+               (u16)L'q',(u16)L'w',(u16)L'e',(u16)L'r',(u16)L't',
+               (u16)L'y',(u16)L'u',(u16)L'i',(u16)L'o',(u16)L'p',
+               
+               (u16)L'a',(u16)L's',(u16)L'd',(u16)L'f',(u16)L'g',
+               (u16)L'h',(u16)L'j',(u16)L'k',(u16)L'l',
+               
+               (u16)L'z',(u16)L'x',(u16)L'c',(u16)L'v',(u16)L'b',
+               (u16)L'n',(u16)L'm',0x1b,       
+       },      
+};
+
+struct sgi_ime g_sgi_ime;                      /* 输入法模块 */
+static s32 g_ime_created  = 0;
+
+void sgi_ime_create(void)
+{
+       if (g_ime_created) {
+               return;
+       }
+       
+       memset(&g_sgi_ime, 0, sizeof(g_sgi_ime));
+       g_sgi_ime.type = SGI_IME;
+       
+       /* 按键坐标绑定 */
+       g_sgi_ime.key = s_ime_key;
+       //memcpy(g_sgi_ime.key, s_ime_key, sizeof(s_ime_key));
+       //memcpy(g_sgi_ime.caption, s_ime_caption, sizeof(s_ime_caption));
+       g_sgi_ime.caption = s_ime_caption;
+       g_sgi_ime.word = s_ime_word;
+       //memcpy(g_sgi_ime.word, s_ime_word, sizeof(s_ime_word));
+       g_sgi_ime.selector = s_ime_selector;
+       
+       /* 其他属性及功能函数指针赋值 */
+       SDL_Color color = {0,0,0,0};
+       set_object_pos((union sgi_object *)&g_sgi_ime, 50, 226, 693, 213, 15);
+       set_object_image((union sgi_object *)&g_sgi_ime, "ime-f.png", 
+               "ime-b.png", NULL, NULL, IMG_OPTIMIZE | IMG_ALPHA);
+       set_object_font((union sgi_object *)&g_sgi_ime, "jht.ttf", 22, color);
+       set_object_default_func((union sgi_object *)&g_sgi_ime);
+       
+       g_ime_created = 1;      
+}
+
+
diff --git a/src/sgi_log.cpp b/src/sgi_log.cpp
new file mode 100644 (file)
index 0000000..dba0a80
--- /dev/null
@@ -0,0 +1,662 @@
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "global_func.h"
+
+static lock_t s_alarm_lock;
+static lock_t s_system_lock;
+static lock_t s_manager_lock;
+static lock_t s_report_lock;
+static lock_t s_borrow_lock;
+
+void *sgi_log_open(const char *name, size_t *size)
+{
+       int fd;
+       void *ptr;
+       
+       /* 打开文件 */
+       if ((fd = open(name, O_RDONLY)) < 0) {
+               return NULL;
+       }
+       
+       *size = lseek(fd, 0, SEEK_END);
+       ptr = mmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0);
+       
+       /* 关闭文件 */
+       close(fd);
+       
+       return ptr;     
+}
+
+void sgi_log_close(void *handle, size_t size)
+{
+       if (handle) {
+               munmap(handle, size);
+       }       
+}
+
+s32 sgi_append_log(const char *name, void *data, size_t size)
+{
+       FILE *fp;
+       
+       /* 打开日志文件 */
+       if (access(name, R_OK | W_OK) == 0) {
+               fp = fopen(name, "ab");         
+       }
+       else {
+               fp = fopen(name, "wb"); 
+       }       
+       if (fp == NULL) {
+               return FAIL;
+       }
+       
+       /* 追加数据 */
+       if (fwrite(data, 1, size, fp) < size) {
+               fclose(fp);
+               return FAIL;
+       }
+       
+       /* 关闭日志文件 */
+       fclose(fp);
+       
+       return 0;       
+}
+
+void record_alarm_log(wchar_t *content)
+{
+       struct log_alarm log;
+
+       memset(&log, 0, sizeof(log_alarm));
+       log.id = get_log_no(LOG_ALARM);
+       time(&log.time);
+       sgi_ncpw2u(log.content, content, COUNTOF(log.content));
+       
+       s_alarm_lock.lock();
+       sgi_append_log(DBL(alarm), &log, sizeof(struct log_alarm));
+       s_alarm_lock.unlock();
+       
+       create_data_packet(CMD_DATA_ALARM, &log, sizeof(struct log_alarm));     
+}
+
+void record_alarm_log(u16 *content)
+{
+       struct log_alarm log;
+
+       memset(&log, 0, sizeof(log_alarm));
+       log.id = get_log_no(LOG_ALARM);
+       time(&log.time);
+       sgi_ncp16(log.content, content, COUNTOF(log.content));
+       
+       s_alarm_lock.lock();
+       sgi_append_log(DBL(alarm), &log, sizeof(struct log_alarm));
+       s_alarm_lock.unlock();
+       
+       create_data_packet(CMD_DATA_ALARM, &log, sizeof(struct log_alarm));     
+}
+
+void record_borrow_log(struct passport_data *pass, struct box_info *info)
+{
+       struct log_borrow log;
+       
+       memset(&log, 0, sizeof(struct log_borrow));
+       log.id = get_log_no(LOG_BORROW);
+       log.time = pass->borrow_time;
+       sgi_ncp16(log.name, g_passport.name, COUNTOF(log.name));
+       sgi_ncp16(log.gun_type, info->gun_model, COUNTOF(log.gun_type));
+       sgi_ncp16(log.gun_code, info->gun_code, COUNTOF(log.gun_code));
+       
+       s_borrow_lock.lock();
+       sgi_append_log(DBL(borrow), &log, sizeof(struct log_borrow));
+       s_borrow_lock.unlock();
+       
+       create_data_packet(CMD_DATA_BORROW, &log, sizeof(struct log_borrow));           
+}
+
+void record_return_log(struct passport_data *pass, struct box_info *info)
+{
+       struct log_borrow log;
+       
+       memset(&log, 0, sizeof(struct log_borrow));
+       log.id = get_log_no(LOG_RETURN);
+       log.time = pass->return_time;
+       sgi_ncp16(log.name, g_passport.name, COUNTOF(log.name));
+       sgi_ncp16(log.gun_type, info->gun_model, COUNTOF(log.gun_type));
+       sgi_ncp16(log.gun_code, info->gun_code, COUNTOF(log.gun_code));
+       
+       s_borrow_lock.lock();
+       sgi_append_log(DBL(back), &log, sizeof(struct log_borrow));
+       s_borrow_lock.unlock();
+       
+       create_data_packet(CMD_DATA_RETURN, &log, sizeof(struct log_borrow));   
+}
+
+void recorcd_borrow_report(struct passport_data *pass, int type, int nums)
+{
+       struct log_report report;
+       u16 *code = get_box_code();
+       
+       memset(&report, 0, sizeof(struct log_report));
+       report.id = time(NULL);
+       sgi_ncp16(report.cid, code, COUNTOF(report.cid));
+       sgi_ncp16(report.uid, pass->uid, COUNTOF(report.uid));
+       sgi_ncp16(report.mid, pass->mid, COUNTOF(report.mid));
+       report.time = time(NULL);
+       report.qzsl = nums;     
+       report.type = type;
+       
+       s_report_lock.lock();
+       sgi_append_log(DBL(report-borrow), &report, sizeof(struct log_report));
+       s_report_lock.unlock();
+       
+       create_data_packet(CMD_DATA_REPORT_BORROW, &report, sizeof(struct log_report)); 
+}
+
+void recorcd_return_report(struct passport_data *pass, int type, int nums)
+{
+       struct log_report report;
+       u16 *code = get_box_code();
+       
+       memset(&report, 0, sizeof(struct log_report));
+       report.id = time(NULL);
+       sgi_ncp16(report.cid, code, COUNTOF(report.cid));
+       sgi_ncp16(report.uid, pass->uid, COUNTOF(report.uid));
+       sgi_ncp16(report.mid, pass->mid, COUNTOF(report.mid));
+       report.time = time(NULL);
+       report.qzsl = nums;     
+       report.type = type;
+       
+       s_report_lock.lock();
+       sgi_append_log(DBL(report-back), &report, sizeof(struct log_report));
+       s_report_lock.unlock();
+       
+       create_data_packet(CMD_DATA_REPORT_RETURN, &report, sizeof(struct log_report)); 
+}
+
+void record_system_log(u16 *name, wchar_t *content)
+{
+       /* log */
+       struct log_system log;
+       memset(&log, 0, sizeof(struct log_system));
+       log.id = get_log_no(LOG_SYSTEM);
+       time(&log.time);
+       sgi_ncp16(log.name, name, COUNTOF(log.name));
+       sgi_cpw2u(log.content, content);
+       
+       s_system_lock.lock();
+       sgi_append_log(DBL(syslog), &log, sizeof(struct log_system));
+       s_system_lock.unlock();
+       
+       create_data_packet(CMD_DATA_SYSTEM, &log, sizeof(struct log_system));
+}
+
+void record_manager_log(u16 *name, wchar_t *content)
+{
+       struct log_manager manager;
+       
+       memset(&manager, 0, sizeof(struct log_manager));
+       manager.id = get_log_no(LOG_MANAGER);
+       time(&manager.time);
+       sgi_ncp16(manager.name, name, COUNTOF(manager.name));
+       sgi_ncpw2u(manager.content, content, COUNTOF(manager.content));
+       
+       s_manager_lock.lock();
+       sgi_append_log(DBL(manager), &manager, sizeof(struct log_manager));
+       s_manager_lock.unlock();
+       
+       create_data_packet(CMD_DATA_MANAGER, &manager, sizeof(struct log_manager));     
+}
+
+static s32 download_borrow_incre(char *path)
+{
+       struct log_borrow *pcont;
+       size_t size;
+       s32 count = 0;
+       FILE *fp;
+       u32 i;
+       
+       fp = fopen(path, "wb");
+       if (!fp) {
+               return count;
+       }       
+       
+       pcont = (struct log_borrow *)open_w(DBL(borrow), &size);
+       if (!pcont) {
+               fclose(fp);
+               return count;
+       }
+       
+       struct log_borrow *p = pcont;
+       for (i = 0; i < size / sizeof(struct log_borrow); ++i) {
+               if (!p->down) {
+                       fwrite(p, 1, sizeof(struct log_borrow), fp);
+                       p->down = 1;
+                       count++;        
+               }
+               p++;    
+       }
+       
+       fclose(fp);
+       
+       /* 更新下载指针 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);
+
+       return count;   
+}
+
+static s32 download_return_incre(char *path)
+{
+       struct log_borrow *pcont;
+       size_t size;
+       s32 count = 0;
+       FILE *fp;
+       u32 i;
+       
+       fp = fopen(path, "wb");
+       if (!fp) {
+               return count;
+       }       
+       
+       pcont = (struct log_borrow *)open_w(DBL(back), &size);
+       if (!pcont) {
+               fclose(fp);
+               return count;
+       }
+       
+       struct log_borrow *p = pcont;
+       for (i = 0; i < size / sizeof(struct log_borrow); ++i) {
+               if (!p->down) {
+                       fwrite(p, 1, sizeof(struct log_borrow), fp);
+                       p->down = 1;
+                       count++;        
+               }
+               p++;    
+       }
+       
+       fclose(fp);
+       
+       /* 更新下载指针 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);
+
+       return count;   
+}
+
+static s32 download_alarm_incre(char *path)
+{
+       struct log_alarm *pcont;
+       size_t size;
+       s32 count = 0;
+       FILE *fp;
+       u32 i;
+       
+       fp = fopen(path, "wb");
+       if (!fp) {
+               return count;
+       }       
+       
+       pcont = (struct log_alarm *)open_w(DBL(alarm), &size);
+       if (!pcont) {
+               fclose(fp);
+               return count;
+       }
+       
+       struct log_alarm *p = pcont;
+       for (i = 0; i < size / sizeof(struct log_alarm); ++i) {
+               if (!p->down) {
+                       fwrite(p, 1, sizeof(struct log_alarm), fp);
+                       p->down = 1;
+                       count++;        
+               }
+               p++;    
+       }
+       
+       fclose(fp);
+       
+       /* 更新下载指针 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);
+
+       return count;   
+}
+
+static s32 download_system_incre(char *path)
+{
+       struct log_system *pcont;
+       size_t size;
+       s32 count = 0;
+       FILE *fp;
+       u32 i;
+       
+       fp = fopen(path, "wb");
+       if (!fp) {
+               return count;
+       }       
+       
+       pcont = (struct log_system *)open_w(DBL(syslog), &size);
+       if (!pcont) {
+               fclose(fp);
+               return count;
+       }
+       
+       struct log_system *p = pcont;
+       for (i = 0; i < size / sizeof(struct log_system); ++i) {
+               if (!p->down) {
+                       fwrite(p, 1, sizeof(struct log_system), fp);
+                       p->down = 1;
+                       count++;        
+               }
+               p++;    
+       }
+       
+       fclose(fp);
+       
+       /* 更新下载指针 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);
+
+       return count;   
+}
+
+static s32 download_manager_incre(char *path)
+{
+       struct log_manager *pcont;
+       size_t size;
+       s32 count = 0;
+       FILE *fp;
+       u32 i;
+       
+       fp = fopen(path, "wb");
+       if (!fp) {
+               return count;
+       }       
+       
+       pcont = (struct log_manager *)open_w(DBL(manager), &size);
+       if (!pcont) {
+               fclose(fp);
+               return count;
+       }
+       
+       struct log_manager *p = pcont;
+       for (i = 0; i < size / sizeof(struct log_manager); ++i) {
+               if (!p->down) {
+                       fwrite(p, 1, sizeof(struct log_manager), fp);
+                       p->down = 1;
+                       count++;        
+               }
+               p++;    
+       }
+       
+       fclose(fp);
+       
+       /* 更新下载指针 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);
+
+       return count;   
+}
+
+s32 download_log(s32 flag)
+{
+       time_t now;
+       struct tm *tmlocal;
+       char cmd[260];
+       s32 count = 0;
+       
+       time(&now);
+       tmlocal = localtime(&now);
+       
+       if (flag) {
+               /* borrow log */
+               sprintf(cmd, "cp -f %s %s/borrow_%04d%02d%02d%02d%02d%02d.log",
+                       DBL(borrow),
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               printf(cmd);
+               printf("\n");
+               system(cmd);
+               
+               /* return log */
+               sprintf(cmd, "cp -f %s %s/return_%04d%02d%02d%02d%02d%02d.log",
+                       DBL(back),
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               printf(cmd);
+               printf("\n");
+               system(cmd);
+               
+               /* alarm log */
+               sprintf(cmd, "cp -f %s %s/alarm_%04d%02d%02d%02d%02d%02d.log",
+                       DBL(alarm),
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               printf(cmd);
+               printf("\n");
+               system(cmd);
+               
+               /* system log */
+               sprintf(cmd, "cp -f %s %s/system_%04d%02d%02d%02d%02d%02d.log",
+                       DBL(syslog),
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               printf(cmd);
+               printf("\n");
+               system(cmd);
+               
+               /* manager log */
+               sprintf(cmd, "cp -f %s %s/manager_%04d%02d%02d%02d%02d%02d.log",
+                       DBL(manager),
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               printf(cmd);
+               printf("\n");
+               system(cmd);            
+       }
+       else {
+               /* borrow log */
+               sprintf(cmd, "%s/borrow_%04d%02d%02d%02d%02d%02d.log",
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               count += download_borrow_incre(cmd);
+               printf(cmd);
+               printf("\n");
+               
+               /* return log */
+               sprintf(cmd, "%s/return_%04d%02d%02d%02d%02d%02d.log",
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               count += download_return_incre(cmd);
+               printf(cmd);
+               printf("\n");
+               
+               /* alarm log */
+               sprintf(cmd, "%s/alarm_%04d%02d%02d%02d%02d%02d.log",
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               count += download_alarm_incre(cmd);
+               printf(cmd);
+               printf("\n");
+               
+               /* system log */
+               sprintf(cmd, "%s/system_%04d%02d%02d%02d%02d%02d.log",
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               count += download_system_incre(cmd);
+               printf(cmd);
+               printf("\n");
+               
+               /* manager log */
+               sprintf(cmd, "%s/manager_%04d%02d%02d%02d%02d%02d.log",
+                       UDISK_DEV, tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min,
+                       tmlocal->tm_sec);
+               count += download_manager_incre(cmd);
+               printf(cmd);
+               printf("\n");           
+       }
+       
+       return count;   
+}
+
+void mark_to_alarm_file(u32 id)
+{
+       u32 i;
+       size_t size;
+       struct log_alarm *pcont;
+       
+       s_alarm_lock.lock();
+       
+       pcont = (struct log_alarm *)open_w(DBL(alarm), &size);  
+       if (!pcont) {
+               goto clean;
+       }
+       
+       for (i = 0; i < size / sizeof(struct log_alarm); ++i) {
+               if (pcont[i].id == id && !pcont[i].up) {
+                       pcont[i].up = 1;
+                       break;  
+               }
+       }
+       
+       /* 更新到文件 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);
+       
+clean:
+       
+       s_alarm_lock.unlock();                  
+}
+
+void mark_to_system_file(u32 id)
+{
+       u32 i;
+       size_t size;
+       struct log_system *pcont;
+       
+       s_system_lock.lock();
+       
+       pcont = (struct log_system *)open_w(DBL(syslog), &size);        
+       if (!pcont) {
+               goto clean;
+       }
+       
+       for (i = 0; i < size / sizeof(struct log_system); ++i) {
+               if (pcont[i].id == id && !pcont[i].up) {
+                       pcont[i].up = 1;
+                       break;  
+               }
+       }
+       
+       /* 更新到文件 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);   
+       
+clean:
+       s_system_lock.unlock();         
+}
+
+void mark_to_manager_file(u32 id)
+{
+       u32 i;
+       size_t size;
+       struct log_manager *pcont;
+       
+       s_manager_lock.lock();
+       
+       pcont = (struct log_manager *)open_w(DBL(manager), &size);      
+       if (!pcont) {
+               goto clean;
+       }
+       
+       for (i = 0; i < size / sizeof(struct log_manager); ++i) {
+               if (pcont[i].id == id && !pcont[i].up) {
+                       pcont[i].up = 1;
+                       break;  
+               }
+       }
+       
+       /* 更新到文件 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);
+       
+clean:
+       s_manager_lock.unlock();                        
+}
+
+void mark_to_report_file(u32 id, s32 type)
+{
+       u32 i;
+       struct log_report *pcont;
+       size_t size;
+       
+       s_report_lock.lock();
+       
+       if (type == CMD_DATA_REPORT_BORROW) {
+               pcont = (struct log_report *)open_w(DBL(report-borrow), &size);
+       }
+       else {
+               pcont = (struct log_report *)open_w(DBL(report-back), &size);
+       }
+       
+       if (!pcont) {
+               goto clean;
+       }
+       
+       for (i = 0; i < size / sizeof(struct log_report); ++i) {
+               if (pcont[i].id == id && !pcont[i].up) {
+                       pcont[i].up = 1;
+                       break;  
+               }
+       }
+       
+       /* 更新到文件 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);   
+       
+clean:
+       s_report_lock.unlock();         
+}
+
+void mark_to_borrow_file(u32 id, s32 type)
+{
+       u32 i;
+       struct log_borrow *pcont;
+       size_t size;
+       
+       s_borrow_lock.lock();
+       
+       if (type == CMD_DATA_BORROW) {
+               pcont = (struct log_borrow *)open_w(DBL(borrow), &size);
+       }
+       else {
+               pcont = (struct log_borrow *)open_w(DBL(back), &size);
+       }
+       
+       if (!pcont) {
+               goto clean;
+       }
+       
+       for (i = 0; i < size / sizeof(struct log_borrow); ++i) {
+               if (pcont[i].id == id && !pcont[i].up) {
+                       pcont[i].up = 1;
+                       break;  
+               }
+       }
+       
+       /* 更新到文件 */
+       msync(pcont, size, MS_SYNC);
+       close_w(pcont, size);   
+       
+clean:
+       s_borrow_lock.unlock();         
+}
diff --git a/src/sgi_log.h b/src/sgi_log.h
new file mode 100644 (file)
index 0000000..58713b2
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef SGI_LOG_H
+#define SGI_LOG_H
+
+#include <time.h>
+#include "sgi_types.h"
+
+struct log_borrow {
+       //char id[8];
+       u32 id;
+       u16 name[8];
+       time_t time;
+       u16 gun_type[8];
+       u16 gun_code[8];
+       u32 bullets;
+       s16 up;
+       s16 down;       
+};
+
+struct log_alarm {
+       //char id[8];
+       u32 id;
+       time_t time;
+       u16 content[32];
+       s16 up;
+       s16 down;
+};
+
+struct log_system {
+       //char id[8];
+       u32 id;
+       u16 name[8];
+       time_t time;
+       u16 content[16];
+       s16 up;
+       s16 down;       
+};
+
+struct log_manager {
+       //char id[8];
+       u32 id;
+       time_t time;
+       u16 name[16];
+       u16 content[32];
+       s16 up;
+       s16 down;       
+};
+
+struct log_report {
+       s32 id;
+       u16 cid[16];
+       u16 uid[16];
+       u16 mid[16];
+       time_t time;
+       s32 qzsl;
+       s32 type;
+       s32 zdlx;
+       s32 zdsl;
+       s32 up;         
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *sgi_log_open(const char *name, size_t *size);
+void sgi_log_close(void *handle, size_t size);
+s32 sgi_append_log(const char *name, void *data, size_t size);
+s32 download_log(s32 flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/sgi_msgbox.cpp b/src/sgi_msgbox.cpp
new file mode 100644 (file)
index 0000000..687dc99
--- /dev/null
@@ -0,0 +1,31 @@
+#include "global_func.h"
+
+struct sgi_msgbox g_sgi_msgbox;                        /* 对话框模块 */
+static s32 g_msgbox_created  = 0;
+
+void sgi_msgbox_create(void)
+{
+       if (g_msgbox_created) {
+               return;
+       }
+       
+       memset(&g_sgi_msgbox, 0, sizeof(g_sgi_msgbox));
+       g_sgi_msgbox.type = SGI_MSGBOX;
+       
+       /* 其他属性及功能函数指针赋值 */
+       SDL_Color color = {0,0,0,0};
+       set_object_image((union sgi_object *)&g_sgi_msgbox, "msgbox.png", 
+               NULL, "btn-confirm-u.png", "btn-confirm-d.png",
+               IMG_OPTIMIZE | IMG_ALPHA);      
+               
+       /* button */
+       g_sgi_msgbox.button.x = 213;
+       g_sgi_msgbox.button.y = 113;
+       
+       set_object_font((union sgi_object *)&g_sgi_msgbox, "jht.ttf", 22, color);
+       set_object_default_func((union sgi_object *)&g_sgi_msgbox);
+       
+       g_msgbox_created = 1;   
+}
+
+
diff --git a/src/sgi_resource.cpp b/src/sgi_resource.cpp
new file mode 100755 (executable)
index 0000000..93d5b69
--- /dev/null
@@ -0,0 +1,374 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <vector>
+#include "global_func.h"
+#include "sgi_resource.h"
+
+static std::vector <union resource_t > s_resource_vec;
+static Mix_Chunk *s_effect = NULL;
+static Mix_Chunk *s_effect_fpr = NULL;
+       
+const char *get_resource_path(void)
+{
+       return "/sdcard/resource";      
+}
+
+int initialize_resource(SDL_Surface *screen)
+{
+       int rc;
+       
+       /* 初始化图形模块 */
+       rc = IMG_Init(IMG_INIT_PNG);
+       if ((rc & IMG_INIT_PNG) == 0) {
+               printf("IMG_Init: %s\n", IMG_GetError());
+               goto err;       
+       }
+       
+       /* 初始化字体模块 */
+       rc = TTF_Init();
+       if (rc != 0) {
+               printf("TTF_Init: %s\n", TTF_GetError());
+               goto err;       
+       }\r 
+       \r       
+       /* 初始化声音模块 */
+       rc = Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024);
+       if (rc != 0) {
+               printf("Mix_OpenAudio: %s\n", Mix_GetError());
+               goto err;       
+       }
+       
+       /* 加载按键声 */
+       s_effect = request_wav("key.wav");
+       s_effect_fpr = request_wav("fpr.wav");
+       Mix_AllocateChannels(2);
+       
+       /* 初始化资源容器 */
+       s_resource_vec.clear(); 
+       
+       return 0;
+       
+err:
+       return -1;      
+}
+
+void destroy_resource(void)
+{
+       std::vector<union resource_t >::iterator it;
+                               
+       /* 释放资源容器中元素所分配的内存 */     
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end(); it++) {           
+               switch ((*it).type) {
+               case RC_IMAGE:
+                       printf("destroy image\n"); 
+                       SDL_FreeSurface((*it).image.data);
+                       break;  
+                       
+               case RC_FONT:
+                       printf("destroy font\n"); 
+                       TTF_CloseFont((*it).font.data);
+                       break;
+                       
+               case RC_WAV:
+                       printf("destroy wav\n"); 
+                       Mix_FreeChunk((*it).wav.data);
+                       break;
+                       
+               case RC_MP3:
+                       printf("destroy mp3\n"); 
+                       Mix_FreeMusic((*it).mp3.data);
+                       break;
+               
+               default:
+                       break;                  
+               }
+       }
+       
+       /* 释放容器本身所占内存 */
+       s_resource_vec.clear();
+       
+       /* 释放图形模块 */
+       IMG_Quit();
+       
+       /* 释放字体模块 */
+       TTF_Quit();     
+       
+       /* 释放声音模块 */
+       Mix_CloseAudio() ;
+       
+       /* */
+       release_wav(s_effect);
+       release_wav(s_effect_fpr);
+}
+
+TTF_Font *request_font(char *id, int font_size)
+{
+       union resource_t res;
+       std::vector<union resource_t >::iterator it;
+       char path[MAX_PATH];
+               
+       if (!id) {
+               return NULL;
+       }
+       
+       printf("request font: %s\n", id);
+       /* 在资源容器中查找是否有符合条件的字体 */    
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end(); it++) {
+               if ((*it).type == RC_FONT 
+                       && (strcmp((*it).font.id, id) == 0)
+                       && (*it).font.size == font_size) {
+                               (*it).font.ref++;
+                               return (*it).font.data;
+               }       
+       }
+       
+       /* 容器中无符合条件的字体,创建后添加到容器 */
+       memset(&res, 0, sizeof(union resource_t));
+       res.type = RC_FONT;
+       res.font.ref++;
+       strncpy(res.font.id, id, sizeof(res.font.id));
+       res.font.size = font_size; 
+       sprintf(path, "%s/%s", get_resource_path(), id);
+       res.font.data = TTF_OpenFont(path, font_size);
+       if (res.font.data != NULL) {
+               s_resource_vec.push_back(res);
+               return res.font.data;   
+       }       
+       
+       return NULL;
+} 
+
+void release_font(void *font)
+{
+       std::vector<union resource_t >::iterator it;    
+               
+       /* 在资源容器中查找被引用的字体 */        
+       if (font == NULL) {
+               return;
+       }
+       
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end(); it++) {
+               if ((*it).type == RC_FONT 
+                       && (Uint32)(*it).font.data == (Uint32)font) {
+                       (*it).font.ref--;
+                       break;
+               }       
+       }
+}
+
+static SDL_Surface *create_image(char *id, int flags)
+{
+       SDL_Surface *temp;
+       SDL_Surface *optimize;
+       char path[MAX_PATH];
+       
+       /* 从文件中加载图片到表面 */
+       sprintf(path, "%s/%s", get_resource_path(), id);
+       temp = IMG_Load(path);  
+       if (temp == NULL) {
+               return NULL;
+       }
+       
+       /* 是否需要对表面进行预处理 */
+       if (flags & IMG_OPTIMIZE) {
+               if ((flags & IMG_ALPHA) == IMG_ALPHA) {
+                       optimize = SDL_DisplayFormatAlpha(temp);        
+               }
+               else {                  
+                       optimize = SDL_DisplayFormat(temp);             
+               }
+               
+               /* 释放原图 */
+               SDL_FreeSurface(temp);                          
+       }
+       else {
+               optimize = temp;
+       }
+       
+       return optimize;                
+}
+
+SDL_Surface *request_image(char *id, int flags)
+{
+       union resource_t res;
+       std::vector<union resource_t >::iterator it;\r 
+               
+       if (!id) {
+               return NULL;
+       }
+       
+       printf("request image: %s\n", id);
+       /* 在资源容器中查找是否有符合条件的图片 */
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end();\r it++) {
+               if ((*it).type == RC_IMAGE
+                       && (strcmp((*it).image.id, id\r) == 0)
+                       && (*it).image.flags == flags) {
+                               (*it).image.ref++;
+                               return (*it).image.data;\r 
+               }
+       }
+       
+       /* 创建图片表面 */        
+       memset(&res, 0, sizeof(union resource_t));
+       res.image.data = create_image(id, flags);
+       if (res.image.data != NULL) {
+               res.image.type = RC_IMAGE;
+               res.image.ref++;
+               strncpy(res.image.id, id, sizeof(res.image.id));
+               res.image.flags = flags;
+               s_resource_vec.push_back(res);
+               printf("push_back image: type=%d\n", res.type); 
+       }               
+                               
+       return res.image.data;          
+}
+
+void release_image(void *image)
+{
+       std::vector<union resource_t >::iterator it;
+               
+       /* 在资源容器中查找被引用的图片表面 */  
+       if (image == NULL) {
+               return;
+       }
+               
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end(); it++) {
+               if ((*it).type == RC_IMAGE 
+                       && (Uint32)(*it).image.data == (Uint32)image) {
+                       (*it).image.ref--;
+                       break;
+               }
+       }       
+}
+
+static Mix_Chunk *load_wav_file(char *id)
+{
+       return Mix_LoadWAV(id);
+}
+
+Mix_Chunk *request_wav(char *id)
+{
+       union resource_t res;
+       std::vector<union resource_t >::iterator it;
+       char path[MAX_PATH];
+               
+       if (!id) {
+               return NULL;
+       }
+       
+       /* 先查找声音资源是否已经加载 */
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end(); it++) {
+               if ((*it).type == RC_WAV
+                       && (strcmp((*it).wav.id, id) == 0)) {
+                       (*it).wav.ref++;
+                       return (*it).wav.data;
+               }
+       }
+       
+       /* 未找到,加载声音资源 */
+       memset(&res, 0, sizeof(union resource_t));
+       sprintf(path, "%s/%s", get_resource_path(), id);
+       res.wav.data = load_wav_file(path);
+       if (res.wav.data != NULL) {
+               res.type = RC_WAV;              
+               res.wav.ref++;
+               strncpy(res.wav.id, id, sizeof(res.wav.id));
+               s_resource_vec.push_back(res);
+               printf("push back wav: %s\n", id);
+       }
+       
+       return res.wav.data;    
+}
+
+void release_wav(void *wav)
+{
+       std::vector<union resource_t >::iterator it;
+               
+       if (wav == NULL) {
+               return;
+       }
+                       
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end(); it++) {
+               if ((*it).type == RC_WAV 
+                       && (Uint32)(*it).wav.data == (Uint32)wav) {
+                       (*it).wav.ref--;
+                       break;
+               }
+       }               
+}
+
+static Mix_Music *load_mp3_file(char *id)
+{
+       return Mix_LoadMUS(id);
+}
+
+Mix_Music *request_mp3(char *id)
+{
+       union resource_t res;
+       std::vector<union resource_t >::iterator it;
+       char path[MAX_PATH];
+       
+       if (!id) {
+               return NULL;
+       }
+               
+       /* 先查找声音资源是否已经加载 */
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end(); it++) {
+               if ((*it).type == RC_MP3
+                       && (strcmp((*it).mp3.id, id) == 0)) {
+                       (*it).mp3.ref++;
+                       return (*it).mp3.data;
+               }
+       }
+       
+       /* 未找到,加载声音资源 */
+       memset(&res, 0, sizeof(union resource_t));
+       sprintf(path, "%s/%s", get_resource_path(), id);
+       res.mp3.data = load_mp3_file(path);
+       if (res.mp3.data != NULL) {
+               res.type = RC_MP3;              
+               res.mp3.ref++;
+               strncpy(res.mp3.id, id, sizeof(res.mp3.id));
+               s_resource_vec.push_back(res);
+               printf("push back mp3: %s\n", id);
+       }
+       
+       return res.mp3.data;    
+}
+
+void release_mp3(void *mp3)
+{
+       std::vector<union resource_t >::iterator it;
+               
+       if (mp3 == NULL) {
+               return;
+       }
+                       
+       for (it = s_resource_vec.begin(); it != s_resource_vec.end(); it++) {
+               if ((*it).type == RC_MP3
+                       && (Uint32)(*it).mp3.data == (Uint32)mp3) {
+                       (*it).mp3.ref--;
+                       break;
+               }
+       }               
+}
+
+void play_effect(void)
+{
+       if (s_effect != NULL) {
+               if(Mix_PlayChannel(-1, s_effect, 0)==-1) {
+                       printf("Mix_PlayChannel: %s\n",Mix_GetError());
+               }
+       }       
+}
+
+void play_effect_fpr(void)
+{
+       if (s_effect_fpr != NULL) {
+               if(Mix_PlayChannel(-1, s_effect_fpr, 0)==-1) {
+                       printf("Mix_PlayChannel: %s\n",Mix_GetError());
+               }
+       }       
+}
diff --git a/src/sgi_resource.h b/src/sgi_resource.h
new file mode 100755 (executable)
index 0000000..a915c93
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+#include "global_def.h"
+
+#define RC_IMAGE               1
+#define RC_FONT                        2
+#define RC_WAV                 3
+#define RC_MP3                 4
+
+struct resource_image_t {
+       int type;
+       int ref;
+       char id[32];
+       int flags;      
+       SDL_Surface *data;
+};
+
+struct resource_font_t {
+       int type;
+       int ref;
+       char id[32];
+       int size;
+       TTF_Font *data;
+};
+
+struct resource_wav_t {
+       int type;
+       int ref;
+       char id[32];
+       Mix_Chunk *data;
+};
+
+struct resource_mp3_t {
+       int type;
+       int ref;
+       char id[32];
+       Mix_Music *data;
+};
+
+union resource_t {
+       int type;
+       struct resource_image_t image;
+       struct resource_font_t font;
+       struct resource_wav_t wav;
+       struct resource_mp3_t mp3;
+};
+
+#endif
diff --git a/src/sgi_string.c b/src/sgi_string.c
new file mode 100644 (file)
index 0000000..fdf8fb7
--- /dev/null
@@ -0,0 +1,190 @@
+#include <stdio.h>
+//#include <stdlib.h>
+
+#include <stdarg.h>
+//#include <unistd.h>
+//#include <string.h>
+//#include <uchar.h>
+#include <wchar.h>
+#include <wctype.h>
+//#include "sqlite3.h"
+#include "sgi_types.h"
+
+#define MAX_CHAR       512
+
+void sgi_sprintf16(u16 *s, const wchar_t *fmt, ...)
+{
+       wchar_t temp[MAX_CHAR];
+       
+       va_list va;
+       va_start(va, fmt);
+       vswprintf(temp, sizeof(temp), fmt, va);
+       va_end(va);
+       
+       wchar_t *t = temp;
+       while (*t != L'\0') {
+               *s++ = (u16)*t++;       
+       }
+       *s = 0;
+} 
+
+size_t sgi_len16(u16 *s)
+{
+       u16 *e = s;
+               
+       while (*e++);   
+       
+       return (e - s - 1);     
+}
+
+u16 *sgi_cp16(u16 *dest, u16 *src)
+{
+       u16 *ptr = dest;
+       
+       while ((*dest++ = *src++));
+       *dest = 0;
+       
+       return ptr;     
+}
+
+u16 *sgi_ncp16(u16 *dest, u16 *src, size_t n)
+{
+       u16 *ptr = dest;
+       
+       while (n-- && (*dest++ = *src++));
+       *dest = 0;
+       
+       return ptr;
+}
+
+s32 sgi_cmp16(u16 *s1, u16 *s2)
+{
+       while (*s1 && *s2 && *s1 == *s2) {
+               s1++; s2++;
+       }
+       
+       return (*s1 | *s2) ? -1 : 0;
+}
+
+s32 sgi_ncmp16(u16 *s1, u16 *s2, size_t n)
+{
+       while (*s1 && *s2 && *s1 == *s2 && n--) {
+               s1++; s2++;
+       }
+       
+       return (*s1 | *s2) ? n : 0;
+}
+
+u16 *sgi_cpw2u(u16 *dest, wchar_t *src)
+{
+       u16 *ptr = dest;
+       
+       while ((*dest++ = (u16)*src++));
+       
+       return ptr;     
+}
+
+wchar_t *sgi_cpu2w(wchar_t *dest, u16 *src)
+{
+       wchar_t *ptr = dest;
+       
+       while ((*dest++ = (wchar_t)*src++));
+       
+       return ptr;     
+}
+
+char *sgi_cpu2a(char *dest, u16 *src)
+{
+       char *ptr = dest;
+       
+       while ((*dest++ = (char)*src++));
+       
+       return ptr;     
+}
+
+u16 *sgi_cpa2u(u16 *dest, char *src)
+{
+       u16 *ptr = dest;
+       
+       while ((*dest++ = (u16)*src++));
+       
+       return ptr;     
+}
+
+u16 *sgi_ncpw2u(u16 *dest, wchar_t *src, size_t n)
+{
+       u16 *ptr = dest;
+       
+       while (n-- && (*dest++ = (u16)*src++));
+       
+       return ptr;     
+}
+
+wchar_t *sgi_ncpu2w(w32 *dest, u16 *src, size_t n)
+{
+       wchar_t *ptr = dest;
+       
+       while (n-- && (*dest++ = (w32)*src++));
+       
+       return ptr;     
+}
+
+char *sgi_ncpu2a(char *dest, u16 *src, size_t n)
+{
+       char *ptr = dest;
+       
+       while (n-- && (*dest++ = (char)*src++));
+       
+       return ptr;     
+}
+
+u16 *sgi_ncpa2u(u16 *dest, char *src, size_t n)
+{
+       u16 *ptr = dest;
+       
+       while (n-- && (*dest++ = (u16)*src++));
+       
+       return ptr;     
+}
+
+u16 *sgi_ncat16(u16 *dest, u16 c, size_t n)
+{
+       u32 i;
+       
+       for (i = 0; i < n; ++i) {
+               if (dest[i] == 0) {
+                       dest[i] = c;
+                       break;
+               }
+       }       
+       
+       return NULL;
+}
+
+u16 *sgi_rdel16(u16 *dest, size_t n)
+{
+       s32 i;
+       
+       for (i = n; i > 0; i--) {
+               if (dest[i - 1] != 0) {
+                       dest[i - 1] = 0;
+                       break;
+               }               
+       }
+       
+       return dest;    
+}
+
+s32 sgi_isdigit16(u16 text)
+{
+       return iswdigit(text);  
+}
+
+s32 sgi_utol(u16 *text, s32 base)
+{
+       wchar_t ch[20] = {0};
+               
+       sgi_cpu2w(ch, text);
+       
+       return wcstol(ch, NULL, base);  
+}
diff --git a/src/sgi_string.h b/src/sgi_string.h
new file mode 100644 (file)
index 0000000..246a5f3
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef SGI_STRING_H
+#define SGI_STRING_H
+
+#include <stdlib.h>
+#include "sgi_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void   sgi_sprintf16(u16 *s, const w32 *fmt, ...);
+size_t sgi_len16(u16 *s);
+u16*   sgi_cp16(u16 *dest, u16 *src);
+u16*   sgi_ncp16(u16 *dest, u16 *src, size_t n);
+s32    sgi_cmp16(u16 *s1, u16 *s2);
+s32    sgi_ncmp16(u16 *s1, u16 *s2, size_t n);
+u16*   sgi_cpw2u(u16 *dest, w32 *src);
+w32*   sgi_cpu2w(w32 *dest, u16 *src); 
+char*  sgi_cpu2a(char *dest, u16 *src);        
+u16*   sgi_cpa2u(u16 *dest, char *src);        
+u16*   sgi_ncpw2u(u16 *dest, w32 *src, size_t n);
+w32*   sgi_ncpu2w(w32 *dest, u16 *src, size_t n);
+char*  sgi_ncpu2a(char *dest, u16 *src, size_t n);
+u16*   sgi_ncpa2u(u16 *dest, char *src, size_t n);
+u16*   sgi_ncat16(u16 *dest, u16 c, size_t n);
+u16*   sgi_rdel16(u16 *dest, size_t n);
+s32    sgi_isdigit16(u16 text);
+s32    sgi_utol(u16 *text, s32 base);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/sgi_types.h b/src/sgi_types.h
new file mode 100644 (file)
index 0000000..c725c74
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef SGI_TYPES_H
+#define SGI_TYPES_H
+
+#include <wchar.h>
+
+/* Base type redefine */
+#undef  u32
+#define u32            unsigned int
+
+#undef  u16
+#define u16            unsigned short
+
+#undef  u8
+#define u8             unsigned char
+
+#undef  s32
+#define s32            int
+
+#undef  s16
+#define s16            short
+
+#undef  s8
+#define s8             signed char
+
+#undef w32
+#define        w32             wchar_t
+
+#undef SOCKET
+#define SOCKET         int
+
+/* Math macro define */
+#define COUNTOF(a)     (sizeof(a) / sizeof((a)[0]))
+
+/* Common define */
+#undef  FAIL
+#define FAIL           -1
+#define COMM_ERR       -1
+#define CANCEL_ERR     -2
+
+#endif
\ No newline at end of file
diff --git a/src/uart.cpp b/src/uart.cpp
new file mode 100644 (file)
index 0000000..b5d9a48
--- /dev/null
@@ -0,0 +1,144 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <string.h>
+#include "global_func.h"
+
+static int s_fd = -1;
+
+s32 open_comm(void)
+{
+       struct termios option;
+       
+       /* open serial port */
+       s_fd = open("/dev/ttySAC2", O_RDWR | O_NOCTTY);
+       if (s_fd == -1) {
+               printf("Can not open ttySAC2!\n");
+               return COMM_ERR;
+       }
+       
+       /* set serial port parameter (B115200, 8 , N , 1) */
+       tcgetattr(s_fd, &option);
+       cfmakeraw(&option);
+       cfsetispeed(&option, B115200);
+       cfsetospeed(&option, B115200);
+       tcsetattr(s_fd, TCSANOW, &option);
+       
+       return 0;       
+}
+
+void close_comm(void)
+{
+       close(s_fd);    
+}
+
+s32 transfer(u8 *tx, u32 tx_len, u8 *rx, u32 rx_len, u32 timeout)
+{
+       s32 remain;
+       s32 s;
+       u8 *p;
+       s32 status;
+       fd_set rd;
+       struct timeval tv;
+   
+       /* flush data */
+       tcflush(s_fd, TCIOFLUSH);               
+
+       /* send data */ 
+       if (write(s_fd, tx, tx_len) < (s32)tx_len) {
+               return COMM_ERR;
+       }
+
+#if 0  
+       /* receive data */
+       FD_ZERO(&rd);   
+       FD_SET(s_fd, &rd);
+       tv.tv_sec = timeout / 1000;
+       tv.tv_usec = (timeout % 1000) * 1000;
+       timeout = SDL_GetTicks() + timeout;
+       if (select(s_fd + 1, &rd, NULL, NULL, &tv) <= 0) {
+               return COMM_ERR;
+       }
+#endif
+       
+       /* receive data until enough or timeout */
+       p = rx;
+       remain = rx_len;
+       timeout = SDL_GetTicks() + timeout;
+       while (remain > 0 && SDL_GetTicks() < timeout) {
+               /* cancel operate if need */
+               if (fpr_get_cancel_flag()) {
+                       return CANCEL_ERR;      
+               }
+               SDL_Delay(10);
+               
+               /* get serial port data length */
+               status = 0;
+               if (ioctl(s_fd, FIONREAD, &status) < 0) {
+                       continue;
+               }
+               
+               /* read data if has data */
+               if (status > 0) {
+                       s = status > remain ? remain : status;
+                       s = read(s_fd, p, s);
+                       p += s;
+                       remain -= s;    
+               }                       
+       } 
+       
+       /* not enough data */
+       if (remain > 0) {
+               return COMM_ERR;        
+       }
+       
+       return 0;       
+}
+
+s32 uart_receive(u8 *rx, u32 rx_len, u32 timeout)
+{
+       s32 remain;
+       s32 s;
+       u8 *p;
+       s32 status;
+       fd_set rd;
+       struct timeval tv;
+       
+       /* receive data */
+       FD_ZERO(&rd);   
+       FD_SET(s_fd, &rd);
+       tv.tv_sec = timeout / 1000;
+       tv.tv_usec = (timeout % 1000) * 1000;
+       timeout = SDL_GetTicks() + timeout;
+       if (select(s_fd + 1, &rd, NULL, NULL, &tv) <= 0) {
+               return COMM_ERR;
+       }
+       
+       /* receive data until enough or timeout */
+       p = rx;
+       remain = rx_len;
+       while (remain > 0 && SDL_GetTicks() < timeout) {
+               status = 0;
+               if (ioctl(s_fd, FIONREAD, &status) < 0) {
+                       continue;
+               }
+               
+               if (status > 0) {
+                       s = status > remain ? remain : status;
+                       s = read(s_fd, p, s);
+                       p += s;
+                       remain -= s;    
+               }
+               SDL_Delay(10);                  
+       } 
+       
+       /* not enough data */
+       if (remain > 0) {
+               return COMM_ERR;        
+       }
+       
+       return 0;       
+}
+
diff --git a/src/udisk.cpp b/src/udisk.cpp
new file mode 100644 (file)
index 0000000..d8d4ce7
--- /dev/null
@@ -0,0 +1,163 @@
+#include "global_def.h"
+#include <sys/vfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#define SKIP_WS(s)                     \
+do {                                   \
+       while (isspace(*s) && s++);     \
+} while (0)
+
+#define FIND_QT(s)                     \
+do {                                   \
+       while (*s != ':' && s++);       \
+} while (0)
+
+s32 udisk_remove_detect(void)
+{
+       if (access("/udisk", F_OK) != 0) {
+               return 1;
+       }
+       
+       return 0;
+}
+
+static s32 get_udisk_info(const char *path, struct udisk_info *udisk)
+{
+       char buf[1024];
+       
+       FILE *fp = fopen(path, "r");
+       if (fp == NULL) {
+               return -1;
+       }
+       
+       memset(udisk, 0, sizeof(struct udisk_info));
+       while (fgets(buf, sizeof(buf), fp)) {
+               char *p = buf;
+               SKIP_WS(p);
+               if (strncmp(p, "Vendor", 6) == 0) {
+                       FIND_QT(p);
+                       char *p1 = strtok(p + 2, "\n");
+                       strncpy(udisk->vendor, p1, sizeof(udisk->vendor) - 1);
+               }
+               else if (strncmp(p, "Product", 7) == 0) {
+                       FIND_QT(p);
+                       char *p1 = strtok(p + 2, "\n");
+                       strncpy(udisk->product, p1, sizeof(udisk->product) - 1);        
+               }
+               else if (strncmp(p, "Serial Number", 13) == 0) {
+                       FIND_QT(p);
+                       char *p1 = strtok(p + 2, "\n");
+                       strncpy(udisk->sn, p1, sizeof(udisk->sn) - 1);  
+               }               
+       }
+       
+       fclose(fp);
+       return 0;       
+}
+
+static s32 get_udisk_space(const char *path, struct udisk_info *udisk)
+{
+       struct statfs s;
+       
+       if (statfs(path, &s) == -1) {
+               return -1;
+       }
+       
+       udisk->total = (long long)s.f_blocks * s.f_bsize / 1024 / 1024;
+       udisk->avail = (long long)s.f_bavail * s.f_bsize / 1024 / 1024;
+       
+       return 0;       
+}
+
+s32 udisk_insert_detect(struct udisk_info *udisk)
+{
+       DIR *d;
+       struct dirent *file;
+       struct stat sb;
+       char path[64] = UDISK_DRV;
+
+       if(!(d = opendir(path))) {
+                       return -1;
+       }
+
+       while((file = readdir(d)) != NULL) {
+               if(strncmp(file->d_name, ".", 1) == 0) {
+                       continue;
+               }
+               
+               sprintf(path, "%s/%s", path, file->d_name);
+               if (stat(path, &sb) < 0) {
+                       continue;                       
+               }
+               
+               if (S_ISREG(sb.st_mode)) {              
+                       if (get_udisk_info(path, udisk) == 0) {                         
+                               /* wait mount is ok */
+                               int i;
+                               int found = 0;
+                               for (i = 0; i < 5; ++i) {
+                                       if (access(UDISK_DEV, F_OK) == 0) {
+                                               found = 1;
+                                               break;
+                                       }
+                                       SDL_Delay(500); 
+                               }
+                               
+                               if (!found) {
+                                       break;  
+                               }
+                               
+                               SDL_Delay(1000);
+                               closedir(d);                    
+                               return get_udisk_space(UDISK_DEV, udisk);
+                       }       
+               }
+       }
+       closedir(d);            
+       
+       return -1;      
+}
+
+#if 0
+int main(int argc, char **argv)
+{
+       int exist = 0;
+       int i = 0;
+       
+       while (i++ < 30) {
+               if (!exist) {
+                       if (udisk_insert_detect(&s_udisk) == 0) {
+                               exist = 1;
+                               printf("Vendor: %s\n", s_udisk.vendor);
+                               printf("Product: %s\n", s_udisk.product);
+                               printf("Serial number: %s\n", s_udisk.sn);
+                               
+                               if (s_udisk.total > 1024) {
+                                       printf("Total: %.2f GB\n", s_udisk.total / 1024.0);
+                               }
+                               else {
+                                       printf("Total: %d MB\n", s_udisk.total);
+                               }
+                               
+                               if (s_udisk.avail > 1024) {
+                                       printf("Avail: %.2f GB\n", s_udisk.avail / 1024.0);
+                               }
+                               else {
+                                       printf("Avail: %d MB\n", s_udisk.avail);
+                               }                               
+                       }
+               }
+               else {
+                       if (udisk_remove_detect()) {
+                               exist = 0;
+                               printf("Udisk is remove\n");
+                       }
+               }
+               
+               usleep(1000000);        
+               
+       }
+}
+#endif
diff --git a/temp/sgi_data.cpp b/temp/sgi_data.cpp
new file mode 100644 (file)
index 0000000..38b7e62
--- /dev/null
@@ -0,0 +1,745 @@
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "global_func.h"
+
+static std::vector <struct sgi_person_mem > s_person_vec;
+static std::vector <struct sgi_gun > s_gun_vec;
+static struct sgi_box s_gun_box;
+static struct sgi_unit s_unit;
+static u8 s_gun_box_info[256] = {0};
+
+static void *open_w(const char *name, size_t *size)
+{
+       int fd;
+       void *ptr;
+       
+       /* 打开文件 */
+       if ((fd = open(name, O_RDWR)) < 0) {
+               return NULL;
+       }
+       
+       *size = lseek(fd, 0, SEEK_END);
+       ptr = mmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       
+       /* 关闭文件 */
+       close(fd);
+       
+       return ptr;     
+}
+
+static void close_w(void *ptr, size_t size)
+{
+       if (ptr) {
+               munmap(ptr, size);
+       }       
+}
+
+static void *open_r(const char *name, size_t *size)
+{
+       int fd;
+       void *ptr;
+       
+       /* 打开文件 */
+       if ((fd = open(name, O_RDONLY)) < 0) {
+               return NULL;
+       }
+       
+       *size = lseek(fd, 0, SEEK_END);
+       ptr = mmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0);
+       
+       /* 关闭文件 */
+       close(fd);
+       
+       return ptr;     
+}
+
+static void close_r(void *ptr, size_t size)
+{
+       if (ptr) {
+               munmap(ptr, size);
+       }       
+}
+       
+static s32 open_person_db(char *dbname, s32 spec)
+{
+       u32 i;
+       u32 count;
+       struct sgi_person_mem person;
+       FILE *fp;
+       
+       /* 打开数据文件 */
+       fp = fopen(dbname, "rb");
+       if (fp == NULL) {
+               return 0;
+       }
+       
+       /* 获取记录数 */
+       fseek(fp, 0, SEEK_END);
+       count = ftell(fp) / sizeof(struct sgi_person);
+       fseek(fp, 0, SEEK_SET);
+       
+       /* 限定最大用户数不能超过65536 */
+       count &= 0xffff;
+       
+       /* 读取人员数据 */
+       for (i = 0; i < count; ++i) {
+               fread(&person, 1, sizeof(struct sgi_person), fp);
+               if (spec) {
+                       person.index = (1 << 30) | i; /* super user flag */
+               }
+               else {
+                       person.index = i;
+               }
+               s_person_vec.push_back(person);
+       }
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+       
+       return count;   
+}
+
+static s32 open_gun_db(const char *dbname)
+{
+       u32 i;
+       u32 count;
+       struct sgi_gun gun;
+       FILE *fp;
+       
+       /* 打开数据文件 */
+       fp = fopen(dbname, "rb");
+       if (fp == NULL) {
+               return 0;
+       }
+       
+       /* 获取记录数 */
+       fseek(fp, 0, SEEK_END);
+       count = ftell(fp) / sizeof(struct sgi_person);
+       fseek(fp, 0, SEEK_SET);
+       
+       /* 读取人员数据 */
+       for (i = 0; i < count; ++i) {
+               fread(&gun, 1, sizeof(struct sgi_gun), fp);
+               s_gun_vec.push_back(gun);
+       }
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+       
+       return count;   
+}
+
+static s32 open_gun_box_db(const char *dbname)
+{
+       FILE *fp;
+       
+       /* 打开数据文件 */
+       fp = fopen(dbname, "rb");
+       if (fp == NULL) {
+               return 0;
+       }
+       
+       /* 读取数据 */
+       fread(&s_gun_box, 1, sizeof(struct sgi_box), fp);
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+       
+       return 1;       
+}
+
+static s32 open_unit_db(const char *dbname)
+{
+       FILE *fp;
+       
+       /* 打开数据文件 */
+       fp = fopen(dbname, "rb");
+       if (fp == NULL) {
+               return 0;
+       }
+       
+       /* 读取数据 */
+       fread(&s_unit, 1, sizeof(struct sgi_unit), fp);
+       
+       /* 关闭数据文件 */
+       fclose(fp);
+       
+       return 1;       
+}
+
+static void update_box_info(u32 *cells)
+{
+       /* box max cap 128 */
+       u32 i,j;
+       s32 index = 0;
+       
+       for (i = 0; i < 4; ++i) {
+               for (j = 0; j < 32; ++j) {
+                       if ((cells[i] & (1 << j)) == 0) {
+                               continue;
+                       }
+                       
+                       s_gun_box_info[index] |= 2;
+                       index++;
+               }
+       }                       
+}
+
+static void load_gun_box_info(void)
+{
+       u32 i;
+       u32 size;
+       
+       memset(&s_gun_box_info, 0, sizeof(s_gun_box_info));
+       
+       /* 用枪支登记信息初始枪柜 */
+       for (i = 0; i < s_gun_vec.size(); ++i) {
+               if (s_gun_vec[i].lock_code >= sizeof(s_gun_box_info)) {
+                       continue;
+               }
+               
+               s_gun_box_info[s_gun_vec[i].lock_code] = 1;     
+       }
+       
+       /* 用枪支借出信息初始枪柜 */
+       struct borrow_ctrl *pcont;
+       pcont = (struct borrow_ctrl *)open_r(DBR(borrow), &size);
+       if (pcont == NULL) {
+               return;
+       }
+       
+       for (i = 0; i < size / sizeof(struct borrow_ctrl); ++i) {
+               update_box_info(pcont->cells);  
+               pcont++;        
+       }
+       
+       /* 关闭 */
+       close_r(pcont, size);   
+}
+       
+s32 data_open(void)
+{
+       u32 count = 0;
+       
+       /* 清空人员记录数据 */
+       s_person_vec.clear();
+       
+       /* 清空枪支记录数据 */
+       s_gun_vec.clear();
+       
+       /* 清空枪柜记录 */
+       memset(&s_gun_box, 0, sizeof(struct sgi_box));
+       
+       /* 清空单位信息 */
+       memset(&s_unit, 0, sizeof(struct sgi_unit));
+       
+       /* 加载特殊权限人员数据 */
+       count += open_person_db(DBD(super), 1);
+       
+       /* 加载普通人员数据 */
+       count += open_person_db(DBD(person), 0);
+       
+       /* 加载枪支信息 */
+       open_gun_db(DBD(gun));
+       
+       /* 加载枪柜信息 */
+       open_gun_box_db(DBD(gun_box));
+       
+       /* 加载单位信息 */
+       open_unit_db(DBD(unit));
+                       
+       return count > 0 ? 0 : -1;
+}
+
+void data_close(void)
+{
+       s_person_vec.clear();
+       s_gun_vec.clear();      
+}
+
+s32 search_uid(struct sgi_passport *pass, s32 type, u32 param)
+{
+       assert(pass != NULL);
+       
+       u32 i;
+       s32 found = 0;
+       
+       if (type == SR_FPR) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].person.level == LV_USER
+                               && (s_person_vec[i].person.fpr1 == param ||
+                               s_person_vec[i].person.fpr2 == param)) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->dept, s_person_vec[i].person.dept,
+                                       COUNTOF(s_person_vec[i].person.dept));
+                               found = 1;
+                               break;          
+                       }       
+               }               
+       }
+       else if (type == SR_CARD) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].person.level == LV_USER
+                               && s_person_vec[i].person.idcard == param) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->dept, s_person_vec[i].person.dept,
+                                       COUNTOF(s_person_vec[i].person.dept));
+                               found = 1;
+                               break;          
+                       }       
+               }       
+       }
+       
+       if (!found) {
+               return FAIL;
+       }
+               
+       return 0;
+}
+
+s32 search_mid(struct sgi_passport *pass, s32 type, u32 param)
+{
+       assert(pass != NULL);
+       
+       u32 i;
+       s32 found = 0;
+       
+       if (type == SR_FPR) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].person.level == LV_MANAGER
+                               && (s_person_vec[i].person.fpr1 == param ||
+                               s_person_vec[i].person.fpr2 == param)) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->mdept, s_person_vec[i].person.dept,
+                                       COUNTOF(s_person_vec[i].person.dept));
+                               found = 1;
+                               break;          
+                       }       
+               }               
+       }
+       else if (type == SR_CARD) {
+               for (i = 0; i < s_person_vec.size(); ++i) {
+                       if (s_person_vec[i].person.level == LV_MANAGER
+                               && s_person_vec[i].person.idcard == param) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                               sgi_ncp16(pass->mdept, s_person_vec[i].person.dept,
+                                       COUNTOF(s_person_vec[i].person.dept));
+                               found = 1;
+                               break;          
+                       }       
+               }       
+       }
+       
+       if (!found) {
+               return FAIL;
+       }
+               
+       return 0;
+}
+
+s32 verify_user_pwd(struct sgi_passport *pass, u16 *uid, u16 *pwd)
+{
+       assert(uid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (s_person_vec[i].person.level != LV_USER
+                       || (sgi_ncmp16(s_person_vec[i].person.uid, uid, 
+                       COUNTOF(s_person_vec[i].person.uid)) != 0)) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].person.pwd, pwd,
+                       COUNTOF(s_person_vec[i].person.pwd)) == 0) {
+                       if (pass) {
+                               sgi_ncp16(pass->uid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->name, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                       }
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+s32 verify_manager_pwd(struct sgi_passport *pass, u16 *mid, u16 *pwd)
+{
+       assert(mid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (s_person_vec[i].person.level != LV_MANAGER
+                       || (sgi_ncmp16(s_person_vec[i].person.uid, mid, 
+                       COUNTOF(s_person_vec[i].person.uid)) != 0)) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].person.pwd, pwd,
+                       COUNTOF(s_person_vec[i].person.pwd)) == 0) {
+                       if (pass) {
+                               sgi_ncp16(pass->mid, s_person_vec[i].person.uid, 
+                                       COUNTOF(s_person_vec[i].person.uid));
+                               sgi_ncp16(pass->mname, s_person_vec[i].person.name,
+                                       COUNTOF(s_person_vec[i].person.name));
+                       }
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+static s32 verify_all_user_pwd(u16 *uid, u16 *pwd)
+{
+       assert(uid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (sgi_ncmp16(s_person_vec[i].person.uid, uid, 
+                       COUNTOF(s_person_vec[i].person.uid)) != 0) {
+                       continue;
+               }
+               
+               /* 校验密码 */
+               r = PWD_INVALID;
+               if (sgi_ncmp16(s_person_vec[i].person.pwd, pwd,
+                       COUNTOF(s_person_vec[i].person.pwd)) == 0) {
+                       r = i;  
+               }
+               
+               break;  
+       }
+       
+       return r;               
+}
+
+static s32 search_all_user(u16 *uid)
+{
+       assert(uid != NULL);
+       
+       u32 i;
+       s32 r = ID_INVALID;
+       
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (sgi_ncmp16(s_person_vec[i].person.uid, uid, 
+                       COUNTOF(s_person_vec[i].person.uid)) == 0) {
+                       r = i;
+                       break;
+               }               
+       }
+       
+       return r;               
+}
+
+static s32 sync_pwd(struct sgi_person_mem *person, u16 *new_pwd)
+{
+       s32 r = FAIL;
+       s32 index;
+       size_t size;
+       struct sgi_person *ptr = NULL;
+       
+       /* 打开数据文件 */
+       if (person->index & (1 << 30)) { /* super user */       
+               ptr = (struct sgi_person *)open_w(DBD(super), &size);                           
+       }       
+       else {
+               ptr = (struct sgi_person *)open_w(DBD(person), &size);  
+       }
+       
+       if (ptr == NULL) {
+               goto err;
+       }
+       
+       /* 修改内容 */
+       index = person->index & 0xffff;
+       if (index > size / sizeof(struct sgi_person)) {
+               goto err;
+       }       
+       sgi_ncp16(ptr[r].pwd, new_pwd, COUNTOF(ptr[r].pwd));
+       
+       /* 更新到文件 */
+       if (msync(ptr, size, MS_SYNC) != 0) {
+               goto err;       
+       }       
+       
+       r = 0;
+       
+err:
+       /* 关闭文件 */
+       close_w(ptr, size);
+       
+       return r;               
+}
+
+s32 change_pwd(u16 *uid, u16 *old_pwd, u16 *new_pwd)
+{
+       assert(uid != NULL || old_pwd != NULL || new_pwd != NULL);
+       
+       s32 r;
+       
+       /* 校验旧密码是否有效 */
+       r = verify_all_user_pwd(uid, old_pwd);
+       if (r < 0) {
+               return r;
+       }
+       
+       /* 修改为新密码 */
+       if (sync_pwd(&s_person_vec[r], new_pwd) != 0) {
+               return FAIL;
+       }
+       
+       sgi_ncp16(s_person_vec[r].person.pwd, new_pwd, 
+               COUNTOF(s_person_vec[r].person.pwd));
+       
+       return 0;
+}
+
+static s32 sgi_append_data(const char *name, void *data, size_t size)
+{
+       FILE *fp;
+       
+       /* 打开日志文件 */
+       if (access(name, R_OK | W_OK) == 0) {
+               fp = fopen(name, "ab");         
+       }
+       else {
+               fp = fopen(name, "wb"); 
+       }       
+       if (fp == NULL) {
+               return FAIL;
+       }
+       
+       /* 追加数据 */
+       if (fwrite(data, 1, size, fp) < size) {
+               fclose(fp);
+               return FAIL;
+       }
+       
+       /* 关闭文件 */
+       fclose(fp);
+       
+       return 0;       
+}
+
+s32 register_person(struct sgi_person_mem *person)
+{
+       u32 i;
+       s32 index = 0;
+       
+       if (search_all_user(person->person.uid) != ID_INVALID)  {
+               /* user exist */
+               return ID_EXIST;        
+       }
+       
+       if (sgi_append_data(DBD(person), person, 
+               sizeof(struct sgi_person)) != 0) {
+               return FAIL;
+       }
+       
+       /* 追加到列表 */
+       for (i = 0; i < s_person_vec.size(); ++i) {
+               if ((s_person_vec[i].index & (1 << 30)) == 0) { /* normal user */
+                       index++;
+               }
+       }
+       person->index = index;
+       s_person_vec.push_back(*person);
+       
+       return 0;
+}
+
+static s32 search_gun(u16 *code)
+{
+       assert(code != NULL);
+       
+       u32 i;
+       s32 r = CODE_INVALID;
+       
+       for (i = 0; i < s_gun_vec.size(); ++i) {
+               /* 匹配编号 */
+               if (sgi_ncmp16(s_gun_vec[i].code, code, 
+                       COUNTOF(s_gun_vec[i].code)) == 0) {
+                       r = i;
+                       break;
+               }               
+       }
+       
+       return r;               
+}
+
+s32 register_gun(struct sgi_gun *gun)
+{
+       if (search_gun(gun->code) != CODE_INVALID) { /* gun exist */
+               return FAIL;
+       }
+       
+       if (sgi_append_data(DBD(gun), gun, 
+               sizeof(struct sgi_gun)) != 0) {
+               return FAIL;
+       }
+       
+       /* 追加到列表 */
+       s_gun_vec.push_back(*gun);
+       
+       return 0;                       
+}
+
+s32 register_box(struct sgi_box *box)
+{
+       FILE *fp;
+       const char *name = DBD(gun_box);
+       
+       /* 打开文件 */
+       fp = fopen(name, "wb");         
+       if (fp == NULL) {
+               return FAIL;
+       }
+       
+       /* 写入数据 */
+       if (fwrite(box, 1, sizeof(struct sgi_box), fp) < sizeof(struct sgi_box)) {
+               fclose(fp);
+               return FAIL;
+       }
+       
+       /* 关闭文件 */
+       fclose(fp);
+       
+       /* */
+       memcpy(&s_gun_box, box, sizeof(struct sgi_box));        
+       
+       return 0;               
+}
+
+s32 register_unit(struct sgi_unit *unit)
+{
+       FILE *fp;
+       const char *name = DBD(unit);
+       
+       /* 打开文件 */
+       fp = fopen(name, "wb");         
+       if (fp == NULL) {
+               return FAIL;
+       }
+       
+       /* 写入数据 */
+       if (fwrite(unit, 1, sizeof(struct sgi_unit), fp) < sizeof(struct sgi_unit)) {
+               fclose(fp);
+               return FAIL;
+       }
+       
+       /* 关闭文件 */
+       fclose(fp);
+       
+       /* */
+       memcpy(&s_unit, unit, sizeof(struct sgi_unit)); 
+       
+       return 0;               
+}
+
+struct sgi_box *get_box_info(void)
+{
+       return &s_gun_box;      
+}
+
+struct sgi_unit *get_unit_info(void)
+{
+       return &s_unit; 
+}
+
+s32 enroll_borrow(struct sgi_passport *pass, u32 *cells)
+{
+       ///* 4 x sizeof(u32) x 8 = 128 bit = box-cap */
+       struct borrow_ctrl content;
+       const char *dbname = DBR(borrow);
+       
+       memset(&content, 0, sizeof(struct borrow_ctrl));
+       sgi_cp16(content.uid, pass->uid);
+       memcpy(content.borrow_time, pass->borrow_time, 
+               sizeof(content.borrow_time));
+       memcpy(content.return_time, pass->return_time, 
+               sizeof(content.return_time));
+       memcpy(content.cells, cells, sizeof(content.cells));
+       
+       if (sgi_append_log(dbname, &content, sizeof(struct borrow_ctrl)) != 0) {
+               return FAIL;    
+       }
+       
+       /* 更新枪柜实时记录 */
+       update_box_info(cells);
+       
+       return 0;
+}
+
+s32 enroll_return(struct sgi_passport *pass, u32 *cells)
+{
+       ///* 4 x sizeof(u32) x 8 = 128 bit = box-cap */
+       u32 i;
+       u32 size;
+       s32 r = FAIL;
+       struct borrow_ctrl *pcont;
+       const char *dbname = DBR(borrow);
+       
+       pcont = (struct borrow_ctrl *)open_w(dbname, &size);
+       if (pcont == NULL) {
+               goto err;
+       }
+       
+       for (i = 0; i < size / sizeof(struct borrow_ctrl); ++i) {
+               if (sgi_ncmp16(pcont->uid, pass->uid, COUNTOF(pcont->uid)) == 0) {
+                       pcont->cells[0] ^= cells[0];
+                       pcont->cells[1] ^= cells[1];
+                       pcont->cells[2] ^= cells[2];
+                       pcont->cells[3] ^= cells[3];    
+               }       
+       }
+       
+       /* 更新到文件 */
+       if (msync(pcont, size, MS_SYNC) != 0) {
+               goto err;       
+       }       
+       
+       /* 更新枪柜实时记录 */
+       update_box_info(cells);
+       
+       r = 0;
+err:
+       if (pcont) {
+               close_w(pcont, size);
+       }
+       
+       return r;
+}
diff --git a/temp/sgi_data.h b/temp/sgi_data.h
new file mode 100644 (file)
index 0000000..cffaeec
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef SGI_DATA_H
+#define SGI_DATA_H
+
+#include "sgi_types.h"
+
+struct sgi_person {
+       u16 uid[16];
+       u16 name[16];
+       u16 sex;
+       u16 age;
+       u16 dept[16];
+       u16 post[16];
+       u16 gun[16];
+       u16 gun_code[16];
+       u16 lock_code;
+       u16 level;
+       u16 fpr1;
+       u16 fpr2;
+       u32 idcard;
+       u16 pwd[16];
+       u16 phone[16];  
+};
+
+struct sgi_person_mem {
+       struct sgi_person person;
+       s32 index;
+};
+
+struct sgi_gun {
+       u16 code[16];
+       u16 model[16];
+       u16 caliber[8];
+       u16 bullet[8];
+       u16 holder[16];
+       u16 unit[16];
+       u16 stock_date[16];
+       u16 lock_code;
+       u16 status;
+};
+
+struct sgi_bullet {
+       u16 name[16];
+       u16 model[16];
+       u16 for_gun[16];
+       u16 amount;
+       u16 lock_code;
+       u16 batch[16];
+       u16 unit[16];   
+};
+
+struct sgi_box {
+       u16 type;
+       u16 cap;
+       u16 code[16];
+       u16 model[16];
+       u16 manager[16];
+       u16 unit[16];   
+};
+
+struct sgi_unit {
+       u16 name[16];
+       u16 addr[32];
+       u16 dept[16];
+       u16 parent[16]; 
+};
+
+struct sgi_passport {
+       u32 visit;
+       u16 uid[16];
+       u16 name[16];
+       u16 dept[16];
+       u16 mid[16];
+       u16 mname[16];
+       u16 mdept[16];
+       char photo[64];
+       u32 borrow_time[2];
+       u32 return_time[2];
+};
+
+struct borrow_ctrl {
+       u16 uid[16];
+       u32 borrow_time[2];
+       u32 return_time[2];
+       u32 cells[4];   
+};
+
+#endif
diff --git a/templet/fm_xxx.cpp b/templet/fm_xxx.cpp
new file mode 100644 (file)
index 0000000..ab92f88
--- /dev/null
@@ -0,0 +1,122 @@
+#include <time.h>
+#include "global_func.h"
+
+#define MODULE_NAME    fm_xxx
+
+FORM_MODULE(MODULE_NAME);                      /*  */          
+
+static union sgi_object s_wnd_main;            /* 主窗口 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static void form_enter(struct sgi_form *)
+{
+       s_timer = 60;   
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = gmtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       sgi_form_show(&FORM_CLASS(fm_main));                    
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       do {
+
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(MODULE_NAME)
+{
+       wchar_t buf[64];
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&FORM_CLASS(MODULE_NAME));
+       FORM_CLASS(MODULE_NAME).name = FORM_NAME(MODULE_NAME);
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, FORM_CLASS(MODULE_NAME), 0, 0, 800, 480, 0,
+                "wnd11.png", IMG_OPTIMIZE, NULL);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, FORM_CLASS(MODULE_NAME), 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, g_sgi_form_get_003, 600, 50, 200, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, g_sgi_form_get_003, 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btnf120.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, g_sgi_form_get_003, 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btnf124.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(FORM_CLASS(MODULE_NAME), s_wnd_main);       
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(MODULE_NAME)
+{
+       FORM_CLASS(MODULE_NAME).deinit(&FORM_CLASS(MODULE_NAME));       
+}
diff --git a/templet/grid-temp.c b/templet/grid-temp.c
new file mode 100644 (file)
index 0000000..ebd2238
--- /dev/null
@@ -0,0 +1,108 @@
+struct cols_info {
+       u16 type;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+};
+
+struct grid_cell {
+       u16 state;
+       s16 val;
+       u16 string[64];
+};
+
+struct grid_cell {
+       u16 type;
+       s16 x;
+       s16 y;
+       s16 w;
+       s16 h;
+       u16 state;
+       s32 val;
+       u16 string[32];
+};
+
++(object)->active_image;
++(object)->pos;
++(object)->readonly;
+#define GRID_STRING
+#define GRID_BUTTON
+#define GRID_RADIO
+
+
+struct grid_cell *cells;
+
+object->cells = (struct grid_cell *)calloc(sizeof(struct grid_cell), 
+       object->col * object->row);
+
+free(cells);
+
+void init_grid(struct draw_grid *object)
+{
+       u32 i,j;
+       s32 y0;
+       
+       for (i = 0; i < object->row; ++i) {
+               y0 = object->y + i * RH + Y0;
+               for (j = 0; j < object->col; ++j) {
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[i * object->col + j].type = T;
+                               object->x = object->x + X0;
+                               object->y = y0;
+                               object->w = CW0;
+                               object->h = RH;
+                               break;
+                               
+                       case 1: /* column 1 */
+                               object->cells[i * object->col + j].type = T;
+                               object->x = object->x + X1;
+                               object->y = y0;
+                               object->w = CW1;
+                               object->h = RH;
+                               break;
+                               
+                       case 2: /* column 2 */
+                               break;
+                               
+                       default:
+                               break;                          
+                       }       
+               }               
+       }               
+}
+
+void grid_load_data(struct draw_grid *object)
+{
+       u32 i,j;
+       struct data *p = s_data;
+       s32 record_nums = s_data_nums;
+       
+       for (i = 0; i < object->row; ++i) {
+               for (j = 0; j < object->col; ++j) {
+                       switch (j) {
+                       case 0: /* column 0 */
+                               object->cells[i * object->col + j].string = p->data;
+                               break;
+                               
+                       case 1:
+                               break;
+                               
+                       case 2:
+                               break;
+                               
+                       default:
+                               break;  
+                               
+                       }
+               }
+               
+               if (record_nums-- <= 0) {
+                       break;
+               }
+               p++;
+                       
+       }
+}
+
diff --git a/templet/sgi_form_xxx.cpp b/templet/sgi_form_xxx.cpp
new file mode 100644 (file)
index 0000000..7903a7e
--- /dev/null
@@ -0,0 +1,121 @@
+#include <time.h>
+#include "global_func.h"
+
+struct sgi_form g_sgi_form_xxx;                        /*  */
+
+static union sgi_object s_wnd_main;            /* 主窗体 */
+static union sgi_object s_lbl_date;            /* 日期标签 */
+static union sgi_object s_lbl_time;            /* 倒计时标签 */
+static union sgi_object s_btn_back;            /* 返回按钮 */
+static union sgi_object s_btn_main;            /* 首页按钮 */
+
+static s32 s_timer = 0;
+
+static void form_enter(struct sgi_form *)
+{
+       s_timer = 60;   
+}
+
+static s32 lbl_date_frame(struct sgi_label *label)
+{
+       static u32 next;
+       time_t now;
+       struct tm *tmlocal;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               time(&now);
+               tmlocal = gmtime(&now);
+               swprintf(buf, sizeof(buf), L"%d-%02d-%02d %02d:%02d", 
+                       tmlocal->tm_year + 1900, tmlocal->tm_mon + 1, 
+                       tmlocal->tm_mday, tmlocal->tm_hour, tmlocal->tm_min);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static s32 lbl_time_frame(struct sgi_label *label)
+{
+       static u32 next;
+       wchar_t buf[64];
+       
+       if (SDL_GetTicks() > next) {
+               s_timer--;
+               if (s_timer <= 0) {
+                       s_btn_main.button.up(&s_btn_main.button);
+               }
+               swprintf(buf, sizeof(buf), L"倒计时: %02d", s_timer);
+               set_object_text_w(label, buf);
+               label->redraw = 1;
+               
+               next = SDL_GetTicks() + 1000;   
+       }
+       
+       return 0;       
+}
+
+static void btn_main_up(struct sgi_button *)
+{
+       //sgi_form_show(&g_sgi_form_get_001);   
+}
+
+static s32 form_frame(struct sgi_form *form)
+{
+       do {
+
+       } while (0);
+       
+       sgi_form_frame_default(form);
+       
+       return 0;       
+}
+
+FORM_CREATE_FN(sgi_form_get_003)
+{
+       SDL_Color color = {255,255,255,0};
+       
+       /* 初始页面容器,加入页面元素 */
+       form_memset(&g_sgi_form_xxx);
+       g_sgi_form_xxx.name = "sgi_form_xxx";
+       
+       /* 窗口背景 */
+       WINDOW_CREATE(s_wnd_main, g_sgi_form_get_003, 0, 0, 800, 480, 0,
+                "wnd13.png", IMG_OPTIMIZE);
+               
+       /* 日期时间 */
+       LABEL_CREATE(s_lbl_date, g_sgi_form_xxx, 600, 20, 200, 25, 1,
+                "jht.ttf", 22, color);
+       s_lbl_date.label.frame = lbl_date_frame;
+       
+       /* 倒计时 */
+       LABEL_CREATE(s_lbl_time, g_sgi_form_get_003, 600, 50, 200, 40, 1,
+                "jht.ttf", 20, color);
+       s_lbl_time.label.frame = lbl_time_frame;
+       
+       /* 返回按钮 */
+       BUTTON_CREATE(s_btn_back, g_sgi_form_get_003, 34, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btnf120.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+               
+       /* 首页按钮 */
+       BUTTON_CREATE(s_btn_main, g_sgi_form_get_003, 686, 348, 80, 81, 1,
+               "btn-c-u.png", "btn-c-d.png", "btn-c-d.png", "btnf124.png",
+               IMG_OPTIMIZE | IMG_ALPHA);
+       s_btn_main.button.up = btn_main_up;
+       
+       /* 创建页面 */
+       FORM_CREATE(g_sgi_form_xxx, s_wnd_main);        
+       g_sgi_form_xxx.enter = form_enter;
+       g_sgi_form_xxx.frame = form_frame;              
+       
+       return 0;
+}
+
+FORM_DESTROY_FN(sgi_form_xxx)
+{
+       g_sgi_form_xxx.deinit(&g_sgi_form_xxx); 
+}