void viewTOTPcode(totp* tkn) { unsigned short key = 0; int keyCol, keyRow; Bdisp_AllClr_VRAM(); drawScreenTitle(tkn->name); int shown_since_beginning = 0; while(key != KEY_PRGM_EXIT && key != KEY_PRGM_LEFT) { int ThirtySecCode = computeTOTP(tkn); char buffer[10]; itoa_zeropad(tkn->totpcode, buffer, 6); long long int ms_spent_ll = currentUTCUEBT() - (long long int)ThirtySecCode * 30LL * 1000LL; int ms_spent = (int)(ms_spent_ll); drawCircularCountdownIndicator(LCD_WIDTH_PX/2, 104, 44, COLOR_BLACK, COLOR_WHITE, (ms_spent*43)/30000, getCurrentSecond() < 30 ? 0 : 1); // fade in/out animation for text int val = 0; if(ms_spent >= 29000) { val += (-29000 + ms_spent)/4; } else if (ms_spent <= 1020) { val += (1020 - ms_spent)/4; } int color = drawRGB24toRGB565(val, val, val); printCentered(buffer, 164, color, COLOR_WHITE); if(ms_spent < 2500) shown_since_beginning = 1; else if(ms_spent < 15000 && shown_since_beginning) DefineStatusMessage((char*)totpHelpMessages[(ms_spent-2500)/2500], 1, 0, 0); else DefineStatusMessage((char*)"", 1, 0, 0); DisplayStatusArea(); Bdisp_PutDisp_DD(); key = PRGM_GetKey(); if(key == KEY_PRGM_MENU) GetKeyWait_OS(&keyCol, &keyRow, 2, 0, 0, &key); //this is here to handle the Menu key if(key == KEY_PRGM_OPTN) { DefineStatusMessage((char*)"", 1, 0, 0); GetKeyWait_OS(&keyCol, &keyRow, 2, 0, 0, &key); // clear keybuffer RTCunadjustedWizard(0, 1); setTimezone(); return; // so we don't have to redraw etc. // Also, this way the Shift+Menu instruction shown in the adjustment wizard becomes vali // immediately, which is great if the user wants to repeat the adjustment. } } DefineStatusMessage((char*)"", 1, 0, 0); // clear keybuffer: GetKeyWait_OS(&keyCol, &keyRow, 2, 0, 0, &key); }
void browse_main() { /* 文件浏览器主函数 */ char ncat[64], workdir[64] = "\\\\fls0"; // 当前目录 f_name *a=get_file_list("\\\\fls0\\*.*"); // 存储文件列表的二维数组 int pos=0,firstn=0; // 列表光标位置、列表下移的行数 unsigned int key; char subdir_fn[32]; // 供接收子目录文件名输入的缓冲区 FONTCHARACTER fname[64]; int handle = 0; DefineStatusAreaFlags(3, 0x01 | 0x02 | 0x100, 0, 0); beg: if (a) qsort(a, getn(a), sizeof(char *), cmp); font16 = open_font("\\\\fls0\\24PX.hzk"); select_font(font16); draw_browser(workdir,firstn,pos,a); // 绘制浏览器界面 close_font(font16); // 显示当前工作目录于状态栏 if (strcmp(workdir, "\\\\fls0") == 0) DefineStatusMessage("", 0, 0, 0); else { memset(ncat, 0, sizeof(ncat)); GetDisplayDirName(workdir, ncat); DefineStatusMessage(ncat, 0, 0, 0); } while (1) { GetKey(&key); switch (key) { case KEY_CTRL_UP: // 光标上移 if (a) { aa(&pos,&firstn,getn(a)); goto beg; } break; case KEY_CTRL_DOWN: // 光标下移 if (a) { bb(&pos,&firstn,getn(a)); goto beg; } break; case KEY_CTRL_F6: // 显示关于信息 Disp_About(); goto beg; break; case KEY_CTRL_F1: // 打开光标位置的文件 case KEY_CTRL_EXE: if (a) // 如果文件列表不为空 { if (strchr(a[pos+firstn].name,'[')) // 如果打开的是文件夹 { memset(ncat,0,sizeof(ncat)); //strcat(ncat,"\\\\fls0\\"); strcat(ncat, workdir); strcat(ncat, "\\"); strcat(ncat, ++a[pos+firstn].name); memset(workdir, 0, sizeof(workdir)); strcpy(workdir, ncat); strcat(ncat, "\\*.*"); // 解析出文件夹名称 a=get_file_list(ncat); // 浏览该文件夹 pos=0; firstn=0; // 列表初始化 goto beg; } else // 如果打开的是文本文件 { memset(ncat,0,sizeof(ncat)); strcpy(ncat,workdir); strcat(ncat,"\\"); strcat(ncat,a[pos+firstn].name); // 解析出文件名称 iRead_main(ncat); // 启动阅读器 goto beg; } } break; case KEY_CTRL_F2: // 根据输入的文件名打开文件 memset(subdir_fn, 0, sizeof(subdir_fn)); if (Subdir_Open(subdir_fn)) { memset(ncat, 0, sizeof(ncat)); strcpy(ncat, workdir); strcat(ncat, "\\"); strcat(ncat, subdir_fn); // 连接上输入的文件名字 strcat(ncat, ".txt"); char_to_font(ncat, fname); handle = Bfile_OpenFile_OS(fname,0); if (handle <= 0) // 如果文件未找到 { Disp_FileNotFound(); MsgBoxPop(); goto beg; break; } MsgBoxPop(); Bfile_CloseFile_OS(handle); // 重新绘制浏览器界面 font16 = open_font("\\\\fls0\\24PX.hzk"); select_font(font16); draw_browser(workdir, firstn, pos, a); close_font(font16); // 启动阅读器 iRead_main(ncat); } goto beg; break; case KEY_CTRL_EXIT: // 从文件夹返回根目录 if (strcmp(workdir,"\\\\fls0")!=0) // 如果当前在文件夹内 { memset(ncat,0,sizeof(ncat)); strncpy(ncat,workdir,strlen(workdir)-strlen(strrchr(workdir,'\\'))); memset(workdir,0,sizeof(workdir)); strcpy(workdir,ncat); strcat(ncat,"\\*.*"); // 解析出上一级目录的名称 a=get_file_list(ncat); // 浏览该文件夹 pos=0;firstn=0; // 初始化列表 goto beg; } break; } } }
void iRead_main(const char* filename) { /* 阅读界面主函数 参数说明: filename: 打开的文件名 (从文件浏览器得到) */ int key,handle; char* buf=(char*)malloc(461); FONTCHARACTER fname[64]; char tip[64], tmp[64]; page=0;cached=0; memset(bytes,0,sizeof(bytes)); memset(bookmark,0,sizeof(bookmark));bookmark[3]=0; Read_Config(filename,&cached); // 读取书签及分页配置 // 如果分的页数不满 500 的整数倍,补分页满 if (cached==0) divide_page(filename,500-cached,1); else if (cached%500!=0) divide_page(filename,500-cached%500,1); // 补至 500 的整数倍 totbytes=0; /* 设置状态栏显示文字 0x0001:显示电量 0x0100:显示文字 */ DefineStatusAreaFlags(3, 0x01 | 0x02 | 0x100, 0, 0); beg: font16=open_font("\\\\fls0\\24PX.hzk"); select_font(font16); Bdisp_AllClr_VRAM(); draw_pic(0,192,124,22,0,Menu_Read); draw_pic(126,192,61,22,0,Menu_Sub_Jump); // 若翻下一页时超出已缓存页面范围 if (cached<=page) { // 如果分的页数不满 500 的整数倍,补分页满 if (!divide_page(filename,1,0)) page=cached-1; else if (cached%500!=0) divide_page(filename,500-cached%500,0); close_font(font16); goto beg; } totbytes=bytes[page]; // 修正读取字节指针位置 char_to_font(filename,fname); handle=Bfile_OpenFile_OS(fname,0); // 打开文件 Bfile_ReadFile_OS(handle,buf,400,totbytes); Bfile_CloseFile_OS(handle); print_chs_page(0,24,totbytes,(unsigned char*)buf); // 绘制一页 close_font(font16); // 准备显示浏览进度 char fn_ptr[64]; memset(fn_ptr, 0, sizeof(fn_ptr)); GetDisplayFileName(filename, fn_ptr); memset(tip, 0, sizeof(tip)); memset(tmp, 0, sizeof(tmp)); strcat(tip, fn_ptr); strcat(tip, " "); itoa(page + 1, tmp, 10); strcat(tip, tmp); strcat(tip, "/"); memset(tmp, 0, sizeof(tmp)); itoa(cached, tmp, 10);strcat(tip, tmp); // 状态栏显示文件名及进度 DefineStatusMessage(tip, 0, 0, 0); while (1) { GetKey(&key); switch (key) { case KEY_CTRL_UP: // 跳到上一页 if (page>0) { --page; goto beg; } break; case KEY_CTRL_DOWN: // 跳到下一页 ++page; goto beg; break; case KEY_CTRL_EXIT: // 离开,返回文件浏览器 Save_Config(filename,cached+1); DefineStatusAreaFlags(3, 0x01 | 0x02 | 0x100, 0, 0); return;break; case KEY_CTRL_F2: // 打开存储书签对话框 Save_Bookmark(filename,page,cached+1); goto beg;break; case KEY_CTRL_F1: // 打开读取书签对话框 Read_Bookmark(filename,&page,&cached); goto beg;break; case KEY_CTRL_F3: // 打开跳页对话框 Page_Jump(filename); goto beg;break; } } }
void input_eval_loop(int isRecording) { char** recHistory = NULL; int curRecHistEntry = 0; if(isRecording) recHistory = (char**)alloca(200); // space for 200 pointers to history entries while (1) { DefineStatusMessage((char*)"", 1, 0, 0); strcpy(expr, (char*)""); printf("\x1e"); dConsoleRedraw(); int res = gets(expr,INPUTBUFLEN); if(res == 2) { dConsolePut("\n"); select_script_and_run(); continue; } if(res == 4) { dConsolePut("\n"); select_strip_script(); continue; } if(res == 3) { dConsolePut("\n"); char buf[100] = ""; sprintf(buf, "prizmUIkeyHandler(%d,%d)", custom_key_to_handle, custom_key_to_handle_modifier); strcpy(expr, (char*)buf); execution_in_progress = 1; run(buf); execution_in_progress = 0; check_do_graph(); if(run_startup_script_again) { run_startup_script_again = 0; run_startup_script(); } continue; } puts(expr); update_cmd_history(expr); dConsoleRedraw(); if(strcmp(expr, "testmode") == 0) { TestMode(1); } else if(strcmp(expr, "meminfo") == 0) { print_mem_info(); } else if(strcmp(expr, "memgc") == 0) { gc(); } else if(strcmp(expr, "record") == 0) { if(!isRecording) script_recorder(); else { // create and save a script. this must be done here, because we used alloca // the "clean" way would be using malloc&free, but on the Prizm the heap is already being heavily used by the Eigenmath core. if(curRecHistEntry == 0) { printf("Nothing to record.\n"); return; } printf("Recording stopped.\n"); printf("Type a name for the script, or\n"); printf("leave empty to discard.\n:"); char inputname[MAX_FILENAME_SIZE+1] = ""; gets(inputname,MAX_FILENAME_SIZE-50); puts(inputname); if(!strlen(inputname)) { // user aborted printf("Recording discarded.\n"); return; } if (aborttimer > 0) { Timer_Stop(aborttimer); Timer_Deinstall(aborttimer); } char filename[MAX_FILENAME_SIZE+1] = ""; sprintf(filename, "\\\\fls0\\%s.txt", inputname); unsigned short pFile[MAX_FILENAME_SIZE+1]; Bfile_StrToName_ncpy(pFile, (unsigned char*)filename, strlen(filename)+1); // calculate size int size = 0; int maxHistory = curRecHistEntry - 1; //because we ++'ed at the end of last addition for(int i=0; i <= maxHistory; i++) { size = size + strlen(recHistory[i]) + 1; // 1 byte for \n. we will use unix line termination } int BCEres = Bfile_CreateEntry_OS(pFile, CREATEMODE_FILE, &size); if(BCEres >= 0) // Did it create? { BCEres = Bfile_OpenFile_OS(pFile, READWRITE, 0); // Get handle for(int i=0; i <= maxHistory; i++) { char* buf = (char*)alloca(strlen(recHistory[i])+5); strcpy(buf, recHistory[i]); strcat(buf, (char*)"\n"); Bfile_WriteFile_OS(BCEres, buf, strlen(recHistory[i])+1); } Bfile_CloseFile_OS(BCEres); printf("Script created.\n"); } else { printf("An error occurred when creating the script for recording.\n"); } aborttimer = Timer_Install(0, check_execution_abort, 100); if (aborttimer > 0) Timer_Start(aborttimer); return; } } else { execution_in_progress = 1; has_drawn_graph = 0; run(expr); // run_startup_script cannot run from inside eval_clear because then it would be a run() inside a run() if(run_startup_script_again) { run_startup_script_again = 0; run_startup_script(); } execution_in_progress = 0; // if recording, add input to record if(isRecording && curRecHistEntry <= 200) { recHistory[curRecHistEntry] = (char*)alloca(strlen(expr)+2); // 2 bytes for security strcpy(recHistory[curRecHistEntry], expr); curRecHistEntry++; } check_do_graph(); } } }
int doMenu(Menu* menu, MenuItemIcon* icontable) { // returns code telling what user did. selection is on menu->selection. menu->selection starts at 1! int itemsStartY=menu->startY; // char Y where to start drawing the menu items. Having a title increases this by one int itemsHeight=menu->height; int showtitle = menu->title != NULL; if (showtitle) { itemsStartY++; itemsHeight--; } if(menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); if(menu->selection-1 < menu->scroll) menu->scroll = menu->selection -1; while(1) { if(menu->statusText != NULL) DefineStatusMessage(menu->statusText, 1, 0, 0); // Clear the area of the screen we are going to draw on if(0 == menu->pBaRtR) drawRectangle(18*(menu->startX-1), 24*(menu->miniMiniTitle ? itemsStartY:menu->startY), 18*menu->width+(menu->scrollbar && menu->scrollout?6:0), 24*menu->height-(menu->miniMiniTitle ? 24:0), COLOR_WHITE); if (menu->numitems>0) { for(int curitem=0; curitem < menu->numitems; curitem++) { // print the menu item only when appropriate if(menu->scroll < curitem+1 && menu->scroll > curitem-itemsHeight) { char menuitem[70] = ""; if(menu->type == MENUTYPE_MULTISELECT) strcpy(menuitem, " "); //allow for the folder and selection icons on MULTISELECT menus (e.g. file browser) strncat(menuitem, menu->items[curitem].text, 68); if(menu->items[curitem].type != MENUITEM_SEPARATOR) { //make sure we have a string big enough to have background when item is selected: // MB_ElementCount is used instead of strlen because multibyte chars count as two with strlen, while graphically they are just one char, making fillerRequired become wrong int fillerRequired = menu->width - MB_ElementCount(menu->items[curitem].text) - (menu->type == MENUTYPE_MULTISELECT ? 2 : 0); for(int i = 0; i < fillerRequired; i++) strcat(menuitem, " "); mPrintXY(menu->startX,curitem+itemsStartY-menu->scroll,(char*)menuitem, (menu->selection == curitem+1 ? TEXT_MODE_INVERT : TEXT_MODE_TRANSPARENT_BACKGROUND), menu->items[curitem].color); } else { /*int textX = (menu->startX-1) * 18; int textY = curitem*24+itemsStartY*24-menu->scroll*24-24+6; clearLine(menu->startX, curitem+itemsStartY-menu->scroll, (menu->selection == curitem+1 ? textColorToFullColor(menu->items[curitem].color) : COLOR_WHITE)); drawLine(textX, textY+24-4, LCD_WIDTH_PX-2, textY+24-4, COLOR_GRAY); PrintMini(&textX, &textY, (unsigned char*)menuitem, 0, 0xFFFFFFFF, 0, 0, (menu->selection == curitem+1 ? COLOR_WHITE : textColorToFullColor(menu->items[curitem].color)), (menu->selection == curitem+1 ? textColorToFullColor(menu->items[curitem].color) : COLOR_WHITE), 1, 0);*/ } // deal with menu items of type MENUITEM_CHECKBOX if(menu->items[curitem].type == MENUITEM_CHECKBOX) { mPrintXY(menu->startX+menu->width-1,curitem+itemsStartY-menu->scroll, (menu->items[curitem].value == MENUITEM_VALUE_CHECKED ? (char*)"\xe6\xa9" : (char*)"\xe6\xa5"), (menu->selection == curitem+1 ? TEXT_MODE_INVERT : (menu->pBaRtR == 1? TEXT_MODE_TRANSPARENT_BACKGROUND : TEXT_MODE_NORMAL)), menu->items[curitem].color); } // deal with multiselect menus if(menu->type == MENUTYPE_MULTISELECT) { if((curitem+itemsStartY-menu->scroll)>=itemsStartY && (curitem+itemsStartY-menu->scroll)<=(itemsStartY+itemsHeight) && icontable != NULL ) { if (menu->items[curitem].isfolder == 1) { // assumes first icon in icontable is the folder icon CopySpriteMasked(icontable[0].data, (menu->startX)*18, (curitem+itemsStartY-menu->scroll)*24, 0x12, 0x18, 0xf81f ); } else { if(menu->items[curitem].icon >= 0) CopySpriteMasked(icontable[menu->items[curitem].icon].data, (menu->startX)*18, (curitem+itemsStartY-menu->scroll)*24, 0x12, 0x18, 0xf81f ); } } if (menu->items[curitem].isselected) { if (menu->selection == curitem+1) { mPrintXY(menu->startX,curitem+itemsStartY-menu->scroll,(char*)"\xe6\x9b", TEXT_MODE_TRANSPARENT_BACKGROUND, (menu->items[curitem].color == TEXT_COLOR_GREEN ? TEXT_COLOR_BLUE : TEXT_COLOR_GREEN)); } else { mPrintXY(menu->startX,curitem+itemsStartY-menu->scroll,(char*)"\xe6\x9b", TEXT_MODE_NORMAL, TEXT_COLOR_PURPLE); } } } } } if (menu->scrollbar) { TScrollbar sb; sb.I1 = 0; sb.I5 = 0; sb.indicatormaximum = menu->numitems; sb.indicatorheight = itemsHeight; sb.indicatorpos = menu->scroll; sb.barheight = itemsHeight*24; sb.bartop = (itemsStartY-1)*24; sb.barleft = menu->startX*18+menu->width*18 - 18 - (menu->scrollout ? 0 : 5); sb.barwidth = 6; Scrollbar(&sb); } //if(menu->type==MENUTYPE_MULTISELECT && menu->fkeypage == 0) drawFkeyLabels(0x0037); // SELECT (white) } else { printCentered((unsigned char*)menu->nodatamsg, (itemsStartY*24)+(itemsHeight*24)/2-12, COLOR_BLACK, COLOR_WHITE); } if(showtitle) { if(menu->miniMiniTitle) { int textX = 0, textY=(menu->startY-1)*24; PrintMiniMini( &textX, &textY, (unsigned char*)menu->title, 16, menu->titleColor, 0 ); } else mPrintXY(menu->startX, menu->startY, menu->title, TEXT_MODE_TRANSPARENT_BACKGROUND, menu->titleColor); if(menu->subtitle != NULL) { int textX=(MB_ElementCount(menu->title)+menu->startX-1)*18+10, textY=6; PrintMini(&textX, &textY, (unsigned char*)menu->subtitle, 0, 0xFFFFFFFF, 0, 0, COLOR_BLACK, COLOR_WHITE, 1, 0); } } /*if(menu->darken) { DrawFrame(COLOR_BLACK); VRAMInvertArea(menu->startX*18-18, menu->startY*24, menu->width*18-(menu->scrollout || !menu->scrollbar ? 0 : 5), menu->height*24); }*/ if(menu->type == MENUTYPE_NO_KEY_HANDLING) return MENU_RETURN_INSTANT; // we don't want to handle keys int key; GetKey(&key); switch(key) { case KEY_CTRL_DOWN: if(menu->selection == menu->numitems) { if(menu->returnOnInfiniteScrolling) { return MENU_RETURN_SCROLLING; } else { menu->selection = 1; menu->scroll = 0; } } else { menu->selection++; if(menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); } if(menu->pBaRtR==1) return MENU_RETURN_INSTANT; break; case KEY_CTRL_UP: if(menu->selection == 1) { if(menu->returnOnInfiniteScrolling) { return MENU_RETURN_SCROLLING; } else { menu->selection = menu->numitems; menu->scroll = menu->selection-(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); } } else { menu->selection--; if(menu->selection-1 < menu->scroll) menu->scroll = menu->selection -1; } if(menu->pBaRtR==1) return MENU_RETURN_INSTANT; break; case KEY_CTRL_F1: if(menu->type==MENUTYPE_MULTISELECT && menu->fkeypage == 0 && menu->numitems > 0) { /*if(menu->items[menu->selection-1].isselected) { menu->items[menu->selection-1].isselected=0; menu->numselitems = menu->numselitems-1; } else { menu->items[menu->selection-1].isselected=1; menu->numselitems = menu->numselitems+1; } return key; //return on F1 too so that parent subroutines have a chance to e.g. redraw fkeys*/ } else if (menu->type == MENUTYPE_FKEYS) { return key; } break; case KEY_CTRL_F2: case KEY_CTRL_F3: case KEY_CTRL_F4: case KEY_CTRL_F5: case KEY_CTRL_F6: if (menu->type == MENUTYPE_FKEYS || menu->type==MENUTYPE_MULTISELECT) return key; // MULTISELECT also returns on Fkeys break; case KEY_CTRL_PASTE: if (menu->type==MENUTYPE_MULTISELECT) return key; // MULTISELECT also returns on paste case KEY_CTRL_OPTN: if (menu->type==MENUTYPE_FKEYS || menu->type==MENUTYPE_MULTISELECT) return key; break; case KEY_CTRL_FORMAT: if (menu->type==MENUTYPE_FKEYS) return key; // return on the Format key so that event lists can prompt to change event category break; case KEY_CTRL_RIGHT: if(menu->type != MENUTYPE_MULTISELECT) break; // else fallthrough case KEY_CTRL_EXE: if(menu->numitems>0) return MENU_RETURN_SELECTION; break; case KEY_CTRL_LEFT: if(menu->type != MENUTYPE_MULTISELECT) break; // else fallthrough case KEY_CTRL_EXIT: return MENU_RETURN_EXIT; break; case KEY_CHAR_1: case KEY_CHAR_2: case KEY_CHAR_3: case KEY_CHAR_4: case KEY_CHAR_5: case KEY_CHAR_6: case KEY_CHAR_7: case KEY_CHAR_8: case KEY_CHAR_9: if(menu->numitems>=(key-0x30)) {menu->selection = (key-0x30); return MENU_RETURN_SELECTION; } break; case KEY_CHAR_0: if(menu->numitems>=10) {menu->selection = 10; return MENU_RETURN_SELECTION; } break; case KEY_CTRL_XTT: if(menu->numitems>=11) {menu->selection = 11; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_LOG: if(menu->numitems>=12) {menu->selection = 12; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_LN: if(menu->numitems>=13) {menu->selection = 13; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_SIN: case KEY_CHAR_COS: case KEY_CHAR_TAN: if(menu->numitems>=(key-115)) {menu->selection = (key-115); return MENU_RETURN_SELECTION; } break; case KEY_CHAR_FRAC: if(menu->numitems>=17) {menu->selection = 17; return MENU_RETURN_SELECTION; } break; case KEY_CTRL_FD: if(menu->numitems>=18) {menu->selection = 18; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_LPAR: case KEY_CHAR_RPAR: if(menu->numitems>=(key-21)) {menu->selection = (key-21); return MENU_RETURN_SELECTION; } break; case KEY_CHAR_COMMA: if(menu->numitems>=21) {menu->selection = 21; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_STORE: if(menu->numitems>=22) {menu->selection = 22; return MENU_RETURN_SELECTION; } break; } } return MENU_RETURN_EXIT; }