/* --------------------------------------- 扩展接口 --------------------------------------- */ static void_t* iPAK_IPAC_getMore ( __CR_IN__ iPACKAGE* that, __CR_IN__ port_t iid ) { /* 判断一下名称 */ if (str_cmpA(iid, "iPACKAGE::TGL_IPAC") != 0) return (NULL); return ((void_t*)that); }
/* --------------------------------------- 获取扩展的绘制接口 --------------------------------------- */ static void_t* iGFX2_FB_getMore ( __CR_IN__ iGFX2* that, __CR_IN__ port_t iid ) { /* 判断一下名称 */ if (str_cmpA(iid, "iGFX2::FB") != 0) return (NULL); return ((void_t*)that); }
/* --------------------------------------- 扩展接口 --------------------------------------- */ static void_t* iXMM_FMOD_getMore ( __CR_IN__ iXMMEDIA* that, __CR_IN__ port_t iid ) { /* 判断一下名称 */ if (str_cmpA(iid, "iXMMEDIA::FMOD") != 0) return (NULL); return ((void_t*)that); }
/* --------------------------------------- 扩展接口 --------------------------------------- */ static void_t* iPIC_AIA_getMore ( __CR_IN__ iPICTURE* that, __CR_IN__ port_t iid ) { /* 判断一下名称 */ if (str_cmpA(iid, "iPICTURE::YS_AIA") != 0) return (NULL); return ((void_t*)that); }
/* --------------------------------------- 绘制文字 (实体/透明) --------------------------------------- */ static bool_t qst_crh_text ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { sRECT rect; bool_t rett; bool_t tran; ansi_t* temp; ansi_t* text; sIMAGE* draw; uint_t ww,hh; uint_t align; /* 参数解析 <X> <Y> <EscText> [Width Height Align] */ if (argc < 4) return (FALSE); if (s_font == NULL) return (FALSE); draw = ((sQstView2D*)parm)->paint; if (draw == NULL) return (FALSE); /* 必须使用转义字符串 */ temp = str_fmtA("\"%s\"", argv[3]); if (temp == NULL) return (FALSE); text = str_esc_dupU(temp); mem_free(temp); if (text == NULL) return (FALSE); /* 区分实体和透明, 两个命令合并起来了 */ if (str_cmpA(argv[0], "crh:texts") == 0) tran = FALSE; else tran = TRUE; rect.x1 = (sint_t)str2intxA(argv[1]); rect.y1 = (sint_t)str2intxA(argv[2]); if (argc > 6) { ww = str2intxA(argv[4]); hh = str2intxA(argv[5]); align = str2intxA(argv[6]); rect_set_wh(&rect, rect.x1, rect.y1, ww, hh); } else { align = 0; } rett = qst_crh_text_int(draw, tran, &rect, text, align); mem_free(text); return (rett); }
/* --------------------------------------- 设置通讯接收模式 --------------------------------------- */ static bool_t qst_com_rtype ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { static ansi_t* name = NULL; /* 参数解析 <接收模式/插件名称> [函数名称] */ if (argc < 2) return (FALSE); sQstComm* ctx = (sQstComm*)parm; CTextOper* opr = (CTextOper*)ctx->oper; _ENTER_COM_SINGLE_ if (str_cmpA(argv[1], "text") == 0) { ctx->comm.text = TRUE; ctx->comm.render = qst_txt_show; ctx->comm.rtype = "text"; } else if (str_cmpA(argv[1], "html") == 0) { ctx->comm.text = TRUE; ctx->comm.render = qst_htm_show; ctx->comm.rtype = "html"; } else if (str_cmpA(argv[1], "hex") == 0) { ctx->comm.text = FALSE; ctx->comm.render = qst_hex_show; ctx->comm.rtype = "hex"; } else if (str_cmpA(argv[1], "ansi") == 0) { qst_csi_clear(); ctx->comm.text = TRUE; ctx->comm.render = qst_csi_show; ctx->comm.rtype = "ansi"; } else { sbin_t sbin; plugin_render_t func; /* 使用外部插件 */ if (argc < 3) goto _failure; sbin = sbin_loadA(argv[1]); if (sbin == NULL) goto _failure; func = sbin_exportT(sbin, argv[2], plugin_render_t); if (func == NULL) { sbin_unload(sbin); goto _failure; } ctx->comm.text = FALSE; ctx->comm.render = func; TRY_FREE(name); name = str_fmtA("%s|%s", argv[1], argv[2]); ctx->comm.rtype = (name == NULL) ? "null" : name; } opr->clear(); _LEAVE_COM_SINGLE_ qst_update_title(ctx); return (TRUE); _failure: _LEAVE_COM_SINGLE_ return (FALSE); }
/* --------------------------------------- 设置通讯发送模式 --------------------------------------- */ static bool_t qst_com_stype ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { static ansi_t* name = NULL; /* 参数解析 <发送模式/插件名称> [函数名称] */ if (argc < 2) return (FALSE); sQstComm* ctx = (sQstComm*)parm; if (str_cmpA(argv[1], "text") == 0) { ctx->comm.tran = NULL; ctx->comm.stype = "text"; } else if (str_cmpA(argv[1], "hex") == 0) { ctx->comm.tran = qst_hex_tran; ctx->comm.stype = "hex"; } else if (str_cmpA(argv[1], "esc") == 0) { ctx->comm.tran = qst_esc_tran; ctx->comm.stype = "esc"; } else if (str_cmpA(argv[1], "dos") == 0) { ctx->comm.tran = qst_dos_tran; ctx->comm.stype = "dos"; } else if (str_cmpA(argv[1], "unix") == 0) { ctx->comm.tran = qst_unx_tran; ctx->comm.stype = "unix"; } else if (str_cmpA(argv[1], "mac") == 0) { ctx->comm.tran = qst_mac_tran; ctx->comm.stype = "mac"; } else { sbin_t sbin; plugin_tran_t func; /* 使用外部插件 */ if (argc < 3) return (FALSE); sbin = sbin_loadA(argv[1]); if (sbin == NULL) return (FALSE); func = sbin_exportT(sbin, argv[2], plugin_tran_t); if (func == NULL) { sbin_unload(sbin); return (FALSE); } ctx->comm.tran = func; TRY_FREE(name); name = str_fmtA("%s|%s", argv[1], argv[2]); ctx->comm.stype = (name == NULL) ? "null" : name; } qst_update_title(ctx); return (TRUE); }
/* --------------------------------------- 打开 RS232 通讯接口 --------------------------------------- */ static bool_t qst_com_rs232 ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { int32u baud; uint_t port, bits; uint_t stop, parity; /* --------------- */ const ansi_t* sstop; const ansi_t* sparity; /* 参数解析 <串口号> [波特率] [数据位] [校验位] [停止位] */ if (argc < 2) return (FALSE); bits = 8; baud = 115200UL; stop = CR_SIO_STOP10; parity = CR_SIO_NOP; sstop = "1"; sparity = "no"; port = str2intxA(argv[1]); if (argc > 2) { baud = str2intx32A(argv[2]); if (argc > 3) { bits = str2intxA(argv[3]); if (argc > 4) { sparity = argv[4]; if (str_cmpA(argv[4], "no") == 0) parity = CR_SIO_NOP; else if (str_cmpA(argv[4], "odd") == 0) parity = CR_SIO_ODD; else if (str_cmpA(argv[4], "even") == 0) parity = CR_SIO_EVEN; else if (str_cmpA(argv[4], "mark") == 0) parity = CR_SIO_MARK; else if (str_cmpA(argv[4], "space") == 0) parity = CR_SIO_SPCE; else sparity = "no"; if (argc > 5) { sstop = argv[5]; if (str_cmpA(argv[5], "1") == 0) stop = CR_SIO_STOP10; else if (str_cmpA(argv[5], "1.5") == 0) stop = CR_SIO_STOP15; else if (str_cmpA(argv[5], "2") == 0) stop = CR_SIO_STOP20; else sstop = "1"; } } } } sQstComm* ctx = (sQstComm*)parm; /* 关闭当前接口并打开串口 */ if (!sio_open(port)) return (FALSE); sio_setup(port, baud, bits, parity, stop); sio_set_buffer(port, 1024, 1024); sio_set_rd_timeout(port, 0, 0, QCOM_CUTDOWN); sio_set_wr_timeout(port, 0, QCOM_SNDTOUT); sio_clear_error(port); sio_flush(port, CR_SIO_FLU_RT); /* 设置工作参数 */ qst_com_close(parm, argc, argv); ctx->comm.obj.port = port; ctx->comm.send = qst_rs232_send; /* 启动接收线程 */ ctx->comm.thrd = thread_new(0, qst_rs232_main, parm, FALSE); if (ctx->comm.thrd == NULL) { sio_close(port); return (FALSE); } TRY_FREE(ctx->comm.title); ctx->comm.title = str_fmtA(" - COM%u, %u, %u, %s, %s", port, baud, bits, sparity, sstop); qst_update_title(ctx); return (TRUE); }
/* --------------------------------------- 工作线程 --------------------------------------- */ static uint_t STDCALL qst_srv_main ( __CR_IN__ void_t* param ) { uint_t self, count; sQstWork* ctx = (sQstWork*)param; sQstWork* tot = (sQstWork*)ctx->self; /* 工作循环 */ self = ctx->id; count = ctx->cnt; for (;;) { ansi_t* shell; ansi_t* string; /* 接收一条命令 */ /* 一有错误表示非法客户端, 直接踢 */ string = netw_cmd_recv_ex(ctx->netw); if (string == NULL) break; _ENTER_SHOW_SAY_ printf("[%s] say: %s\n", ctx->name, string); _LEAVE_SHOW_SAY_ /* 广播这条消息 */ mtlock_acquire(&s_qst_lck_wrk); for (uint_t idx = 0; idx < count; idx++) { /* 跳过自己和空闲的单元 */ if (idx == self || tot[idx].over) continue; netw_cmd_send(tot[idx].netw, string); } mtlock_release(&s_qst_lck_wrk); /* 处理一些公共指令 */ shell = cmd_shl_get(string); mem_free(string); if (shell == NULL) continue; if (str_cmpA(shell, "app:exit") == 0 || str_cmpA(shell, "qsrv:app:exit") == 0) { thread_sleep(1000); exit(0); } if (str_cmpA(shell, "win:load") == 0) qst_srv_win_load(); else if (str_cmpA(shell, "win:save") == 0) qst_srv_win_save(); else if (str_cmpA(shell, "win:show") == 0 || str_cmpA(shell, "qsrv:win:show") == 0) qst_srv_win_show(); mem_free(shell); } /* 显示已经断线 */ _ENTER_SHOW_OUT_ printf("[%s] is offline.\n", ctx->name); _LEAVE_SHOW_OUT_ /* 释放资源 */ mem_free(ctx->name); ctx->name = NULL; mtlock_acquire(&s_qst_lck_wrk); netw_cli_close(ctx->netw); ctx->netw = NULL; ctx->over = TRUE; mtlock_release(&s_qst_lck_wrk); return (QST_OKAY); }
/* --------------------------------------- 绘制文字 (使用外部定义) --------------------------------------- */ static bool_t qst_crh_text_ex ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { sRECT* rect; bool_t free; bool_t rett; bool_t tran; uint_t algn; ansi_t* temp; ansi_t* text; sIMAGE* draw; /* 参数解析 <EscText/TextName> <RectName> <Align> [IsTextName] */ if (argc < 4) return (FALSE); if (s_font == NULL) return (FALSE); if (s_resx == NULL) return (FALSE); draw = ((sQstView2D*)parm)->paint; if (draw == NULL) return (FALSE); /* 查找目标矩形对象 */ rect = egui_res_get_rct(s_resx, argv[2]); if (rect == NULL) return (FALSE); /* 找不到或不使用文本名称的时候使用转义字符串 */ if (argc > 4) text = egui_res_get_txt(s_resx, argv[1]); else text = NULL; if (text == NULL) { temp = str_fmtA("\"%s\"", argv[1]); if (temp == NULL) return (FALSE); text = str_esc_dupU(temp); mem_free(temp); if (text == NULL) return (FALSE); free = TRUE; } else { free = FALSE; } /* 区分实体和透明, 两个命令合并起来了 */ if (str_cmpA(argv[0], "crh:texts_ex") == 0) tran = FALSE; else tran = TRUE; algn = str2intxA(argv[3]); rett = qst_crh_text_int(draw, tran, rect, text, algn); if (free) mem_free(text); return (rett); }
/* --------------------------------------- 文件处理回调 --------------------------------------- */ static bool_t hasher (void_t *param, sSEARCHa *info) { sHASH hash; /* 过滤掉两个生成的文件 */ if (str_cmpA(info->name, "__hash__.old") == 0 || str_cmpA(info->name, "__hash__.txt") == 0) return (TRUE); /* 显示文件名和大小字节数 */ printf("%s (%" CR_FSZ "u Bytes) ", info->name, info->size); /* 根据内存大小选择读取方式 */ timer_set_base(s_profile); if (info->size == 0) { /* 空文件 */ hash_init(&hash); hash_update(&hash, NULL, 0); hash_finish(param, info->size, info->name, &hash); } else if (info->size <= s_total) { sVFILE file; void_t *data; /* 内存映射 */ data = file_mappingA(info->name, &file); if (data == NULL) goto _read_it; hash_init(&hash); hash_update(&hash, data, (leng_t)info->size); hash_finish(param, info->size, info->name, &hash); file_release(&file); } else { fraw_t file; leng_t rest; fsize_t blks; _read_it: /* 分块读取 */ file = file_raw_openA(info->name, CR_FO_RO | CR_FO_SEQ); if (file == NULL) goto _failure; /* 文件很大, 只能分块读取 */ if (s_rdata == NULL) s_rdata = mem_malloc(FREAD_BLOCK); rest = ( leng_t)(info->size % FREAD_BLOCK); blks = (fsize_t)(info->size / FREAD_BLOCK); for (hash_init(&hash); blks != 0; blks--) { if (file_raw_read(s_rdata, FREAD_BLOCK, file) != FREAD_BLOCK) { file_raw_close(file); goto _failure; } hash_update(&hash, s_rdata, FREAD_BLOCK); } if (rest != 0) { if (file_raw_read(s_rdata, rest, file) != rest) { file_raw_close(file); goto _failure; } hash_update(&hash, s_rdata, rest); } hash_finish(param, info->size, info->name, &hash); file_raw_close(file); } fp32_t time; time = timer_get_delta(s_profile); time *= 1.024f; printf(" %.2f KB/S\n", info->size / time); return (TRUE); _failure: printf(" [FAILED]\n"); return (TRUE); }