mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 19:49:58 +02:00
External application, API v2
This commit is contained in:
@@ -1,14 +1,6 @@
|
||||
#ifdef SIMULATOR
|
||||
#include <FL/Fl.H>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include "port.h"
|
||||
|
||||
#include <ion.h>
|
||||
#include <kandinsky.h>
|
||||
#include <poincare/preferences.h>
|
||||
#include "../../apps/apps_container.h"
|
||||
#include "../../apps/global_preferences.h"
|
||||
#include <ion/keyboard.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
@@ -86,9 +78,9 @@ void MicroPython::ExecutionEnvironment::runCode(const char * str) {
|
||||
/* End of mp_obj_print_exception. */
|
||||
}
|
||||
|
||||
assert(sCurrentExecutionEnvironment == this);
|
||||
sCurrentExecutionEnvironment = nullptr;
|
||||
}
|
||||
assert(sCurrentExecutionEnvironment == this);
|
||||
sCurrentExecutionEnvironment = nullptr;
|
||||
}
|
||||
|
||||
void MicroPython::ExecutionEnvironment::interrupt() {
|
||||
mp_keyboard_interrupt();
|
||||
@@ -205,485 +197,11 @@ mp_import_stat_t mp_import_stat(const char *path) {
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char * str, size_t len) {
|
||||
if (sCurrentExecutionEnvironment != nullptr)
|
||||
sCurrentExecutionEnvironment->printText(str, len);
|
||||
assert(sCurrentExecutionEnvironment != nullptr);
|
||||
sCurrentExecutionEnvironment->printText(str, len);
|
||||
}
|
||||
|
||||
const char * mp_hal_input(const char * prompt) {
|
||||
if (sCurrentExecutionEnvironment != nullptr)
|
||||
return sCurrentExecutionEnvironment->inputText(prompt);
|
||||
return 0;
|
||||
assert(sCurrentExecutionEnvironment != nullptr);
|
||||
return sCurrentExecutionEnvironment->inputText(prompt);
|
||||
}
|
||||
|
||||
/* C-- SDK , (c) B. Parisse 2019 */
|
||||
|
||||
const char * read_file(const char * filename){
|
||||
#if 1
|
||||
Ion::Storage * s=Ion::Storage::sharedStorage();
|
||||
const Ion::Storage::Record r=s->recordNamed(filename);
|
||||
if (r.isNull())
|
||||
return 0;
|
||||
Ion::Storage::Record::Data d=r.value();
|
||||
const char * ptr=(const char *)d.buffer;
|
||||
if (ptr)
|
||||
return ptr+1;
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
if (sScriptProvider != nullptr)
|
||||
return sScriptProvider->contentOfScript(filename);
|
||||
return "undef";
|
||||
}
|
||||
|
||||
bool write_file(const char * filename,const char * content,size_t len){
|
||||
Ion::Storage * s=Ion::Storage::sharedStorage();
|
||||
auto res=s->createRecordWithFullName(filename,content,strlen(content)+1);
|
||||
if (res==Ion::Storage::Record::ErrorStatus::NameTaken){
|
||||
auto r=s->recordNamed(filename);
|
||||
Ion::Storage::Record::Data d;
|
||||
d.buffer=content;
|
||||
d.size=(len?len:strlen(content))+1;
|
||||
return r.setValue(d)==Ion::Storage::Record::ErrorStatus::None;
|
||||
}
|
||||
if (res==Ion::Storage::Record::ErrorStatus::None)
|
||||
return write_file(filename,content,len);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool file_exists(const char * filename){
|
||||
Ion::Storage * s=Ion::Storage::sharedStorage();
|
||||
return s->isFullNameTaken(filename);
|
||||
}
|
||||
|
||||
bool erase_file(const char * filename){
|
||||
Ion::Storage * s=Ion::Storage::sharedStorage();
|
||||
auto r= s->recordNamed(filename);
|
||||
if (r.isNull())
|
||||
return false;
|
||||
r.destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
int os_file_browser(const char ** filenames,int maxrecords,const char * extension){
|
||||
Ion::Storage * s=Ion::Storage::sharedStorage();
|
||||
int n=s->numberOfRecordsWithExtension(extension);
|
||||
if (!n) return 0;
|
||||
if (n>maxrecords) n=maxrecords;
|
||||
for (int i=0;i<n;i++){
|
||||
const Ion::Storage::Record & r=s->recordWithExtensionAtIndex(extension, i);
|
||||
filenames[i]=r.fullName();
|
||||
}
|
||||
filenames[n]=0;
|
||||
return n;
|
||||
}
|
||||
// const char * ptr=(const char *)r.value().buffer;
|
||||
/* storage.h
|
||||
Ion::Storage::Record::Data structure avec 2 membres
|
||||
const void * buffer et size_t size
|
||||
|
||||
Record(const char * fullName = nullptr);
|
||||
Record(const char * basename, const char * extension);
|
||||
Data value();
|
||||
Ion::Storage::Record::ErrorStatus setValue(Ion::Storage::Record::Data);
|
||||
void destroy(void);
|
||||
|
||||
// Record creation
|
||||
Record::ErrorStatus createRecordWithFullName(const char * fullName, const void * data, size_t size);
|
||||
Record::ErrorStatus createRecordWithExtension(const char * baseName, const char * extension, const void * data, size_t size);
|
||||
|
||||
// Record getters
|
||||
Record recordWithExtensionAtIndex(const char * extension, int index);
|
||||
Record recordNamed(const char * fullName);
|
||||
Record recordBaseNamedWithExtension(const char * baseName, const char * extension);
|
||||
Record recordBaseNamedWithExtensions(const char * baseName, const char * const extension[], size_t numberOfExtensions);
|
||||
|
||||
// Record destruction
|
||||
void destroyAllRecords();
|
||||
void destroyRecordWithBaseNameAndExtension(const char * baseName, const char * extension);
|
||||
void destroyRecordsWithExtension(const char * extension);
|
||||
|
||||
|
||||
*/
|
||||
#endif
|
||||
|
||||
void statuslinemsg(const char * msg){
|
||||
AppsContainer::sharedAppsContainer()->reloadTitleBarView();
|
||||
auto ptr=MicroPython::ExecutionEnvironment::currentExecutionEnvironment();
|
||||
if (ptr)
|
||||
ptr->displaySandbox();
|
||||
auto ctx=KDIonContext::sharedContext();
|
||||
KDRect save=ctx->m_clippingRect;
|
||||
KDPoint o=ctx->m_origin;
|
||||
ctx->setClippingRect(KDRect(0,0,280,18));
|
||||
ctx->setOrigin(KDPoint(0,0));
|
||||
KDRect rect(0,0,280,18);
|
||||
KDIonContext::sharedContext()->pushRectUniform(rect,64934 /* Palette::YellowDark*/);
|
||||
if (strlen(msg)>25)
|
||||
ctx->drawString(msg, KDPoint(0,0), KDFont::SmallFont, 0, 64934);
|
||||
else
|
||||
ctx->drawString(msg, KDPoint(0,0), KDFont::LargeFont, 0, 64934);
|
||||
ctx->setClippingRect(save);
|
||||
ctx->setOrigin(o);
|
||||
}
|
||||
|
||||
bool os_set_angle_unit(int mode){
|
||||
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
|
||||
if (mode==0){ // rad
|
||||
preferences->setAngleUnit(Poincare::Preferences::AngleUnit::Radian);
|
||||
return true;
|
||||
}
|
||||
if (mode==1){ // deg
|
||||
preferences->setAngleUnit(Poincare::Preferences::AngleUnit::Degree);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (mode==2){ // grad
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int os_get_angle_unit(){
|
||||
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
|
||||
if (preferences->angleUnit()==Poincare::Preferences::AngleUnit::Radian)
|
||||
return 0;
|
||||
if (preferences->angleUnit()==Poincare::Preferences::AngleUnit::Degree)
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
#ifdef SIMULATOR
|
||||
#define TICKS_PER_MINUTE 60000
|
||||
#else
|
||||
#define TICKS_PER_MINUTE 11862
|
||||
extern const void * _stack_start;
|
||||
extern const void * _heap_start;
|
||||
#endif
|
||||
//int time_shift=0; // set it via time() command in KhiCAS
|
||||
void statusline(int mode, size_t heap){
|
||||
AppsContainer::sharedAppsContainer()->reloadTitleBarView();
|
||||
auto ctx=KDIonContext::sharedContext();
|
||||
KDRect save=ctx->m_clippingRect;
|
||||
KDPoint o=ctx->m_origin;
|
||||
ctx->setClippingRect(KDRect(0,0,320,18));
|
||||
ctx->setOrigin(KDPoint(0,0));
|
||||
KDRect rect(0,0,mode==1?320:280,18);
|
||||
KDIonContext::sharedContext()->pushRectUniform(rect,64934 /* Palette::YellowDark*/);
|
||||
const char * text=0;
|
||||
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
|
||||
if (preferences->angleUnit() == Poincare::Preferences::AngleUnit::Radian)
|
||||
text="rad";
|
||||
else
|
||||
text="deg";
|
||||
// ctx->drawString(text, KDPoint(5,1), KDFont::SmallFont, 0, 63488 /* Palette::Red*/);
|
||||
ctx->drawString(text, KDPoint(5,1), KDFont::SmallFont, 0, 64934);
|
||||
#ifdef GIAC_LINKED
|
||||
if (khicas_eval)
|
||||
text="KHICAS";
|
||||
else
|
||||
text="PYTHON";
|
||||
#else
|
||||
text="KHICAS";
|
||||
#endif
|
||||
ctx->drawString(text, KDPoint(70,1), KDFont::SmallFont, 0, 64934);
|
||||
char bufheap[16];
|
||||
#if 0 //ndef SIMULATOR
|
||||
#endif
|
||||
int x;
|
||||
x=(heap&0xf0000000)>>28;
|
||||
bufheap[0]=(x>9?'a'+(x-10):'0'+x);
|
||||
x=(heap&0xf000000)>>24;
|
||||
bufheap[1]=(x>9?'a'+(x-10):'0'+x);
|
||||
x=(heap&0xf00000)>>20;
|
||||
bufheap[2]=(x>9?'a'+(x-10):'0'+x);
|
||||
x=(heap&0xf0000)>>16;
|
||||
bufheap[3]=(x>9?'a'+(x-10):'0'+x);
|
||||
x=(heap&0xf000)>>12;
|
||||
bufheap[4]=(x>9?'a'+(x-10):'0'+x);
|
||||
x=(heap&0xf00)>>8;
|
||||
bufheap[5]=(x>9?'a'+(x-10):'0'+x);
|
||||
x=(heap&0xf0)>>4;
|
||||
bufheap[6]=(x>9?'a'+(x-10):'0'+x);
|
||||
x=(heap&0xf);
|
||||
bufheap[7]=(x>9?'a'+(x-10):'0'+x);
|
||||
bufheap[8]=0;
|
||||
if(heap != 0) ctx->drawString(bufheap,KDPoint(130,1),KDFont::SmallFont, 0, 64934);
|
||||
#ifdef GIAC_SHOWTIME
|
||||
int d=(Ion::Timing::millis()/TICKS_PER_MINUTE +time_shift) % (24*60); // minutes
|
||||
char buf[32]={0,0,0,0};
|
||||
int h=d/60;
|
||||
buf[0]='0'+h/10;
|
||||
buf[1]='0'+(h%10);
|
||||
buf[2]=':';
|
||||
ctx->drawString(buf, KDPoint(148,1), KDFont::SmallFont, 0, 64934);
|
||||
int mn=d%60;
|
||||
buf[0]='0'+mn/10;
|
||||
buf[1]='0'+(mn%10);
|
||||
buf[2]=0;
|
||||
ctx->drawString(buf, KDPoint(168,1), KDFont::SmallFont, 0, 64934);
|
||||
#endif
|
||||
text=" ";
|
||||
if (Ion::Events::shiftAlphaStatus()==Ion::Events::ShiftAlphaStatus::Shift)
|
||||
text="shift ";
|
||||
else {
|
||||
if (Ion::Events::isAlphaActive()){
|
||||
if (Ion::Events::shiftAlphaStatus()==Ion::Events::ShiftAlphaStatus::AlphaLock)
|
||||
text="alphal";
|
||||
if (Ion::Events::shiftAlphaStatus()==Ion::Events::ShiftAlphaStatus::ShiftAlphaLock)
|
||||
text="ALPHAL";
|
||||
if (Ion::Events::shiftAlphaStatus()==Ion::Events::ShiftAlphaStatus::Alpha)
|
||||
text="1alpha";
|
||||
if (Ion::Events::shiftAlphaStatus()==Ion::Events::ShiftAlphaStatus::ShiftAlpha)
|
||||
text="1ALPHA";
|
||||
}
|
||||
}
|
||||
ctx->drawString(text, KDPoint(232,1), KDFont::SmallFont, 0, 64934 /* Palette::YellowDark*/);
|
||||
if (mode==1){
|
||||
if (Ion::USB::isPlugged())
|
||||
text="charge";
|
||||
else {
|
||||
auto c=Ion::Battery::level();
|
||||
if (c==Ion::Battery::Charge::EMPTY)
|
||||
text="empty ";
|
||||
if (c==Ion::Battery::Charge::LOW)
|
||||
text="low ";
|
||||
if (c==Ion::Battery::Charge::FULL)
|
||||
text="full ";
|
||||
}
|
||||
ctx->drawString(text, KDPoint(280,1), KDFont::SmallFont, 0, 64934 /* Palette::YellowDark*/);
|
||||
}
|
||||
ctx->setClippingRect(save);
|
||||
ctx->setOrigin(o);
|
||||
}
|
||||
|
||||
bool isalphaactive(){
|
||||
return Ion::Events::isAlphaActive();
|
||||
}
|
||||
|
||||
void lock_alpha(){
|
||||
Ion::Events::setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::AlphaLock);
|
||||
statusline(0,0);
|
||||
}
|
||||
|
||||
void reset_kbd(){
|
||||
Ion::Events::setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default);
|
||||
statusline(0,0);
|
||||
}
|
||||
|
||||
bool alphawasactive_=false;
|
||||
bool alphawasactive(){
|
||||
return alphawasactive_;
|
||||
}
|
||||
|
||||
bool waitforvblank(){
|
||||
return Ion::Display::waitForVBlank();
|
||||
}
|
||||
|
||||
bool back_key_pressed() {
|
||||
static int c = 0;
|
||||
|
||||
++c ;
|
||||
if (c<400 || (c & 0xf)!= 0) {
|
||||
return false;
|
||||
}
|
||||
#ifdef SIMULATOR
|
||||
Fl::wait(0.00001);
|
||||
#endif
|
||||
|
||||
Ion::Keyboard::State scan = Ion::Keyboard::scan();
|
||||
// if (scan!=16) std::cerr << scan << '\n';
|
||||
Ion::Keyboard::Key interruptKey = static_cast<Ion::Keyboard::Key>(mp_interrupt_char);
|
||||
if (scan.keyDown(interruptKey)
|
||||
// || scan.keyDown(static_cast<Ion::Keyboard::Key>(16))
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int getkey_raw(bool allow_suspend){
|
||||
int key=-1;
|
||||
size_t t1=Ion::Timing::millis();
|
||||
for (;;){
|
||||
int timeout=10000;
|
||||
alphawasactive_=Ion::Events::isAlphaActive();
|
||||
Ion::Events::Event event=Ion::Events::getEvent(&timeout);
|
||||
auto ctx=KDIonContext::sharedContext();
|
||||
KDRect save=ctx->m_clippingRect;
|
||||
KDPoint o=ctx->m_origin;
|
||||
ctx->setClippingRect(KDRect(0,0,320,240));
|
||||
ctx->setOrigin(KDPoint(0,18));
|
||||
KDRect rect(90,63,140,75);
|
||||
if (event==Ion::Events::None){
|
||||
size_t t2=Ion::Timing::millis();
|
||||
if (t2-t1>2*TICKS_PER_MINUTE){
|
||||
// KDIonContext::sharedContext()->pushRectUniform(rect,64934 /* Palette::YellowDark*/);
|
||||
event=Ion::Events::OnOff;
|
||||
}
|
||||
}
|
||||
else
|
||||
t1=Ion::Timing::millis();
|
||||
if (event == Ion::Events::USBPlug) {
|
||||
statusline(0,0);
|
||||
// KDIonContext::sharedContext()->pushRectUniform(rect,33333);
|
||||
if (Ion::USB::isPlugged()) {
|
||||
if (GlobalPreferences::sharedGlobalPreferences()->examMode()) {
|
||||
Ion::LED::setColor(KDColorBlack);
|
||||
Ion::LED::updateColorWithPlugAndCharge();
|
||||
GlobalPreferences::sharedGlobalPreferences()->setExamMode(false);
|
||||
// displayExamModePopUp(false);
|
||||
} else {
|
||||
Ion::USB::enable();
|
||||
}
|
||||
Ion::Backlight::setBrightness(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel());
|
||||
} else {
|
||||
Ion::USB::disable();
|
||||
}
|
||||
}
|
||||
if (event == Ion::Events::USBEnumeration || event == Ion::Events::USBPlug || event == Ion::Events::BatteryCharging) {
|
||||
Ion::LED::updateColorWithPlugAndCharge();
|
||||
}
|
||||
if (event == Ion::Events::USBEnumeration
|
||||
) {
|
||||
KDIonContext::sharedContext()->pushRectUniform(rect,64934 /* Palette::YellowDark*/);
|
||||
if (Ion::USB::isPlugged()) {
|
||||
/* Just after a software update, the battery timer does not have time to
|
||||
* fire before the calculator enters DFU mode. As the DFU mode blocks the
|
||||
* event loop, we update the battery state "manually" here.
|
||||
* We do it before switching to USB application to redraw the battery
|
||||
* pictogram. */
|
||||
// updateBatteryState();
|
||||
KDIonContext::sharedContext()->pushRectUniform(rect,22222);
|
||||
auto ctx=KDIonContext::sharedContext();
|
||||
int y=58;
|
||||
ctx->drawString("Connecte ! ", KDPoint(100,y), KDFont::LargeFont, 65535, 0);
|
||||
y+=18;
|
||||
ctx->drawString(" DFU mode ", KDPoint(100,y), KDFont::LargeFont, 65535, 0);
|
||||
y+=18;
|
||||
ctx->drawString("Back quitte", KDPoint(100,y), KDFont::LargeFont, 65535, 0);
|
||||
y-=18;
|
||||
Ion::USB::DFU();
|
||||
KDIonContext::sharedContext()->pushRectUniform(rect,44444);
|
||||
ctx->drawString("Deconnecte!", KDPoint(100,y), KDFont::LargeFont, 65535, 0);
|
||||
// Update LED when exiting DFU mode
|
||||
Ion::LED::updateColorWithPlugAndCharge();
|
||||
} else {
|
||||
/* Sometimes, the device gets an ENUMDNE interrupts when being unplugged
|
||||
* from a non-USB communicating host (e.g. a USB charger). The interrupt
|
||||
* must me cleared: if not the next enumeration attempts will not be
|
||||
* detected. */
|
||||
Ion::USB::clearEnumerationInterrupt();
|
||||
}
|
||||
}
|
||||
if (event.isKeyboardEvent()) {
|
||||
// m_backlightDimmingTimer.reset();
|
||||
// m_suspendTimer.reset();
|
||||
Ion::Backlight::setBrightness(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel());
|
||||
}
|
||||
ctx->setClippingRect(save);
|
||||
ctx->setOrigin(o);
|
||||
|
||||
if (event==Ion::Events::Shift || event==Ion::Events::Alpha){
|
||||
statusline(0,0);
|
||||
continue;
|
||||
}
|
||||
if (event.isKeyboardEvent()){
|
||||
key=event.id();
|
||||
if (key==17 || key==4 || key==5 || key==52)
|
||||
reset_kbd();
|
||||
if (allow_suspend && (key==7 || key==8) ){ // power
|
||||
Ion::Power::suspend(true);
|
||||
numworks_fill_rect(0,0,320,240,65535);
|
||||
Ion::Backlight::setBrightness(GlobalPreferences::sharedGlobalPreferences()->brightnessLevel());
|
||||
AppsContainer::sharedAppsContainer()->reloadTitleBarView();
|
||||
//AppsContainer::sharedAppsContainer()->redrawWindow();
|
||||
statusline(1,0);
|
||||
//continue;
|
||||
}
|
||||
else
|
||||
statusline(0,0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
const short int translated_keys[]=
|
||||
{
|
||||
// non shifted
|
||||
KEY_CTRL_LEFT,KEY_CTRL_UP,KEY_CTRL_DOWN,KEY_CTRL_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
|
||||
KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
|
||||
KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,KEY_CTRL_XTT,KEY_CTRL_VARS,KEY_CTRL_CATALOG,KEY_CTRL_DEL,
|
||||
KEY_CHAR_EXPN,KEY_CHAR_LN,KEY_CHAR_LOG,KEY_CHAR_IMGNRY,',',KEY_CHAR_POW,
|
||||
KEY_CHAR_SIN,KEY_CHAR_COS,KEY_CHAR_TAN,KEY_CHAR_PI,KEY_CHAR_ROOT,KEY_CHAR_SQUARE,
|
||||
'7','8','9','(',')',-1,
|
||||
'4','5','6','*','/',-1,
|
||||
'1','2','3','+','-',-1,
|
||||
'0','.',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
|
||||
// shifted
|
||||
KEY_SHIFT_LEFT,KEY_CTRL_PAGEUP,KEY_CTRL_PAGEDOWN,KEY_SHIFT_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
|
||||
KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
|
||||
KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,KEY_CTRL_CUT,KEY_CTRL_CLIP,KEY_CTRL_PASTE,KEY_CTRL_AC,
|
||||
KEY_CHAR_LBRCKT,KEY_CHAR_RBRCKT,KEY_CHAR_LBRACE,KEY_CHAR_RBRACE,'_',KEY_CHAR_STORE,
|
||||
KEY_CHAR_ASIN,KEY_CHAR_ACOS,KEY_CHAR_ATAN,'=','<','>',
|
||||
KEY_CTRL_F7,KEY_CTRL_F8,KEY_CTRL_F9,KEY_CTRL_F13,KEY_CTRL_F14,-1,
|
||||
KEY_CTRL_F4,KEY_CTRL_F5,KEY_CTRL_F6,KEY_CHAR_FACTOR,'%',-1,
|
||||
KEY_CTRL_F1,KEY_CTRL_F2,KEY_CTRL_F3,KEY_CHAR_NORMAL,'\\',-1,
|
||||
KEY_CTRL_F10,KEY_CTRL_F11,KEY_CTRL_F12,KEY_SHIFT_ANS,KEY_CTRL_EXE,-1,
|
||||
// alpha
|
||||
KEY_CTRL_LEFT,KEY_CTRL_UP,KEY_CTRL_DOWN,KEY_CTRL_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
|
||||
KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
|
||||
KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,':',';','"',KEY_CTRL_DEL,
|
||||
'a','b','c','d','e','f',
|
||||
'g','h','i','j','k','l',
|
||||
'm','n','o','p','q',-1,
|
||||
'r','s','t','u','v',-1,
|
||||
'w','x','y','z',' ',-1,
|
||||
'?','!',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
|
||||
// alpha shifted
|
||||
KEY_SHIFT_LEFT,KEY_CTRL_PAGEUP,KEY_CTRL_PAGEDOWN,KEY_SHIFT_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
|
||||
KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
|
||||
KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,':',';','\'','%',
|
||||
'A','B','C','D','E','F',
|
||||
'G','H','I','J','K','L',
|
||||
'M','N','O','P','Q',-1,
|
||||
'R','S','T','U','V',-1,
|
||||
'W','X','Y','Z',' ',-1,
|
||||
'?','!',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
|
||||
};
|
||||
|
||||
int getkey(bool allow_suspend){
|
||||
int k=getkey_raw(allow_suspend);
|
||||
// translate
|
||||
return translated_keys[k];
|
||||
}
|
||||
|
||||
// Casio prototype
|
||||
void GetKey(int * key){
|
||||
*key=getkey(true);
|
||||
}
|
||||
|
||||
|
||||
void numworks_wait_1ms(int ms){
|
||||
for (int i=0;i<ms/128;++i){
|
||||
#ifdef SIMULATOR
|
||||
Fl::wait(0.00001);
|
||||
#endif
|
||||
Ion::Keyboard::State scan = Ion::Keyboard::scan();
|
||||
// if (scan!=16) std::cerr << scan << '\n';
|
||||
Ion::Keyboard::Key interruptKey = static_cast<Ion::Keyboard::Key>(Ion::Keyboard::Key::Back);
|
||||
if (scan.keyDown(interruptKey))
|
||||
return;
|
||||
Ion::Timing::msleep(128);
|
||||
}
|
||||
Ion::Timing::msleep(ms % 128);
|
||||
}
|
||||
|
||||
void enable_back_interrupt(){
|
||||
mp_interrupt_char = (int)Ion::Keyboard::Key::Back;
|
||||
}
|
||||
|
||||
void disable_back_interrupt(){
|
||||
mp_interrupt_char = -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user