diff --git a/configure.ac b/configure.ac index b47dcf8b..f8b44816 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,11 @@ AC_ARG_ENABLE(mosync, [ac_build_mosync="yes"], [ac_build_mosync="no"]) +AC_ARG_ENABLE(tizen, + AS_HELP_STRING([--enable-tizen],[build common library for Tizen(default=no)]), + [ac_build_tizen="yes"], + [ac_build_tizen="no"]) + AC_ARG_ENABLE(dist, AS_HELP_STRING([--enable-dist],[prepare to run make dist(default=no)]), [ac_build_dist="yes"], @@ -99,6 +104,9 @@ function checkPCRE() { if test x$ac_build_mosync = xyes; then have_pcre="no" fi + if test x$ac_build_tizen = xyes; then + have_pcre="no" + fi if test "${have_pcre}" = "yes" ; then AC_DEFINE(USE_PCRE, 1, [match.c used with libpcre.]) @@ -333,28 +341,6 @@ function buildSDL() { PACKAGE_CFLAGS="${PACKAGE_CFLAGS} -mms-bitfields -mno-cygwin" PACKAGE_LIBS="${PACKAGE_LIBS} -lwsock32" ;; - *-*-beos*) - SYS_GL_LIBS="-lGL" - ;; - *-*-darwin* ) - SYS_GL_LIBS="-Wl,-framework,OpenGL" - ;; - *-*-aix*) - if test x$ac_cv_c_compiler_gnu = xyes; then - CFLAGS="-mthreads" - fi - ;; - *-*-mint*) - AC_PATH_PROG(OSMESA_CONFIG, osmesa-config, no) - if test "x$OSMESA_CONFIG" = "xyes"; then - OSMESA_CFLAGS=`$OSMESA_CONFIG --cflags` - OSMESA_LIBS=`$OSMESA_CONFIG --libs` - CFLAGS="$CFLAGS $OSMESA_CFLAGS" - SYS_GL_LIBS="$OSMESA_LIBS" - else - SYS_GL_LIBS="-lOSMesa" - fi - ;; *) MATHLIB="-lm" SYS_GL_LIBS="-lGL" @@ -368,8 +354,8 @@ function buildSDL() { dnl AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) dnl ) - PACKAGE_CFLAGS="${PACKAGE_CFLAGS} ${SDL_CFLAGS}" - PACKAGE_LIBS="${PACKAGE_LIBS} ${SDL_LIBS} ${MATHLIB}" + PACKAGE_CFLAGS="${PACKAGE_CFLAGS} `sdl-config --cflags`" + PACKAGE_LIBS="${PACKAGE_LIBS} `sdl-config --libs` ${MATHLIB}" dnl Check for OpenGL AC_MSG_CHECKING(for OpenGL support) @@ -525,6 +511,30 @@ function buildMosync() { AC_SUBST(BUILD_SUBDIRS) } +function buildTizen() { + TARGET="Building common library for Tizen." + + defaultConditionals + + AC_DEFINE(_UnixOS, 1, [Building under Unix like systems.]) + AC_DEFINE(_TIZEN, 1, [Defined for Tizen build.]) + AC_DEFINE(IMPL_DEV_READ, 1, [Implement dev_read()]) + AC_DEFINE(HAVE_SEARCH_H, 1, [Found GNU search.h]) + AC_DEFINE(HAVE_TDESTROY, 1, [Found GNU search.h]) + AC_DEFINE(DEV_EVENTS_OSD, 1, [dev_events() implemented using osd_events().]) + AC_DEFINE(IMPL_DEV_GETS, 1, [Driver implements dev_gets()]) + AC_DEFINE(IMPL_DEV_DELAY, 1, [Driver implements dev_delay()]) + AC_DEFINE(IMPL_IMAGE, 1, [Driver implements image commands]) + AC_DEFINE(HAVE_MALLOC_USABLE_SIZE, 0, [Newlib version causes mosync stack panic]) + AC_DEFINE(CPU_BIGENDIAN, 1, [Tizen uses big-endian]) + AC_DEFINE(NO_SCAN_ERROR_PROMPT, 1, [No prompt for detailed scan report]) + AC_DEFINE(IMPL_LOG_WRITE, 1, [Driver implements lwrite()]) + AC_DEFINE(USE_TERM_IO, 0, [Does not use terminal-io functions.]) + + BUILD_SUBDIRS="src/platform/tizen/common" + AC_SUBST(BUILD_SUBDIRS) +} + function buildConsole() { win32=no case "${host_os}" in @@ -618,6 +628,8 @@ elif test x$ac_build_qt = xyes; then buildQT elif test x$ac_build_mosync = xyes; then buildMosync +elif test x$ac_build_tizen = xyes; then + buildTizen else buildConsole fi @@ -642,6 +654,7 @@ src/platform/cygwin/Makefile src/platform/mingw/Makefile src/platform/unix/Makefile src/platform/mosync/common/Makefile +src/platform/tizen/common/Makefile ]) AC_OUTPUT diff --git a/ide/tizen/.cproject b/ide/tizen/.cproject new file mode 100644 index 00000000..deff99b8 --- /dev/null +++ b/ide/tizen/.cproject @@ -0,0 +1,487 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ide/tizen/.project b/ide/tizen/.project new file mode 100644 index 00000000..f2c917f7 --- /dev/null +++ b/ide/tizen/.project @@ -0,0 +1,115 @@ + + + SmallBASIC + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + ?children? + ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\|| + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + sbi-make + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/SmallBASIC/Debug} + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + true + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + org.tizen.nativecpp.apichecker.core.builder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.tizen.nativecpp.apichecker.core.tizenCppNature + + + + common + 2 + WORKSPACE_LOC/src/platform/common + + + tizen + 2 + WORKSPACE_LOC/src/platform/tizen + + + + + 1378759337103 + + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-matches-false-false-*/.tpk + + + + diff --git a/ide/tizen/manifest.xml b/ide/tizen/manifest.xml new file mode 100644 index 00000000..99cbea97 --- /dev/null +++ b/ide/tizen/manifest.xml @@ -0,0 +1,25 @@ + + + Ya8TxGlMB1 + 1.0.0 + C++App + + true + true + true + + + 2.2 + + + + + SmallBASIC + + + mainmenu.png + + + + + diff --git a/ide/tizen/res/main.bas b/ide/tizen/res/main.bas new file mode 100644 index 00000000..03db807a --- /dev/null +++ b/ide/tizen/res/main.bas @@ -0,0 +1,166 @@ +const app = "main.bas?" +const exitLinkType = "exit_link" +const exitButtonType = "exit_button" +const linkType = "link" + +sub space_print(s) + local ch, len_s + len_s = len(s) + for ch = 1 to len_s + print mid(s, ch, 1) + " "; + next ch +end + +sub intro() + local i + for i = 1 to 4 + color i, 0: print "Welcome to SmallBASIC" + next i + color 7, 0 + space_print "Welcome to SmallBASIC" + print "" +end + +sub about() + local bn_ok + cls + print " __ _ _____ _" + print "(_ ._ _ _.|| |_) /\ (_ | / " + print "__)| | |(_||| |_)/--\__)_|_\_" + print + print "Version 0.11.4" + print + print "Copyright (c) 2002-2013 Chris Warren-Smith" + print "Copyright (c) 2000-2006 Nic Christopoulos" + chr(10) + print "http://smallbasic.sourceforge.net" + chr(10) + print "SmallBASIC comes with ABSOLUTELY NO WARRANTY. "; + print "This program is free software; you can use it "; + print "redistribute it and/or modify it under the terms of the "; + print "GNU General Public License version 2 as published by "; + print "the Free Software Foundation." + chr(10) + print "Envy Code R Font v0.8 used with permission "; + print "http://damieng.com/envy-code-r" + chr(10) + print + color 10, 8 + button xmax / 2, ypos * txth("A"), 0, 0, bn_ok, "OK" + doform + color 7, 0 + cls +end + +sub listFiles(path, byref basList, byref dirList) + local fileList, ent, esc, name, lastItem + + erase basList + erase dirList + + if (right(path, 1) != "/") then + path += "/" + endif + + color 7, 0 + print "Files in " + path + + esc = chr(27) + "[ H" + fileList = files(path) + + for ent in fileList + name = ent + if (isdir(path + name)) then + dirList << name + else if (right(ent, 4) == ".bas") then + basList << name + endif + next ent + + sort dirList + sort basList + + color 3, 0 + lastItem = len(dirList) - 1 + for i = 0 to lastItem + button 0, -1, 0, 0, dirList(i), "[" + dirList(i) + "]", linkType + dirList(i) = path + dirList(i) + print + next ent + + color 2, 0 + lastItem = len(basList) - 1 + for i = 0 to lastItem + button 0, -1, 0, 0, basList(i), basList(i), exitLinkType + basList(i) = path + basList(i) + print + next ent +end + +sub main + local basList, dirList, path + local form_var, bn_back, bn_about, bn_online + local y_height, do_intro + + dim basList + dim dirList + + form_var = "" + bn_back = "_back" + bn_about= "_about" + bn_online = "http://smallbasic.sourceforge.net/?q=export/code/1102" + y_height = txth(about_button) + 5 + + sub make_ui(path, welcome) + color 10, 8 + button 0, 0, 0, 0, bn_back, "Go up" + button -4, 0, 0, 0, bn_online, "Online", exitButtonType + button -4, 0, 0, 0, bn_about, "About" + at 0, y_height + if (welcome) then + intro + fi + listFiles path, basList, dirList + end + + sub go_back + local backPath, index + backPath = "" + index = iff(isstring(path), rinstr(path, "/"), 0) + if (index > 0 && index == len(path)) then + index = rinstr(left(path, index - 1), "/") + fi + if (index == 1) then + index++ + fi + if (index > 0) + backPath = left(path, index - 1) + else + backPath = "/" + endif + path = backPath + end + + do_intro = false + if (command == "welcome") then + do_intro = true + fi + path = cwd + + make_ui path, do_intro + + while 1 + doform form_var + cls + + if (isdir(form_var)) then + path = form_var + chdir path + make_ui path, false + elif form_var == "About" then + about + make_ui path, false + elif form_var == "Go up" then + go_back + make_ui path, false + fi + wend +end + +main diff --git a/ide/tizen/shared/res/screen-density-xhigh/mainmenu.png b/ide/tizen/shared/res/screen-density-xhigh/mainmenu.png new file mode 100644 index 00000000..4d90fd41 Binary files /dev/null and b/ide/tizen/shared/res/screen-density-xhigh/mainmenu.png differ diff --git a/src/common/device.c b/src/common/device.c index 9defa630..e213ba21 100644 --- a/src/common/device.c +++ b/src/common/device.c @@ -800,11 +800,11 @@ void log_printf(const char *format, ...) { *p = '\0'; #if defined(IMPL_LOG_WRITE) - lwrite(buf); + lwrite(buf); #else - dev_print(buf); + dev_print(buf); #endif - } +} #ifndef IMPL_HTML void dev_html(const char *html, const char *title, int x, int y, int w, int h) { diff --git a/src/common/panic.c b/src/common/panic.c index f3aaa1cf..f81e0382 100755 --- a/src/common/panic.c +++ b/src/common/panic.c @@ -18,7 +18,7 @@ static char preload_panic_buffer[SB_PANICMSG_SIZE + 1]; /** - * + * Displays a fatal error message */ void panic(const char *fmt, ...) { va_list ap; @@ -26,23 +26,24 @@ void panic(const char *fmt, ...) { vsnprintf(preload_panic_buffer, SB_PANICMSG_SIZE, fmt, ap); va_end(ap); -#if defined(_WinGUI) || defined(_Win32) - MessageBox(NULL, preload_panic_buffer, "SB Panic", MB_OK); +#if defined(IMPL_LOG_WRITE) + log_printf(preload_panic_buffer); +#elif defined(_WinGUI) || defined(_Win32) + MessageBox(NULL, preload_panic_buffer, "SB Panic", MB_OK); #elif defined (__MINGW32__) - MessageBox(NULL, preload_panic_buffer, "SB Panic", MB_OK); - exit(1); + MessageBox(NULL, preload_panic_buffer, "SB Panic", MB_OK); + exit(1); #else - fprintf(stderr, "\n\nPANIC: %s\a\n\n", preload_panic_buffer); - fflush(stderr); - - assert(0); - memmgr_setabort(1); - exit(1); + fprintf(stderr, "\n\nPANIC: %s\a\n\n", preload_panic_buffer); + fflush(stderr); + assert(0); + memmgr_setabort(1); + exit(1); #endif - } +} /** - * + * Displays a warning message */ void warning(const char *fmt, ...) { va_list ap; @@ -50,15 +51,17 @@ void warning(const char *fmt, ...) { vsprintf(preload_panic_buffer, fmt, ap); va_end(ap); -#if defined(_WinGUI) || defined(_Win32) - MessageBox(NULL, preload_panic_buffer, "SB Warning", MB_OK); +#if defined(IMPL_LOG_WRITE) + log_printf(preload_panic_buffer); +#elif defined(_WinGUI) || defined(_Win32) + MessageBox(NULL, preload_panic_buffer, "SB Warning", MB_OK); #else // defined(_UnixOS) - fprintf(stderr, preload_panic_buffer, 0); + fprintf(stderr, preload_panic_buffer, 0); #endif } /** - * + * Displays a debugging message */ void debug(const char *fmt, ...) { va_list ap; @@ -67,12 +70,14 @@ void debug(const char *fmt, ...) { vsprintf(&preload_panic_buffer[7], fmt, ap); va_end(ap); -#if defined(_WinGUI) || defined(_Win32) - MessageBox(NULL, preload_panic_buffer, "SB Debug", MB_OK); +#if defined(IMPL_LOG_WRITE) + log_printf(preload_panic_buffer); +#elif defined(_WinGUI) || defined(_Win32) + MessageBox(NULL, preload_panic_buffer, "SB Debug", MB_OK); #else // defined(_UnixOS) - fprintf(stderr, preload_panic_buffer, 0); + fprintf(stderr, preload_panic_buffer, 0); #endif - } +} /** * memory dump @@ -83,15 +88,15 @@ void hex_dump(const unsigned char *block, int size) { printf("\n---HexDump---\n\t"); for (i = 0; i < size; i++) { - printf("%02X ", block[i]); if (((i + 1) % 8) == 0 || (i == size - 1)) { printf(" "); for (j = ((i - 7 <= 0) ? 0 : i - 7); j <= i; j++) { - if (block[j] < 32) - printf("."); - else - printf("%c", block[j]); + if (block[j] < 32) { + printf("."); + } else { + printf("%c", block[j]); + } } printf("\n\t"); } diff --git a/src/common/scan.c b/src/common/scan.c index 8cdf018c..d25665d0 100644 --- a/src/common/scan.c +++ b/src/common/scan.c @@ -3420,6 +3420,7 @@ char *comp_load(const char *file_name) { #else h = open(comp_file_name, O_BINARY | O_RDONLY, 0644); if (h == -1) { + buf = NULL; #if defined(__CYGWIN__) char temp[1024]; getcwd(temp, 1024); diff --git a/src/platform/common/StringLib.h b/src/platform/common/StringLib.h index 9b637b8b..0fc9cfb8 100644 --- a/src/platform/common/StringLib.h +++ b/src/platform/common/StringLib.h @@ -191,21 +191,6 @@ struct List { add(new String(s, strlen(s))); } - /** - * String specialisation - Appends unique strings - */ - void addSet(String *s) { - if (s && s->length()) { - List_each(String*, it, this) { - String *item = (*it); - if (item->equals(s->toString())) { - return; - } - } - add(new String(*s)); - } - } - void sort(int(*compareFunc)(const void *p1, const void *p2)) { if (_size > 1) { qsort(_head, _count, sizeof(TP), compareFunc); diff --git a/src/platform/mosync/ansiwidget.cpp b/src/platform/common/ansiwidget.cpp similarity index 97% rename from src/platform/mosync/ansiwidget.cpp rename to src/platform/common/ansiwidget.cpp index 49f85e38..0e3e6baf 100755 --- a/src/platform/mosync/ansiwidget.cpp +++ b/src/platform/common/ansiwidget.cpp @@ -13,8 +13,8 @@ #include #include -#include "platform/mosync/ansiwidget.h" -#include "platform/mosync/utils.h" +#include "platform/common/ansiwidget.h" +#include "platform/common/utils.h" /* class AnsiWidget @@ -58,7 +58,7 @@ char *options = NULL; FormList *clickedList = NULL; -#if !defined(_FLTK) +#if !defined(_FLTK) && !defined(_TIZEN) void form_ui::optionsBox(StringList *items) { if (items->size()) { // calculate the size of the options buffer @@ -224,12 +224,13 @@ bool FormLineInput::edit(int key) { bool changed = false; int len = strlen(_buffer); - if (key >= MAK_SPACE && key <= MAK_Z) { + if (key >= MAK_SPACE && key <= 255) { // insert if (len < _maxSize - 1) { _buffer[len] = key; _buffer[++len] = '\0'; - int textWidth = get_text_width(_buffer); + MAExtent textSize = maGetTextSize(_buffer); + int textWidth = EXTENT_X(textSize); if (textWidth > width) { if (textWidth > getScreen()->width) { _scroll++; @@ -248,7 +249,7 @@ bool FormLineInput::edit(int key) { } changed = true; } - } else { + } else if (key) { maShowVirtualKeyboard(); } @@ -304,7 +305,7 @@ AnsiWidget::AnsiWidget(IButtonListener *listener, int width, int height) : for (int i = 0; i < MAX_SCREENS; i++) { _screens[i] = NULL; } - _fontSize = min(width, height) / FONT_FACTOR; + _fontSize = MIN(width, height) / FONT_FACTOR; trace("width: %d height: %d fontSize:%d", _width, height, _fontSize); } @@ -412,7 +413,7 @@ void AnsiWidget::flush(bool force, bool vscroll, int maxPending) { update = (maGetMilliSecondCount() - _front->_dirty >= maxPending); } if (update) { - _front->draw(vscroll); + _front->drawBase(vscroll); } } } @@ -479,6 +480,7 @@ void AnsiWidget::print(const char *str) { break; default: p += _back->print(p, lineHeight) - 1; // allow for p++ + break; }; if (*p == '\0') { @@ -520,7 +522,7 @@ void AnsiWidget::resize(int newWidth, int newHeight) { if (screen) { screen->resize(newWidth, newHeight, _width, _height, lineHeight); if (screen == _front || i < SYSTEM_SCREENS) { - screen->draw(false); + screen->drawBase(false); } } } @@ -900,7 +902,7 @@ void AnsiWidget::screenCommand(char *&p) { case 'R': // redraw all user screens for (int i = 0; i < MAX_SCREENS; i++) { if (_screens[i] != NULL && i < SYSTEM_SCREENS) { - _screens[i]->draw(false); + _screens[i]->drawBase(false); _front = _back = _screens[i]; } } @@ -971,10 +973,10 @@ Screen *AnsiWidget::selectScreen(char *&p) { n = 0; } - x = min(max(x, 0), 100); - y = min(max(y, 0), 100); - w = min(max(w, 0), 100); - h = min(max(h, 0), 100); + x = MIN(MAX(x, 0), 100); + y = MIN(MAX(y, 0), 100); + w = MIN(MAX(w, 0), 100); + h = MIN(MAX(h, 0), 100); result = _screens[n]; @@ -1042,7 +1044,7 @@ void AnsiWidget::swapScreens() { _front = _back; _back = tmp; if (_front->_dirty) { - _front->draw(false); + _front->drawBase(false); } } } diff --git a/src/platform/mosync/ansiwidget.h b/src/platform/common/ansiwidget.h similarity index 98% rename from src/platform/mosync/ansiwidget.h rename to src/platform/common/ansiwidget.h index d8e60e59..ed5bfe3d 100755 --- a/src/platform/mosync/ansiwidget.h +++ b/src/platform/common/ansiwidget.h @@ -13,15 +13,15 @@ #include #endif -#if defined(_FLTK) +#if defined(_FLTK) || defined(_TIZEN) #include "platform/common/maapi.h" #else #include #endif #include "platform/common/StringLib.h" -#include "platform/mosync/screen.h" -#include "platform/mosync/interface.h" +#include "platform/common/screen.h" +#include "platform/common/interface.h" #define MAX_PENDING 250 #define MAX_PENDING_GRAPHICS 25 diff --git a/src/platform/mosync/form_ui.cpp b/src/platform/common/form_ui.cpp similarity index 98% rename from src/platform/mosync/form_ui.cpp rename to src/platform/common/form_ui.cpp index 6d67d005..796030fc 100644 --- a/src/platform/mosync/form_ui.cpp +++ b/src/platform/common/form_ui.cpp @@ -8,7 +8,7 @@ #include "config.h" -#if defined(_FLTK) +#if defined(_FLTK) || defined(_TIZEN) #include "platform/common/maapi.h" #else #include @@ -21,8 +21,8 @@ #include "common/device.h" #include "common/blib_ui.h" -#include "platform/mosync/utils.h" -#include "platform/mosync/form_ui.h" +#include "platform/common/utils.h" +#include "platform/common/form_ui.h" Form *form; @@ -294,6 +294,7 @@ void WidgetData::updateVarFlag() { break; default: orig.i = 0; + break; } } diff --git a/src/platform/mosync/form_ui.h b/src/platform/common/form_ui.h similarity index 97% rename from src/platform/mosync/form_ui.h rename to src/platform/common/form_ui.h index bd25f91b..9bfa181b 100644 --- a/src/platform/mosync/form_ui.h +++ b/src/platform/common/form_ui.h @@ -14,8 +14,8 @@ #include "common/var.h" #include "platform/common/StringLib.h" -#include "platform/mosync/ansiwidget.h" -#include "platform/mosync/interface.h" +#include "platform/common/ansiwidget.h" +#include "platform/common/interface.h" namespace form_ui { AnsiWidget *getOutput(); diff --git a/src/platform/mosync/interface.h b/src/platform/common/interface.h similarity index 96% rename from src/platform/mosync/interface.h rename to src/platform/common/interface.h index 84462576..7d16befe 100755 --- a/src/platform/mosync/interface.h +++ b/src/platform/common/interface.h @@ -1,55 +1,55 @@ -// This file is part of SmallBASIC -// -// Copyright(C) 2001-2012 Chris Warren-Smith. -// -// This program is distributed under the terms of the GPL v2.0 or later -// Download the GNU Public License (GPL) from www.gnu.org -// - -#ifndef INTERFACE_H -#define INTERFACE_H - -#include "platform/common/StringLib.h" - -typedef strlib::List StringList; - -struct IButtonListener { - virtual ~IButtonListener() {} - virtual void buttonClicked(const char *action) = 0; -}; - -struct IFormWidgetListModel { - virtual ~IFormWidgetListModel() {} - virtual const char *getTextAt(int index) = 0; - virtual int getIndex(const char *label) = 0; - virtual int rows() const = 0; - virtual int selected() const = 0; - virtual void selected(int index) = 0; -}; - -struct IFormWidget { - virtual ~IFormWidget() {} - virtual bool edit(int key) = 0; - virtual IFormWidgetListModel *getList() const = 0; - virtual const char *getText() const = 0; - virtual void setText(const char *text) = 0; - virtual void setListener(IButtonListener *listener) = 0; - virtual int getX() = 0; - virtual int getY() = 0; - virtual int getW() = 0; - virtual int getH() = 0; - virtual void setX(int x) = 0; - virtual void setY(int y) = 0; - virtual void setW(int w) = 0; - virtual void setH(int h) = 0; -}; - -namespace form_ui { - bool isRunning(); - bool isBreak(); - void processEvents(); - void buttonClicked(const char *url); - void optionsBox(StringList *items); -}; - -#endif +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2012 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#ifndef INTERFACE_H +#define INTERFACE_H + +#include "platform/common/StringLib.h" + +typedef strlib::List StringList; + +struct IButtonListener { + virtual ~IButtonListener() {} + virtual void buttonClicked(const char *action) = 0; +}; + +struct IFormWidgetListModel { + virtual ~IFormWidgetListModel() {} + virtual const char *getTextAt(int index) = 0; + virtual int getIndex(const char *label) = 0; + virtual int rows() const = 0; + virtual int selected() const = 0; + virtual void selected(int index) = 0; +}; + +struct IFormWidget { + virtual ~IFormWidget() {} + virtual bool edit(int key) = 0; + virtual IFormWidgetListModel *getList() const = 0; + virtual const char *getText() const = 0; + virtual void setText(const char *text) = 0; + virtual void setListener(IButtonListener *listener) = 0; + virtual int getX() = 0; + virtual int getY() = 0; + virtual int getW() = 0; + virtual int getH() = 0; + virtual void setX(int x) = 0; + virtual void setY(int y) = 0; + virtual void setW(int w) = 0; + virtual void setH(int h) = 0; +}; + +namespace form_ui { + bool isRunning(); + bool isBreak(); + void processEvents(); + void buttonClicked(const char *url); + void optionsBox(StringList *items); +}; + +#endif diff --git a/src/platform/common/maapi.h b/src/platform/common/maapi.h index 8bc2dfd3..555cd877 100755 --- a/src/platform/common/maapi.h +++ b/src/platform/common/maapi.h @@ -1,316 +1,338 @@ -/* - Copyright (C) 2009 Mobile Sorcery AB - - This program is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License, version 2, as published by - the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the Free - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#if !defined(MAAPI_H) -#define MAAPI_H - -#include - -#define EXTENT_Y(e) ((short)(e)) -#define EXTENT_X(e) ((short)((e) >> 16)) -#define TRANS_NONE 0 -#define FONT_TYPE_SERIF 0 -#define FONT_TYPE_SANS_SERIF 1 -#define FONT_TYPE_MONOSPACE 2 -#define FONT_STYLE_NORMAL 0 -#define FONT_STYLE_BOLD 1 -#define FONT_STYLE_ITALIC 2 -#define HANDLE_LOCAL 0 -#define RES_OUT_OF_MEMORY -1 -#define RES_BAD_INPUT -2 -#define RES_OK 1 -#define HANDLE_SCREEN 0 -#define RES_FONT_OK 1 -#define MAK_SPACE 32 -#define MAK_Z 122 -#define MAK_CLEAR 12 -#define EVENT_TYPE_POINTER_PRESSED 8 -#define EVENT_TYPE_POINTER_RELEASED 9 -#define EVENT_TYPE_POINTER_DRAGGED 10 - -#ifndef _WCHAR_DEFINED -#define _WCHAR_DEFINED -typedef wchar_t wchar; -#endif //_WCHAR_DEFINED - -#ifndef _SYSV_TYPES_DEFINED -#define _SYSV_TYPES_DEFINED -typedef unsigned short ushort; -typedef unsigned int uint; -#endif //_SYSV_TYPES_DEFINED - -typedef int MAExtent; -typedef void* MAAddress; -typedef intptr_t MAHandle; - -typedef struct MARect { - int left; - int top; - int width; - int height; -} MARect; - -typedef struct MAPoint2d { - int x; - int y; -} MAPoint2d; - -/** - * \brief An event; a message indicating that something has happened, e.g. that a key has been pressed. - */ -typedef struct MAEvent { - /** - * One of the \link #EVENT_TYPE_CLOSE EVENT_TYPE \endlink constants. - */ - int type; - union { - struct { - /** - * In POINTER events, this will be the location of the pointer. - */ - MAPoint2d point; - }; - }; -} MAEvent; - -/** - * Deletes a loaded font - * \param 'font' A font handle - * \return RES_FONT_OK, RES_FONT_INVALID_HANDLE, or RES_FONT_DELETE_DENIED. - */ -int maFontDelete(MAHandle font); - -/** - * Sets the color used by drawing functions. Returns previous color. Initial color is 0 (black). - * \param rgb A color in RGB8 format (0xRRGGBB). The top byte is ignored. - */ -int maSetColor(int rgb); - -/** - * Sets the clipping rectangle for the current draw target. - * The screen and every drawable image each maintains a clipping rectangle. - * Drawing operations have no effect outside the clipping rectangle. - * The default clipping rectangle covers the entire draw target, so that - * clipping occurs at the draw target's edges. - */ -void maSetClipRect(int left, int top, int width, int height); - -/** - * Draws a single pixel using the current color. - * \see maSetColor() - */ -void maPlot(int posX, int posY); - -/** - * Draws a line using the current color. - * \see maSetColor() - */ -void maLine(int startX, int startY, int endX, int endY); - -/** - * Draws a filled rectangle using the current color. - * Width and height must be greater than zero. - * \see maSetColor() - */ -void maFillRect(int left, int top, int width, int height); - -/** - * Draws Latin-1 text using the current color. - * The coordinates are the top-left corner of the text's bounding box. - * \see maSetColor() - */ -void maDrawText(int left, int top, const char* str); - -/** - * Copies the back buffer to the physical screen. - */ -void maUpdateScreen(void); - -/** - * Normally, a phone's backlight turns itself off after - * a few seconds of the user not pressing any keys. - * To avoid this behaviour, call this function periodically. - * As the timeout period is different for every device, and sometimes even user-configurable, - * it's recommended that you call this function at least once every 500 milliseconds - * to ensure that the light stays on at all times. - */ -void maResetBacklight(void); - -/** - * Returns the size in pixels of Latin-1 text as it would appear on-screen. - */ -MAExtent maGetTextSize(const char* str); - -/** - * Returns the screen size. - * Returns the screen size. - */ -MAExtent maGetScrSize(void); - -/** - * Returns a handle to one of the default fonts of the device, in the style and size you specify. - * \param 'type' The type of the font, can be FONT_TYPE_[SANS_SERIF,SERIF,MONOSPACE]. - * \param 'style' The style of the font, can be FONT_STYLE_[NORMAL,BOLD,ITALIC]. - * \param 'size' The size of the font. - * \return The handle to the font, RES_FONT_NO_TYPE_STYLE_COMBINATION, or RES_FONT_INVALID_SIZE. - */ -MAHandle maFontLoadDefault(int type, int style, int size); - -/** - * Sets the font to be used with maDrawText and maDrawTextW, and returns the handle - * to the previous font. - * \param 'font' an MAHandle for a font object. - * \return The handle to the previous font, or RES_FONT_INVALID_HANDLE. - */ -MAHandle maFontSetCurrent(MAHandle font); - -/** - * Draws a portion of an image using a transformation. - * \param image The source image. - * \param srcRect The portion of the source image to be drawn. - * Must not exceed the bounds of the source image. - * \param dstPoint The top-left point on the draw target. - * \param transformMode One of the \link #TRANS_NONE TRANS \endlink constants. - * \see maDrawImage - */ -void maDrawImageRegion(MAHandle image, const MARect* srcRect, const MAPoint2d* dstPoint, int transformMode); - -/** - * Creates a drawable image of the specified size. A drawable image has no alpha channel, - * which is to say, no transparency. - * Its initial contents are undefined, so you should draw onto the entire surface to - * be sure what will happen when you draw this image onto something else. - * \param placeholder The resource handle of the new image. - * \param width Width, in pixels, of the new image. Must be \> 0. - * \param height Height, in pixels, of the new image. Must be \> 0. - * \see maSetDrawTarget() - * \returns #RES_OK if succeded and #RES_OUT_OF_MEMORY if failed. - */ -int maCreateDrawableImage(MAHandle placeholder, int width, int height); - -/** - * Creates a new placeholder and returns the handle to it. - */ -MAHandle maCreatePlaceholder(void); - -/** - * Releases a handle returned by maCreatePlaceholder(). - * If the handle refers to an object, such as an image or a data object, - * that object is destroyed, as if maDestroyObject() had been called. - * - * The released handle may be reused by the system - * and returned by future calls to maCreatePlaceholder(), - * or by other system functions that allocate resources dynamically. - * - * This function is preferred to maDestroyObject(), unless you need - * to reuse the handle. - * - * Attempting to destroy a handle that has already been released, - * or was not returned by maCreatePlaceholder(), will cause a MoSync Panic. - * - * @param handle The handle to be released. - */ -void maDestroyPlaceholder(MAHandle handle); - -/** - * Copies an image into an array of ints that represent pixels in ARGB format. - * The destination rectangle is defined as { 0,0, \a srcRect.width, \a srcRect.height }. - * Parts of the destination array that are outside the destination rectangle are not modified. - * If \a srcRect is outside the bounds of the source image, - * or if \a srcRect.width is greater than \a scanlength, a MoSync Panic is thrown. - * \param image The handle to the source image. - * \param dst The address of the destination array. - * \param scanlength The width of the image, in pixels, represented by the destination array. - * \param srcRect The portion of the source image to be copied. - */ -void maGetImageData(MAHandle image, void* dst, const MARect* srcRect, int scanlength); - -/** - * Sets the current draw target. - * The handle must be a drawable image or #HANDLE_SCREEN, which represents the back buffer. - * The initial draw target is the back buffer. - * If an image is set as draw target, its object handle goes into flux, which prevents - * its destruction or use as a source in maDrawImage. When a different draw target is set, - * the image's handle is restored. Returns the the previously set draw target. - * \see maCreateDrawableImage() - */ -MAHandle maSetDrawTarget(MAHandle image); - -/** - * Returns the number of milliseconds that has passed since some unknown point in time. - * Accuracy is platform-specific, but should be better than 20 ms. - */ -int maGetMilliSecondCount(void); - -/** - * Shows the virtual keyboard. - */ -int maShowVirtualKeyboard(void); - -/** - * There is a FIFO buffer that contains up to #EVENT_BUFFER_SIZE events. - * Each event has a type. Some types have additional data. - * - * This function retrieves the next event, unless the queue is empty. - * Use maWait() to wait until more events are available. - * \param event Pointer to an MAEvent struct that will be filled with the next event. - * - * When the \link #EVENT_TYPE_CLOSE Close event \endlink is posted, - * you must call maExit as soon as possible, or - * your program will be forcibly terminated. The timeout is device-dependent, but - * never longer than #EVENT_CLOSE_TIMEOUT milliseconds. - * - * After the Close event has been posted, most syscalls will stop working, - * returning default values and doing nothing. - * Only the following groups of functions are guaranteed to remain operational: - * Memory management, math, Resource management, Store, time, logging, maExit() and maPanic(). - * - * \note Not all platforms have the capability to generate a Close event. - * You must always provide another way for the user to exit your application. - * - * \returns \> 0 on success, or zero if the buffer is empty. - */ -int maGetEvent(MAEvent* event); - -/** - * Suspends execution until there is an event in the buffer, - * or \a timeout milliseconds have passed. A timeout <= 0 is considered infinite. - * Timer accuracy is platform-specific, but should be better than 20 ms. - * - * Use this function rather than idle loops to save CPU/battery power. - * \see maGetEvent() - */ -void maWait(int timeout); - -/** - * Displays a message to the user. - * It contains optional title, message and 3 buttons for selection. - * On Android the buttons point to a positive, negative or neutral action. - * When one of the buttons are clicked the alert is automatically dismissed. - * When a selection is made a #EVENT_TYPE_ALERT event is sent with the button index. - * \param title The title of the message box shown. - * \param message The message should be short, not more than 40 characters, - * to ensure its visibility on all screen sizes. - * \param button1 The text on the first button. On Android it indicates a positive selection. - * \param button2 The text on the second button. On Android it indicates a neutral selection. - * \param button3 The text on the third button. On Android it indicates that a negative selection. - */ -void maAlert(const char* title, const char* message, const char* button1, - const char* button2, const char* button3); - -#endif +/* + Copyright (C) 2009 Mobile Sorcery AB + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License, version 2, as published by + the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#if !defined(MAAPI_H) +#define MAAPI_H + +#include + +#define EXTENT_Y(e) ((short)(e)) +#define EXTENT_X(e) ((short)((e) >> 16)) +#define TRANS_NONE 0 +#define FONT_TYPE_SERIF 0 +#define FONT_TYPE_SANS_SERIF 1 +#define FONT_TYPE_MONOSPACE 2 +// same values as tizen enum FontStyle +#define FONT_STYLE_NORMAL 0x0001 +#define FONT_STYLE_BOLD 0x0002 +#define FONT_STYLE_ITALIC 0x0004 +#define HANDLE_LOCAL 0 +#define RES_OUT_OF_MEMORY -1 +#define RES_BAD_INPUT -2 +#define RES_OK 1 +#define HANDLE_SCREEN 0 +#define RES_FONT_OK 1 +#define MAK_SPACE 32 +#define MAK_Z 122 +#define MAK_CLEAR 12 +#define MAK_MENU 293 +#define EVENT_TYPE_POINTER_PRESSED 8 +#define EVENT_TYPE_POINTER_RELEASED 9 +#define EVENT_TYPE_POINTER_DRAGGED 10 +#define EVENT_TYPE_KEY_PRESSED 11 +#define EVENT_TYPE_OPTIONS_BOX_BUTTON_CLICKED 41 +#define EVENT_TYPE_SCREEN_CHANGED 21 + +#ifndef _WCHAR_DEFINED +#define _WCHAR_DEFINED +typedef wchar_t wchar; +#endif //_WCHAR_DEFINED + +#ifndef _SYSV_TYPES_DEFINED +#define _SYSV_TYPES_DEFINED +typedef unsigned short ushort; +typedef unsigned int uint; +#endif //_SYSV_TYPES_DEFINED + +typedef int MAExtent; +typedef void* MAAddress; +typedef intptr_t MAHandle; + +typedef struct MARect { + int left; + int top; + int width; + int height; +} MARect; + +typedef struct MAPoint2d { + int x; + int y; +} MAPoint2d; + +/** + * \brief An event; a message indicating that something has happened, e.g. that a key has been pressed. + */ +typedef struct MAEvent { + /** + * One of the \link #EVENT_TYPE_CLOSE EVENT_TYPE \endlink constants. + */ + int type; + union { + struct { + /** + * In KEY events, this will be one of the \link #MAK_UNKNOWN MAK \endlink constants. + */ + int key; + + /** + * In KEY events, this will be the native keycode. + */ + int nativeKey; + }; + + struct { + /** + * In POINTER events, this will be the location of the pointer. + */ + MAPoint2d point; + }; + + /** + * #EVENT_TYPE_OPTIONS_BOX_BUTTON_CLICKED event, contains the index of the selected option. + */ + int optionsBoxButtonIndex; + }; +} MAEvent; + +/** + * Deletes a loaded font + * \param 'font' A font handle + * \return RES_FONT_OK, RES_FONT_INVALID_HANDLE, or RES_FONT_DELETE_DENIED. + */ +int maFontDelete(MAHandle font); + +/** + * Sets the color used by drawing functions. Returns previous color. Initial color is 0 (black). + * \param rgb A color in RGB8 format (0xRRGGBB). The top byte is ignored. + */ +int maSetColor(int rgb); + +/** + * Sets the clipping rectangle for the current draw target. + * The screen and every drawable image each maintains a clipping rectangle. + * Drawing operations have no effect outside the clipping rectangle. + * The default clipping rectangle covers the entire draw target, so that + * clipping occurs at the draw target's edges. + */ +void maSetClipRect(int left, int top, int width, int height); + +/** + * Draws a single pixel using the current color. + * \see maSetColor() + */ +void maPlot(int posX, int posY); + +/** + * Draws a line using the current color. + * \see maSetColor() + */ +void maLine(int startX, int startY, int endX, int endY); + +/** + * Draws a filled rectangle using the current color. + * Width and height must be greater than zero. + * \see maSetColor() + */ +void maFillRect(int left, int top, int width, int height); + +/** + * Draws Latin-1 text using the current color. + * The coordinates are the top-left corner of the text's bounding box. + * \see maSetColor() + */ +void maDrawText(int left, int top, const char* str); + +/** + * Copies the back buffer to the physical screen. + */ +void maUpdateScreen(void); + +/** + * Normally, a phone's backlight turns itself off after + * a few seconds of the user not pressing any keys. + * To avoid this behaviour, call this function periodically. + * As the timeout period is different for every device, and sometimes even user-configurable, + * it's recommended that you call this function at least once every 500 milliseconds + * to ensure that the light stays on at all times. + */ +void maResetBacklight(void); + +/** + * Returns the size in pixels of Latin-1 text as it would appear on-screen. + */ +MAExtent maGetTextSize(const char* str); + +/** + * Returns the screen size. + * Returns the screen size. + */ +MAExtent maGetScrSize(void); + +/** + * Returns a handle to one of the default fonts of the device, in the style and size you specify. + * \param 'type' The type of the font, can be FONT_TYPE_[SANS_SERIF,SERIF,MONOSPACE]. + * \param 'style' The style of the font, can be FONT_STYLE_[NORMAL,BOLD,ITALIC]. + * \param 'size' The size of the font. + * \return The handle to the font, RES_FONT_NO_TYPE_STYLE_COMBINATION, or RES_FONT_INVALID_SIZE. + */ +MAHandle maFontLoadDefault(int type, int style, int size); + +/** + * Sets the font to be used with maDrawText and maDrawTextW, and returns the handle + * to the previous font. + * \param 'font' an MAHandle for a font object. + * \return The handle to the previous font, or RES_FONT_INVALID_HANDLE. + */ +MAHandle maFontSetCurrent(MAHandle font); + +/** + * Draws a portion of an image using a transformation. + * \param image The source image. + * \param srcRect The portion of the source image to be drawn. + * Must not exceed the bounds of the source image. + * \param dstPoint The top-left point on the draw target. + * \param transformMode One of the \link #TRANS_NONE TRANS \endlink constants. + * \see maDrawImage + */ +void maDrawImageRegion(MAHandle image, const MARect* srcRect, const MAPoint2d* dstPoint, int transformMode); + +/** + * Creates a drawable image of the specified size. A drawable image has no alpha channel, + * which is to say, no transparency. + * Its initial contents are undefined, so you should draw onto the entire surface to + * be sure what will happen when you draw this image onto something else. + * \param placeholder The resource handle of the new image. + * \param width Width, in pixels, of the new image. Must be \> 0. + * \param height Height, in pixels, of the new image. Must be \> 0. + * \see maSetDrawTarget() + * \returns #RES_OK if succeded and #RES_OUT_OF_MEMORY if failed. + */ +int maCreateDrawableImage(MAHandle placeholder, int width, int height); + +/** + * Creates a new placeholder and returns the handle to it. + */ +MAHandle maCreatePlaceholder(void); + +/** + * Releases a handle returned by maCreatePlaceholder(). + * If the handle refers to an object, such as an image or a data object, + * that object is destroyed, as if maDestroyObject() had been called. + * + * The released handle may be reused by the system + * and returned by future calls to maCreatePlaceholder(), + * or by other system functions that allocate resources dynamically. + * + * This function is preferred to maDestroyObject(), unless you need + * to reuse the handle. + * + * Attempting to destroy a handle that has already been released, + * or was not returned by maCreatePlaceholder(), will cause a MoSync Panic. + * + * @param handle The handle to be released. + */ +void maDestroyPlaceholder(MAHandle handle); + +/** + * Copies an image into an array of ints that represent pixels in ARGB format. + * The destination rectangle is defined as { 0,0, \a srcRect.width, \a srcRect.height }. + * Parts of the destination array that are outside the destination rectangle are not modified. + * If \a srcRect is outside the bounds of the source image, + * or if \a srcRect.width is greater than \a scanlength, a MoSync Panic is thrown. + * \param image The handle to the source image. + * \param dst The address of the destination array. + * \param scanlength The width of the image, in pixels, represented by the destination array. + * \param srcRect The portion of the source image to be copied. + */ +void maGetImageData(MAHandle image, void* dst, const MARect* srcRect, int scanlength); + +/** + * Sets the current draw target. + * The handle must be a drawable image or #HANDLE_SCREEN, which represents the back buffer. + * The initial draw target is the back buffer. + * If an image is set as draw target, its object handle goes into flux, which prevents + * its destruction or use as a source in maDrawImage. When a different draw target is set, + * the image's handle is restored. Returns the the previously set draw target. + * \see maCreateDrawableImage() + */ +MAHandle maSetDrawTarget(MAHandle image); + +/** + * Returns the number of milliseconds that has passed since some unknown point in time. + * Accuracy is platform-specific, but should be better than 20 ms. + */ +int maGetMilliSecondCount(void); + +/** + * Shows the virtual keyboard. + */ +int maShowVirtualKeyboard(void); + +/** + * There is a FIFO buffer that contains up to #EVENT_BUFFER_SIZE events. + * Each event has a type. Some types have additional data. + * + * This function retrieves the next event, unless the queue is empty. + * Use maWait() to wait until more events are available. + * \param event Pointer to an MAEvent struct that will be filled with the next event. + * + * When the \link #EVENT_TYPE_CLOSE Close event \endlink is posted, + * you must call maExit as soon as possible, or + * your program will be forcibly terminated. The timeout is device-dependent, but + * never longer than #EVENT_CLOSE_TIMEOUT milliseconds. + * + * After the Close event has been posted, most syscalls will stop working, + * returning default values and doing nothing. + * Only the following groups of functions are guaranteed to remain operational: + * Memory management, math, Resource management, Store, time, logging, maExit() and maPanic(). + * + * \note Not all platforms have the capability to generate a Close event. + * You must always provide another way for the user to exit your application. + * + * \returns \> 0 on success, or zero if the buffer is empty. + */ +int maGetEvent(MAEvent* event); + +/** + * Suspends execution until there is an event in the buffer, + * or \a timeout milliseconds have passed. A timeout <= 0 is considered infinite. + * Timer accuracy is platform-specific, but should be better than 20 ms. + * + * Use this function rather than idle loops to save CPU/battery power. + * \see maGetEvent() + */ +void maWait(int timeout); + +/** + * Displays a message to the user. + * It contains optional title, message and 3 buttons for selection. + * On Android the buttons point to a positive, negative or neutral action. + * When one of the buttons are clicked the alert is automatically dismissed. + * When a selection is made a #EVENT_TYPE_ALERT event is sent with the button index. + * \param title The title of the message box shown. + * \param message The message should be short, not more than 40 characters, + * to ensure its visibility on all screen sizes. + * \param button1 The text on the first button. On Android it indicates a positive selection. + * \param button2 The text on the second button. On Android it indicates a neutral selection. + * \param button3 The text on the third button. On Android it indicates that a negative selection. + */ +void maAlert(const char* title, const char* message, const char* button1, + const char* button2, const char* button3); + +#endif diff --git a/src/platform/mosync/screen.cpp b/src/platform/common/screen.cpp similarity index 98% rename from src/platform/mosync/screen.cpp rename to src/platform/common/screen.cpp index c8301d2a..94fe66d6 100644 --- a/src/platform/mosync/screen.cpp +++ b/src/platform/common/screen.cpp @@ -8,7 +8,7 @@ #include -#include "platform/mosync/screen.h" +#include "platform/common/screen.h" #define WHITE 15 #define SCROLL_IND 4 @@ -295,7 +295,7 @@ void GraphicScreen::clear() { Screen::clear(); } -void GraphicScreen::draw(bool vscroll) { +void GraphicScreen::drawBase(bool vscroll) { MARect srcRect; MAPoint2d dstPoint; srcRect.left = 0; @@ -445,13 +445,13 @@ void GraphicScreen::resize(int newWidth, int newHeight, int oldWidth, int oldHei MARect srcRect; MAPoint2d dstPoint; MAHandle newImage = maCreatePlaceholder(); - int newImageWidth = max(newWidth, _imageWidth); - int newImageHeight = max(newHeight, _imageHeight); + int newImageWidth = MAX(newWidth, _imageWidth); + int newImageHeight = MAX(newHeight, _imageHeight); srcRect.left = 0; srcRect.top = 0; - srcRect.width = min(_imageWidth, newImageWidth); - srcRect.height = min(_imageHeight, newImageHeight); + srcRect.width = MIN(_imageWidth, newImageWidth); + srcRect.height = MIN(_imageHeight, newImageHeight); dstPoint.x = 0; dstPoint.y = 0; @@ -477,7 +477,7 @@ void GraphicScreen::resize(int newWidth, int newHeight, int oldWidth, int oldHei width = newWidth; height = newHeight; if (!fullscreen) { - draw(false); + drawBase(false); } } @@ -606,14 +606,14 @@ void GraphicScreen::setPixel(int x, int y, int c) { struct LineShape : Shape { LineShape(int x, int y, int w, int h) : Shape(x, y, w, h) {} - void draw() { + void draw(int ax, int ay) { maLine(x, y, width, height); } }; struct RectShape : Shape { RectShape(int x, int y, int w, int h) : Shape(x, y, w, h) {} - void draw() { + void draw(int ax, int ay) { int x1 = x; int y1 = y; int x2 = x + width; @@ -627,7 +627,7 @@ struct RectShape : Shape { struct RectFilledShape : Shape { RectFilledShape(int x, int y, int w, int h) : Shape(x, y, w, h) {} - void draw() { + void draw(int ax, int ay) { maFillRect(x, y, width, height); } }; @@ -674,7 +674,7 @@ void TextScreen::clear() { // // draw the text // -void TextScreen::draw(bool vscroll) { +void TextScreen::drawBase(bool vscroll) { // prepare escape state variables bool bold = false; bool italic = false; diff --git a/src/platform/mosync/screen.h b/src/platform/common/screen.h similarity index 95% rename from src/platform/mosync/screen.h rename to src/platform/common/screen.h index a59d4bca..4cf56dc5 100755 --- a/src/platform/mosync/screen.h +++ b/src/platform/common/screen.h @@ -13,7 +13,7 @@ #include #endif -#if defined(_FLTK) +#if defined(_FLTK) || defined(_TIZEN) #include "platform/common/maapi.h" #define LINE_SPACING 0 #else @@ -22,7 +22,7 @@ #endif #include "platform/common/StringLib.h" -#include "platform/mosync/utils.h" +#include "platform/common/utils.h" using namespace strlib; @@ -36,6 +36,8 @@ struct Shape { virtual ~Shape() {} virtual void draw(int x, int y) {} + int w() { return width; } + int h() { return height; } int x, y, width, height; }; @@ -46,7 +48,7 @@ struct Screen : public Shape { virtual void calcTab() = 0; virtual bool construct() = 0; virtual void clear(); - virtual void draw(bool vscroll) = 0; + virtual void drawBase(bool vscroll) = 0; virtual void drawInto(bool background=false); virtual void drawLine(int x1, int y1, int x2, int y2) = 0; virtual void drawRect(int x1, int y1, int x2, int y2) = 0; @@ -82,7 +84,7 @@ struct Screen : public Shape { int _curY; int _dirty; int _linePadding; - List _shapes; + strlib::List _shapes; String _label; }; @@ -93,7 +95,7 @@ struct GraphicScreen : public Screen { void calcTab(); bool construct(); void clear(); - void draw(bool vscroll); + void drawBase(bool vscroll); void drawInto(bool background=false); void newLine(int lineHeight); void drawLine(int x1, int y1, int x2, int y2); @@ -194,8 +196,9 @@ struct TextSeg { } // width of this segment in pixels - int width() const { - return get_text_width(_str); + int width() const { + MAExtent textSize = maGetTextSize(_str); + return EXTENT_X(textSize); } // number of chars in this segment @@ -308,7 +311,7 @@ struct TextScreen : public Screen { void calcTab(); bool construct(); void clear(); - void draw(bool vscroll); + void drawBase(bool vscroll); void drawText(const char *text, int len, int x, int lineHeight); void drawLine(int x1, int y1, int x2, int y2); void drawRect(int x1, int y1, int x2, int y2); diff --git a/src/platform/common/system.cpp b/src/platform/common/system.cpp new file mode 100644 index 00000000..cee6e4bd --- /dev/null +++ b/src/platform/common/system.cpp @@ -0,0 +1,385 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#include +#include +#include + +#include "platform/common/system.h" +#include "common/sbapp.h" +#include "common/sys.h" +#include "common/smbas.h" +#include "common/osd.h" +#include "common/device.h" +#include "common/blib_ui.h" + +#define SYSTEM_MENU "\033[ OConsole|Show Keypad|View Source|Restart" +#define MENU_CONSOLE 0 +#define MENU_KEYPAD 1 +#define MENU_SOURCE 2 +#define MENU_RESTART 3 +#define MENU_ZOOM_UP 4 +#define MENU_ZOOM_DN 5 +#define FONT_SCALE_INTERVAL 10 +#define FONT_MIN 20 +#define FONT_MAX 200 +#define EVENT_CHECK_EVERY 2000 +#define EVENT_MAX_BURN_TIME 30 + +System::System() : + _output(NULL), + _state(kInitState), + _lastEventTime(0), + _eventTicks(0), + _touchX(-1), + _touchY(-1), + _touchCurX(-1), + _touchCurY(-1), + _initialFontSize(0), + _fontScale(100), + _drainError(false), + _systemMenu(false), + _systemScreen(false), + _mainBas(false), + _programSrc(NULL) { +} + +System::~System() { + delete [] _programSrc; +} + +int System::getPen(int code) { + int result = 0; + MAEvent event; + if (!isClosing()) { + switch (code) { + case 0: + // UNTIL PEN(0) - wait until click or move + event = getNextEvent(); + // fallthru + + case 3: // returns true if the pen is down (and save curpos) + if (_touchX != -1 && _touchY != -1) { + result = 1; + } else { + osd_events(0); + } + break; + + case 1: // last pen-down x + result = _touchX; + break; + + case 2: // last pen-down y + result = _touchY; + break; + + case 4: // cur pen-down x + case 10: + result = _touchCurX; + break; + + case 5: // cur pen-down y + case 11: + result = _touchCurY; + break; + } + } + return result; +} + +char *System::getText(char *dest, int maxSize) { + int x = _output->getX(); + int y = _output->getY(); + int w = EXTENT_X(maGetTextSize("YNM")); + int h = _output->textHeight(); + + dest[0] = '\0'; + _state = kModalState; + IFormWidget *formWidget = _output->createLineInput(dest, maxSize, x, y, w, h); + _output->redraw(); + maShowVirtualKeyboard(); + + while (isModal()) { + MAEvent event = getNextEvent(); + if (event.type == EVENT_TYPE_KEY_PRESSED) { + dev_clrkb(); + if (isModal()) { + if (event.key == SB_KEY_ENTER) { + _state = kRunState; + } else { + _output->edit(formWidget, event.key); + } + } + } + } + + // paint the widget result onto the backing screen + if (dest[0]) { + _output->print(dest); + } + + delete formWidget; + return dest; +} + +void System::handleMenu(int menuId) { + int fontSize = _output->getFontSize(); + _systemMenu = false; + + switch (menuId) { + case MENU_SOURCE: + showSystemScreen(true); + break; + case MENU_CONSOLE: + showSystemScreen(false); + break; + case MENU_KEYPAD: + maShowVirtualKeyboard(); + break; + case MENU_RESTART: + if (isRunning()) { + brun_break(); + } + _state = kRestartState; + break; + case MENU_ZOOM_UP: + if (_fontScale > FONT_MIN) { + _fontScale -= FONT_SCALE_INTERVAL; + fontSize = (_initialFontSize * _fontScale / 100); + } + break; + case MENU_ZOOM_DN: + if (_fontScale < FONT_MAX) { + _fontScale += FONT_SCALE_INTERVAL; + fontSize = (_initialFontSize * _fontScale / 100); + } + break; + } + + if (fontSize != _output->getFontSize()) { + // restart the shell + _output->setFontSize(fontSize); + if (isRunning()) { + brun_break(); + } + _state = kRestartState; + } + + if (!isRunning()) { + _output->flush(true); + } +} + +void System::resize() { + MAExtent screenSize = maGetScrSize(); + logEntered(); + _output->resize(EXTENT_X(screenSize), EXTENT_Y(screenSize)); + os_graf_mx = _output->getWidth(); + os_graf_my = _output->getHeight(); + dev_pushkey(SB_PKEY_SIZE_CHG); +} + +void System::runMain(const char *mainBasPath) { + logEntered(); + + String activePath = mainBasPath; + _loadPath = mainBasPath; + _mainBas = true; + strcpy(opt_command, "welcome"); + sbasic_main(_loadPath); + + while (!isClosing()) { + if (isRestart()) { + _loadPath = activePath; + _state = kActiveState; + } else { + if (_loadPath.length() > 0) { + _mainBas = false; + activePath = _loadPath; + setPath(_loadPath); + } else { + _mainBas = true; + _loadPath = mainBasPath; + activePath = mainBasPath; + } + } + opt_command[0] = '\0'; + bool success = sbasic_main(_loadPath); + if (!isBack() && !isClosing()) { + // load the next network file without displaying the previous result + bool networkFile = (_loadPath.indexOf("://", 1) != -1); + if (!_mainBas && !networkFile) { + // display an indication the program has completed + showCompletion(success); + } + if (!success) { + // highlight the error + showError(); + } + if (!_mainBas && !networkFile) { + // press back to continue + while (!isBack() && !isClosing() && !isRestart()) { + getNextEvent(); + } + } + } + } +} + +void System::setBack() { + if (_systemScreen) { + // restore user screens00 + _output->print("\033[ SR"); + _systemScreen = false; + } else { + // quit app when shell is active + setExit(_mainBas); + } +} + +bool System::setParentPath() { + bool result = true; + char path[FILENAME_MAX + 1]; + getcwd(path, FILENAME_MAX); + if (!path[0] || strcmp(path, "/") == 0) { + result = false; + } else { + int len = strlen(path); + if (path[len - 1] == '/') { + // eg /sdcard/bas/ + path[len - 1] = '\0'; + } + const char *slash = strrchr(path, '/'); + len = slash - path; + if (!len) { + strcpy(path, "/"); + } else { + path[len] = 0; + } + chdir(path); + } + return result; +} + +void System::setPath(const char *filename) { + if (strstr(filename, "://") == NULL) { + const char *slash = strrchr(filename, '/'); + if (!slash) { + slash = strrchr(filename, '\\'); + } + if (slash) { + int len = slash - filename; + if (len > 0) { + char path[1024]; + strncpy(path, filename, len); + path[len] = 0; + chdir(path); + } + } + } +} + +void System::setRunning(bool running) { + if (running) { + dev_fgcolor = -DEFAULT_FOREGROUND; + dev_bgcolor = -DEFAULT_BACKGROUND; + os_graf_mx = _output->getWidth(); + os_graf_my = _output->getHeight(); + + os_ver = 1; + os_color = 1; + os_color_depth = 16; + + dev_clrkb(); + ui_reset(); + + _output->reset(); + _state = kRunState; + _loadPath.empty(); + _lastEventTime = maGetMilliSecondCount(); + _eventTicks = 0; + _drainError = false; + } else if (!isClosing() && !isRestart() && !isBack()) { + _state = kActiveState; + } +} + +void System::showCompletion(bool success) { + if (success) { + _output->print("\033[ LDone - press back [<-]"); + } else { + _output->print("\033[ LError - see console"); + } + _output->flush(true); +} + +void System::showError() { + _state = kActiveState; + _loadPath.empty(); + showSystemScreen(false); +} + +// detect when we have been called too frequently +void System::showLoadError() { + int now = maGetMilliSecondCount(); + _eventTicks++; + if (now - _lastEventTime >= EVENT_CHECK_EVERY) { + // next time inspection interval + if (_eventTicks >= EVENT_MAX_BURN_TIME) { + _output->print("\033[ LBattery drain"); + _drainError = true; + } else if (_drainError) { + _output->print("\033[ L"); + _drainError = false; + } + _lastEventTime = now; + _eventTicks = 0; + } +} + +void System::showMenu() { + _systemMenu = true; + if (_mainBas) { + char buffer[128]; + sprintf(buffer, "%s|Zoom %d%%|Zoom %d%%", SYSTEM_MENU, + _fontScale - FONT_SCALE_INTERVAL, + _fontScale + FONT_SCALE_INTERVAL); + _output->print(buffer); + } else { + _output->print(SYSTEM_MENU); + } +} + +void System::showSystemScreen(bool showSrc) { + if (showSrc) { + // screen command write screen 2 (\014=CLS) + _output->print("\033[ SW6\014"); + if (_programSrc) { + _output->print(_programSrc); + } + // restore write screen, display screen 6 (source) + _output->print("\033[ Sw; SD6"); + } else { + // screen command display screen 7 (console) + _output->print("\033[ SD7"); + } + _systemScreen = true; +} + + +void System::systemPrint(const char *str) { + if (isSystemScreen()) { + _output->print(str); + } else { + _output->print("\033[ SW7"); + _output->print(str); + _output->print("\033[ Sw"); + } +} + diff --git a/src/platform/common/system.h b/src/platform/common/system.h new file mode 100755 index 00000000..0af08b5f --- /dev/null +++ b/src/platform/common/system.h @@ -0,0 +1,81 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#ifndef SYSTEM_H +#define SYSTEM_H + +#include "platform/common/StringLib.h" +#include "platform/common/ansiwidget.h" + +struct System { + System(); + virtual ~System(); + + int getPen(int code); + char *getText(char *dest, int maxSize); + bool isActive() { return _state != kInitState && _state != kDoneState; } + bool isBack() { return _state == kBackState; } + bool isBreak() { return _state >= kBreakState; } + bool isClosing() { return _state >= kClosingState; } + bool isInitial() { return _state == kInitState; } + bool isModal() { return _state == kModalState; } + bool isRestart() { return _state == kRestartState; } + bool isRunning() { return _state == kRunState || _state == kModalState; } + bool isSystemScreen() { return _systemScreen; } + void setBack(); + void setRunning(bool running); + void systemPrint(const char *msg); + + AnsiWidget *_output; + +protected: + virtual void setExit(bool quit) = 0; + virtual MAEvent getNextEvent() = 0; + + void handleMenu(int menuId); + void resize(); + void runMain(const char *mainBasPath); + void setPath(const char *filename); + bool setParentPath(); + void showCompletion(bool success); + void showError(); + void showLoadError(); + void showSystemScreen(bool showSrc); + void showMenu(); + + enum { + kInitState = 0,// thread not active + kActiveState, // thread activated + kRunState, // program is running + kRestartState, // running program should restart + kModalState, // retrieving user input inside program + kConnState, // retrieving remote program source + kBreakState, // running program should abort + kBackState, // back button detected + kClosingState, // thread is terminating + kDoneState // thread has terminated + } _state; + + + strlib::String _loadPath; + int _lastEventTime; + int _eventTicks; + int _touchX; + int _touchY; + int _touchCurX; + int _touchCurY; + int _initialFontSize; + int _fontScale; + bool _drainError; + bool _systemMenu; + bool _systemScreen; + bool _mainBas; + char *_programSrc; +}; + +#endif diff --git a/src/platform/mosync/utils.h b/src/platform/common/utils.h old mode 100755 new mode 100644 similarity index 75% rename from src/platform/mosync/utils.h rename to src/platform/common/utils.h index ea0b50ac..3c1d7a3c --- a/src/platform/mosync/utils.h +++ b/src/platform/common/utils.h @@ -6,11 +6,20 @@ // Download the GNU Public License (GPL) from www.gnu.org // -#ifndef max -#define max(a,b) ((ab) ? (b) : (a)) +#ifndef MIN + #define MIN(a,b) ((a>b) ? (b) : (a)) #endif #if defined(_FLTK) @@ -23,6 +32,8 @@ #define HANDLE_SCREEN_BUFFER HANDLE_SCREEN #endif +#define USER_MESSAGE_EXIT 1000 + #define OUTSIDE_RECT(px, py, x, y, w, h) \ (px < (x) || py < (y) || px > ((x)+(w)) || py > ((y)+(h))) @@ -36,6 +47,9 @@ #define trace lprintfln #elif defined(_FLTK) extern "C" void trace(const char *format, ...); + #elif defined (_TIZEN) + #include + #define trace AppLog #endif #else #define trace(...) @@ -46,9 +60,8 @@ #define logLeaving() trace("%s leaving (%s %d)", \ __FUNCTION__, __FILE__, __LINE__); -int get_text_width(char *s); -void set_path(const char *filename); -bool set_parent_path(); - #define C_LINKAGE_BEGIN extern "C" { #define C_LINKAGE_END } + +#endif + diff --git a/src/platform/fltk/MainWindow.cxx b/src/platform/fltk/MainWindow.cxx index 74b7e91a..e56db156 100644 --- a/src/platform/fltk/MainWindow.cxx +++ b/src/platform/fltk/MainWindow.cxx @@ -26,7 +26,6 @@ #include "FileWidget.h" #include "common/sbapp.h" #include "platform/common/StringLib.h" -#include "platform/mosync/utils.h" #include "common/sys.h" #include "common/fs_socket_client.h" diff --git a/src/platform/fltk/Makefile.am b/src/platform/fltk/Makefile.am index 792a380d..506477ef 100644 --- a/src/platform/fltk/Makefile.am +++ b/src/platform/fltk/Makefile.am @@ -22,9 +22,9 @@ EXTRA_DIST = \ bin_PROGRAMS = sbasici sbasici_SOURCES = \ - ../mosync/ansiwidget.cpp \ - ../mosync/screen.cpp \ - ../mosync/form_ui.cpp \ + ../common/ansiwidget.cpp \ + ../common/screen.cpp \ + ../common/form_ui.cpp \ ../common/StringLib.cpp \ MosyncWidget.cxx MosyncWidget.h \ HelpWidget.cxx HelpWidget.h \ diff --git a/src/platform/fltk/MosyncWidget.cxx b/src/platform/fltk/MosyncWidget.cxx index 7184cb6d..40cfb4d0 100755 --- a/src/platform/fltk/MosyncWidget.cxx +++ b/src/platform/fltk/MosyncWidget.cxx @@ -20,8 +20,8 @@ #include #include "platform/fltk/MosyncWidget.h" #include "platform/fltk/utils.h" -#include "platform/mosync/ansiwidget.h" -#include "platform/mosync/form_ui.h" +#include "platform/common/ansiwidget.h" +#include "platform/common/form_ui.h" using namespace fltk; @@ -99,7 +99,8 @@ void Canvas::drawPixel(int posX, int posY) { if (posX > -1 && posY > -1 && posX < _img->buffer_width() && posY < _img->buffer_height()) { - U32 *row = (U32 *)_img->linebuffer(posY); + int delta = _img->buffer_linedelta(); + U32 *row = (U32 *) (_img->buffer() + (posY * delta)); row[posX] = drawColorRaw; } #if !defined(_Win32) @@ -162,8 +163,9 @@ int Canvas::getPixel(int x, int y) { int result = 0; if (x > -1 && x < _img->w() && y > -1 && y < _img->h()) { - U32 *pixel = (U32 *)_img->linebuffer(y); - result = pixel[x]; + int delta = _img->buffer_linedelta(); + U32 *row = (U32 *) (_img->buffer() + (y * delta)); + result = row[x]; } return result; } @@ -219,6 +221,13 @@ MosyncWidget::~MosyncWidget() { delete _screen; } +void MosyncWidget::createAnsiWidget() { + _ansiWidget = new AnsiWidget(this, w(), h()); + _ansiWidget->construct(); + _ansiWidget->setTextColor(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); + _ansiWidget->setFontSize(_defsize); +} + void MosyncWidget::layout() { if (_screen != NULL && _ansiWidget != NULL && (layout_damage() & LAYOUT_WH)) { @@ -274,10 +283,7 @@ int MosyncWidget::handle(int e) { drawTarget = _screen; } if (!_ansiWidget) { - _ansiWidget = new AnsiWidget(this, w(), h()); - _ansiWidget->construct(); - _ansiWidget->setTextColor(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); - _ansiWidget->setFontSize(_defsize); + createAnsiWidget(); } break; @@ -318,6 +324,9 @@ void MosyncWidget::buttonClicked(const char *action) { } void MosyncWidget::clearScreen() { + if (!_ansiWidget) { + createAnsiWidget(); + } _ansiWidget->clearScreen(); } @@ -508,14 +517,8 @@ void maDestroyPlaceholder(MAHandle maHandle) { void maGetImageData(MAHandle maHandle, void *dst, const MARect *srcRect, int scanlength) { Canvas *holder = (Canvas *)maHandle; - U32 *dest = (U32 *)dst; - int index = 0; - for (int y = 0; y < srcRect->height && y + srcRect->top < holder->_img->buffer_height(); y++) { - for (int x = 0; x < srcRect->width && x + srcRect->left < holder->_img->buffer_width(); x++) { - U32 *pixel = (U32 *)holder->_img->linebuffer(y + srcRect->top); - dest[index++] = pixel[x + srcRect->left]; - } - } + // maGetImageData is only used for getPixel() + *((int *)dst) = holder->getPixel(srcRect->left, srcRect->top); } MAHandle maSetDrawTarget(MAHandle maHandle) { diff --git a/src/platform/fltk/MosyncWidget.h b/src/platform/fltk/MosyncWidget.h index 3753b78c..bfe82fd6 100755 --- a/src/platform/fltk/MosyncWidget.h +++ b/src/platform/fltk/MosyncWidget.h @@ -14,7 +14,7 @@ #include #include "platform/common/maapi.h" -#include "platform/mosync/interface.h" +#include "platform/common/interface.h" struct AnsiWidget; @@ -77,6 +77,7 @@ class MosyncWidget : public fltk::Widget, IButtonListener { void draw(); void layout(); int handle(int e); + void createAnsiWidget(); void buttonClicked(const char *action); Canvas *_screen; diff --git a/src/platform/fltk/dev_fltk.cxx b/src/platform/fltk/dev_fltk.cxx index 08cd4bb6..6d6e9394 100644 --- a/src/platform/fltk/dev_fltk.cxx +++ b/src/platform/fltk/dev_fltk.cxx @@ -24,8 +24,8 @@ #include "platform/fltk/HelpWidget.h" #include "platform/fltk/TtyWidget.h" #include "platform/fltk/utils.h" -#include "platform/mosync/utils.h" -#include "platform/mosync/interface.h" +#include "platform/common/utils.h" +#include "platform/common/interface.h" #include "common/fs_socket_client.h" #ifdef WIN32 @@ -286,21 +286,7 @@ void osd_setpixel(int x, int y) { } long osd_getpixel(int x, int y) { - int xoffs = 0; - int yoffs = 0; - -#if !defined(WIN32) - // offset x/y as getPixel is relative to the outer window - fltk::Rectangle rc; - wnd->_out->get_absolute_rect(&rc); - xoffs = rc.x(); - yoffs = rc.y(); - - wnd->get_absolute_rect(&rc); - xoffs -= rc.x(); - yoffs -= rc.y(); -#endif - return wnd->_out->getPixel(x + xoffs, y + yoffs); + return wnd->_out->getPixel(x, y); } void osd_line(int x1, int y1, int x2, int y2) { diff --git a/src/platform/fltk/utils.h b/src/platform/fltk/utils.h index ce2c189a..98501299 100755 --- a/src/platform/fltk/utils.h +++ b/src/platform/fltk/utils.h @@ -6,8 +6,8 @@ // Download the GNU Public License (GPL) from www.gnu.org // -#ifndef UTILS_H -#define UTILS_H +#ifndef FLTK_UTILS_H +#define FLTK_UTILS_H #define C_LINKAGE_BEGIN extern "C" { #define C_LINKAGE_END } diff --git a/src/platform/mosync/controller.cpp b/src/platform/mosync/controller.cpp index 5175436e..da64ad8a 100755 --- a/src/platform/mosync/controller.cpp +++ b/src/platform/mosync/controller.cpp @@ -18,7 +18,7 @@ #include #include "platform/mosync/controller.h" -#include "platform/mosync/utils.h" +#include "platform/common/utils.h" #define SYSTEM_MENU "\033[ OConsole|Show Keypad|View Source" #define MENU_CONSOLE 0 diff --git a/src/platform/mosync/dev_mosync.cpp b/src/platform/mosync/dev_mosync.cpp index 4b15c104..0d94bb7a 100755 --- a/src/platform/mosync/dev_mosync.cpp +++ b/src/platform/mosync/dev_mosync.cpp @@ -8,8 +8,8 @@ #include "MAHeaders.h" +#include "platform/common/utils.h" #include "platform/mosync/controller.h" -#include "platform/mosync/utils.h" #include "platform/mosync/form_ui.h" extern Controller *controller; diff --git a/src/platform/mosync/main.cpp b/src/platform/mosync/main.cpp index 03e8730e..f87c5eda 100755 --- a/src/platform/mosync/main.cpp +++ b/src/platform/mosync/main.cpp @@ -9,7 +9,7 @@ #include #include "platform/mosync/controller.h" -#include "platform/mosync/utils.h" +#include "platform/common/utils.h" Controller *controller; diff --git a/src/platform/qt/dev_qt.cpp b/src/platform/qt/dev_qt.cpp index 685688e7..00b11e09 100644 --- a/src/platform/qt/dev_qt.cpp +++ b/src/platform/qt/dev_qt.cpp @@ -64,7 +64,7 @@ int osd_devinit() { // allow the application to set the preferred width and height if ((opt_pref_width || opt_pref_height)) { int delta_x = wnd->width() - wnd->out->width(); - int delta_y = wnd->_height() - wnd->out->_height(); + int delta_y = wnd->height() - wnd->out->height(); if (opt_pref_width < 10) { opt_pref_width = 10; } @@ -75,7 +75,7 @@ int osd_devinit() { } os_graf_mx = wnd->out->width(); - os_graf_my = wnd->out->_height(); + os_graf_my = wnd->out->height(); os_ver = QT_VERSION; os_color = 1; @@ -393,7 +393,7 @@ void dev_image(int handle, int index, int x, int y, int sx, int sy, int w, int h if (img != 0) { // input/read image and display imgw = img->width(); - imgh = img->_height(); + imgh = img->height(); wnd->out->drawImage(img, x, y, sx, sy, (w == 0 ? imgw : w), (h == 0 ? imgh : h)); } } else { @@ -425,7 +425,7 @@ int dev_image_height(int handle, int index) { QImage *img = getImage(filep, index); if (img) { - imgh = img->_height(); + imgh = img->height(); } return imgh; } diff --git a/src/platform/qt/form_ui.cpp b/src/platform/qt/form_ui.cpp index 2fa75b0e..c4edd0d5 100644 --- a/src/platform/qt/form_ui.cpp +++ b/src/platform/qt/form_ui.cpp @@ -496,8 +496,8 @@ void update_widget(QWidget *widget, WidgetInfoPtr inf, QRect &rect) { widget->setFixedWidth(rect.width()); } - if (rect._height() != -1) { - widget->setFixedHeight(rect._height()); + if (rect.height() != -1) { + widget->setFixedHeight(rect.height()); } if (rect.x() < 0) { @@ -509,7 +509,7 @@ void update_widget(QWidget *widget, WidgetInfoPtr inf, QRect &rect) { } form->prev_x = rect.x() + rect.width(); - form->prev_y = rect.y() + rect._height(); + form->prev_y = rect.y() + rect.height(); widget->setGeometry(rect); widget->setProperty("widgetInfo", QVariant::fromValue(inf)); @@ -532,8 +532,8 @@ void update_button(QAbstractButton *widget, WidgetInfoPtr inf, rect.setWidth((int)wnd->out->textWidth(caption) + def_w + (-rect.width() - 1)); } - if (rect._height() < 0) { - rect.setHeight((int)(wnd->out->textHeight() + def_h + (-rect._height() - 1))); + if (rect.height() < 0) { + rect.setHeight((int)(wnd->out->textHeight() + def_h + (-rect.height() - 1))); } update_widget(widget, inf, rect); @@ -545,7 +545,7 @@ void update_button(QAbstractButton *widget, WidgetInfoPtr inf, void form_create() { if (form == 0) { form = new Form(wnd->out->x() + 2, - wnd->out->y() + 2, wnd->out->width() - 2, wnd->out->_height() - 2); + wnd->out->y() + 2, wnd->out->width() - 2, wnd->out->height() - 2); } // form->begin(); mode = m_init; @@ -554,7 +554,7 @@ void form_create() { // prepare the form for display void form_init() { if (form) { - form->setGeometry(0, 0, form->width(), form->_height()); + form->setGeometry(0, 0, form->width(), form->height()); } } @@ -701,7 +701,7 @@ void cmd_text() { inf->var = v; inf->type = ctrl_text; update_widget(widget, inf, rect); - if (rect._height() > (wnd->out->textHeight() + BN_H)) { + if (rect.height() > (wnd->out->textHeight() + BN_H)) { // widget->type(QPlainTextEdit::MULTILINE | QPlainTextEdit::WORDWRAP); } } diff --git a/src/platform/qt/form_ui.h b/src/platform/qt/form_ui.h index 9a007364..d66c7d4c 100644 --- a/src/platform/qt/form_ui.h +++ b/src/platform/qt/form_ui.h @@ -7,8 +7,8 @@ // #include "config.h" -#include "sys.h" -#include "var.h" +#include "common/sys.h" +#include "common/var.h" // whether a widget event has fired bool form_event(); diff --git a/src/platform/qt/sbasic.pro b/src/platform/qt/sbasic.pro index 7f89b5f0..e3732662 100644 --- a/src/platform/qt/sbasic.pro +++ b/src/platform/qt/sbasic.pro @@ -33,8 +33,8 @@ HEADERS += mainwindow.h \ httpfile.h \ fixedlayout.h -INCLUDEPATH += ../common ../../../ +INCLUDEPATH += ../../common ../.. ../../.. -LIBS += -L../common -lsb_common +LIBS += -L../../common -lsb_common RESOURCES += sbasic.qrc diff --git a/src/platform/qt/sbasic.qrc b/src/platform/qt/sbasic.qrc index af5623c7..fb77f6be 100644 --- a/src/platform/qt/sbasic.qrc +++ b/src/platform/qt/sbasic.qrc @@ -10,6 +10,6 @@ images/previous.png images/refresh.png images/stop.png - ../../images/smallbasic.png + ../../../images/sb-desktop-64x64.png diff --git a/src/platform/sdl/Makefile.am b/src/platform/sdl/Makefile.am index b1136559..82065507 100644 --- a/src/platform/sdl/Makefile.am +++ b/src/platform/sdl/Makefile.am @@ -5,7 +5,7 @@ # Download the GNU Public License (GPL) from www.gnu.org # -AM_CPPFLAGS = -I../../common -I. @PACKAGE_CFLAGS@ +AM_CPPFLAGS = -I$(top_srcdir)/src -I. @PACKAGE_CFLAGS@ EXTRA_DIST = \ fixedfont.xpm \ @@ -19,6 +19,6 @@ sbasicg_SOURCES = \ dev_sdl.c \ blib_sdl_ui.cpp -sbasicg_LDADD = -L$(top_srcdir)/src -lsb_common @PACKAGE_LIBS@ +sbasicg_LDADD = -L$(top_srcdir)/src/common -lsb_common @PACKAGE_LIBS@ -sbasicg_DEPENDENCIES = ../../common/libsb_common.a +sbasicg_DEPENDENCIES = $(top_srcdir)/src/common/libsb_common.a diff --git a/src/platform/sdl/blib_sdl_ui.cpp b/src/platform/sdl/blib_sdl_ui.cpp index 536d9eaa..cb66c2a8 100644 --- a/src/platform/sdl/blib_sdl_ui.cpp +++ b/src/platform/sdl/blib_sdl_ui.cpp @@ -7,13 +7,13 @@ // Implements GUI commands BUTTON, TEXT and DOFORM // using guichan - see http://guichan.sourceforge.net/wiki/index.php -#include "sys.h" -#include "var.h" -#include "kw.h" -#include "pproc.h" -#include "device.h" -#include "smbas.h" -#include "osd.h" +#include "common/sys.h" +#include "common/var.h" +#include "common/kw.h" +#include "common/pproc.h" +#include "common/device.h" +#include "common/smbas.h" +#include "common/osd.h" #ifdef IMPL_UI diff --git a/src/platform/sdl/dev_sdl.c b/src/platform/sdl/dev_sdl.c index 8837cd03..029bad16 100644 --- a/src/platform/sdl/dev_sdl.c +++ b/src/platform/sdl/dev_sdl.c @@ -47,10 +47,10 @@ * */ -#include "device.h" -#include "osd.h" -#include "smbas.h" -#include "str.h" +#include "common/device.h" +#include "common/osd.h" +#include "common/smbas.h" +#include "common/str.h" #include #include #include @@ -1405,7 +1405,7 @@ void osd_write(const char *str) { make_update(cur_x, cur_y, os_graf_mx - cur_x, cur_y + font_h); break; case 'G': - dev_setxy(esc_val * font_w, dev_gety()); // default font = 9x16 + dev_setxy(esc_val * font_w, dev_gety(), 0); // default font = 9x16 break; case 'N': next_is_graphic = 1; diff --git a/src/platform/tizen/application.cpp b/src/platform/tizen/application.cpp new file mode 100644 index 00000000..776fbac9 --- /dev/null +++ b/src/platform/tizen/application.cpp @@ -0,0 +1,126 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#include "config.h" +#include "platform/tizen/form.h" +#include "platform/tizen/application.h" +#include "platform/common/utils.h" + +Application *TizenApp::createInstance() { + logEntered(); + return new TizenApp(); +} + +TizenApp::TizenApp() : _appForm(NULL) { + logEntered(); +} + +TizenApp::~TizenApp() { + logEntered(); +} + +bool TizenApp::OnAppInitialized(void) { + logEntered(); + return true; +} + +bool TizenApp::OnAppInitializing(AppRegistry &appRegistry) { + logEntered(); + bool result = false; + Frame *appFrame = new (std::nothrow) Frame(); + if (appFrame && appFrame->Construct() == E_SUCCESS && + AddFrame(*appFrame) == E_SUCCESS) { + Rectangle rc = appFrame->GetBounds(); + _appForm = new (std::nothrow) AppForm(); + if (_appForm && + _appForm->Construct(rc.width, rc.height) == E_SUCCESS && + appFrame->AddControl(_appForm) == E_SUCCESS && + appFrame->SetCurrentForm(_appForm) == E_SUCCESS) { + result = true; + } + } + + if (!result) { + AppLog("Application startup failed"); + delete _appForm; + _appForm = NULL; + } else { + appFrame->Invalidate(true); + } + return result; +} + +bool TizenApp::OnAppTerminating(AppRegistry &appRegistry, bool forcedTermination) { + logEntered(); + return true; +} + +bool TizenApp::OnAppWillTerminate(void) { + logEntered(); + return true; +} + +void TizenApp::OnBackground(void) { + logEntered(); + pauseRuntime(true); +} + +void TizenApp::OnBatteryLevelChanged(BatteryLevel batteryLevel) { + logEntered(); +} + +void TizenApp::OnForeground(void) { + logEntered(); + pauseRuntime(false); +} + +void TizenApp::OnLowMemory(void) { + logEntered(); +} + +void TizenApp::OnScreenBrightnessChanged(int brightness) { + logEntered(); +} + +void TizenApp::OnScreenOff(void) { + logEntered(); +} + +void TizenApp::OnScreenOn(void) { + logEntered(); +} + +void TizenApp::OnUserEventReceivedN(RequestId requestId, IList *args) { + logEntered(); + switch (requestId) { + case MSG_ID_REDRAW: + _appForm->redraw(); + break; + case USER_MESSAGE_EXIT: + Terminate(); + break; + case MSG_ID_SHOW_KEYPAD: + _appForm->showKeypad(); + break; + case MSG_ID_SHOW_MENU: + _appForm->showMenu((ArrayList *)args); + args->RemoveAll(true); + delete args; + break; + case MSG_ID_SHOW_ALERT: + _appForm->showAlert((ArrayList *)args); + args->RemoveAll(true); + delete args; + break; + } +} + +void TizenApp::pauseRuntime(bool pause) { + if (_appForm) { + } +} diff --git a/src/platform/tizen/application.h b/src/platform/tizen/application.h new file mode 100644 index 00000000..5a296594 --- /dev/null +++ b/src/platform/tizen/application.h @@ -0,0 +1,54 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#ifndef TIZEN_APPLICATION_H +#define TIZEN_APPLICATION_H + +#include +#include +#include +#include +#include + +#include "platform/tizen/form.h" + +using namespace Tizen::App; +using namespace Tizen::System; +using namespace Tizen::Ui; +using namespace Tizen::Ui::Controls; +using namespace Tizen::Base::Collection; + +class TizenApp : + public UiApp, + public IScreenEventListener { + +public: + TizenApp(); + ~TizenApp(); + + static UiApp *createInstance(void); + +private: + bool OnAppInitializing(AppRegistry &appRegistry); + bool OnAppInitialized(void); + bool OnAppWillTerminate(void); + bool OnAppTerminating(AppRegistry &appRegistry, bool forcedTermination = false); + void OnLowMemory(void); + void OnBatteryLevelChanged(BatteryLevel batteryLevel); + void OnUserEventReceivedN(RequestId requestId, IList *args); + void OnForeground(void); + void OnBackground(void); + void OnScreenOn(void); + void OnScreenOff(void); + void OnScreenBrightnessChanged(int brightness); + + void pauseRuntime(bool pause); + AppForm *_appForm; +}; + +#endif diff --git a/src/platform/tizen/common/Makefile.am b/src/platform/tizen/common/Makefile.am new file mode 100755 index 00000000..4a3c245f --- /dev/null +++ b/src/platform/tizen/common/Makefile.am @@ -0,0 +1,74 @@ +# SmallBASIC +# Copyright(C) 2001-2012 Chris Warren-Smith. +# +# This program is distributed under the terms of the GPL v2.0 or later +# Download the GNU Public License (GPL) from www.gnu.org +# + +COMMON=$(top_srcdir)/src/common + +CC=$(TIZEN_BIN)/arm-linux-gnueabi-gcc + +AR=$(TIZEN_BIN)/arm-linux-gnueabi-ar + +ARFLAGS = Tru + +RANLIB=echo + +AM_CPPFLAGS=-I$(top_srcdir)/src @PACKAGE_CFLAGS@ + +noinst_LIBRARIES = libsb_common.a + +libsb_common_a_SOURCES = \ + $(COMMON)/bc.c $(COMMON)/bc.h \ + $(COMMON)/blib.c $(COMMON)/blib.h \ + $(COMMON)/blib_db.c \ + $(COMMON)/blib_func.c \ + $(COMMON)/blib_graph.c \ + $(COMMON)/blib_math.c \ + $(COMMON)/matrix.c \ + $(COMMON)/blib_math.h \ + $(COMMON)/blib_sound.c \ + $(COMMON)/brun.c \ + $(COMMON)/ceval.c \ + $(COMMON)/circle.c \ + $(COMMON)/decomp.c \ + $(COMMON)/device.c $(COMMON)/device.h \ + $(COMMON)/screen.c \ + $(COMMON)/system.c \ + $(COMMON)/drvmouse.h $(COMMON)/drvsound.h \ + $(COMMON)/eval.c \ + $(COMMON)/extlib.c $(COMMON)/extlib.h \ + $(COMMON)/file.c \ + $(COMMON)/ffill.c \ + $(COMMON)/fmt.c $(COMMON)/fmt.h \ + $(COMMON)/fs_serial.c $(COMMON)/fs_serial.h \ + $(COMMON)/fs_socket_client.c $(COMMON)/fs_socket_client.h \ + $(COMMON)/fs_stream.c $(COMMON)/fs_stream.h \ + $(COMMON)/g_line.c \ + $(COMMON)/geom.c $(COMMON)/geom.h $(COMMON)/g_bmp.h \ + $(COMMON)/inet.c $(COMMON)/inet.h \ + $(COMMON)/kw.c $(COMMON)/kw.h \ + $(COMMON)/match.c $(COMMON)/match.h \ + $(COMMON)/mem.c \ + $(COMMON)/panic.c $(COMMON)/panic.h \ + $(COMMON)/pfill.c \ + $(COMMON)/plot.c \ + $(COMMON)/proc.c $(COMMON)/pproc.h \ + $(COMMON)/sberr.c $(COMMON)/sberr.h \ + $(COMMON)/scan.c $(COMMON)/scan.h \ + $(COMMON)/str.c $(COMMON)/str.h \ + $(COMMON)/tasks.c $(COMMON)/tasks.h \ + $(COMMON)/var_uds.c $(COMMON)/var_uds.h \ + $(COMMON)/var_hash.c $(COMMON)/var_hash.h \ + $(COMMON)/keymap.c $(COMMON)/keymap.h \ + $(COMMON)/units.c $(COMMON)/units.h \ + $(COMMON)/var.c $(COMMON)/var.h \ + $(COMMON)/vmt.c $(COMMON)/vmt.h \ + $(COMMON)/messages.h \ + $(COMMON)/osd.h \ + $(COMMON)/pdb.h \ + $(COMMON)/pmem.h \ + $(COMMON)/sbapp.h \ + $(COMMON)/smbas.h \ + $(COMMON)/sys.h diff --git a/src/platform/tizen/display.cpp b/src/platform/tizen/display.cpp new file mode 100644 index 00000000..4c96ecc6 --- /dev/null +++ b/src/platform/tizen/display.cpp @@ -0,0 +1,386 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#include "config.h" +#include +#include "platform/tizen/display.h" +#include "platform/common/form_ui.h" +#include "platform/common/utils.h" + +#define SIZE_LIMIT 4 +#define FONT_FACE_NAME "Envy Code R.ttf" + +FormViewable *widget; +Drawable *drawTarget; +Font *activeFont; +bool mouseActive; +Color drawColor; +int drawColorRaw; +long long epoch; + +using namespace Tizen::App; +using namespace Tizen::Ui::Controls; + +// +// Drawable +// +Drawable::Drawable() : + _canvas(NULL), + _clip(NULL) { +} + +Drawable::~Drawable() { + delete _canvas; + delete _clip; +} + +void Drawable::beginDraw() { + _canvas->SetForegroundColor(drawColor); + if (_clip) { + _canvas->SetClipBounds(*_clip); + } +} + +bool Drawable::create(int w, int h) { + Rectangle rect = Rectangle(0, 0, w, h); + _canvas = new Canvas(); + return (_canvas && _canvas->Construct(rect) == E_SUCCESS && + _canvas->FillRectangle(drawColor, rect) == E_SUCCESS); +} + +void Drawable::drawImageRegion(Drawable *dst, const MAPoint2d *dstPoint, const MARect *srcRect) { + const Rectangle from = Rectangle(srcRect->left, srcRect->top, srcRect->width, srcRect->height); + const Rectangle to = Rectangle(dstPoint->x, dstPoint->y, srcRect->width, srcRect->height); + dst->beginDraw(); + if (dst->_canvas->Copy(to, *_canvas, from) != E_SUCCESS) { + AppLog("Canvas copy error"); + } + dst->endDraw(); +} + +void Drawable::drawLine(int startX, int startY, int endX, int endY) { + beginDraw(); + if (_canvas->DrawLine(Point(startX, startY), Point(endX, endY)) != E_SUCCESS) { + AppLog("drawLine error"); + } + endDraw(); +} + +void Drawable::drawPixel(int posX, int posY) { + beginDraw(); + _canvas->SetPixel(Point(posX, posY)); + endDraw(); +} + +void Drawable::drawRectFilled(int left, int top, int width, int height) { + beginDraw(); + _canvas->FillRectangle(drawColor, Rectangle(left, top, width, height)); + endDraw(); +} + +void Drawable::drawText(int left, int top, const char *str) { + if (activeFont) { + if (_canvas->SetFont(*activeFont) != E_SUCCESS) { + AppLog("Failed to set active font onto canvas"); + } + } + beginDraw(); + if (_canvas->DrawText(Point(left, top), Tizen::Base::String(str)) != E_SUCCESS) { + AppLog("drawText error"); + } + endDraw(); +} + +void Drawable::endDraw() { + if (_clip) { + _canvas->SetClipBounds(widget->GetBounds()); + } +} + +int Drawable::getPixel(int x, int y) { + int result = 0; + Color color; + if (_canvas->GetPixel(Point(x, y), color) == E_SUCCESS) { + result = color.GetRGB32(); + } else { + AppLog("getPixel error"); + } + return result; +} + +void Drawable::resize(int w, int h) { + if (_canvas) { + Canvas *old = _canvas; + create(w, h); + _canvas->Copy(_canvas->GetBounds(), *old, old->GetBounds()); + delete old; + } +} + +void Drawable::setClip(int x, int y, int w, int h) { + delete _clip; + Rectangle rect = _canvas->GetBounds(); + if (rect.x != x || rect.y != y || rect.width != w || rect.height != h) { + _clip = new Rectangle(x, y, w, h); + } else { + _clip = NULL; + } +} + +// +// FormViewable +// +FormViewable::FormViewable() : + Control(), + _canvasLock(NULL), + _screen(NULL), + _w(0), + _h(0) { + Tizen::System::SystemTime::GetTicks(epoch); +} + +FormViewable::~FormViewable() { + logEntered(); + delete _screen; + delete _canvasLock; + _screen = NULL; + _canvasLock = NULL; +} + +result FormViewable::Construct(String &appRootPath, int w, int h) { + logEntered(); + result r = Control::Construct(); + if (!IsFailed(r)) { + _canvasLock = new Mutex(); + r = _canvasLock != NULL ? _canvasLock->Create() : E_OUT_OF_MEMORY; + } + if (!IsFailed(r)) { + SetBounds(0, 0, w, h); + _w = w; _h = h; + _screen = new Drawable(); + if (_screen && _screen->create(w, h)) { + drawTarget = _screen; + drawColorRaw = DEFAULT_BACKGROUND; + drawColor = Color(maSetColor(drawColorRaw)); + widget = this; + fontPath = appRootPath.c_str(); + fontPath += "res/"; + fontPath += FONT_FACE_NAME; + } else { + r = E_OUT_OF_MEMORY; + } + } + if (IsFailed(r)) { + AppLog("FormViewable::Construct failed"); + } + return r; +} + +Font *FormViewable::createFont(int style, int size) { + logEntered(); + Font *font = new Font(); + if (!font || font->Construct(fontPath, style, size) != E_SUCCESS) { + delete font; + font = (Font *)-1; + } + return font; +} + +result FormViewable::OnDraw() { + Canvas *canvas = GetCanvasN(); + if (canvas) { + canvas->Copy(Point(0, 0), *_screen->_canvas, GetBounds()); + } + delete canvas; + return E_SUCCESS; +} + +void FormViewable::redraw() { + _canvasLock->Acquire(); + OnDraw(); + _canvasLock->Release(); +} + +MAHandle FormViewable::setDrawTarget(MAHandle maHandle) { + if (maHandle == (MAHandle) HANDLE_SCREEN || + maHandle == (MAHandle) HANDLE_SCREEN_BUFFER) { + _canvasLock->Acquire(); + drawTarget = _screen; + } else { + drawTarget = (Drawable *)maHandle; + if (drawTarget == _screen) { + // returning the screen + _canvasLock->Release(); + } + } + delete drawTarget->_clip; + drawTarget->_clip = NULL; + return (MAHandle) drawTarget; +} + +// +// form_ui implementation +// +void form_ui::optionsBox(StringList *items) { + ArrayList *args = new ArrayList(); + args->Construct(); + List_each(String *, it, *items) { + char *str = (char *)(* it)->c_str(); + args->Add(new Tizen::Base::String(str)); + } + Application::GetInstance()->SendUserEvent(MSG_ID_SHOW_MENU, args); +} + +// +// maapi implementation +// +int maFontDelete(MAHandle maHandle) { + if (maHandle != -1) { + Font *font = (Font *) maHandle; + if (font == activeFont) { + activeFont = NULL; + } + AppLog("Delete font %x", font); + delete font; + } + return RES_FONT_OK; +} + +int maSetColor(int c) { + int r = (c >> 16) & 0xFF; + int g = (c >> 8) & 0xFF; + int b = (c) & 0xFF; + drawColor = Color(r, g, b); + drawColorRaw = c; + return c; +} + +void maSetClipRect(int left, int top, int width, int height) { + if (drawTarget) { + drawTarget->setClip(left, top, width, height); + } +} + +void maPlot(int posX, int posY) { + if (drawTarget) { + drawTarget->drawPixel(posX, posY); + } +} + +void maLine(int startX, int startY, int endX, int endY) { + if (drawTarget) { + drawTarget->drawLine(startX, startY, endX, endY); + } +} + +void maFillRect(int left, int top, int width, int height) { + if (drawTarget) { + drawTarget->drawRectFilled(left, top, width, height); + } +} + +void maDrawText(int left, int top, const char *str) { + if (drawTarget && str && str[0]) { + drawTarget->drawText(left, top, str); + } +} + +void maUpdateScreen(void) { + Application::GetInstance()->SendUserEvent(MSG_ID_REDRAW, NULL); +} + +void maResetBacklight(void) { +} + +MAExtent maGetTextSize(const char *str) { + MAExtent result; + if (activeFont && str && str[0]) { + Dimension dim; + activeFont->GetTextExtent(str, strlen(str), dim); + result = (MAExtent)((dim.width << 16) + dim.height); + } else { + result = 0; + } + return result; +} + +MAExtent maGetScrSize(void) { + short width = widget->getWidth(); + short height = widget->getHeight(); + return (MAExtent)((width << 16) + height); +} + +MAHandle maFontLoadDefault(int type, int style, int size) { + return (MAHandle) widget->createFont(style, size); +} + +MAHandle maFontSetCurrent(MAHandle maHandle) { + activeFont = (Font *) maHandle; + return maHandle; +} + +void maDrawImageRegion(MAHandle maHandle, const MARect *srcRect, + const MAPoint2d *dstPoint, int transformMode) { + Drawable *drawable = (Drawable *)maHandle; + if (drawTarget != drawable) { + drawable->drawImageRegion(drawTarget, dstPoint, srcRect); + } +} + +int maCreateDrawableImage(MAHandle maHandle, int width, int height) { + int result = RES_OK; + if (height > widget->GetHeight() * SIZE_LIMIT) { + result -= 1; + } else { + Drawable *canvas = (Drawable *)maHandle; + canvas->create(width, height); + } + return result; +} + +MAHandle maCreatePlaceholder(void) { + MAHandle maHandle = (MAHandle) new Drawable(); + return maHandle; +} + +void maDestroyPlaceholder(MAHandle maHandle) { + Drawable *holder = (Drawable *)maHandle; + delete holder; +} + +void maGetImageData(MAHandle maHandle, void *dst, const MARect *srcRect, int scanlength) { + Drawable *holder = (Drawable *)maHandle; + // maGetImageData is only used for getPixel() + *((int *)dst) = holder->getPixel(srcRect->left, srcRect->top); +} + +MAHandle maSetDrawTarget(MAHandle maHandle) { + return widget->setDrawTarget(maHandle); +} + +int maGetMilliSecondCount(void) { + long long result, ticks = 0; + Tizen::System::SystemTime::GetTicks(ticks); + result = ticks - epoch; + return result; +} + +int maShowVirtualKeyboard(void) { + Application::GetInstance()->SendUserEvent(MSG_ID_SHOW_KEYPAD, NULL); + return 0; +} + +void maAlert(const char *title, const char *message, const char *button1, + const char *button2, const char *button3) { + ArrayList *args = new ArrayList(); + args->Construct(); + args->Add(new Tizen::Base::String(title)); + args->Add(new Tizen::Base::String(message)); + Application::GetInstance()->SendUserEvent(MSG_ID_SHOW_ALERT, args); +} + diff --git a/src/platform/tizen/display.h b/src/platform/tizen/display.h new file mode 100644 index 00000000..443508d5 --- /dev/null +++ b/src/platform/tizen/display.h @@ -0,0 +1,72 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#ifndef TIZEN_DISPLAY +#define TIZEN_DISPLAY + +#include +#include +#include +#include +#include + +#include "platform/common/maapi.h" +#include "platform/common/StringLib.h" + +#define MSG_ID_REDRAW 5001 +#define MSG_ID_SHOW_KEYPAD 5002 +#define MSG_ID_SHOW_MENU 5003 +#define MSG_ID_SHOW_ALERT 5004 + +using namespace Tizen::Ui; +using namespace Tizen::Graphics; +using namespace Tizen::Base::Collection; +using namespace Tizen::Base::Runtime; +using namespace strlib; + +struct Drawable { + Drawable(); + ~Drawable(); + + void beginDraw(); + bool create(int w, int h); + void drawImageRegion(Drawable *dst, const MAPoint2d *dstPoint, const MARect *srcRect); + void drawLine(int startX, int startY, int endX, int endY); + void drawPixel(int posX, int posY); + void drawRectFilled(int left, int top, int width, int height); + void drawText(int left, int top, const char *str); + void endDraw(); + int getPixel(int x, int y); + void resize(int w, int h); + void setClip(int x, int y, int w, int h); + + Canvas *_canvas; + Rectangle *_clip; +}; + +struct FormViewable : public Control { + FormViewable(); + virtual ~FormViewable(); + + result Construct(String &resourcePath, int w, int h); + Font *createFont(int style, int size); + int getWidth() { return _w; } + int getHeight() { return _h; } + MAHandle setDrawTarget(MAHandle maHandle); + result OnDraw(); + void redraw(); + void resize(int w, int h) { _w = w; _h = h; } + +private: + Tizen::Base::String fontPath; + Mutex *_canvasLock; + Drawable *_screen; + int _w, _h; +}; + +#endif diff --git a/src/platform/tizen/form.cpp b/src/platform/tizen/form.cpp new file mode 100644 index 00000000..5bf3d397 --- /dev/null +++ b/src/platform/tizen/form.cpp @@ -0,0 +1,277 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#include "config.h" +#include "platform/tizen/form.h" +#include "platform/common/utils.h" + +using namespace Tizen::App; +using namespace Tizen::Base::Collection; +using namespace Tizen::Base::Runtime; +using namespace Tizen::Base::Utility; +using namespace Tizen::Ui::Controls; + +#define EXIT_SLEEP_STEP 10 +#define EXIT_SLEEP 250 + +// hack for missing API to obtain the keypad height (unless using ScrollPanel) +#define KEYPAD_HEIGHT 836 + +// +// converts a Tizen (wchar) String into a StringLib (char) string +// +String fromString(const Tizen::Base::String &in) { + Tizen::Base::ByteBuffer *buf = StringUtil::StringToUtf8N(in); + String result((const char*)buf->GetPointer()); + delete buf; + return result; +} + +// +// AppForm +// +AppForm::AppForm() : + _editField(NULL), + _contextMenu(NULL), + _display(NULL), + _runtime(NULL) { +} + +AppForm::~AppForm() { + logEntered(); + if (_runtime) { + if (_runtime->isActive()) { + // push an exit message onto the thread event queue + _runtime->setExit(true); + + // block while thread ends + AppLog("Waiting for runtime shutdown"); + for (int i = 0; i < EXIT_SLEEP_STEP && _runtime->isClosing(); i++) { + Thread::Sleep(EXIT_SLEEP); + } + + _runtime->Stop(); + _runtime->Join(); + } + delete _runtime; + _runtime = NULL; + } + + logLeaving(); +} + +result AppForm::Construct(int w, int h) { + logEntered(); + result r = Form::Construct(FORM_STYLE_NORMAL); + String appRootPath = fromString(App::GetInstance()->GetAppRootPath()); + + if (!IsFailed(r)) { + _runtime = new RuntimeThread(); + r = _runtime != NULL ? _runtime->Construct(appRootPath, w, h) : E_OUT_OF_MEMORY; + } + if (!IsFailed(r)) { + _display = new FormViewable(); + if (_display && _display->Construct(appRootPath, w, h) == E_SUCCESS && + AddControl(_display) == E_SUCCESS) { + SetOrientation(ORIENTATION_PORTRAIT); + } else { + AppLog("Failed to create FormViewable"); + r = E_OUT_OF_MEMORY; + } + } + if (!IsFailed(r)) { + _editField = new EditField(); + r = _editField == NULL ? E_OUT_OF_MEMORY : + _editField->Construct(Rectangle(0, 0, 1, 1), + EDIT_FIELD_STYLE_NORMAL_SMALL, + INPUT_STYLE_OVERLAY, + EDIT_FIELD_TITLE_STYLE_NONE, + false, 100, GROUP_STYLE_NONE); + if (!IsFailed(r)) { + r = AddControl(_editField); + } + } + if (!IsFailed(r)) { + _contextMenu = new ContextMenu(); + r = _contextMenu == NULL ? E_OUT_OF_MEMORY : + _contextMenu->Construct(Point(0, h), CONTEXT_MENU_STYLE_GRID, + CONTEXT_MENU_ANCHOR_DIRECTION_UPWARD); + } + if (IsFailed(r)) { + AppLog("Form startup failed"); + delete _display; + delete _runtime; + delete _editField; + delete _contextMenu; + _runtime = NULL; + _display = NULL; + _editField = NULL; + _contextMenu = NULL; + } + return r; +} + +void AppForm::layout(bool keypadActive) { + logEntered(); + MAEvent maEvent; + maEvent.type = EVENT_TYPE_SCREEN_CHANGED; + int height = keypadActive ? KEYPAD_HEIGHT : GetHeight(); + _display->resize(GetWidth(), height); + _runtime->pushEvent(maEvent); +} + +void AppForm::OnActionPerformed(const Control &source, int actionId) { + MAEvent maEvent; + maEvent.type = EVENT_TYPE_OPTIONS_BOX_BUTTON_CLICKED; + maEvent.optionsBoxButtonIndex = actionId; + _runtime->pushEvent(maEvent); +} + +result AppForm::OnDraw() { + logEntered(); + return _display->OnDraw(); +} + +void AppForm::OnFormBackRequested(Form &source) { + logEntered(); + _runtime->setBack(); +} + +void AppForm::OnFormMenuRequested(Form &source) { + logEntered(); + MAEvent maEvent; + maEvent.type = EVENT_TYPE_KEY_PRESSED; + maEvent.nativeKey = KEY_CONTEXT_MENU; + maEvent.key = 0; + _runtime->pushEvent(maEvent); +} + +result AppForm::OnInitializing(void) { + logEntered(); + + AddOrientationEventListener(*this); + SetFormBackEventListener(this); + SetFormMenuEventListener(this); + + Color colorClear = Color(0, 0, 0, 0xFF); + _editField->AddKeyEventListener(*this); + _editField->AddKeypadEventListener(*this); + _editField->SetKeypadEnabled(true); + _editField->SetKeypadAction(KEYPAD_ACTION_GO); + _editField->SetEnabled(true); + _editField->SetShowState(false); + _editField->SetColor(EDIT_STATUS_NORMAL, colorClear); + _editField->SetColor(EDIT_STATUS_HIGHLIGHTED, colorClear); + _editField->SetColor(EDIT_STATUS_PRESSED, colorClear); + _editField->SetTextColor(EDIT_TEXT_COLOR_HIGHLIGHTED, colorClear); + _contextMenu->AddActionEventListener(*this); + + // set focus to enable receiving key events + _display->AddTouchEventListener(*this); + SetEnabled(true); + SetFocusable(true); + SetFocus(); + + if (_runtime->isInitial()) { + _runtime->Start(); + } + + logLeaving(); + return E_SUCCESS; +} + +void AppForm::OnKeypadOpened(Control &source) { + _editField->SetFocus(); + layout(true); +} + +void AppForm::OnKeypadClosed(Control &source) { + layout(false); +} + +void AppForm::OnKeyReleased(const Control &source, KeyCode keyCode) { + MAEvent maEvent; + wchar_t ch = 0; + maEvent.type = EVENT_TYPE_KEY_PRESSED; + maEvent.nativeKey = keyCode; + if (_editField->GetTextLength() > 0 && + _editField->GetText().GetCharAt(0, ch) == E_SUCCESS) { + maEvent.key = ch; + } + _editField->Clear(); + _runtime->pushEvent(maEvent); + if (keyCode == KEY_ENTER) { + _editField->HideKeypad(); + _editField->RequestRedraw(); + } +} + +void AppForm::OnOrientationChanged(const Control &source, + OrientationStatus orientationStatus) { + logEntered(); +} + +void AppForm::OnTouchMoved(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo) { + MAEvent maEvent; + maEvent.type = EVENT_TYPE_POINTER_DRAGGED; + maEvent.point.x = touchInfo.GetCurrentPosition().x; + maEvent.point.y = touchInfo.GetCurrentPosition().y; + _runtime->pushEvent(maEvent); +} + +void AppForm::OnTouchPressed(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo) { + MAEvent maEvent; + maEvent.type = EVENT_TYPE_POINTER_PRESSED; + maEvent.point.x = touchInfo.GetCurrentPosition().x; + maEvent.point.y = touchInfo.GetCurrentPosition().y; + _runtime->pushEvent(maEvent); +} + +void AppForm::OnTouchReleased(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo) { + MAEvent maEvent; + maEvent.type = EVENT_TYPE_POINTER_RELEASED; + maEvent.point.x = touchInfo.GetCurrentPosition().x; + maEvent.point.y = touchInfo.GetCurrentPosition().y; + _runtime->pushEvent(maEvent); +} + +void AppForm::showAlert(ArrayList *args) { + int modalResult = 0; + MessageBox messageBox; + Tizen::Base::String *title = (Tizen::Base::String *)args->GetAt(0); + Tizen::Base::String *text = (Tizen::Base::String *)args->GetAt(1); + messageBox.Construct(*title, *text, MSGBOX_STYLE_OK); + messageBox.ShowAndWait(modalResult); +} + +void AppForm::showKeypad() { + _editField->RequestRedraw(); + _editField->SetShowState(true); + _editField->ShowKeypad(); + _editField->SetFocus(); +} + +void AppForm::showMenu(ArrayList *args) { + if (_contextMenu->GetItemCount() > 0) { + _contextMenu->RemoveAllItems(); + } + int len = args->GetCount(); + for (int i = 0; i < len; i++) { + Tizen::Base::String *text = (Tizen::Base::String *)args->GetAt(i); + _contextMenu->AddItem(*text, i); + } + _contextMenu->SetShowState(true); + _contextMenu->Show(); +} + diff --git a/src/platform/tizen/form.h b/src/platform/tizen/form.h new file mode 100644 index 00000000..30558d90 --- /dev/null +++ b/src/platform/tizen/form.h @@ -0,0 +1,84 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#ifndef TIZEN_FORM_H +#define TIZEN_FORM_H + +#include "config.h" +#include "platform/tizen/display.h" +#include "platform/tizen/runtime.h" + +using namespace Tizen::Ui; +using namespace Tizen::Graphics; +using namespace Tizen::Base::Runtime; +using namespace Tizen::Ui::Controls; + +// +// AppForm +// +class AppForm : + public Controls::Form, + public IActionEventListener, + public IFormBackEventListener, + public IFormMenuEventListener, + public IKeyEventListener, + public IKeypadEventListener, + public IOrientationEventListener, + public ITouchEventListener { + +public: + AppForm(); + virtual ~AppForm(); + result Construct(int w, int h); + + void showAlert(ArrayList *args); + void showKeypad(); + void showMenu(ArrayList *args); + void redraw() { _display->redraw(); } + +private: + void layout(bool keypadActive); + void OnActionPerformed(const Control &source, int actionId); + result OnDraw(); + void OnFormBackRequested(Form &source); + void OnFormMenuRequested(Form &source); + result OnInitializing(void); + + void OnKeypadWillOpen(Control &source) {} + void OnKeypadOpened(Control &source); + void OnKeypadClosed(Control &source); + void OnKeypadActionPerformed(Control &source, KeypadAction keypadAction) {} + + void OnKeyPressed(const Control &source, KeyCode keyCode) {} + void OnKeyReleased(const Control &source, KeyCode keyCode); + void OnKeyLongPressed(const Control &source, KeyCode keyCode) {} + void OnOrientationChanged(const Control &source, + OrientationStatus orientationStatus); + void OnTouchFocusIn(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo) {} + void OnTouchFocusOut(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo) {} + void OnTouchMoved(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + void OnTouchPressed(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + void OnTouchReleased(const Control &source, + const Point ¤tPosition, + const TouchEventInfo &touchInfo); + + EditField *_editField; + ContextMenu *_contextMenu; + FormViewable *_display; + RuntimeThread *_runtime; +}; + +#endif diff --git a/src/platform/tizen/main.cpp b/src/platform/tizen/main.cpp new file mode 100644 index 00000000..e0023ccd --- /dev/null +++ b/src/platform/tizen/main.cpp @@ -0,0 +1,34 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#include "config.h" +#include "platform/tizen/application.h" + +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; + +/** + * The entry function of tizen application called by the operating system. + */ +extern "C" _EXPORT_ int OspMain(int argc, char *pArgv[]) { + result r = E_SUCCESS; + + AppLog("Application started."); + ArrayList args(SingleObjectDeleter); + args.Construct(); + for (int i = 0; i < argc; i++) { + args.Add(new (std::nothrow) Tizen::Base::String(pArgv[i])); + } + + r = Tizen::App::UiApp::Execute(TizenApp::createInstance, &args); + TryLog(r == E_SUCCESS, "[%s] Application execution failed", GetErrorMessage(r)); + AppLog("Application finished."); + + return static_cast(r); +} + diff --git a/src/platform/tizen/runtime.cpp b/src/platform/tizen/runtime.cpp new file mode 100644 index 00000000..27fd698b --- /dev/null +++ b/src/platform/tizen/runtime.cpp @@ -0,0 +1,527 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#include "config.h" +#include +#include +#include "platform/tizen/runtime.h" +#include "platform/common/maapi.h" +#include "platform/common/utils.h" +#include "platform/common/form_ui.h" +#include "common/sbapp.h" +#include "common/sys.h" +#include "common/smbas.h" +#include "common/osd.h" +#include "common/device.h" +#include "common/blib_ui.h" +#include "common/fs_socket_client.h" + +#define WAIT_INTERVAL 10 +#define DEFAULT_FONT_SIZE 32 + +struct RuntimeEvent : + public Tizen::Base::Object { + MAEvent maEvent; +}; + +// The runtime thread owns the ansiwidget which uses +// ma apis. The ma apis are handled in the main thread +RuntimeThread *thread; + +RuntimeThread::RuntimeThread() : + System(), + _eventQueueLock(NULL), + _eventQueue(NULL) { + thread = this; +} + +RuntimeThread::~RuntimeThread() { + delete _eventQueueLock; + delete _eventQueue; + _eventQueueLock = NULL; + _eventQueue = NULL; +} + +void RuntimeThread::buttonClicked(const char *url) { + _loadPath.empty(); + _loadPath.append(url, strlen(url)); +} + +result RuntimeThread::Construct(String &appRootPath, int w, int h) { + logEntered(); + result r = Thread::Construct(); + if (!IsFailed(r)) { + _eventQueueLock = new Mutex(); + r = _eventQueueLock != NULL ? _eventQueueLock->Create() : E_OUT_OF_MEMORY; + } + if (!IsFailed(r)) { + _eventQueue = new Queue(); + r = _eventQueue != NULL ? _eventQueue->Construct() : E_OUT_OF_MEMORY; + } + if (!IsFailed(r)) { + _appRootPath = appRootPath; + _output = new AnsiWidget(this, w, h); + if (!_output) { + r = E_OUT_OF_MEMORY; + } + } + return r; +} + +void RuntimeThread::handleKey(MAEvent &event) { + bool pushed = false; + switch ((KeyCode) event.nativeKey) { + case KEY_TAB: + event.key = SB_KEY_TAB; + break; + case KEY_HOME: + event.key = SB_KEY_KP_HOME; + break; + case KEY_MOVE_END: + event.key = SB_KEY_END; + break; + case KEY_INSERT: + event.key = SB_KEY_INSERT; + break; + case KEY_NUMPAD_MULTIPLY: + dev_pushkey(SB_KEY_KP_MUL); + pushed = true; + break; + case KEY_NUMPAD_ADD: + dev_pushkey(SB_KEY_KP_PLUS); + pushed = true; + break; + case KEY_NUMPAD_SUBTRACT: + dev_pushkey(SB_KEY_KP_MINUS); + pushed = true; + break; + case KEY_SLASH: + dev_pushkey(SB_KEY_KP_DIV); + pushed = true; + break; + case KEY_PAGE_UP: + event.key = SB_KEY_PGUP; + break; + case KEY_PAGE_DOWN: + event.key = SB_KEY_PGDN; + break; + case KEY_UP: + event.key = SB_KEY_UP; + break; + case KEY_DOWN: + event.key = SB_KEY_DN; + break; + case KEY_LEFT: + event.key = SB_KEY_LEFT; + break; + case KEY_RIGHT: + event.key = SB_KEY_RIGHT; + break; + case KEY_CLEAR: + case KEY_BACKSPACE: + case KEY_DELETE: + event.key = MAK_CLEAR; + break; + case KEY_ENTER: + event.key = SB_KEY_ENTER; + break; + default: + break; + } + if (!pushed) { + dev_pushkey(event.key); + } +} + +bool RuntimeThread::hasEvent() { + _eventQueueLock->Acquire(); + bool result = _eventQueue->GetCount() > 0; + _eventQueueLock->Release(); + return result; +} + +MAEvent RuntimeThread::popEvent() { + _eventQueueLock->Acquire(); + RuntimeEvent *event = (RuntimeEvent *)_eventQueue->Dequeue(); + _eventQueueLock->Release(); + + MAEvent result = event->maEvent; + delete event; + return result; +} + +void RuntimeThread::pushEvent(MAEvent maEvent) { + _eventQueueLock->Acquire(); + bool addItem = true; + if (maEvent.type == EVENT_TYPE_POINTER_DRAGGED && + _eventQueue->GetCount() > 0) { + RuntimeEvent *previous = (RuntimeEvent *)_eventQueue->Peek(); + if (previous->maEvent.type == EVENT_TYPE_POINTER_DRAGGED) { + addItem = false; + } + } + if (addItem) { + RuntimeEvent *event = new RuntimeEvent(); + event->maEvent = maEvent; + _eventQueue->Enqueue(event); + } + _eventQueueLock->Release(); +} + +MAEvent RuntimeThread::processEvents(bool waitFlag) { + MAEvent event; + + if (!waitFlag) { + showLoadError(); + } else { + // wait for an event + _output->flush(true); + maWait(-1); + } + + _eventQueueLock->Acquire(); + if (_eventQueue->GetCount() > 0) { + RuntimeEvent *runtimeEvent = (RuntimeEvent *)_eventQueue->Dequeue(); + event = runtimeEvent->maEvent; + delete runtimeEvent; + } else { + event.type = 0; + } + _eventQueueLock->Release(); + + switch (event.type) { + case EVENT_TYPE_OPTIONS_BOX_BUTTON_CLICKED: + if (_systemMenu) { + handleMenu(event.optionsBoxButtonIndex); + } else if (isRunning()) { + if (!_output->optionSelected(event.optionsBoxButtonIndex)) { + dev_pushkey(event.optionsBoxButtonIndex); + } + } + break; + case EVENT_TYPE_SCREEN_CHANGED: + resize(); + break; + case EVENT_TYPE_KEY_PRESSED: + if (event.nativeKey == KEY_CONTEXT_MENU) { + showMenu(); + } else if (isRunning()) { + handleKey(event); + } + break; + case EVENT_TYPE_POINTER_PRESSED: + _touchX = _touchCurX = event.point.x; + _touchY = _touchCurY = event.point.y; + dev_pushkey(SB_KEY_MK_PUSH); + _output->pointerTouchEvent(event); + break; + case EVENT_TYPE_POINTER_DRAGGED: + _touchCurX = event.point.x; + _touchCurY = event.point.y; + _output->pointerMoveEvent(event); + break; + case EVENT_TYPE_POINTER_RELEASED: + _touchX = _touchY = _touchCurX = _touchCurY = -1; + _output->pointerReleaseEvent(event); + break; + default: + // no event + _output->flush(false); + break; + } + return event; +} + +char *RuntimeThread::readSource(const char *fileName) { + char *buffer = NULL; + bool networkFile = (strstr(fileName, "://") != NULL); + + if (networkFile) { + int handle = 1; + var_t *var_p = v_new(); + dev_file_t *f = dev_getfileptr(handle); + systemPrint(fileName); + _output->print("\033[ LLoading..."); + if (dev_fopen(handle, fileName, 0)) { + http_read(f, var_p, 0); + int len = var_p->v.p.size; + buffer = (char *)tmp_alloc(len + 1); + memcpy(buffer, var_p->v.p.ptr, len); + buffer[len] = '\0'; + } else { + systemPrint("\nfailed"); + } + dev_fclose(handle); + v_free(var_p); + tmp_free(var_p); + } else { + int h = open(comp_file_name, O_BINARY | O_RDONLY, 0644); + if (h != -1) { + int len = lseek(h, 0, SEEK_END); + lseek(h, 0, SEEK_SET); + buffer = (char *)tmp_alloc(len + 1); + read(h, buffer, len); + buffer[len] = '\0'; + close(h); + } + } + if (buffer != NULL) { + delete [] _programSrc; + int len = strlen(buffer); + _programSrc = new char[len + 1]; + strncpy(_programSrc, buffer, len); + _programSrc[len] = 0; + } + return buffer; +} + +void RuntimeThread::setExit(bool quit) { + if (!isClosing()) { + _eventQueueLock->Acquire(); + _state = quit ? kClosingState : kBackState; + if (isRunning()) { + brun_break(); + } + _eventQueueLock->Release(); + } +} + +Tizen::Base::Object *RuntimeThread::Run() { + logEntered(); + + _state = kActiveState; + opt_ide = IDE_NONE; + opt_graphics = true; + opt_pref_bpp = 0; + opt_nosave = true; + opt_interactive = true; + opt_verbose = false; + opt_quiet = true; + opt_command[0] = 0; + opt_usevmt = 0; + os_graphics = 1; + + _output->construct(); + _output->setTextColor(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); + _output->setFontSize(DEFAULT_FONT_SIZE); + _initialFontSize = _output->getFontSize(); + + String mainBasPath = _appRootPath + "res/main.bas"; + setPath(_appRootPath + "res/samples/"); + runMain(mainBasPath); + + delete _output; + _state = kDoneState; + logLeaving(); + App::GetInstance()->SendUserEvent(USER_MESSAGE_EXIT, NULL); + return 0; +} + +MAEvent RuntimeThread::getNextEvent() { + return processEvents(true); +} + +// +// form_ui implementation +// +bool form_ui::isRunning() { + return thread->isRunning(); +} + +bool form_ui::isBreak() { + return thread->isBreak(); +} + +void form_ui::processEvents() { + if (!isBreak()) { + thread->processEvents(true); + } +} + +void form_ui::buttonClicked(const char *url) { + thread->buttonClicked(url); +} + +AnsiWidget *form_ui::getOutput() { + return thread->_output; +} + +// +// ma event handling +// +int maGetEvent(MAEvent *event) { + int result; + if (thread->hasEvent()) { + MAEvent nextEvent = thread->popEvent(); + event->point = nextEvent.point; + event->type = nextEvent.type; + result = 1; + } else { + result = 0; + } + return result; +} + +void maWait(int timeout) { + int slept = 0; + while (1) { + if (thread->hasEvent() + || thread->isBack() + || thread->isClosing()) { + break; + } + thread->Sleep(WAIT_INTERVAL); + slept += WAIT_INTERVAL; + if (timeout > 0 && slept > timeout) { + break; + } + } +} + +// +// sbasic implementation +// +void osd_sound(int frq, int dur, int vol, int bgplay) { +} + +void osd_clear_sound_queue() { +} + +void osd_beep(void) { +} + +void osd_cls(void) { + logEntered(); + ui_reset(); + thread->_output->clearScreen(); +} + +int osd_devinit(void) { + logEntered(); + thread->setRunning(true); + setsysvar_str(SYSVAR_OSNAME, "Tizen"); + return 1; +} + +int osd_devrestore(void) { + ui_reset(); + thread->setRunning(false); + return 0; +} + +int osd_events(int wait_flag) { + int result; + if (thread->isBreak()) { + result = -2; + } else { + thread->processEvents(wait_flag); + result = 0; + } + return result; +} + +int osd_getpen(int mode) { + return thread->getPen(mode); +} + +long osd_getpixel(int x, int y) { + return thread->_output->getPixel(x, y); +} + +int osd_getx(void) { + return thread->_output->getX(); +} + +int osd_gety(void) { + return thread->_output->getY(); +} + +void osd_line(int x1, int y1, int x2, int y2) { + thread->_output->drawLine(x1, y1, x2, y2); +} + +void osd_rect(int x1, int y1, int x2, int y2, int fill) { + if (fill) { + thread->_output->drawRectFilled(x1, y1, x2, y2); + } else { + thread->_output->drawRect(x1, y1, x2, y2); + } +} + +void osd_refresh(void) { + if (!thread->isClosing()) { + thread->_output->flush(true); + } +} + +void osd_setcolor(long color) { + if (!thread->isClosing()) { + thread->_output->setColor(color); + } +} + +void osd_setpenmode(int enable) { + // touch mode is always active +} + +void osd_setpixel(int x, int y) { + thread->_output->setPixel(x, y, dev_fgcolor); +} + +void osd_settextcolor(long fg, long bg) { + thread->_output->setTextColor(fg, bg); +} + +void osd_setxy(int x, int y) { + thread->_output->setXY(x, y); +} + +int osd_textheight(const char *str) { + return thread->_output->textHeight(); +} + +int osd_textwidth(const char *str) { + MAExtent textSize = maGetTextSize(str); + return EXTENT_X(textSize); +} + +void osd_write(const char *str) { + if (!thread->isClosing()) { + thread->_output->print(str); + } +} + +void lwrite(const char *str) { + if (!thread->isClosing()) { + thread->systemPrint(str); + } +} + +void dev_image(int handle, int index, + int x, int y, int sx, int sy, int w, int h) { +} + +int dev_image_width(int handle, int index) { + return 0; +} + +int dev_image_height(int handle, int index) { + return 0; +} + +void dev_delay(dword ms) { + maWait(ms); +} + +char *dev_gets(char *dest, int maxSize) { + return thread->getText(dest, maxSize); +} + +char *dev_read(const char *fileName) { + return thread->readSource(fileName); +} diff --git a/src/platform/tizen/runtime.h b/src/platform/tizen/runtime.h new file mode 100644 index 00000000..ae551866 --- /dev/null +++ b/src/platform/tizen/runtime.h @@ -0,0 +1,51 @@ +// This file is part of SmallBASIC +// +// Copyright(C) 2001-2013 Chris Warren-Smith. +// +// This program is distributed under the terms of the GPL v2.0 or later +// Download the GNU Public License (GPL) from www.gnu.org +// + +#ifndef RUNTIME_H +#define RUNTIME_H + +#include + +#include "platform/common/maapi.h" +#include "platform/common/interface.h" +#include "platform/common/ansiwidget.h" +#include "platform/common/system.h" + +using namespace Tizen::App; +using namespace Tizen::Base::Collection; +using namespace Tizen::Base::Runtime; +using namespace Tizen::Ui; + +struct RuntimeThread : + public System, + public IButtonListener, + public Thread { + + RuntimeThread(); + ~RuntimeThread(); + + void buttonClicked(const char *action); + result Construct(String &resourcePath, int w, int h); + void handleKey(MAEvent &event); + bool hasEvent(); + MAEvent popEvent(); + void pushEvent(MAEvent event); + MAEvent processEvents(bool waitFlag); + char *readSource(const char *fileName); + void setExit(bool quit); + +private: + Object *Run(); + MAEvent getNextEvent(); + + String _appRootPath; + Mutex *_eventQueueLock; + Queue *_eventQueue; +}; + +#endif