diff --git a/.gitmodules b/.gitmodules
index 134e135f693..02641c8d556 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
[submodule "apps/rpn"]
path = apps/rpn
url = https://github.com/Omega-Numworks/Omega-RPN.git
-[submodule "apps/atom"]
- path = apps/atom
- url = https://github.com/Omega-Numworks/Omega-Atom.git
+[submodule "apps/atomic"]
+ path = apps/atomic
+ url = https://github.com/Omega-Numworks/Omega-Atomic.git
diff --git a/README.fr.md b/README.fr.md
index 98c4ecc3d3f..0eda582df08 100644
--- a/README.fr.md
+++ b/README.fr.md
@@ -1,4 +1,4 @@
-
+
@@ -155,7 +155,7 @@ Pour contribuer, merci de lire le [Wiki](https://github.com/Omega-Numworks/Omega
* [Omega Themes](https://github.com/Omega-Numworks/Omega-Themes)
* [Omega Website](https://github.com/Omega-Numworks/Omega-Website)
* [Omega RPN `APP`](https://github.com/Omega-Numworks/Omega-RPN)
-* [Omega Atom `APP`](https://github.com/Omega-Numworks/Omega-Atom)
+* [Omega Atomic `APP`](https://github.com/Omega-Numworks/Omega-Atomic)
* [Omega Design](https://github.com/Omega-Numworks/Omega-Design)
* [Omega Discord Bot](https://github.com/Omega-Numworks/Omega-Discord-Bot)
* [Omega App Template `BETA`](https://github.com/Omega-Numworks/Omega-App-Template)
diff --git a/README.md b/README.md
index 0bf964083c1..2620c8f49cf 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
@@ -154,7 +154,7 @@ To contribute, please refer to the [Wiki](https://github.com/Omega-Numworks/Omeg
* [Omega Themes](https://github.com/Omega-Numworks/Omega-Themes)
* [Omega Website](https://github.com/Omega-Numworks/Omega-Website)
* [Omega RPN `APP`](https://github.com/Omega-Numworks/Omega-RPN)
-* [Omega Atom `APP`](https://github.com/Omega-Numworks/Omega-Atom)
+* [Omega Atomic `APP`](https://github.com/Omega-Numworks/Omega-Atomic)
* [Omega Design](https://github.com/Omega-Numworks/Omega-Design)
* [Omega Discord Bot](https://github.com/Omega-Numworks/Omega-Discord-Bot)
* [Omega App Template `BETA`](https://github.com/Omega-Numworks/Omega-App-Template)
diff --git a/apps/Makefile b/apps/Makefile
index c27cc6465c8..69f88165e38 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -110,6 +110,7 @@ $(BUILD_DIR)/apps/i18n.h: $(BUILD_DIR)/apps/i18n.cpp
$(eval $(call depends_on_image,apps/title_bar_view.cpp,apps/exam_icon.png))
$(call object_for,$(apps_src) $(tests_src)): $(BUILD_DIR)/apps/i18n.h
+$(call object_for,$(apps_src) $(tests_src)): $(BUILD_DIR)/apps/home/apps_layout.h
$(call object_for,$(apps_src) $(tests_src)): $(BUILD_DIR)/python/port/genhdr/qstrdefs.generated.h
apps_tests_src = $(app_calculation_test_src) $(app_code_test_src) $(app_graph_test_src) $(app_probability_test_src) $(app_regression_test_src) $(app_sequence_test_src) $(app_shared_test_src) $(app_statistics_test_src) $(app_settings_test_src) $(app_solver_test_src)
diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp
index 0bbe77d117c..acf3feb383d 100644
--- a/apps/apps_container.cpp
+++ b/apps/apps_container.cpp
@@ -8,6 +8,8 @@
#include
#include
+#include
+
extern "C" {
#include
}
@@ -218,6 +220,13 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) {
return didProcessEvent || alphaLockWantsRedraw;
}
+static constexpr Ion::Events::Event switch_events[] = {
+ Ion::Events::ShiftSeven, Ion::Events::ShiftEight, Ion::Events::ShiftNine,
+ Ion::Events::ShiftFour, Ion::Events::ShiftFive, Ion::Events::ShiftSix,
+ Ion::Events::ShiftOne, Ion::Events::ShiftTwo, Ion::Events::ShiftThree,
+ Ion::Events::ShiftZero, Ion::Events::ShiftDot, Ion::Events::ShiftEE
+};
+
bool AppsContainer::processEvent(Ion::Events::Event event) {
// Warning: if the window is dirtied, you need to call window()->redraw()
if (event == Ion::Events::USBPlug) {
@@ -242,6 +251,15 @@ bool AppsContainer::processEvent(Ion::Events::Event event) {
switchTo(appSnapshotAtIndex(1));
return true;
}
+
+ for(int i = 0; i < std::min((int) (sizeof(switch_events) / sizeof(Ion::Events::Event)), APPS_CONTAINER_SNAPSHOT_COUNT); i++) {
+ if (event == switch_events[i]) {
+ m_window.redraw(true);
+ switchTo(appSnapshotAtIndex(i+1));
+ return true;
+ }
+ }
+
if (event == Ion::Events::OnOff) {
suspend(true);
return true;
diff --git a/apps/atom b/apps/atom
deleted file mode 160000
index 8f710a9d3fa..00000000000
--- a/apps/atom
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 8f710a9d3fa4daedde14ba489e418dbac5d590c5
diff --git a/apps/atomic b/apps/atomic
new file mode 160000
index 00000000000..69f7a06ba53
--- /dev/null
+++ b/apps/atomic
@@ -0,0 +1 @@
+Subproject commit 69f7a06ba53eaae9ba2ab8f0c0318e2f77455f4d
diff --git a/apps/calculation/expression_field.cpp b/apps/calculation/expression_field.cpp
index a190a9558d1..b96c4b1fed6 100644
--- a/apps/calculation/expression_field.cpp
+++ b/apps/calculation/expression_field.cpp
@@ -17,7 +17,8 @@ bool ExpressionField::handleEvent(Ion::Events::Event event) {
event == Ion::Events::Power ||
event == Ion::Events::Square ||
event == Ion::Events::Division ||
- event == Ion::Events::Sto)) {
+ event == Ion::Events::Sto ||
+ event == Ion::Events::EE)) {
handleEventWithText(Poincare::Symbol::k_ans);
}
return(::ExpressionField::handleEvent(event));
diff --git a/apps/code/Makefile b/apps/code/Makefile
index de11dcb4c66..92646ed6122 100644
--- a/apps/code/Makefile
+++ b/apps/code/Makefile
@@ -15,6 +15,7 @@ app_code_src = $(addprefix apps/code/,\
sandbox_controller.cpp \
script_name_cell.cpp \
script_parameter_controller.cpp \
+ toolbox_ion_keys.cpp \
)
app_code_test_src = $(addprefix apps/code/,\
diff --git a/apps/code/app.cpp b/apps/code/app.cpp
index 4db851b222b..f56559c7c84 100644
--- a/apps/code/app.cpp
+++ b/apps/code/app.cpp
@@ -124,6 +124,10 @@ Toolbox * App::toolboxForInputEventHandler(InputEventHandler * textInput) {
return &m_toolbox;
}
+Code::toolboxIonKeys * App::toolboxIonKeys() {
+ return &m_toolboxIonKeys;
+}
+
VariableBoxController * App::variableBoxForInputEventHandler(InputEventHandler * textInput) {
return &m_variableBoxController;
}
diff --git a/apps/code/app.h b/apps/code/app.h
index 494f5c0f8c7..82a0ad0dd11 100644
--- a/apps/code/app.h
+++ b/apps/code/app.h
@@ -10,6 +10,7 @@
#include "python_toolbox.h"
#include "variable_box_controller.h"
#include "../shared/shared_app.h"
+#include "toolbox_ion_keys.h"
namespace Code {
@@ -77,6 +78,8 @@ class App : public Shared::InputEventHandlerDelegateApp {
static constexpr int k_pythonHeapSize = 100000;
+ Code::toolboxIonKeys * toolboxIonKeys();
+
private:
/* Python delegate:
* MicroPython requires a heap. To avoid dynamic allocation, we keep a working
@@ -93,6 +96,7 @@ class App : public Shared::InputEventHandlerDelegateApp {
StackViewController m_codeStackViewController;
PythonToolbox m_toolbox;
VariableBoxController m_variableBoxController;
+ Code::toolboxIonKeys m_toolboxIonKeys;
};
}
diff --git a/apps/code/base.fr.i18n b/apps/code/base.fr.i18n
index b9006a2d0a6..46d7109ad38 100644
--- a/apps/code/base.fr.i18n
+++ b/apps/code/base.fr.i18n
@@ -12,4 +12,4 @@ ImportedModulesAndScripts = "Modules et scripts importés"
NoWordAvailableHere = "Aucun mot disponible à cet endroit."
ScriptInProgress = "Script en cours"
ScriptOptions = "Options de script"
-ScriptSize = "Script size"
+ScriptSize = "Taille du script"
diff --git a/apps/code/catalog.de.i18n b/apps/code/catalog.de.i18n
index f1c208068f7..9cb321ab8e4 100644
--- a/apps/code/catalog.de.i18n
+++ b/apps/code/catalog.de.i18n
@@ -45,6 +45,7 @@ PythonCosh = "Hyperbolic cosine"
PythonCount = "Zählt wie oft x vorkommt"
PythonDegrees = "x von Radian zu Grad umwandeln"
PythonDivMod = "Quotient und Rest"
+PythonDrawLine = "Draw a line"
PythonDrawString = "Schreibt Text bei (x,y)"
PythonErf = "Fehlerfunktion"
PythonErfc = "Complementary error function"
@@ -86,52 +87,6 @@ PythonIsInfinite = "Prüft ob x unendlich ist"
PythonIsNaN = "Prüft ob x NaN ist"
PythonIsKeyDown = "true wenn k gedrückt ist"
PythonKandinskyFunction = "kandinsky module function prefix"
-PythonKeyLeft = "Linke Pfeiltaste"
-PythonKeyUp = "Pfeiltaste nach oben"
-PythonKeyDown = "Pfeiltaste nach unten"
-PythonKeyRight = "Rechte Pfeiltaste"
-PythonKeyOk = "OK Taste"
-PythonKeyBack = "ZURÜCK Taste"
-PythonKeyHome = "HOME Taste"
-PythonKeyOnOff = "AN/AUS Taste"
-PythonKeyShift = "SHIFT Taste"
-PythonKeyAlpha = "ALPHA Taste"
-PythonKeyXnt = "X,N,T Taste"
-PythonKeyVar = "VAR Taste"
-PythonKeyToolbox = "WERKZEUGBOX Taste"
-PythonKeyBackspace = "LÖSCHEN Taste"
-PythonKeyExp = "EXPONENTIAL Taste"
-PythonKeyLn = "NATURAL LOGARITHM Taste"
-PythonKeyLog = "DECIMAL LOGARITHM Taste"
-PythonKeyImaginary = "IMAGINÄRES I Taste"
-PythonKeyComma = "KOMMA Taste"
-PythonKeyPower = "HOCH Taste"
-PythonKeySine = "SINUS Taste"
-PythonKeyCosine = "COSINUS Taste"
-PythonKeyTangent = "TANGENZ Taste"
-PythonKeyPi = "PI Taste"
-PythonKeySqrt = "WURZEL Taste"
-PythonKeySquare = "QUADRAT Taste"
-PythonKeySeven = "7 Taste"
-PythonKeyEight = "8 Taste"
-PythonKeyNine = "9 Taste"
-PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
-PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
-PythonKeyFour = "4 Taste"
-PythonKeyFive = "5 Taste"
-PythonKeySix = "6 Taste"
-PythonKeyMultiplication = "MULTIPLIKATIONSTASTE"
-PythonKeyDivision = "DIVISIONSTASTE"
-PythonKeyOne = "1 Taste"
-PythonKeyTwo = "2 Taste"
-PythonKeyThree = "3 Taste"
-PythonKeyPlus = "PLUS Taste"
-PythonKeyMinus = "MINUS Taste"
-PythonKeyZero = "0 Taste"
-PythonKeyDot = "PUNKT Taste"
-PythonKeyEe = "10 HOCH X Taste"
-PythonKeyAns = "ANS Taste"
-PythonKeyExe = "EXE Taste"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
diff --git a/apps/code/catalog.en.i18n b/apps/code/catalog.en.i18n
index cd115b9aa5b..819887dbbef 100644
--- a/apps/code/catalog.en.i18n
+++ b/apps/code/catalog.en.i18n
@@ -45,6 +45,7 @@ PythonCosh = "Hyperbolic cosine"
PythonCount = "Count the occurrences of x"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
+PythonDrawLine = "Draw a line"
PythonDrawString = "Display a text from pixel (x,y)"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
@@ -81,52 +82,6 @@ PythonIsInfinite = "Check if x is infinity"
PythonIsKeyDown = "Return True if the k key is down"
PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix"
-PythonKeyLeft = "LEFT ARROW key"
-PythonKeyUp = "UP ARROW key"
-PythonKeyDown = "DOWN ARROW key"
-PythonKeyRight = "RIGHT ARROW key"
-PythonKeyOk = "OK key"
-PythonKeyBack = "BACK key"
-PythonKeyHome = "HOME key"
-PythonKeyOnOff = "ON/OFF key"
-PythonKeyShift = "SHIFT key"
-PythonKeyAlpha = "ALPHA key"
-PythonKeyXnt = "X,N,T key"
-PythonKeyVar = "VAR key"
-PythonKeyToolbox = "TOOLBOX key"
-PythonKeyBackspace = "BACKSPACE key"
-PythonKeyExp = "EXPONENTIAL key"
-PythonKeyLn = "NATURAL LOGARITHM key"
-PythonKeyLog = "DECIMAL LOGARITHM key"
-PythonKeyImaginary = "IMAGINARY I key"
-PythonKeyComma = "COMMA key"
-PythonKeyPower = "POWER key"
-PythonKeySine = "SINE key"
-PythonKeyCosine = "COSINE key"
-PythonKeyTangent = "TANGENT key"
-PythonKeyPi = "PI key"
-PythonKeySqrt = "SQUARE ROOT key"
-PythonKeySquare = "SQUARE key"
-PythonKeySeven = "7 key"
-PythonKeyEight = "8 key"
-PythonKeyNine = "9 key"
-PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
-PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
-PythonKeyFour = "4 key"
-PythonKeyFive = "5 key"
-PythonKeySix = "6 key"
-PythonKeyMultiplication = "MULTIPLICATION key"
-PythonKeyDivision = "DIVISION key"
-PythonKeyOne = "1 key"
-PythonKeyTwo = "2 key"
-PythonKeyThree = "3 key"
-PythonKeyPlus = "PLUS key"
-PythonKeyMinus = "MINUS key"
-PythonKeyZero = "0 key"
-PythonKeyDot = "DOT key"
-PythonKeyEe = "10 POWER X key"
-PythonKeyAns = "ANS key"
-PythonKeyExe = "EXE key"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
diff --git a/apps/code/catalog.es.i18n b/apps/code/catalog.es.i18n
index ee8b58f598b..960dd7eb9bc 100644
--- a/apps/code/catalog.es.i18n
+++ b/apps/code/catalog.es.i18n
@@ -45,6 +45,7 @@ PythonCosh = "Hyperbolic cosine"
PythonCount = "Count the occurrences of x"
PythonDegrees = "Convert x from radians to degrees"
PythonDivMod = "Quotient and remainder"
+PythonDrawLine = "Draw a line"
PythonDrawString = "Display a text from pixel (x,y)"
PythonErf = "Error function"
PythonErfc = "Complementary error function"
@@ -81,52 +82,6 @@ PythonIsInfinite = "Check if x is infinity"
PythonIsKeyDown = "Return True if the k key is down"
PythonIsNaN = "Check if x is a NaN"
PythonKandinskyFunction = "kandinsky module function prefix"
-PythonKeyLeft = "LEFT ARROW key"
-PythonKeyUp = "UP ARROW key"
-PythonKeyDown = "DOWN ARROW key"
-PythonKeyRight = "RIGHT ARROW key"
-PythonKeyOk = "OK key"
-PythonKeyBack = "BACK key"
-PythonKeyHome = "HOME key"
-PythonKeyOnOff = "ON/OFF key"
-PythonKeyShift = "SHIFT key"
-PythonKeyAlpha = "ALPHA key"
-PythonKeyXnt = "X,N,T key"
-PythonKeyVar = "VAR key"
-PythonKeyToolbox = "TOOLBOX key"
-PythonKeyBackspace = "BACKSPACE key"
-PythonKeyExp = "EXPONENTIAL key"
-PythonKeyLn = "NATURAL LOGARITHM key"
-PythonKeyLog = "DECIMAL LOGARITHM key"
-PythonKeyImaginary = "IMAGINARY I key"
-PythonKeyComma = "COMMA key"
-PythonKeyPower = "POWER key"
-PythonKeySine = "SINE key"
-PythonKeyCosine = "COSINE key"
-PythonKeyTangent = "TANGENT key"
-PythonKeyPi = "PI key"
-PythonKeySqrt = "SQUARE ROOT key"
-PythonKeySquare = "SQUARE key"
-PythonKeySeven = "7 key"
-PythonKeyEight = "8 key"
-PythonKeyNine = "9 key"
-PythonKeyLeftParenthesis = "LEFT PARENTHESIS key"
-PythonKeyRightParenthesis = "RIGHT PARENTHESIS key"
-PythonKeyFour = "4 key"
-PythonKeyFive = "5 key"
-PythonKeySix = "6 key"
-PythonKeyMultiplication = "MULTIPLICATION key"
-PythonKeyDivision = "DIVISION key"
-PythonKeyOne = "1 key"
-PythonKeyTwo = "2 key"
-PythonKeyThree = "3 key"
-PythonKeyPlus = "PLUS key"
-PythonKeyMinus = "MINUS key"
-PythonKeyZero = "0 key"
-PythonKeyDot = "DOT key"
-PythonKeyEe = "10 POWER X key"
-PythonKeyAns = "ANS key"
-PythonKeyExe = "EXE key"
PythonLdexp = "Return x*(2**i), inverse of frexp"
PythonLength = "Length of an object"
PythonLgamma = "Log-gamma function"
diff --git a/apps/code/catalog.fr.i18n b/apps/code/catalog.fr.i18n
index 3a7d94eb896..756ef882e0f 100644
--- a/apps/code/catalog.fr.i18n
+++ b/apps/code/catalog.fr.i18n
@@ -45,6 +45,7 @@ PythonCosh = "Cosinus hyperbolique"
PythonCount = "Compte les occurrences de x"
PythonDegrees = "Conversion de radians en degrés"
PythonDivMod = "Quotient et reste"
+PythonDrawLine = "Trace une ligne"
PythonDrawString = "Affiche un texte au pixel (x,y)"
PythonErf = "Fonction d'erreur"
PythonErfc = "Fonction d'erreur complémentaire"
@@ -81,52 +82,6 @@ PythonIsInfinite = "Teste si x est infini"
PythonIsKeyDown = "Renvoie True si touche k enfoncée"
PythonIsNaN = "Teste si x est NaN"
PythonKandinskyFunction = "Préfixe fonction module kandinsky"
-PythonKeyLeft = "Touche FLECHE GAUCHE"
-PythonKeyUp = "Touche FLECHE HAUT"
-PythonKeyDown = "Touche FLECHE BAS"
-PythonKeyRight = "Touche FLECHE DROITE"
-PythonKeyOk = "Touche OK"
-PythonKeyBack = "Touche RETOUR"
-PythonKeyHome = "Touche HOME"
-PythonKeyOnOff = "Touche ON/OFF"
-PythonKeyShift = "Touche SHIFT"
-PythonKeyAlpha = "Touche ALPHA"
-PythonKeyXnt = "Touche X,N,T"
-PythonKeyVar = "Touche VAR"
-PythonKeyToolbox = "Touche BOITE A OUTILS"
-PythonKeyBackspace = "Touche EFFACER"
-PythonKeyExp = "Touche EXPONENTIELLE"
-PythonKeyLn = "Touche LOGARITHME NEPERIEN"
-PythonKeyLog = "Touche LOGARITHME DECIMAL"
-PythonKeyImaginary = "Touche I IMAGINAIRE"
-PythonKeyComma = "Touche VIRGULE"
-PythonKeyPower = "Touche PUISSANCE"
-PythonKeySine = "Touche SINUS"
-PythonKeyCosine = "Touche COSINUS"
-PythonKeyTangent = "Touche TANGENTE"
-PythonKeyPi = "Touche PI"
-PythonKeySqrt = "Touche RACINE CARREE"
-PythonKeySquare = "Touche CARRE"
-PythonKeySeven = "Touche 7"
-PythonKeyEight = "Touche 8"
-PythonKeyNine = "Touche 9"
-PythonKeyLeftParenthesis = "Touche PARENTHESE GAUCHE"
-PythonKeyRightParenthesis = "Touche PARENTHESE DROITE"
-PythonKeyFour = "Touche 4"
-PythonKeyFive = "Touche 5"
-PythonKeySix = "Touche 6"
-PythonKeyMultiplication = "Touche MULTIPLICATION"
-PythonKeyDivision = "Touche DIVISION"
-PythonKeyOne = "Touche 1"
-PythonKeyTwo = "Touche 2"
-PythonKeyThree = "Touche 3"
-PythonKeyPlus = "Touche PLUS"
-PythonKeyMinus = "Touche MOINS"
-PythonKeyZero = "Touche 0"
-PythonKeyDot = "Touche POINT"
-PythonKeyEe = "Touche 10 PUISSANCE X"
-PythonKeyAns = "Touche ANS"
-PythonKeyExe = "Touche EXE"
PythonLdexp = "Inverse de frexp : x*(2**i)"
PythonLength = "Longueur d'un objet"
PythonLgamma = "Logarithme de la fonction gamma"
@@ -210,12 +165,12 @@ PythonFileSeek = "Déplace le curseur interne"
PythonFileTell = "Donne la posititon du curseur"
PythonFileClose = "Ferme un fichier"
PythonFileClosed = "True si le fichier a été fermé"
-PythonFileRead = "Lis jusqu'à size bytes"
-PythonFileWrite = "Écris b dans le fichier"
-PythonFileReadline = "Lis une ligne ou jusqu'à size bytes"
-PythonFileReadlines = "Lis une liste de lignes"
+PythonFileRead = "Lit jusqu'à size bytes"
+PythonFileWrite = "Écrit b dans le fichier"
+PythonFileReadline = "Lit une ligne ou jusqu'à size bytes"
+PythonFileReadlines = "Lit une liste de lignes"
PythonFileTruncate = "Redimensionne le fichier"
-PythonFileWritelines = "Écris une liste de lignes"
+PythonFileWritelines = "Écrit une liste de lignes"
PythonFileName = "Nom du fichier"
PythonFileMode = "Mode d'ouverture du fichier"
PythonFileReadable = "Indique si read peut être utilisé"
diff --git a/apps/code/catalog.hu.i18n b/apps/code/catalog.hu.i18n
index 6871a7dcfbe..a837db91b58 100644
--- a/apps/code/catalog.hu.i18n
+++ b/apps/code/catalog.hu.i18n
@@ -45,6 +45,7 @@ PythonCosh = "Hiperbolikus koszinusz"
PythonCount = "Számolja az x elöfordulását"
PythonDegrees = "x konvertálása radiánokrol fokokra"
PythonDivMod = "Hányados és maradék"
+PythonDrawLine = "Húzzon egy vonalat "
PythonDrawString = "Szöveg megjelenítése (x, y)-en"
PythonErf = "Hiba funkció"
PythonErfc = "Kiegészítö hiba funkció"
@@ -81,52 +82,6 @@ PythonIsInfinite = "x végtelen-e"
PythonIsKeyDown = "True-t válaszol ha a k gomb le van nyomva"
PythonIsNaN = "Ellenörizze hogy x nem NaN"
PythonKandinskyFunction = "kandinsky modul funkció elötag"
-PythonKeyLeft = "BAL NYÍL gomb"
-PythonKeyUp = "FEL NYÍL gomb"
-PythonKeyDown = "LE NYÍL gomb"
-PythonKeyRight = "JOBB NYÍL gomb"
-PythonKeyOk = "OK gomb"
-PythonKeyBack = "VISSZA gomb"
-PythonKeyHome = "HOME gomb"
-PythonKeyOnOff = "ON/OFF gomb"
-PythonKeyShift = "SHIFT gomb"
-PythonKeyAlpha = "ALPHA gomb"
-PythonKeyXnt = "X,N,T gomb"
-PythonKeyVar = "VAR gomb"
-PythonKeyToolbox = "TOOLBOX gomb"
-PythonKeyBackspace = "TÖRLÉS gomb"
-PythonKeyExp = "EXPONENCIÁLIS gomb"
-PythonKeyLn = "NEPERIAI LOGARITHM gomb"
-PythonKeyLog = "DECIMÁLIS LOGARITHM gomb"
-PythonKeyImaginary = "KÉPZELETBELI I gomb"
-PythonKeyComma = "VESSZÖ gomb"
-PythonKeyPower = "KIÁLLÍTÓ gomb"
-PythonKeySine = "SZINUSZ gomb"
-PythonKeyCosine = "KOSZINUSZ gomb"
-PythonKeyTangent = "TANGENS gomb"
-PythonKeyPi = "PI gomb"
-PythonKeySqrt = "NÉGYZETGYÖK gomb"
-PythonKeySquare = "NÉGYZET gomb"
-PythonKeySeven = "7 gomb"
-PythonKeyEight = "8 gomb"
-PythonKeyNine = "9 gomb"
-PythonKeyLeftParenthesis = "BAL ZÁRÓJEL gomb"
-PythonKeyRightParenthesis = "JOB ZÁRÓJEL gomb"
-PythonKeyFour = "4 gomb"
-PythonKeyFive = "5 gomb"
-PythonKeySix = "6 gomb"
-PythonKeyMultiplication = "SZOZÁS gomb"
-PythonKeyDivision = "OSZTÁS gomb"
-PythonKeyOne = "1 gomb"
-PythonKeyTwo = "2 gomb"
-PythonKeyThree = "3 gomb"
-PythonKeyPlus = "PLUS gomb"
-PythonKeyMinus = "MINUS gomb"
-PythonKeyZero = "0 gomb"
-PythonKeyDot = "PONT gomb"
-PythonKeyEe = "10 X KITEVÖ gomb"
-PythonKeyAns = "ANS gomb"
-PythonKeyExe = "EXE gomb"
PythonLdexp = "frexp ellentéte : x*(2**i)"
PythonLength = "Egy targy hossza"
PythonLgamma = "Gamma funkció logaritmusa"
diff --git a/apps/code/catalog.it.i18n b/apps/code/catalog.it.i18n
index 27a7ea40845..94eacc262f0 100644
--- a/apps/code/catalog.it.i18n
+++ b/apps/code/catalog.it.i18n
@@ -45,6 +45,7 @@ PythonCosh = "Coseno iperbolico"
PythonCount = "Conta le ricorrenze di x"
PythonDegrees = "Conversione di radianti in gradi"
PythonDivMod = "Quoziente e resto"
+PythonDrawLine = "Disegna una linea"
PythonDrawString = "Visualizza il testo dal pixel x,y"
PythonErf = "Funzione d'errore"
PythonErfc = "Funzione d'errore complementare"
@@ -86,52 +87,6 @@ PythonIsInfinite = "Testa se x est infinito"
PythonIsKeyDown = "Restituisce True premendo tasto k"
PythonIsNaN = "Testa se x è NaN"
PythonKandinskyFunction = "Prefisso funzione modulo kandinsky"
-PythonKeyLeft = "Tasto FRECCIA SINISTRA"
-PythonKeyUp = "Tasto FRECCIA ALTO"
-PythonKeyDown = "Tasto FRECCIA BASSO"
-PythonKeyRight = "Tasto FRECCIA DESTRA"
-PythonKeyOk = "Tasto OK"
-PythonKeyBack = "Tasto INDIETRO"
-PythonKeyHome = "Tasto CASA"
-PythonKeyOnOff = "Tasto ON/OFF"
-PythonKeyShift = "Tasto SHIFT"
-PythonKeyAlpha = "Tasto ALPHA"
-PythonKeyXnt = "Tasto X,N,T"
-PythonKeyVar = "Tasto VAR"
-PythonKeyToolbox = "Tasto TOOLBOX"
-PythonKeyBackspace = "Tasto CANCELLA"
-PythonKeyExp = "Tasto ESPONENZIALE"
-PythonKeyLn = "Tasto LOGARITMO NEPERIANO"
-PythonKeyLog = "Tasto LOGARITMO DECIMALE"
-PythonKeyImaginary = "Tasto I IMMAGINE"
-PythonKeyComma = "Tasto VIRGOLA"
-PythonKeyPower = "Tasto POTENZA"
-PythonKeySine = "Tasto SENO"
-PythonKeyCosine = "Tasto COSENO"
-PythonKeyTangent = "Tasto TANGENTE"
-PythonKeyPi = "Tasto PI"
-PythonKeySqrt = "Tasto RADICE QUADRATA"
-PythonKeySquare = "Tasto QUADRATO"
-PythonKeySeven = "Tasto 7"
-PythonKeyEight = "Tasto 8"
-PythonKeyNine = "Tasto 9"
-PythonKeyLeftParenthesis = "Tasto PARENTESI SINISTRA"
-PythonKeyRightParenthesis = "Tasto PARENTESI DESTRA"
-PythonKeyFour = "Tasto 4"
-PythonKeyFive = "Tasto 5"
-PythonKeySix = "Tasto 6"
-PythonKeyMultiplication = "Tasto MOLTIPLICAZIONE"
-PythonKeyDivision = "Tasto DIVISIONE"
-PythonKeyOne = "Tasto 1"
-PythonKeyTwo = "Tasto 2"
-PythonKeyThree = "Tasto 3"
-PythonKeyPlus = "Tasto PIÙ"
-PythonKeyMinus = "Tasto MENO"
-PythonKeyZero = "Tasto 0"
-PythonKeyDot = "Tasto PUNTO"
-PythonKeyEe = "Tasto 10 POTENZA X"
-PythonKeyAns = "Tasto ANS"
-PythonKeyExe = "Tasto EXE"
PythonLdexp = "Inversa di frexp : x*(2**i)"
PythonLength = "Longhezza di un oggetto"
PythonLgamma = "Logaritmo della funzione gamma"
diff --git a/apps/code/catalog.nl.i18n b/apps/code/catalog.nl.i18n
index b3ec4225723..1ee1f667ccb 100644
--- a/apps/code/catalog.nl.i18n
+++ b/apps/code/catalog.nl.i18n
@@ -45,6 +45,7 @@ PythonCosh = "Cosinus hyperbolicus"
PythonCount = "Tel voorkomen van x"
PythonDegrees = "Zet x om van radialen naar graden"
PythonDivMod = "Quotiënt en rest"
+PythonDrawLine = "Teken een lijn"
PythonDrawString = "Geef een tekst weer van pixel (x,y)"
PythonErf = "Error functie"
PythonErfc = "Complementaire error functie"
@@ -86,52 +87,6 @@ PythonIsInfinite = "Controleer of x oneindig is"
PythonIsKeyDown = "Geef True als k toets omlaag is"
PythonIsNaN = "Controleer of x geen getal is"
PythonKandinskyFunction = "kandinsky module voorvoegsel"
-PythonKeyLeft = "PIJL NAAR LINKS toets"
-PythonKeyUp = "PIJL OMHOOG toets"
-PythonKeyDown = "PIJL OMLAAG toets"
-PythonKeyRight = "PIJL NAAR RECHTS toets"
-PythonKeyOk = "OK toets"
-PythonKeyBack = "TERUG toets"
-PythonKeyHome = "HOME toets"
-PythonKeyOnOff = "AAN/UIT toets"
-PythonKeyShift = "SHIFT toets"
-PythonKeyAlpha = "ALPHA toets"
-PythonKeyXnt = "X,N,T toets"
-PythonKeyVar = "VAR toets"
-PythonKeyToolbox = "TOOLBOX toets"
-PythonKeyBackspace = "BACKSPACE toets"
-PythonKeyExp = "EXPONENTIEEL toets"
-PythonKeyLn = "NATUURLIJKE LOGARITME toets"
-PythonKeyLog = "BRIGGSE LOGARITME toets"
-PythonKeyImaginary = "IMAGINAIRE I toets"
-PythonKeyComma = "KOMMA toets"
-PythonKeyPower = "MACHT toets"
-PythonKeySine = "SINUS toets"
-PythonKeyCosine = "COSINUS toets"
-PythonKeyTangent = "TANGENS toets"
-PythonKeyPi = "PI toets"
-PythonKeySqrt = "VIERKANTSWORTEL toets"
-PythonKeySquare = "KWADRAAT toets"
-PythonKeySeven = "7 toets"
-PythonKeyEight = "8 toets"
-PythonKeyNine = "9 toets"
-PythonKeyLeftParenthesis = "HAAKJE OPENEN toets"
-PythonKeyRightParenthesis = "HAAKJE SLUITEN toets"
-PythonKeyFour = "4 toets"
-PythonKeyFive = "5 toets"
-PythonKeySix = "6 toets"
-PythonKeyMultiplication = "VERMENIGVULDIGEN toets"
-PythonKeyDivision = "DELEN toets"
-PythonKeyOne = "1 toets"
-PythonKeyTwo = "2 toets"
-PythonKeyThree = "3 toets"
-PythonKeyPlus = "PLUS toets"
-PythonKeyMinus = "MIN toets"
-PythonKeyZero = "0 toets"
-PythonKeyDot = "PUNT toets"
-PythonKeyEe = "10 TOT DE MACHT X toets"
-PythonKeyAns = "ANS toets"
-PythonKeyExe = "EXE toets"
PythonLdexp = "Geeft x*(2**i), inversie van frexp"
PythonLength = "Lengte van een object"
PythonLgamma = "Log-gammafunctie"
diff --git a/apps/code/catalog.pt.i18n b/apps/code/catalog.pt.i18n
index de29d19d465..a17ea0ad5c0 100644
--- a/apps/code/catalog.pt.i18n
+++ b/apps/code/catalog.pt.i18n
@@ -45,6 +45,7 @@ PythonCosh = "Cosseno hiperbólico"
PythonCount = "Contar as ocorrências de x"
PythonDegrees = "Converter x de radianos para graus"
PythonDivMod = "Quociente e resto"
+PythonDrawLine = "Desenhe uma linha"
PythonDrawString = "Mostrar o texto do pixel (x,y)"
PythonErf = "Função erro"
PythonErfc = "Função erro complementar"
@@ -81,52 +82,6 @@ PythonIsInfinite = "Verificar se x é infinito"
PythonIsKeyDown = "Devolve True se tecla k pressionada"
PythonIsNaN = "Verificar se x é um NaN"
PythonKandinskyFunction = "Prefixo da função do módulo kandinsky"
-PythonKeyLeft = "tecla SETA ESQUERDA"
-PythonKeyUp = "tecla SETA CIMA "
-PythonKeyDown = "tecla SETA BAIXO"
-PythonKeyRight = "tecla SETA DIREITA"
-PythonKeyOk = "tecla OK"
-PythonKeyBack = "tecla VOLTAR"
-PythonKeyHome = "tecla HOME"
-PythonKeyOnOff = "tecla ON/OFF"
-PythonKeyShift = "tecla SHIFT"
-PythonKeyAlpha = "tecla ALPHA"
-PythonKeyXnt = "tecla X,N,T"
-PythonKeyVar = "tecla VAR"
-PythonKeyToolbox = "tecla CAIXA DE FERRAMENTAS"
-PythonKeyBackspace = "tecla APAGAR"
-PythonKeyExp = "tecla EXPONENCIAL"
-PythonKeyLn = "tecla LOGARITMO NATURAL"
-PythonKeyLog = "tecla LOGARITMO DECIMAL"
-PythonKeyImaginary = "tecla I IMAGINÁRIO"
-PythonKeyComma = "tecla VÍRGULA"
-PythonKeyPower = "tecla EXPOENTE"
-PythonKeySine = "tecla SENO"
-PythonKeyCosine = "tecla COSSENO"
-PythonKeyTangent = "tecla TANGENTE"
-PythonKeyPi = "tecla PI"
-PythonKeySqrt = "tecla RAIZ QUADRADA"
-PythonKeySquare = "tecla AO QUADRADO"
-PythonKeySeven = "tecla 7"
-PythonKeyEight = "tecla 8"
-PythonKeyNine = "tecla 9"
-PythonKeyLeftParenthesis = "tecla PARÊNTESE ESQUERDO"
-PythonKeyRightParenthesis = "tecla PARÊNTESE DIREITO"
-PythonKeyFour = "tecla 4"
-PythonKeyFive = "tecla 5"
-PythonKeySix = "tecla 6"
-PythonKeyMultiplication = "tecla MULTIPLICAÇÃO"
-PythonKeyDivision = "tecla DIVISÃO"
-PythonKeyOne = "tecla 1"
-PythonKeyTwo = "tecla 2"
-PythonKeyThree = "tecla 3"
-PythonKeyPlus = "tecla MAIS"
-PythonKeyMinus = "tecla MENOS"
-PythonKeyZero = "tecla 0"
-PythonKeyDot = "tecla PONTO"
-PythonKeyEe = "tecla 10 expoente X"
-PythonKeyAns = "tecla ANS"
-PythonKeyExe = "tecla EXE"
PythonLdexp = "Devolve x*(2**i), inverso de frexp"
PythonLength = "Comprimento de um objeto"
PythonLgamma = "Logaritmo da função gama"
diff --git a/apps/code/catalog.universal.i18n b/apps/code/catalog.universal.i18n
index 001c5834909..39d1ff3b494 100644
--- a/apps/code/catalog.universal.i18n
+++ b/apps/code/catalog.universal.i18n
@@ -50,6 +50,7 @@ PythonCommandCount = "list.count(x)"
PythonCommandCountWithoutArg = ".count(\x11)"
PythonCommandDegrees = "degrees(x)"
PythonCommandDivMod = "divmod(a,b)"
+PythonCommandDrawLine = "draw_line(x1,y1,x2,y2,color)"
PythonCommandDrawString = "draw_string(\"text\",x,y)"
PythonCommandConstantE = "e"
PythonCommandErf = "erf(x)"
diff --git a/apps/code/python_toolbox.cpp b/apps/code/python_toolbox.cpp
index 2a0ba410d8e..34aa96bfac3 100644
--- a/apps/code/python_toolbox.cpp
+++ b/apps/code/python_toolbox.cpp
@@ -5,6 +5,7 @@ extern "C" {
#include
#include
}
+#include "app.h"
namespace Code {
@@ -192,6 +193,7 @@ const ToolboxMessageTree KandinskyModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandSetPixel, I18n::Message::PythonSetPixel),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandColor, I18n::Message::PythonColor),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawString, I18n::Message::PythonDrawString),
+ ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawLine, I18n::Message::PythonDrawLine),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandFillRect, I18n::Message::PythonFillRect)
};
@@ -200,52 +202,7 @@ const ToolboxMessageTree IonModuleChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandImportFromIon, I18n::Message::PythonImportIon, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIonFunction, I18n::Message::PythonIonFunction, false, I18n::Message::PythonCommandIonFunctionWithoutArg),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandIsKeyDown, I18n::Message::PythonIsKeyDown),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLeft, I18n::Message::PythonKeyLeft, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyUp, I18n::Message::PythonKeyUp, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDown, I18n::Message::PythonKeyDown, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyRight, I18n::Message::PythonKeyRight, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOk, I18n::Message::PythonKeyOk, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyBack, I18n::Message::PythonKeyBack, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyHome, I18n::Message::PythonKeyHome, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOnOff, I18n::Message::PythonKeyOnOff, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyShift, I18n::Message::PythonKeyShift, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyAlpha, I18n::Message::PythonKeyAlpha, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyXnt, I18n::Message::PythonKeyXnt, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyVar, I18n::Message::PythonKeyVar, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyToolbox, I18n::Message::PythonKeyToolbox, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyBackspace, I18n::Message::PythonKeyBackspace, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyExp, I18n::Message::PythonKeyExp, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLn, I18n::Message::PythonKeyLn, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLog, I18n::Message::PythonKeyLog, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyImaginary, I18n::Message::PythonKeyImaginary, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyComma, I18n::Message::PythonKeyComma, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPower, I18n::Message::PythonKeyPower, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySine, I18n::Message::PythonKeySine, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyCosine, I18n::Message::PythonKeyCosine, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyTangent, I18n::Message::PythonKeyTangent, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPi, I18n::Message::PythonKeyPi, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySqrt, I18n::Message::PythonKeySqrt, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySquare, I18n::Message::PythonKeySquare, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySeven, I18n::Message::PythonKeySeven, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyEight, I18n::Message::PythonKeyEight, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyNine, I18n::Message::PythonKeyNine, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyLeftParenthesis, I18n::Message::PythonKeyLeftParenthesis, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyRightParenthesis, I18n::Message::PythonKeyRightParenthesis, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyFour, I18n::Message::PythonKeyFour, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyFive, I18n::Message::PythonKeyFive, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeySix, I18n::Message::PythonKeySix, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyMultiplication, I18n::Message::PythonKeyMultiplication, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDivision, I18n::Message::PythonKeyDivision, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyOne, I18n::Message::PythonKeyOne, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyTwo, I18n::Message::PythonKeyTwo, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyThree, I18n::Message::PythonKeyThree, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyPlus, I18n::Message::PythonKeyPlus, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyMinus, I18n::Message::PythonKeyMinus, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyZero, I18n::Message::PythonKeyZero, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyDot, I18n::Message::PythonKeyDot, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyEe, I18n::Message::PythonKeyEe, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyAns, I18n::Message::PythonKeyAns, false),
- ToolboxMessageTree::Leaf(I18n::Message::PythonCommandKeyExe, I18n::Message::PythonKeyExe, false)
+ ToolboxMessageTree::Leaf(I18n::Message::IonSelector, I18n::Message::IonSelector)
};
const ToolboxMessageTree TimeModuleChildren[] = {
@@ -315,6 +272,7 @@ const ToolboxMessageTree catalogChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandCosh, I18n::Message::PythonCosh),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDegrees, I18n::Message::PythonDegrees),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDivMod, I18n::Message::PythonDivMod),
+ ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawLine, I18n::Message::PythonDrawLine),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandDrawString, I18n::Message::PythonDrawString),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandConstantE, I18n::Message::PythonConstantE, false),
ToolboxMessageTree::Leaf(I18n::Message::PythonCommandErf, I18n::Message::PythonErf),
@@ -536,6 +494,11 @@ KDCoordinate PythonToolbox::rowHeight(int j) {
bool PythonToolbox::selectLeaf(int selectedRow) {
m_selectableTableView.deselectTable();
ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->childAtIndex(selectedRow);
+ if(node->insertedText() == I18n::Message::IonSelector){
+ App::app()->toolboxIonKeys()->setSender(sender());
+ Container::activeApp()->displayModalViewController(static_cast(App::app()->toolboxIonKeys()), 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin);
+ return true;
+ }
const char * editedText = I18n::translate(node->insertedText());
// strippedEditedText array needs to be in the same scope as editedText
char strippedEditedText[k_maxMessageSize];
diff --git a/apps/code/toolbox.universal.i18n b/apps/code/toolbox.universal.i18n
index 72bd47ef965..4dd5345def6 100644
--- a/apps/code/toolbox.universal.i18n
+++ b/apps/code/toolbox.universal.i18n
@@ -57,3 +57,5 @@ PythonCommandDef = "def \x11():\n "
PythonCommandDefWithArg = "def function(x):"
PythonCommandReturn = "return "
RandomModule = "random"
+IonSelector = "Key selector"
+PressAKey = "Press a key"
diff --git a/apps/code/toolbox_ion_keys.cpp b/apps/code/toolbox_ion_keys.cpp
new file mode 100644
index 00000000000..b3e67f63f04
--- /dev/null
+++ b/apps/code/toolbox_ion_keys.cpp
@@ -0,0 +1,50 @@
+#include "toolbox_ion_keys.h"
+#include
+#include
+#include
+extern "C" {
+#include
+#include
+}
+extern const mp_rom_map_elem_t modion_module_globals_table[48];
+
+namespace Code {
+ toolboxIonKeys::toolboxIonKeys() :
+ ViewController(nullptr),
+ m_view()
+ {
+ }
+
+ bool toolboxIonKeys::handleEvent(Ion::Events::Event e) {
+ Ion::Keyboard::State state = Ion::Keyboard::scan();
+ for(uint16_t i = 0; i < sizeof(modion_module_globals_table)/sizeof(_mp_rom_map_elem_t); i++){
+ _mp_rom_map_elem_t element = modion_module_globals_table[i];
+ if(mp_obj_is_small_int(element.value)){
+ int key = mp_obj_get_int(element.value);
+ if(state.keyDown(static_cast(key))){
+ m_sender->handleEventWithText(qstr_str(MP_OBJ_QSTR_VALUE(element.key)), true);
+ }
+ }
+ }
+ Container::activeApp()->dismissModalViewController();
+ AppsContainer::sharedAppsContainer()->redrawWindow();
+ return true;
+ }
+
+ toolboxIonKeys::toolboxIonView::toolboxIonView():
+ View()
+ {
+ }
+
+ void toolboxIonKeys::toolboxIonView::drawRect(KDContext * ctx, KDRect rect) const {
+ ctx->fillRect(rect, Palette::GrayBright);
+ ctx->strokeRect(rect, Palette::GrayDark);
+ ctx->drawString(I18n::translate(I18n::Message::PressAKey),KDPoint(rect.left()+80, rect.top()+20));
+
+ }
+
+ View * toolboxIonKeys::view(){
+ return &m_view;
+ }
+
+}
diff --git a/apps/code/toolbox_ion_keys.h b/apps/code/toolbox_ion_keys.h
new file mode 100644
index 00000000000..4efe2036d9e
--- /dev/null
+++ b/apps/code/toolbox_ion_keys.h
@@ -0,0 +1,21 @@
+#include
+
+namespace Code {
+
+ class toolboxIonKeys : public ViewController {
+ public :
+ toolboxIonKeys();
+ View * view() override;
+ bool handleEvent(Ion::Events::Event e) override;
+ void setSender(InputEventHandler * sender) { m_sender = sender; }
+ private :
+ class toolboxIonView : public View {
+ public :
+ toolboxIonView();
+ void drawRect(KDContext * ctx, KDRect rect) const override;
+ };
+ toolboxIonView m_view;
+ InputEventHandler * m_sender;
+ };
+
+}
diff --git a/apps/external/archive.cpp b/apps/external/archive.cpp
index 5636f0ef61f..8f3d000bf7c 100644
--- a/apps/external/archive.cpp
+++ b/apps/external/archive.cpp
@@ -55,29 +55,43 @@ bool fileAtIndex(size_t index, File &entry) {
* TAR files are comprised of a set of records aligned to 512 bytes boundary
* followed by data.
*/
- while (index-- > 0) {
+
+ for(;;) {
+ // Calculate the size
size = 0;
for (int i = 0; i < 11; i++)
size = size * 8 + (tar->size[i] - '0');
+
+ // Check if we found our file.
+ if (index == 0) {
+ // If yes, check for sanity and for exam mode stuff
+ if (!isSane(tar) || isExamModeAndFileNotExecutable(tar)) {
+ return false;
+ }
- // Move to the next TAR header.
- unsigned stride = (sizeof(TarHeader) + size + 511);
- stride = (stride >> 9) << 9;
- tar = reinterpret_cast(reinterpret_cast(tar) + stride);
-
- // Sanity check.
- if (!isSane(tar) || isExamModeAndFileNotExecutable(tar)) {
- return false;
+ // File entry found, copy data out.
+ entry.name = tar->name;
+ entry.data = reinterpret_cast(tar) + sizeof(TarHeader);
+ entry.dataLength = size;
+ entry.isExecutable = (tar->mode[4] & 0x01) == 1;
+
+ return true;
+ } else {
+ // move to the next TAR header.
+ unsigned stride = (sizeof(TarHeader) + size + 511);
+ stride = (stride >> 9) << 9;
+ tar = reinterpret_cast(reinterpret_cast(tar) + stride);
+
+ // Sanity check.
+ if (!isSane(tar)) {
+ return false;
+ }
}
+ index--;
}
-
- // File entry found, copy data out.
- entry.name = tar->name;
- entry.data = reinterpret_cast(tar) + sizeof(TarHeader);
- entry.dataLength = size;
- entry.isExecutable = (tar->mode[4] & 0x01) == 1;
-
- return true;
+
+ // Achievement unlock: How did we get there ?
+ return false;
}
extern "C" void (* const apiPointers[])(void);
diff --git a/apps/home/apps_layout.csv b/apps/home/apps_layout.csv
index 64469620c74..77e47e4b882 100644
--- a/apps/home/apps_layout.csv
+++ b/apps/home/apps_layout.csv
@@ -1,2 +1,2 @@
-Default,calculation,rpn,graph,code,statistics,probability,solver,atom,sequence,regression,settings
-HidePython,calculation,rpn,graph,code,statistics,probability,solver,atom,sequence,regression,settings
\ No newline at end of file
+Default,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,settings
+HidePython,calculation,rpn,graph,code,statistics,probability,solver,atomic,sequence,regression,settings
diff --git a/apps/main.cpp b/apps/main.cpp
index 3a22fda5c77..d501a0d9a57 100644
--- a/apps/main.cpp
+++ b/apps/main.cpp
@@ -53,8 +53,12 @@ void ion_main(int argc, const char * const argv[]) {
const char * appNames[] = {"home", EPSILON_APPS_NAMES};
for (int j = 0; j < AppsContainer::sharedAppsContainer()->numberOfApps(); j++) {
App::Snapshot * snapshot = AppsContainer::sharedAppsContainer()->appSnapshotAtIndex(j);
- int cmp = strcmp(argv[i]+2, appNames[j]);
- if (cmp == '-') {
+ // Compare name in order to find if the firsts chars which are different are NULL and '-'
+ // -> check if the app name is in the argv
+ const char * s1 = argv[i]+2;
+ const char * s2 = appNames[j];
+ while (*s1 != '\0' && (*s1 == *s2)) {s1++; s2++;}
+ if (*s2 == '\0' && *s1 == '-') {
snapshot->setOpt(argv[i]+2+strlen(appNames[j])+1, argv[i+1]);
break;
}
diff --git a/apps/settings/main_controller.cpp b/apps/settings/main_controller.cpp
index 75b598d87b2..6b65f15d3ea 100644
--- a/apps/settings/main_controller.cpp
+++ b/apps/settings/main_controller.cpp
@@ -19,12 +19,8 @@ constexpr SettingsMessageTree s_symbolFunctionChildren[3] = {SettingsMessageTree
constexpr SettingsMessageTree s_modelMathOptionsChildren[6] = {SettingsMessageTree(I18n::Message::AngleUnit, s_modelAngleChildren), SettingsMessageTree(I18n::Message::DisplayMode, s_modelFloatDisplayModeChildren), SettingsMessageTree(I18n::Message::EditionMode, s_modelEditionModeChildren), SettingsMessageTree(I18n::Message::SymbolFunction, s_symbolFunctionChildren), SettingsMessageTree(I18n::Message::ComplexFormat, s_modelComplexFormatChildren), SettingsMessageTree(I18n::Message::SymbolMultiplication, s_symbolChildren)};
constexpr SettingsMessageTree s_modelFontChildren[2] = {SettingsMessageTree(I18n::Message::LargeFont), SettingsMessageTree(I18n::Message::SmallFont)};
constexpr SettingsMessageTree s_accessibilityChildren[6] = {SettingsMessageTree(I18n::Message::AccessibilityInvertColors), SettingsMessageTree(I18n::Message::AccessibilityMagnify),SettingsMessageTree(I18n::Message::AccessibilityGamma),SettingsMessageTree(I18n::Message::AccessibilityGammaRed),SettingsMessageTree(I18n::Message::AccessibilityGammaGreen),SettingsMessageTree(I18n::Message::AccessibilityGammaBlue)};
-constexpr SettingsMessageTree s_contributorsChildren[20] = {SettingsMessageTree(I18n::Message::Developers), SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::SandraSimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::David), SettingsMessageTree(I18n::Message::DamienNicolet), SettingsMessageTree(I18n::Message::EvannDreumont), SettingsMessageTree(I18n::Message::SzaboLevente), SettingsMessageTree(I18n::Message::VenceslasDuet), SettingsMessageTree(I18n::Message::CharlotteThomas), SettingsMessageTree(I18n::Message::AntoninLoubiere), SettingsMessageTree(I18n::Message::BetaTesters), SettingsMessageTree(I18n::Message::CyprienMejat), SettingsMessageTree(I18n::Message::TimeoArnouts), SettingsMessageTree(I18n::Message::JulieC), SettingsMessageTree(I18n::Message::LelahelHideux), SettingsMessageTree(I18n::Message::Madil), SettingsMessageTree(I18n::Message::HilaireLeRoux)};
-#ifdef OMEGA_USERNAME
+constexpr SettingsMessageTree s_contributorsChildren[23] = {SettingsMessageTree(I18n::Message::Developers), SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::SandraSimmons), SettingsMessageTree(I18n::Message::David), SettingsMessageTree(I18n::Message::DamienNicolet), SettingsMessageTree(I18n::Message::EvannDreumont), SettingsMessageTree(I18n::Message::SzaboLevente), SettingsMessageTree(I18n::Message::VenceslasDuet), SettingsMessageTree(I18n::Message::CharlotteThomas), SettingsMessageTree(I18n::Message::AntoninLoubiere), SettingsMessageTree(I18n::Message::CyprienMejat), SettingsMessageTree(I18n::Message::BetaTesters), SettingsMessageTree(I18n::Message::TimeoArnouts), SettingsMessageTree(I18n::Message::JulieC), SettingsMessageTree(I18n::Message::LelahelHideux), SettingsMessageTree(I18n::Message::Madil), SettingsMessageTree(I18n::Message::HilaireLeRoux), SettingsMessageTree(I18n::Message::HectorNussbaumer), SettingsMessageTree(I18n::Message::RaphaelDyda), SettingsMessageTree(I18n::Message::ThibautC)};
constexpr SettingsMessageTree s_modelAboutChildren[8] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::OmegaVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::MemUse), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren)};
-#else
-constexpr SettingsMessageTree s_modelAboutChildren[7] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::OmegaVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::MemUse), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren)};
-#endif
MainController::MainController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate) :
ViewController(parentResponder),
diff --git a/apps/settings/main_controller.h b/apps/settings/main_controller.h
index 7ef06c84a67..fd638a0cd9e 100644
--- a/apps/settings/main_controller.h
+++ b/apps/settings/main_controller.h
@@ -24,12 +24,8 @@ extern const Shared::SettingsMessageTree s_modelMathOptionsChildren[6];
extern const Shared::SettingsMessageTree s_modelFontChildren[2];
extern const Shared::SettingsMessageTree s_modelDateTimeChildren[3];
extern const Shared::SettingsMessageTree s_accessibilityChildren[6];
-extern const Shared::SettingsMessageTree s_contributorsChildren[20];
-#ifdef OMEGA_USERNAME
+extern const Shared::SettingsMessageTree s_contributorsChildren[23];
extern const Shared::SettingsMessageTree s_modelAboutChildren[8];
-#else
-extern const Shared::SettingsMessageTree s_modelAboutChildren[7];
-#endif
extern const Shared::SettingsMessageTree s_model;
class MainController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource {
diff --git a/apps/settings/sub_menu/about_controller.cpp b/apps/settings/sub_menu/about_controller.cpp
index a295eb02934..e2fe3f5a611 100644
--- a/apps/settings/sub_menu/about_controller.cpp
+++ b/apps/settings/sub_menu/about_controller.cpp
@@ -29,7 +29,7 @@ AboutController::AboutController(Responder * parentResponder) :
}
bool AboutController::handleEvent(Ion::Events::Event event) {
- I18n::Message childLabel = m_messageTreeModel->childAtIndex(selectedRow())->label();
+ I18n::Message childLabel = m_messageTreeModel->childAtIndex(selectedRow()+(!hasUsernameCell()))->label();
/* We hide here the activation hardware test app: in the menu "about", by
* clicking on '6' on the last row. */
if ((event == Ion::Events::Six || event == Ion::Events::LowerT || event == Ion::Events::UpperT) && childLabel == I18n::Message::FccId) {
@@ -39,8 +39,9 @@ bool AboutController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) {
if (childLabel == I18n::Message::Contributors) {
GenericSubController * subController = &m_contributorsController;
- subController->setMessageTreeModel(m_messageTreeModel->childAtIndex(selectedRow()));
+ subController->setMessageTreeModel(m_messageTreeModel->childAtIndex(selectedRow()+(!hasUsernameCell())));
StackViewController * stack = stackController();
+ m_lastSelect = selectedRow();
stack->push(subController);
return true;
}
@@ -96,11 +97,15 @@ bool AboutController::handleEvent(Ion::Events::Event event) {
return GenericSubController::handleEvent(event);
}
+int AboutController::numberOfRows() const {
+ return m_messageTreeModel->numberOfChildren() - (!hasUsernameCell());
+}
+
HighlightCell * AboutController::reusableCell(int index, int type) {
assert(index >= 0);
if (type == 0) {
- assert(index < k_totalNumberOfCell-1);
- return &m_cells[index];
+ assert(index < k_totalNumberOfCell-1-(!hasUsernameCell()));
+ return &m_cells[index+(!hasUsernameCell())];
}
assert(index == 0);
return &m_contributorsCell;
@@ -113,7 +118,7 @@ int AboutController::typeAtLocation(int i, int j) {
int AboutController::reusableCellCount(int type) {
switch (type) {
case 0:
- return k_totalNumberOfCell-1;
+ return k_totalNumberOfCell-1-(!hasUsernameCell());
case 1:
return 1;
default:
@@ -122,13 +127,18 @@ int AboutController::reusableCellCount(int type) {
}
}
+bool AboutController::hasUsernameCell() const {
+ return (*Ion::username()) != 0;
+}
+
void AboutController::willDisplayCellForIndex(HighlightCell * cell, int index) {
- GenericSubController::willDisplayCellForIndex(cell, index);
+ int i = index + (!hasUsernameCell());
+ GenericSubController::willDisplayCellForIndex(cell, i);
assert(index >= 0 && index < k_totalNumberOfCell);
- if (m_messageTreeModel->childAtIndex(index)->label() == I18n::Message::Contributors) {
+ if (m_messageTreeModel->childAtIndex(i)->label() == I18n::Message::Contributors) {
MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell;
myTextCell->setSubtitle(I18n::Message::Default);
- } else if (m_messageTreeModel->childAtIndex(index)->label() == I18n::Message::MemUse) {
+ } else if (m_messageTreeModel->childAtIndex(i)->label() == I18n::Message::MemUse) {
char memUseBuffer[15];
int len = Poincare::Integer((int)((float) (Ion::Storage::k_storageSize - Ion::Storage::sharedStorage()->availableSize()) / 1024.f)).serialize(memUseBuffer, 4);
memUseBuffer[len] = 'k';
@@ -146,17 +156,16 @@ void AboutController::willDisplayCellForIndex(HighlightCell * cell, int index) {
MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell;
static const char * mpVersion = MICROPY_VERSION_STRING;
static const char * messages[] = {
-#ifdef OMEGA_USERNAME
Ion::username(),
-#endif
Ion::softwareVersion(),
Ion::omegaVersion(),
mpVersion,
"",
Ion::serialNumber(),
- Ion::fccId()
+ Ion::fccId(),
+ ""
};
- myCell->setAccessoryText(messages[index]);
+ myCell->setAccessoryText(messages[i]);
}
}
diff --git a/apps/settings/sub_menu/about_controller.h b/apps/settings/sub_menu/about_controller.h
index e94a6e2aa67..beef15d95cb 100644
--- a/apps/settings/sub_menu/about_controller.h
+++ b/apps/settings/sub_menu/about_controller.h
@@ -20,12 +20,10 @@ class AboutController : public GenericSubController {
int reusableCellCount(int type) override;
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
int typeAtLocation(int i, int j) override;
+ int numberOfRows() const override;
private:
-#ifdef OMEGA_USERNAME
constexpr static int k_totalNumberOfCell = 8;
-#else
- constexpr static int k_totalNumberOfCell = 7;
-#endif
+ bool hasUsernameCell() const;
ContributorsController m_contributorsController;
MessageTableCellWithChevronAndMessage m_contributorsCell;
//SelectableViewWithMessages m_view;
diff --git a/apps/settings/sub_menu/contributors_controller.cpp b/apps/settings/sub_menu/contributors_controller.cpp
index 19fc88895ee..26bab3326a5 100644
--- a/apps/settings/sub_menu/contributors_controller.cpp
+++ b/apps/settings/sub_menu/contributors_controller.cpp
@@ -28,13 +28,13 @@ int ContributorsController::reusableCellCount(int type) {
return k_totalNumberOfCell;
}
-constexpr static int s_numberOfDevelopers = 12;
+constexpr static int s_numberOfDevelopers = 13;
constexpr static I18n::Message s_developersUsernames[s_numberOfDevelopers] = {
I18n::Message::PQuentinGuidee,
- I18n::Message::PSandraSimmons,
I18n::Message::PJoachimLeFournis,
- I18n::Message::PJeanBaptisteBoric,
I18n::Message::PMaximeFriess,
+ I18n::Message::PJeanBaptisteBoric,
+ I18n::Message::PSandraSimmons,
I18n::Message::PDavid,
I18n::Message::PDamienNicolet,
I18n::Message::PEvannDreumont,
@@ -42,16 +42,19 @@ constexpr static I18n::Message s_developersUsernames[s_numberOfDevelopers] = {
I18n::Message::PVenceslasDuet,
I18n::Message::PCharlotteThomas,
I18n::Message::PAntoninLoubiere,
+ I18n::Message::PCyprienMejat,
};
-constexpr static int s_numberOfBetaTesters = 6;
+constexpr static int s_numberOfBetaTesters = 8;
constexpr static I18n::Message s_betaTestersUsernames[s_numberOfBetaTesters] = {
- I18n::Message::PCyprienMejat,
I18n::Message::PTimeoArnouts,
I18n::Message::PJulieC,
I18n::Message::PLelahelHideux,
I18n::Message::PMadil,
I18n::Message::PHilaireLeRoux,
+ I18n::Message::PHectorNussbaumer,
+ I18n::Message::PRaphaelDyda,
+ I18n::Message::PThibautC,
};
void ContributorsController::willDisplayCellForIndex(HighlightCell * cell, int index) {
diff --git a/apps/settings/sub_menu/generic_sub_controller.h b/apps/settings/sub_menu/generic_sub_controller.h
index c149a250857..d48336d9fe5 100644
--- a/apps/settings/sub_menu/generic_sub_controller.h
+++ b/apps/settings/sub_menu/generic_sub_controller.h
@@ -23,8 +23,9 @@ class GenericSubController : public ViewController, public ListViewDataSource, p
void setMessageTreeModel(const MessageTree * messageTreeModel);
void viewDidDisappear() override;
protected:
+ int m_lastSelect = 0;
StackViewController * stackController() const;
- virtual int initialSelectedRow() const { return 0; }
+ virtual int initialSelectedRow() const { return m_lastSelect; }
constexpr static KDCoordinate k_topBottomMargin = 13;
SelectableTableView m_selectableTableView;
MessageTree * m_messageTreeModel;
diff --git a/apps/settings/sub_menu/math_options_controller.cpp b/apps/settings/sub_menu/math_options_controller.cpp
index b1a239506f3..50566ba60ff 100644
--- a/apps/settings/sub_menu/math_options_controller.cpp
+++ b/apps/settings/sub_menu/math_options_controller.cpp
@@ -25,6 +25,7 @@ bool MathOptionsController::handleEvent(Ion::Events::Event event) {
subController = &m_preferencesController;
subController->setMessageTreeModel(m_messageTreeModel->childAtIndex(selectedRow()));
StackViewController * stack = stackController();
+ m_lastSelect = selectedRow();
stack->push(subController);
return true;
}
diff --git a/apps/shared.universal.i18n b/apps/shared.universal.i18n
index 97c75c00e60..fb927a65962 100644
--- a/apps/shared.universal.i18n
+++ b/apps/shared.universal.i18n
@@ -343,7 +343,7 @@ CyprienMejat = "Cyprien Méjat"
PCyprienMejat = "@A2drien"
TimeoArnouts = "Timéo Arnouts"
PTimeoArnouts = "@Dogm"
-JulieC = "Julie C"
+JulieC = "Julie C."
PJulieC = "@windows9x95"
LelahelHideux = "Lélahel Hideux"
PLelahelHideux = "@Lelahelry"
@@ -351,6 +351,12 @@ Madil = "Madil"
PMadil = "@le-grand-mannitout"
HilaireLeRoux = "Hilaire Le Roux"
PHilaireLeRoux = "@0Babass2"
+HectorNussbaumer = "Hector Nussbaumer"
+PHectorNussbaumer = "@Sycorax"
+RaphaelDyda = "Raphaël Dyda"
+PRaphaelDyda = "@Trixciel"
+ThibautC = "Thibaut C."
+PThibautC = "@Tibo_C"
SpeedOfLight = "2.99792458·10^8_m_s^-1"
YearLight = "9.461·10^15_m"
Boltzmann = "1.380649·10^-23_J_K^-1"
diff --git a/build/config.mak b/build/config.mak
index a45c7d936dc..444542c7198 100644
--- a/build/config.mak
+++ b/build/config.mak
@@ -5,11 +5,11 @@ DEBUG ?= 0
HOME_DISPLAY_EXTERNALS ?= 1
EPSILON_VERSION ?= 15.3.1
-OMEGA_VERSION ?= 1.21.0
+OMEGA_VERSION ?= 1.22.0
# OMEGA_USERNAME ?= N/A
OMEGA_STATE ?= public
-EPSILON_APPS ?= calculation rpn graph code statistics probability solver atom sequence regression settings external
-SUBMODULES_APPS = atom rpn
+EPSILON_APPS ?= calculation rpn graph code statistics probability solver atomic sequence regression settings external
+SUBMODULES_APPS = atomic rpn
EPSILON_I18N ?= en fr nl pt it de es hu
EPSILON_COUNTRIES ?= WW CA DE ES FR GB IT NL PT US
EPSILON_GETOPT ?= 0
diff --git a/build/device/dfu.py b/build/device/dfu.py
index bcb566b6331..bac05e3e5d7 100644
--- a/build/device/dfu.py
+++ b/build/device/dfu.py
@@ -4,6 +4,8 @@
# This work is licensed under the MIT license, see the file LICENSE for
# details.
+# This script has been modified by NumWorks contributors
+
"""This module implements enough functionality to program the STM32F4xx over
DFU, without requiring dfu-util.
See app note AN3156 for a description of the DFU protocol.
diff --git a/build/device/usb/__init__.py b/build/device/usb/__init__.py
old mode 100755
new mode 100644
index 6d510457722..13c2fbf3220
--- a/build/device/usb/__init__.py
+++ b/build/device/usb/__init__.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
r"""PyUSB - Easy USB access in Python
@@ -33,8 +48,19 @@
__author__ = 'Wander Lairson Costa'
# Use Semantic Versioning, http://semver.org/
-version_info = (1, 0, 2)
-__version__ = '%d.%d.%d' % version_info
+try:
+ from usb._version import version as __version__
+except ImportError:
+ __version__ = '0.0.0'
+
+def _get_extended_version_info(version):
+ import re
+ m = re.match(r'(\d+)\.(\d+)\.(\d+)[.-]?(.*)', version)
+ major, minor, patch, suffix = m.groups()
+ return int(major), int(minor), int(patch), suffix
+
+extended_version_info = _get_extended_version_info(__version__)
+version_info = extended_version_info[:3]
__all__ = ['legacy', 'control', 'core', 'backend', 'util', 'libloader']
diff --git a/build/device/usb/_debug.py b/build/device/usb/_debug.py
old mode 100755
new mode 100644
index 8c2a2b1aa21..a4ca7e82e4a
--- a/build/device/usb/_debug.py
+++ b/build/device/usb/_debug.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
__author__ = 'Wander Lairson Costa'
diff --git a/build/device/usb/_interop.py b/build/device/usb/_interop.py
old mode 100755
new mode 100644
index 96b019365bf..5729f910eda
--- a/build/device/usb/_interop.py
+++ b/build/device/usb/_interop.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# All the hacks necessary to assure compatibility across all
# supported versions come here.
@@ -81,5 +96,5 @@ def as_array(data=None):
# When you pass a unicode string or a character sequence,
# you get a TypeError if the first parameter does not match
a = array.array('B')
- a.fromstring(data) # deprecated since 3.2
+ a.frombytes(data.encode('utf-8'))
return a
diff --git a/build/device/usb/_lookup.py b/build/device/usb/_lookup.py
old mode 100755
new mode 100644
index 82170b744da..68695de0e13
--- a/build/device/usb/_lookup.py
+++ b/build/device/usb/_lookup.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
r"""usb._lookups - Lookup tables for USB
"""
diff --git a/build/device/usb/_objfinalizer.py b/build/device/usb/_objfinalizer.py
old mode 100755
new mode 100644
index ad873607400..dededa85381
--- a/build/device/usb/_objfinalizer.py
+++ b/build/device/usb/_objfinalizer.py
@@ -1,19 +1,34 @@
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import sys
diff --git a/build/device/usb/backend/__init__.py b/build/device/usb/backend/__init__.py
old mode 100755
new mode 100644
index 2ff11806928..f28e4940f6a
--- a/build/device/usb/backend/__init__.py
+++ b/build/device/usb/backend/__init__.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
r"""usb.backend - Backend interface.
@@ -62,7 +77,7 @@ def get_backend():
__author__ = 'Wander Lairson Costa'
-__all__ = ['IBackend', 'libusb01', 'libusb10', 'openusb']
+__all__ = ['IBackend', 'libusb0', 'libusb1', 'openusb']
def _not_implemented(func):
raise NotImplementedError(func.__name__)
@@ -196,7 +211,7 @@ def set_interface_altsetting(self, dev_handle, intf, altsetting):
This method should only be called when the interface has more than
one alternate setting. The dev_handle is the value returned by the
- open_device() method. intf and altsetting are respectivelly the
+ open_device() method. intf and altsetting are respectively the
bInterfaceNumber and bAlternateSetting fields of the related interface.
"""
_not_implemented(self.set_interface_altsetting)
@@ -268,7 +283,7 @@ def intr_write(self, dev_handle, ep, intf, data, timeout):
_not_implemented(self.intr_write)
def intr_read(self, dev_handle, ep, intf, size, timeout):
- r"""Perform an interrut read.
+ r"""Perform an interrupt read.
dev_handle is the value returned by the open_device() method.
The ep parameter is the bEndpointAddress field whose endpoint
diff --git a/build/device/usb/backend/libusb0.py b/build/device/usb/backend/libusb0.py
old mode 100755
new mode 100644
index ff04475f5ec..c2183af8ddd
--- a/build/device/usb/backend/libusb0.py
+++ b/build/device/usb/backend/libusb0.py
@@ -1,24 +1,40 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from ctypes import *
+import errno
import os
import usb.backend
import usb.util
import sys
-from usb.core import USBError
+from usb.core import USBError, USBTimeoutError
from usb._debug import methodtrace
import usb._interop as _interop
import logging
@@ -30,6 +46,8 @@
_logger = logging.getLogger('usb.backend.libusb0')
+_USBFS_MAXDRIVERNAME = 255
+
# usb.h
if sys.platform.find('bsd') != -1 or sys.platform.find('mac') != -1 or \
@@ -350,6 +368,14 @@ def _setup_prototypes(lib):
# linux only
+ # int usb_get_driver_np(usb_dev_handle *dev,
+ # int interface,
+ # char *name,
+ # unsigned int namelen);
+ if hasattr(lib, 'usb_get_driver_np'):
+ lib.usb_get_driver_np.argtypes = \
+ [_usb_dev_handle, c_int, c_char_p, c_uint]
+
# int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface);
if hasattr(lib, 'usb_detach_kernel_driver_np'):
lib.usb_detach_kernel_driver_np.argtypes = [_usb_dev_handle, c_int]
@@ -415,6 +441,9 @@ def _check(ret):
errmsg = os.strerror(-ret)
else:
return ret
+
+ if ret is not None and -ret == errno.ETIMEDOUT:
+ raise USBTimeoutError(errmsg, ret, -ret)
raise USBError(errmsg, ret)
def _has_iso_transfer():
@@ -588,8 +617,35 @@ def clear_halt(self, dev_handle, ep):
def reset_device(self, dev_handle):
_check(_lib.usb_reset(dev_handle))
+ @methodtrace(_logger)
+ def is_kernel_driver_active(self, dev_handle, intf):
+ if not hasattr(_lib, 'usb_get_driver_np'):
+ raise NotImplementedError(self.is_kernel_driver_active.__name__)
+ from errno import ENODATA
+ buf = usb.util.create_buffer(_USBFS_MAXDRIVERNAME + 1)
+ name, length = buf.buffer_info()
+ length *= buf.itemsize
+ # based on the implementation of libusb_kernel_driver_active
+ # (see libusb/os/linux_usbfs.c @@ op_kernel_driver_active):
+ # usb_get_driver_np fails with ENODATA when no kernel driver is bound,
+ # and if 'usbfs' is bound that means that a userspace program is
+ # controlling the device (e.g. using this very library)
+ try:
+ _check(_lib.usb_get_driver_np(
+ dev_handle,
+ intf,
+ cast(name, c_char_p),
+ length))
+ return cast(name, c_char_p).value != b'usbfs'
+ except USBError as err:
+ if err.backend_error_code == -ENODATA:
+ return False
+ raise err
+
@methodtrace(_logger)
def detach_kernel_driver(self, dev_handle, intf):
+ if not hasattr(_lib, 'usb_detach_kernel_driver_np'):
+ raise NotImplementedError(self.detach_kernel_driver.__name__)
_check(_lib.usb_detach_kernel_driver_np(dev_handle, intf))
def __write(self, fn, dev_handle, ep, intf, data, timeout):
diff --git a/build/device/usb/backend/libusb1.py b/build/device/usb/backend/libusb1.py
old mode 100755
new mode 100644
index de30c256a7a..6615d68b780
--- a/build/device/usb/backend/libusb1.py
+++ b/build/device/usb/backend/libusb1.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from ctypes import *
import usb.util
@@ -22,14 +37,14 @@
import usb._objfinalizer as _objfinalizer
import errno
import math
-from usb.core import USBError
+from usb.core import USBError, USBTimeoutError
import usb.libloader
__author__ = 'Wander Lairson Costa'
__all__ = [
'get_backend',
- 'LIBUSB_SUCESS',
+ 'LIBUSB_SUCCESS',
'LIBUSB_ERROR_IO',
'LIBUSB_ERROR_INVALID_PARAM',
'LIBUSB_ERROR_ACCESS',
@@ -42,14 +57,14 @@
'LIBUSB_ERROR_INTERRUPTED',
'LIBUSB_ERROR_NO_MEM',
'LIBUSB_ERROR_NOT_SUPPORTED',
- 'LIBUSB_ERROR_OTHER'
+ 'LIBUSB_ERROR_OTHER',
'LIBUSB_TRANSFER_COMPLETED',
'LIBUSB_TRANSFER_ERROR',
'LIBUSB_TRANSFER_TIMED_OUT',
'LIBUSB_TRANSFER_CANCELLED',
'LIBUSB_TRANSFER_STALL',
'LIBUSB_TRANSFER_NO_DEVICE',
- 'LIBUSB_TRANSFER_OVERFLOW'
+ 'LIBUSB_TRANSFER_OVERFLOW',
]
_logger = logging.getLogger('usb.backend.libusb1')
@@ -256,6 +271,7 @@ def _get_iso_packet_list(transfer):
return list_type.from_address(addressof(transfer.iso_packet_desc))
_lib = None
+_lib_object = None
def _load_library(find_library=None):
# Windows backend uses stdcall calling convention
@@ -582,6 +598,8 @@ def _check(ret):
if ret < 0:
if ret == LIBUSB_ERROR_NOT_SUPPORTED:
raise NotImplementedError(_strerror(ret))
+ elif ret == LIBUSB_ERROR_TIMEOUT:
+ raise USBTimeoutError(_strerror(ret), ret, _libusb_errno[ret])
else:
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
@@ -700,7 +718,8 @@ def __init__(self, lib):
@methodtrace(_logger)
def _finalize_object(self):
- self.lib.libusb_exit(self.ctx)
+ if self.ctx:
+ self.lib.libusb_exit(self.ctx)
@methodtrace(_logger)
@@ -936,12 +955,13 @@ def __read(self, fn, dev_handle, ep, intf, buff, timeout):
return transferred.value
def get_backend(find_library=None):
- global _lib
+ global _lib, _lib_object
try:
- if _lib is None:
+ if _lib_object is None:
_lib = _load_library(find_library=find_library)
_setup_prototypes(_lib)
- return _LibUSB(_lib)
+ _lib_object = _LibUSB(_lib)
+ return _lib_object
except usb.libloader.LibraryException:
# exception already logged (if any)
_logger.error('Error loading libusb 1.0 backend', exc_info=False)
diff --git a/build/device/usb/backend/openusb.py b/build/device/usb/backend/openusb.py
old mode 100755
new mode 100644
index 55e75c9941b..11e419ac958
--- a/build/device/usb/backend/openusb.py
+++ b/build/device/usb/backend/openusb.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from ctypes import *
import ctypes.util
@@ -24,7 +39,7 @@
import usb._objfinalizer as _objfinalizer
import usb.util as util
import usb.libloader
-from usb.core import USBError
+from usb.core import USBError, USBTimeoutError
__author__ = 'Wander Lairson Costa'
@@ -458,7 +473,7 @@ def _setup_prototypes(lib):
POINTER(_openusb_intr_request)
]
- lib.openusb_bulk_xfer.restype = c_int32
+ lib.openusb_intr_xfer.restype = c_int32
# int32_t openusb_bulk_xfer(openusb_dev_handle_t dev,
# uint8_t ifc,
@@ -491,7 +506,11 @@ def _check(ret):
ret = ret.value
if ret != 0:
- raise USBError(_lib.openusb_strerror(ret), ret, _openusb_errno[ret])
+ if ret == OPENUSB_IO_TIMEOUT:
+ raise USBTimeoutError(_lib.openusb_strerror(ret), ret, _openusb_errno[ret])
+ else:
+ raise USBError(_lib.openusb_strerror(ret), ret, _openusb_errno[ret])
+
return ret
class _Context(_objfinalizer.AutoFinalizedObject):
@@ -726,6 +745,7 @@ def get_backend(find_library=None):
_lib = _load_library(find_library)
_setup_prototypes(_lib)
_ctx = _Context()
+ _logger.warning('OpenUSB backend deprecated (https://github.com/pyusb/pyusb/issues/284)')
return _OpenUSB()
except usb.libloader.LibraryException:
# exception already logged (if any)
diff --git a/build/device/usb/control.py b/build/device/usb/control.py
old mode 100755
new mode 100644
index 53b18826d2f..f46ced1bfa3
--- a/build/device/usb/control.py
+++ b/build/device/usb/control.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
r"""usb.control - USB standard control requests
@@ -152,13 +167,18 @@ def get_descriptor(dev, desc_size, desc_type, desc_index, wIndex = 0):
util.CTRL_TYPE_STANDARD,
util.CTRL_RECIPIENT_DEVICE)
- return dev.ctrl_transfer(
+ desc = dev.ctrl_transfer(
bmRequestType = bmRequestType,
bRequest = 0x06,
wValue = wValue,
wIndex = wIndex,
data_or_wLength = desc_size)
+ if len(desc) < 2:
+ raise USBError('Invalid descriptor')
+
+ return desc
+
def set_descriptor(dev, desc, desc_type, desc_index, wIndex = None):
r"""Update an existing descriptor or add a new one.
diff --git a/build/device/usb/core.py b/build/device/usb/core.py
old mode 100755
new mode 100644
index 39685fe1bb1..7546de2bc2e
--- a/build/device/usb/core.py
+++ b/build/device/usb/core.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
r"""usb.core - Core USB features.
@@ -27,8 +42,8 @@
__author__ = 'Wander Lairson Costa'
-__all__ = [ 'Device', 'Configuration', 'Interface', 'Endpoint', 'find',
- 'show_devices' ]
+__all__ = [ 'Device', 'Configuration', 'Interface', 'Endpoint', 'USBError',
+ 'USBTimeoutError', 'NoBackendError', 'find', 'show_devices' ]
import usb.util as util
import copy
@@ -45,10 +60,19 @@
_DEFAULT_TIMEOUT = 1000
+_sentinel = object()
+
def _set_attr(input, output, fields):
for f in fields:
setattr(output, f, getattr(input, f))
+def _try_getattr(object, name):
+ try:
+ attr = getattr(object, name)
+ except :
+ attr = _sentinel
+ return attr
+
def _try_get_string(dev, index, langid = None, default_str_i0 = "",
default_access_error = "Error Accessing String"):
""" try to get a string, but return a string no matter what
@@ -182,6 +206,8 @@ def managed_set_interface(self, device, intf, alt):
i = util.find_descriptor(cfg, bInterfaceNumber=intf, bAlternateSetting=alt)
else:
i = util.find_descriptor(cfg, bInterfaceNumber=intf)
+ if i is None:
+ raise ValueError('No matching interface (' + str(intf) + ',' + str(alt) + ')')
self.managed_claim_interface(device, i)
@@ -270,6 +296,14 @@ def __init__(self, strerror, error_code = None, errno = None):
IOError.__init__(self, errno, strerror)
self.backend_error_code = error_code
+class USBTimeoutError(USBError):
+ r"""Exception class for connection timeout errors.
+
+ Backends must raise this exception when a call on a USB connection returns
+ a timeout error code.
+ """
+ pass
+
class NoBackendError(ValueError):
r"Exception class when a valid backend is not found."
pass
@@ -1247,7 +1281,7 @@ def is_printer(dev):
def device_iter(**kwargs):
for dev in backend.enumerate_devices():
d = Device(dev, backend)
- tests = (val == getattr(d, key) for key, val in kwargs.items())
+ tests = (val == _try_getattr(d, key) for key, val in kwargs.items())
if _interop._all(tests) and (custom_match is None or custom_match(d)):
yield d
diff --git a/build/device/usb/legacy.py b/build/device/usb/legacy.py
old mode 100755
new mode 100644
index ae84ae1b0de..67d1d175d51
--- a/build/device/usb/legacy.py
+++ b/build/device/usb/legacy.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import usb.core as core
import usb.util as util
diff --git a/build/device/usb/libloader.py b/build/device/usb/libloader.py
old mode 100755
new mode 100644
index 07fa85a9dae..b4bea55df61
--- a/build/device/usb/libloader.py
+++ b/build/device/usb/libloader.py
@@ -1,19 +1,34 @@
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import ctypes
import ctypes.util
diff --git a/build/device/usb/util.py b/build/device/usb/util.py
old mode 100755
new mode 100644
index ff9ec81e0c6..0f3967efbd2
--- a/build/device/usb/util.py
+++ b/build/device/usb/util.py
@@ -1,17 +1,32 @@
-# Copyright (C) 2009-2017 Wander Lairson Costa
-# Copyright (C) 2017-2018 Robert Wlodarczyk
+# Copyright 2009-2017 Wander Lairson Costa
+# Copyright 2009-2021 PyUSB contributors
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
r"""usb.util - Utility functions.
@@ -286,32 +301,28 @@ def get_string(dev, index, langid = None):
The return value is the unicode string present in the descriptor, or None
if the requested index was zero.
-
- It is a ValueError to request a real string (index not zero), if: the
- device's langid tuple is empty, or with an explicit langid the device does
- not support.
"""
if 0 == index:
return None
from usb.control import get_descriptor
- langids = dev.langids
- if 0 == len(langids):
- raise ValueError("The device has no langid")
if langid is None:
+ langids = dev.langids
+ if 0 == len(langids):
+ raise ValueError("The device has no langid"
+ " (permission issue, no string descriptors supported or device error)")
langid = langids[0]
- elif langid not in langids:
- raise ValueError("The device does not support the specified langid")
buf = get_descriptor(
dev,
- 255, # Maximum descriptor size
+ 254, # maximum even length
DESC_TYPE_STRING,
index,
langid
)
+ blen = buf[0] & 0xfe # should be even, ignore any trailing byte (see #154)
if hexversion >= 0x03020000:
- return buf[2:buf[0]].tobytes().decode('utf-16-le')
+ return buf[2:blen].tobytes().decode('utf-16-le')
else:
- return buf[2:buf[0]].tostring().decode('utf-16-le')
+ return buf[2:blen].tostring().decode('utf-16-le')
diff --git a/build/targets.simulator.windows.mak b/build/targets.simulator.windows.mak
index eef0ca30ea3..c0aa03b8f48 100644
--- a/build/targets.simulator.windows.mak
+++ b/build/targets.simulator.windows.mak
@@ -1,4 +1,4 @@
PHONY: %_run
-t %_run: $(BUILD_DIR)/%.$(EXE)
+%_run: $(BUILD_DIR)/%.$(EXE)
$(call rule_label,EXE)
$(Q) ./$^
diff --git a/escher/image/inliner.c b/escher/image/inliner.c
index 289fec639a0..c2e9d489448 100644
--- a/escher/image/inliner.c
+++ b/escher/image/inliner.c
@@ -104,6 +104,12 @@ int main(int argc, char * argv[]) {
FILE * implementation = fopen(implementationPath, "w");
generateImplementationFromImage(implementation, lowerSnakeCaseName, camelCaseName, width, height, colorType, rowPointers);
fclose(implementation);
+
+ for (int i=0; i(SDL_AndroidGetJNIEnv());
jobject activity = static_cast(SDL_AndroidGetActivity());
- jclass j_class = env->FindClass("com/numworks/calculator/EpsilonActivity");
+ jclass j_class = env->FindClass("io/github/omega/simulator/OmegaActivity");
jmethodID j_methodId = env->GetMethodID(j_class,"hapticFeedbackIsEnabled", "()Z");
return env->CallObjectMethod(activity, j_methodId);
diff --git a/ion/src/simulator/shared/clipboard.cpp b/ion/src/simulator/shared/clipboard.cpp
index 896def716db..9c3303691e3 100644
--- a/ion/src/simulator/shared/clipboard.cpp
+++ b/ion/src/simulator/shared/clipboard.cpp
@@ -25,6 +25,14 @@ const char * read() {
return nullptr;
}
+ char * cursor = &buffer[0];
+ while(*cursor) {
+ if(*cursor == '\r' && *(cursor + 1) == '\n') {
+ memmove(cursor, cursor + 1, strlen(cursor));
+ }
+ cursor++;
+ }
+
/* If version has not changed, the user has not copied any text since the
* last call to write. A copy of the text already exists in
* Escher::Clipboard, and has been translated to best suit the current app :
diff --git a/poincare/Makefile b/poincare/Makefile
index 45d66bdc971..eca0b7ed8d8 100644
--- a/poincare/Makefile
+++ b/poincare/Makefile
@@ -12,6 +12,7 @@ poincare_src += $(addprefix poincare/src/,\
grid_layout.cpp \
horizontal_layout.cpp \
integral_layout.cpp \
+ kmat.cpp \
layout_cursor.cpp \
layout.cpp \
layout_node.cpp \
diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h
index 305c0099e4d..5a5dbccb241 100644
--- a/poincare/include/poincare/expression_node.h
+++ b/poincare/include/poincare/expression_node.h
@@ -79,6 +79,7 @@ class ExpressionNode : public TreeNode {
Integral,
InvBinom,
InvNorm,
+ KMat,
LeastCommonMultiple,
Logarithm,
MatrixTrace,
diff --git a/poincare/include/poincare/kmat.h b/poincare/include/poincare/kmat.h
new file mode 100644
index 00000000000..d0e5df23a9a
--- /dev/null
+++ b/poincare/include/poincare/kmat.h
@@ -0,0 +1,57 @@
+#ifndef POINCARE_KMAT_H
+#define POINCARE_KMAT_H
+
+#include
+#include
+
+namespace Poincare {
+
+class KMatNode final : public ExpressionNode {
+public:
+
+ // TreeNode
+ size_t size() const override { return sizeof(KMatNode); }
+ int numberOfChildren() const override;
+#if POINCARE_TREE_LOG
+ void logNodeName(std::ostream & stream) const override {
+ stream << "KMat";
+ }
+#endif
+
+ // Properties
+ Type type() const override { return Type::KMat; }
+
+private:
+ // Layout
+ Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
+ int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
+
+ // Simplification
+ Expression shallowReduce(ReductionContext reductionContext) override;
+ LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
+ LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
+
+ // Evaluation
+ Evaluation approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate(approximationContext); }
+ Evaluation approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate(approximationContext); }
+ template
+ Evaluation templatedApproximate(ApproximationContext approximationContext) const {
+ return Complex::Undefined();
+ }
+};
+
+class KMat final : public Expression {
+public:
+ KMat(const KMatNode * n) : Expression(n) {}
+ static KMat Builder(Expression child0, Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder({child0, child1, child2}); }
+
+
+ static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("kmat", 3, &UntypedBuilderThreeChildren);
+
+ Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
+
+};
+
+}
+
+#endif
diff --git a/poincare/include/poincare_nodes.h b/poincare/include/poincare_nodes.h
index c0d3a853e15..a3f8499953b 100644
--- a/poincare/include/poincare_nodes.h
+++ b/poincare/include/poincare_nodes.h
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/poincare/src/kmat.cpp b/poincare/src/kmat.cpp
new file mode 100644
index 00000000000..45a7a891c34
--- /dev/null
+++ b/poincare/src/kmat.cpp
@@ -0,0 +1,70 @@
+#include
+#include
+#include
+#include
+#include
+#include "parsing/token.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Poincare {
+
+constexpr Expression::FunctionHelper KMat::s_functionHelper;
+
+int KMatNode::numberOfChildren() const { return KMat::s_functionHelper.numberOfChildren(); }
+
+Layout KMatNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
+ return LayoutHelper::Prefix(KMat(this), floatDisplayMode, numberOfSignificantDigits, KMat::s_functionHelper.name());
+}
+
+int KMatNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
+ return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, KMat::s_functionHelper.name());
+}
+
+Expression KMatNode::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
+ return KMat(this).shallowReduce(reductionContext);
+}
+
+Expression KMat::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
+ Expression c0 = childAtIndex(0);
+ Expression c1 = childAtIndex(1);
+ if (c0.type() == ExpressionNode::Type::Rational) {
+ Rational r0 = static_cast(c0);
+ if (!r0.isInteger() || r0.signedIntegerNumerator().isNegative()) {
+ return replaceWithUndefinedInPlace();
+ }
+ }
+ if (c1.type() == ExpressionNode::Type::Rational) {
+ Rational r1 = static_cast(c1);
+ if (!r1.isInteger() || r1.signedIntegerNumerator().isNegative()) {
+ return replaceWithUndefinedInPlace();
+ }
+ }
+ if (c0.type() != ExpressionNode::Type::Rational || c1.type() != ExpressionNode::Type::Rational) {
+ return *this;
+ }
+
+ Rational r0 = static_cast(c0);
+ Rational r1 = static_cast(c1);
+
+ Integer w = r0.signedIntegerNumerator();
+ Integer h = r1.signedIntegerNumerator();
+ uint32_t size = *Integer::Multiplication(w,h).digits();
+ Matrix matrix = Matrix::Builder();
+ matrix.addChildAtIndexInPlace(childAtIndex(2).clone(), 0, 0);
+ for (uint32_t i = 1; i < size; i++) {
+ matrix.addChildAtIndexInPlace(childAtIndex(2).clone(), matrix.numberOfChildren(), matrix.numberOfChildren());
+ }
+ matrix.setDimensions(*w.digits(), *h.digits());
+ replaceWithInPlace(matrix);
+ return std::move(matrix);
+}
+
+
+
+}
diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp
index 135082316ba..55090711e25 100644
--- a/poincare/src/parsing/parser.cpp
+++ b/poincare/src/parsing/parser.cpp
@@ -71,7 +71,8 @@ Expression Parser::parseUntil(Token::Type stoppingType) {
&Parser::parseTimes, // Token::Times
&Parser::parseSlash, // Token::Slash
&Parser::parseImplicitTimes, // Token::ImplicitTimes
- &Parser::parseCaret, // Token::Power
+ &Parser::parseCaret, // Token::Power,
+ &Parser::parseSingleQuote, // Token::SingleQuote
&Parser::parseBang, // Token::Bang
&Parser::parseCaretWithParenthesis, // Token::CaretWithParenthesis
&Parser::parseMatrix, // Token::LeftBracket
@@ -333,6 +334,15 @@ void Parser::parseLeftSystemParenthesis(Expression & leftHandSide, Token::Type s
defaultParseLeftParenthesis(true, leftHandSide, stoppingType);
}
+void Parser::parseSingleQuote(Expression & leftHandSide, Token::Type stoppingType) {
+ if (leftHandSide.isUninitialized()) {
+ m_status = Status::Error; // Left-hand side missing
+ } else {
+ leftHandSide = Derivative::Builder(leftHandSide, Symbol::Builder('x'), Symbol::Builder('x'));
+ }
+ isThereImplicitMultiplication();
+}
+
void Parser::parseBang(Expression & leftHandSide, Token::Type stoppingType) {
if (leftHandSide.isUninitialized()) {
m_status = Status::Error; // Left-hand side missing
diff --git a/poincare/src/parsing/parser.h b/poincare/src/parsing/parser.h
index e6fe72f5883..f68a6a9a5f8 100644
--- a/poincare/src/parsing/parser.h
+++ b/poincare/src/parsing/parser.h
@@ -56,6 +56,7 @@ class Parser {
void parseMatrix(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseLeftParenthesis(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseLeftSystemParenthesis(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
+ void parseSingleQuote(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseBang(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parsePlus(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseMinus(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
@@ -125,6 +126,7 @@ class Parser {
&InvBinom::s_functionHelper,
&MatrixInverse::s_functionHelper,
&InvNorm::s_functionHelper,
+ &KMat::s_functionHelper,
&LeastCommonMultiple::s_functionHelper,
&NaperianLogarithm::s_functionHelper,
&CommonLogarithm::s_functionHelper,
diff --git a/poincare/src/parsing/token.h b/poincare/src/parsing/token.h
index 93273004187..162c12cd8f3 100644
--- a/poincare/src/parsing/token.h
+++ b/poincare/src/parsing/token.h
@@ -39,6 +39,7 @@ class Token {
* the ImplicitTimes Token Type is defined here with the desired precedence,
* in order to allow the Parser to insert such Tokens where needed. */
Caret,
+ SingleQuote,
Bang,
CaretWithParenthesis,
LeftBracket,
diff --git a/poincare/src/parsing/tokenizer.cpp b/poincare/src/parsing/tokenizer.cpp
index c1c66a18464..eca290fb8e6 100644
--- a/poincare/src/parsing/tokenizer.cpp
+++ b/poincare/src/parsing/tokenizer.cpp
@@ -206,6 +206,9 @@ Token Tokenizer::popToken() {
}
return Token(Token::Caret);
}
+ if (c == '\'') {
+ return Token(Token::SingleQuote);
+ }
if (c == '!') {
return Token(Token::Bang);
}
diff --git a/poincare/src/tree_handle.cpp b/poincare/src/tree_handle.cpp
index 992e22cee67..ea171237109 100644
--- a/poincare/src/tree_handle.cpp
+++ b/poincare/src/tree_handle.cpp
@@ -325,6 +325,8 @@ template IntegralLayout TreeHandle::FixedArityBuilder(const Tuple &);
template InvNorm TreeHandle::FixedArityBuilder(const Tuple &);
template LeastCommonMultiple TreeHandle::NAryBuilder(const Tuple &);
+template KMat TreeHandle::FixedArityBuilder(const Tuple &);
+template LeastCommonMultiple TreeHandle::FixedArityBuilder(const Tuple &);
template LeftParenthesisLayout TreeHandle::FixedArityBuilder(const Tuple &);
template LeftSquareBracketLayout TreeHandle::FixedArityBuilder(const Tuple &);
template Logarithm TreeHandle::FixedArityBuilder >(const Tuple &);
diff --git a/python/port/genhdr/qstrdefs.in.h b/python/port/genhdr/qstrdefs.in.h
index 6660d8c548f..c580bcb8ea4 100644
--- a/python/port/genhdr/qstrdefs.in.h
+++ b/python/port/genhdr/qstrdefs.in.h
@@ -373,10 +373,13 @@ Q(KEY_EXE)
// Kandinsky QSTRs
Q(kandinsky)
Q(color)
+Q(draw_line)
Q(draw_string)
Q(fill_rect)
Q(get_pixel)
Q(set_pixel)
+Q(large_font)
+Q(small_font)
Q(wait_vblank)
Q(get_keys)
diff --git a/python/port/mod/ion/modion_table.cpp b/python/port/mod/ion/modion_table.cpp
index b1d861f51e2..7e6a53bdd33 100644
--- a/python/port/mod/ion/modion_table.cpp
+++ b/python/port/mod/ion/modion_table.cpp
@@ -16,7 +16,7 @@ const mp_obj_fun_builtin_fixed_t modion_keyboard_keydown_obj = {
{(mp_fun_0_t)modion_keyboard_keydown}
};
-STATIC const mp_rom_map_elem_t modion_module_globals_table[] = {
+extern "C" const mp_rom_map_elem_t modion_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ion) },
{ MP_ROM_QSTR(MP_QSTR_keydown), MP_ROM_PTR(&modion_keyboard_keydown_obj) },
{ MP_ROM_QSTR(MP_QSTR_KEY_LEFT), MP_OBJ_NEW_SMALL_INT(Ion::Keyboard::Key::Left) },
diff --git a/python/port/mod/kandinsky/modkandinsky.cpp b/python/port/mod/kandinsky/modkandinsky.cpp
index 41d163ce66e..201b482359c 100644
--- a/python/port/mod/kandinsky/modkandinsky.cpp
+++ b/python/port/mod/kandinsky/modkandinsky.cpp
@@ -61,8 +61,22 @@ mp_obj_t modkandinsky_draw_string(size_t n_args, const mp_obj_t * args) {
KDPoint point(mp_obj_get_int(args[1]), mp_obj_get_int(args[2]));
KDColor textColor = (n_args >= 4) ? MicroPython::Color::Parse(args[3]) : KDColorBlack;
KDColor backgroundColor = (n_args >= 5) ? MicroPython::Color::Parse(args[4]) : KDColorWhite;
+ const KDFont * font = (n_args >= 6) ? ((mp_obj_is_true(args[5])) ? KDFont::SmallFont : KDFont::LargeFont) : KDFont::LargeFont;
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
- KDIonContext::sharedContext()->drawString(text, point, KDFont::LargeFont, textColor, backgroundColor);
+ KDIonContext::sharedContext()->drawString(text, point, font, textColor, backgroundColor);
+ return mp_const_none;
+}
+
+mp_obj_t modkandinsky_draw_line(size_t n_args, const mp_obj_t * args) {
+ mp_int_t x1 = mp_obj_get_int(args[0]);
+ mp_int_t y1 = mp_obj_get_int(args[1]);
+ mp_int_t x2 = mp_obj_get_int(args[2]);
+ mp_int_t y2 = mp_obj_get_int(args[3]);
+ KDPoint p1 = KDPoint(x1, y1);
+ KDPoint p2 = KDPoint(x2, y2);
+ KDColor color = MicroPython::Color::Parse(args[4]);
+ MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
+ KDIonContext::sharedContext()->drawLine(p1, p2, color);
return mp_const_none;
}
diff --git a/python/port/mod/kandinsky/modkandinsky.h b/python/port/mod/kandinsky/modkandinsky.h
index 12fd2cbc198..acb47d6f8ee 100644
--- a/python/port/mod/kandinsky/modkandinsky.h
+++ b/python/port/mod/kandinsky/modkandinsky.h
@@ -4,6 +4,7 @@ mp_obj_t modkandinsky_color(size_t n_args, const mp_obj_t *args);
mp_obj_t modkandinsky_get_pixel(mp_obj_t x, mp_obj_t y);
mp_obj_t modkandinsky_set_pixel(mp_obj_t x, mp_obj_t y, mp_obj_t color);
mp_obj_t modkandinsky_draw_string(size_t n_args, const mp_obj_t *args);
+mp_obj_t modkandinsky_draw_line(size_t n_args, const mp_obj_t *args);
mp_obj_t modkandinsky_fill_rect(size_t n_args, const mp_obj_t *args);
mp_obj_t modkandinsky_wait_vblank();
mp_obj_t modkandinsky_get_keys();
diff --git a/python/port/mod/kandinsky/modkandinsky_table.c b/python/port/mod/kandinsky/modkandinsky_table.c
index 565d44e71a4..5bbb2e640ce 100644
--- a/python/port/mod/kandinsky/modkandinsky_table.c
+++ b/python/port/mod/kandinsky/modkandinsky_table.c
@@ -3,7 +3,8 @@
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_color_obj, 1, 3, modkandinsky_color);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(modkandinsky_get_pixel_obj, modkandinsky_get_pixel);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(modkandinsky_set_pixel_obj, modkandinsky_set_pixel);
-STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_draw_string_obj, 3, 5, modkandinsky_draw_string);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_draw_string_obj, 3, 6, modkandinsky_draw_string);
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_draw_line_obj, 5, 5, modkandinsky_draw_line);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_fill_rect_obj, 5, 5, modkandinsky_fill_rect);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modkandinsky_wait_vblank_obj, modkandinsky_wait_vblank);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modkandinsky_get_keys_obj, modkandinsky_get_keys);
@@ -14,7 +15,10 @@ STATIC const mp_rom_map_elem_t modkandinsky_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_get_pixel), (mp_obj_t)&modkandinsky_get_pixel_obj },
{ MP_ROM_QSTR(MP_QSTR_set_pixel), (mp_obj_t)&modkandinsky_set_pixel_obj },
{ MP_ROM_QSTR(MP_QSTR_draw_string), (mp_obj_t)&modkandinsky_draw_string_obj },
+ { MP_ROM_QSTR(MP_QSTR_draw_line), (mp_obj_t)&modkandinsky_draw_line_obj },
{ MP_ROM_QSTR(MP_QSTR_fill_rect), (mp_obj_t)&modkandinsky_fill_rect_obj },
+ { MP_ROM_QSTR(MP_QSTR_large_font), mp_const_true },
+ { MP_ROM_QSTR(MP_QSTR_small_font), mp_const_false },
{ MP_ROM_QSTR(MP_QSTR_wait_vblank), (mp_obj_t)&modkandinsky_wait_vblank_obj },
{ MP_ROM_QSTR(MP_QSTR_get_keys), (mp_obj_t)&modkandinsky_get_keys_obj },
};
diff --git a/python/port/mpconfigport.h b/python/port/mpconfigport.h
index a55925d826b..fa3d71da6a4 100644
--- a/python/port/mpconfigport.h
+++ b/python/port/mpconfigport.h
@@ -146,3 +146,10 @@ extern const struct _mp_obj_module_t modturtle_module;
{ MP_ROM_QSTR(MP_QSTR_os), MP_ROM_PTR(&modos_module) }, \
{ MP_ROM_QSTR(MP_QSTR_turtle), MP_ROM_PTR(&modturtle_module) }, \
+// Enable setjmp in debug mode. This is to avoid some optimizations done
+// specifically for x86_64 using inline assembly, which makes the debug binary
+// crash with an illegal instruction
+#ifndef NDEBUG
+ #define MICROPY_NLR_SETJMP 1
+#endif
+
diff --git a/themes/icons.json b/themes/icons.json
index d16c64c857c..3dc1ae52da1 100644
--- a/themes/icons.json
+++ b/themes/icons.json
@@ -2,7 +2,7 @@
"apps/exam_icon.png" : "exam_icon.png",
"apps/on_boarding/logo_icon.png" : "logo_icon.png",
- "apps/atom/atom_icon.png" : "apps/atom_icon.png",
+ "apps/atomic/atomic_icon.png" : "apps/atomic_icon.png",
"apps/calculation/calculation_icon.png" : "apps/calculation_icon.png",
"apps/code/code_icon.png" : "apps/code_icon.png",
"apps/external/external_icon.png" : "apps/external_icon.png",
diff --git a/themes/themes/local/epsilon_dark.json b/themes/themes/local/epsilon_dark.json
index 012dd654d2c..9121a7efe36 100644
--- a/themes/themes/local/epsilon_dark.json
+++ b/themes/themes/local/epsilon_dark.json
@@ -132,17 +132,19 @@
"Atom": {
"Unknown": "eeeeee",
"Text": "000000",
- "AlkaliMetal": "ffaa00",
- "AlkaliEarthMetal": "f6f200",
- "Lanthanide": "ffaa8b",
- "Actinide": "deaacd",
- "TransitionMetal": "de999c",
- "PostTransitionMetal": "9cbaac",
- "Metalloid": "52ce8b",
- "Halogen": "00debd",
- "ReactiveNonmetal": "00ee00",
- "NobleGas": "8baaff",
- "TableLines": "323532"
+ "AlkaliMetal": "CC9E7E",
+ "AlkaliEarthMetal": "D69477",
+ "Lanthanide": "A5DDAD",
+ "Actinide": "96D481",
+ "TransitionMetal": "99C6E7",
+ "PostTransitionMetal": "D69877",
+ "Metalloid": "D6B071",
+ "Halogen": "84ABE3",
+ "ReactiveNonmetal": "DBC377",
+ "NobleGas": "8FC2E6",
+ "TableLines": "323532",
+ "Highlight": "000000",
+ "Background": "d9d9d9"
}
}
}
diff --git a/themes/themes/local/epsilon_light.json b/themes/themes/local/epsilon_light.json
index 91423fa142e..679b244564d 100644
--- a/themes/themes/local/epsilon_light.json
+++ b/themes/themes/local/epsilon_light.json
@@ -132,17 +132,19 @@
"Atom": {
"Unknown": "eeeeee",
"Text": "000000",
- "AlkaliMetal": "ffaa00",
- "AlkaliEarthMetal": "f6f200",
- "Lanthanide": "ffaa8b",
- "Actinide": "deaacd",
- "TransitionMetal": "de999c",
- "PostTransitionMetal": "9cbaac",
- "Metalloid": "52ce8b",
- "Halogen": "00debd",
- "ReactiveNonmetal": "00ee00",
- "NobleGas": "8baaff",
- "TableLines": "323532"
+ "AlkaliMetal": "CC9E7E",
+ "AlkaliEarthMetal": "D69477",
+ "Lanthanide": "A5DDAD",
+ "Actinide": "96D481",
+ "TransitionMetal": "99C6E7",
+ "PostTransitionMetal": "D69877",
+ "Metalloid": "D6B071",
+ "Halogen": "84ABE3",
+ "ReactiveNonmetal": "DBC377",
+ "NobleGas": "8FC2E6",
+ "TableLines": "323532",
+ "Highlight": "000000",
+ "Background": "d9d9d9"
}
}
}
diff --git a/themes/themes/local/epsilon_light/apps/atom_icon.png b/themes/themes/local/epsilon_light/apps/atomic_icon.png
similarity index 100%
rename from themes/themes/local/epsilon_light/apps/atom_icon.png
rename to themes/themes/local/epsilon_light/apps/atomic_icon.png
diff --git a/themes/themes/local/omega_dark.json b/themes/themes/local/omega_dark.json
index 0426dc2f9a0..adf64c2c507 100644
--- a/themes/themes/local/omega_dark.json
+++ b/themes/themes/local/omega_dark.json
@@ -132,17 +132,19 @@
"Atom": {
"Unknown": "eeeeee",
"Text": "000000",
- "AlkaliMetal": "ffaa00",
- "AlkaliEarthMetal": "f6f200",
- "Lanthanide": "ffaa8b",
- "Actinide": "deaacd",
- "TransitionMetal": "de999c",
- "PostTransitionMetal": "9cbaac",
- "Metalloid": "52ce8b",
- "Halogen": "00debd",
- "ReactiveNonmetal": "00ee00",
- "NobleGas": "8baaff",
- "TableLines": "323532"
+ "AlkaliMetal": "CC9E7E",
+ "AlkaliEarthMetal": "D69477",
+ "Lanthanide": "A5DDAD",
+ "Actinide": "96D481",
+ "TransitionMetal": "99C6E7",
+ "PostTransitionMetal": "D69877",
+ "Metalloid": "D6B071",
+ "Halogen": "84ABE3",
+ "ReactiveNonmetal": "DBC377",
+ "NobleGas": "8FC2E6",
+ "TableLines": "323532",
+ "Highlight": "000000",
+ "Background": "d9d9d9"
}
}
}
diff --git a/themes/themes/local/omega_dark/apps/atom_icon.png b/themes/themes/local/omega_dark/apps/atomic_icon.png
similarity index 100%
rename from themes/themes/local/omega_dark/apps/atom_icon.png
rename to themes/themes/local/omega_dark/apps/atomic_icon.png
diff --git a/themes/themes/local/omega_light.json b/themes/themes/local/omega_light.json
index 1e4ecf3da86..4381ce63450 100644
--- a/themes/themes/local/omega_light.json
+++ b/themes/themes/local/omega_light.json
@@ -132,17 +132,19 @@
"Atom": {
"Unknown": "eeeeee",
"Text": "000000",
- "AlkaliMetal": "ffaa00",
- "AlkaliEarthMetal": "f6f200",
- "Lanthanide": "ffaa8b",
- "Actinide": "deaacd",
- "TransitionMetal": "de999c",
- "PostTransitionMetal": "9cbaac",
- "Metalloid": "52ce8b",
- "Halogen": "00debd",
- "ReactiveNonmetal": "00ee00",
- "NobleGas": "8baaff",
- "TableLines": "323532"
+ "AlkaliMetal": "CC9E7E",
+ "AlkaliEarthMetal": "D69477",
+ "Lanthanide": "A5DDAD",
+ "Actinide": "96D481",
+ "TransitionMetal": "99C6E7",
+ "PostTransitionMetal": "D69877",
+ "Metalloid": "D6B071",
+ "Halogen": "84ABE3",
+ "ReactiveNonmetal": "DBC377",
+ "NobleGas": "8FC2E6",
+ "TableLines": "323532",
+ "Highlight": "000000",
+ "Background": "d9d9d9"
}
}
}
diff --git a/themes/themes/local/omega_light/apps/atom_icon.png b/themes/themes/local/omega_light/apps/atomic_icon.png
similarity index 100%
rename from themes/themes/local/omega_light/apps/atom_icon.png
rename to themes/themes/local/omega_light/apps/atomic_icon.png