diff --git a/ReadMe.txt b/ReadMe.txt
index 0bb0f1a..a75ac76 100644
--- a/ReadMe.txt
+++ b/ReadMe.txt
@@ -60,7 +60,7 @@ CHANGES
Version 2.8 (2024-xx-xx)
-- Update the usb serial drivers usb-serial-for-android to version 3.7.3
+- Updated source code with Emu48 version 1.66+.
Version 2.7 (2024-06-14)
@@ -277,6 +277,7 @@ FAQ
TODO
- NDK 26 does not compile
+- Adding a new KML command for Android only: CUSTOM_PIXEL_BORDER_ON 10001 / CUSTOM_PIXEL_BORDER_OFF 10002 / CUSTOM_PIXEL_BORDER_TOGGLE 10003
- Patching 49G to disable 10 min auto off causes a reset when touching the Recent button and coming back to the app (with a Flashcard loaded).
- Add an "haptic" feedback with a sound instead of a vibration (F. Giampietro).
- Add a Cancel button to the HP48 memory card creator dialog.
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index c7869d9..d0f0dd8 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -65,7 +65,7 @@ add_library( # Sets the name of the library.
src/main/cpp/core/disrpl.c
# src/main/cpp/core/Emu48.c #-> To rewrite
src/main/cpp/core/engine.c
- src/main/cpp/core/external.c
+# src/main/cpp/core/external.c # Removed 167/166+
src/main/cpp/core/fetch.c
src/main/cpp/core/files.c
src/main/cpp/core/i28f160.c
diff --git a/app/build.gradle b/app/build.gradle
index 206140f..a82288b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -34,8 +34,8 @@ android {
applicationId "org.emulator.forty.eight"
minSdk 21
targetSdk 34
- versionCode 27
- versionName "2.8"
+ versionCode 26
+ versionName "2.7"
setProperty("archivesBaseName", "Emu48-v$versionName")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c07e59e..45978ec 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -16,7 +16,6 @@
android:fullBackupContent="@xml/backup_descriptor">
- The decimal point (radix mark) of "Real Numbers" in the
- clipboard is equal to the calculator setting. This is important when
- you try to paste the numbers into a program using the locale settings
- of the host operating system.
+ The decimal point of "Real Numbers" in the clipboard is
+ equal to the calculator setting. This is important when you try to
+ paste the numbers into a program using the locale settings of the host
+ operating system.
This menu item is enabled for the HP48SX, HP48GX and the HP49G
emulation.
@@ -539,14 +539,18 @@ h3 { color:red; font-size:1.1em; }
object. Is the content a complex number object, the number will be
saved as "Complex Number" object, otherwise cases as
"String" object.
- To import "Real or Complex Numbers" from the clipboard, the
- decimal point (radix mark) of the clipboard and calculator must
- match. A real or complex number is only detected in the case of valid
- real number characters in the clipboard. Especially heading and tailing
- white spaces aren't valid number characters also.
- Complex numbers must be in the form (a,b) when using the point
- radix mark or in the form (a;b) when using the comma radix mark.
- The Cartesian or algebraic form a+bi is not supported.
+ To import "Real Numbers" from the clipboard, the decimal
+ point character of the clipboard and calculator must not match any
+ more. There's an auto detection for decoding the thousands separator and
+ decimal point character. The thousands separator is removed at decoding.
+ A real number is detected in the case of valid real number characters in
+ the clipboard.
+ "Complex Numbers" must be in the form (a,b) when
+ using the decimal point or in the form (a;b) when using the decimal
+ comma. Using a thousands separator is not allowed in complex number
+ strings because in decimal point mode, the comma is used as separator
+ between real and imaginary part of the number. The Cartesian or algebraic
+ form a+bi is not supported.
This emulates the Reset pin of the internal CPU.
@@ -675,7 +679,7 @@ h3 { color:red; font-size:1.1em; }
Cyrille de Brebisson of Hewlett-Packard.
Emu48 - A HP38G/39G/40G/48SX/48GX/49G Emulator
- Copyright (C) 2022 Christoph Gießelink
+ Copyright (C) 2024 Christoph Gießelink
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
diff --git a/app/src/main/assets/ReadMe.txt b/app/src/main/assets/ReadMe.txt
index 5ae997e..71490fd 100644
--- a/app/src/main/assets/ReadMe.txt
+++ b/app/src/main/assets/ReadMe.txt
@@ -58,11 +58,6 @@ LINKS
CHANGES
-Version 2.8 (2024-xx-xx)
-
-- Update the usb serial drivers usb-serial-for-android to version 3.7.3
-
-
Version 2.7 (2024-06-14)
- Updated source code with Emu48 version 1.65+. This new version improve the serial communication.
diff --git a/app/src/main/cpp/core/Emu48.c b/app/src/main/cpp/core/Emu48.c
index fe045f6..5251f40 100644
--- a/app/src/main/cpp/core/Emu48.c
+++ b/app/src/main/cpp/core/Emu48.c
@@ -13,7 +13,7 @@
#include "kml.h"
#include "debugger.h"
-#define VERSION "1.65+"
+#define VERSION "1.66+"
#ifdef _DEBUG
LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug");
@@ -2045,6 +2045,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
MSG msg;
WNDCLASS wc;
ATOM classAtom;
+ WSADATA wsd;
RECT rectWindow;
HACCEL hAccel;
DWORD dwThreadId;
@@ -2059,16 +2060,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
hApp = hInst;
- #if defined _UNICODE
- {
- ppArgv = (LPCTSTR*) CommandLineToArgvW(GetCommandLine(),&nArgc);
- }
- #else
- {
- nArgc = __argc; // no. of command line arguments
- ppArgv = (LPCTSTR*) __argv; // command line arguments
- }
- #endif
+ nArgc = __argc; // no. of command line arguments
+ ppArgv = __targv; // command line arguments
wc.style = CS_BYTEALIGNCLIENT;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
@@ -2298,6 +2291,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
if (NewDocument()) SetWindowTitle(_T("Untitled"));
start:
+ VERIFY(WSAStartup(MAKEWORD(1,1),&wsd) == 0);
if (bStartupBackup) SaveBackup(); // make a RAM backup at startup
if (pbyRom) SwitchToState(SM_RUN);
@@ -2313,6 +2307,7 @@ start:
DispatchMessage(&msg);
}
}
+ WSACleanup(); // cleanup network stack
// clean up DDE server
DdeNameService(idDdeInst, hszService, NULL, DNS_UNREGISTER);
diff --git a/app/src/main/cpp/core/Emu48.h b/app/src/main/cpp/core/Emu48.h
index 26eb81e..d826005 100644
--- a/app/src/main/cpp/core/Emu48.h
+++ b/app/src/main/cpp/core/Emu48.h
@@ -369,6 +369,7 @@ extern BOOL SendByteUdp(BYTE byData);
// Stack.c
extern BOOL bDetectClpObject;
+extern BOOL bLocaleDecimalPoint;
extern LRESULT OnStackCopy(VOID);
extern LRESULT OnStackPaste(VOID);
diff --git a/app/src/main/cpp/core/debugger.c b/app/src/main/cpp/core/debugger.c
index 67218f3..591907a 100644
--- a/app/src/main/cpp/core/debugger.c
+++ b/app/src/main/cpp/core/debugger.c
@@ -65,8 +65,8 @@ static CONST TCHAR cHex[] = { _T('0'),_T('1'),_T('2'),_T('3'),
_T('8'),_T('9'),_T('A'),_T('B'),
_T('C'),_T('D'),_T('E'),_T('F') };
-static INT nDbgPosX = 0; // position of debugger window
-static INT nDbgPosY = 0;
+static INT nDbgPosX = CW_USEDEFAULT; // position of debugger window
+static INT nDbgPosY = CW_USEDEFAULT;
static WORD wBreakpointCount = 0; // number of breakpoints
static BP_T sBreakpoint[MAXBREAKPOINTS]; // breakpoint table
@@ -1885,7 +1885,10 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
switch (message)
{
case WM_INITDIALOG:
+ if (nDbgPosX != CW_USEDEFAULT) // not default window position
+ {
SetWindowLocation(hDlg,nDbgPosX,nDbgPosY);
+ }
if (bAlwaysOnTop) SetWindowPos(hDlg,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
SendMessage(hDlg,WM_SETICON,ICON_BIG,(LPARAM) LoadIcon(hApp,MAKEINTRESOURCE(IDI_EMU48)));
@@ -2201,7 +2204,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
LRESULT OnToolDebug(VOID) // debugger dialogbox call
{
- if ((hDlgDebug = CreateDialog(hApp,MAKEINTRESOURCE(IDD_DEBUG),NULL,
+ if ((hDlgDebug = CreateDialog(hApp,MAKEINTRESOURCE(IDD_DEBUG),hWnd,
(DLGPROC)Debugger)) == NULL)
AbortMessage(_T("Debugger Dialog Box Creation Error !"));
return 0;
@@ -3501,46 +3504,79 @@ static BOOL OnBrowseSaveMem(HWND hDlg)
//
// write file to memory
//
-static BOOL LoadMemData(LPCTSTR lpszFilename,DWORD dwStartAddr)
+static BOOL LoadMemData(LPCTSTR lpszFilename,DWORD dwStartAddr,UINT uBitMode)
{
HANDLE hFile;
- DWORD dwRead;
- BYTE byData;
+ DWORD dwFileSize,dwRead;
+ LPBYTE pbyData;
hFile = CreateFile(lpszFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file
return FALSE;
- while (dwStartAddr <= 0xFFFFF) // read until EOF or end of Saturn address space
+ dwFileSize = GetFileSize(hFile, NULL);
+ if ((pbyData = (LPBYTE) malloc(dwFileSize)) != NULL)
{
- ReadFile(hFile,&byData,sizeof(byData),&dwRead,NULL);
- if (dwRead == 0) break; // EOF
-
- if (dwStartAddr < 0xFFFFF)
+ ReadFile(hFile,pbyData,dwFileSize,&dwRead,NULL);
+ if (uBitMode == 2) // auto mode (0=8-bit, 1=4-bit, 2=auto)
{
- Write2(dwStartAddr,byData); // write byte in map mode
- dwStartAddr += 2;
+ BOOL bPacked = FALSE; // data not packed
+ DWORD dwIndex;
+ for (dwIndex = 0; !bPacked && dwIndex < dwFileSize; ++dwIndex)
+ {
+ bPacked = ((pbyData[dwIndex] & 0xF0) != 0);
+ }
+ uBitMode = bPacked ? 0 : 1; // 0=8-bit, 1=4-bit
}
+
+ if (uBitMode == 0) // 0=8-bit
+ {
+ LPBYTE pbyDataNew = (LPBYTE) realloc(pbyData,2*dwFileSize);
+ if (pbyDataNew)
+ {
+ LPBYTE pbySrc,pbyDest;
+ pbyData = pbyDataNew;
+ pbySrc = pbyData + dwFileSize;
+ dwFileSize *= 2; // new filesize
+ pbyDest = pbyData + dwFileSize;
+ while (pbySrc != pbyDest) // unpack source
+ {
+ CONST BYTE byValue = *(--pbySrc);
+ *(--pbyDest) = byValue >> 4;
+ *(--pbyDest) = byValue & 0xF;
+ }
+ _ASSERT(pbySrc == pbyData);
+ _ASSERT(pbyDest == pbyData);
+ }
else // special handling to avoid address wrap around
{
- byData &= 0xF;
- Nwrite(&byData,dwStartAddr,1); // write nibble in map mode
- ++dwStartAddr;
+ free(pbyData);
+ pbyData = NULL;
+ }
+ }
+ if (pbyData) // have data to save
+ {
+ LPBYTE p = pbyData;
+ while (dwFileSize > 0 && dwStartAddr <= 0xFFFFF)
+ {
+ Nwrite(p++,dwStartAddr++,1);
+ --dwFileSize;
}
}
-
+ free(pbyData);
+ }
CloseHandle(hFile);
- return TRUE;
+ return pbyData != NULL;
}
//
// write memory data to file
//
-static BOOL SaveMemData(LPCTSTR lpszFilename,DWORD dwStartAddr,DWORD dwEndAddr)
+static BOOL SaveMemData(LPCTSTR lpszFilename,DWORD dwStartAddr,DWORD dwEndAddr,UINT uBitMode)
{
HANDLE hFile;
- DWORD dwAddr,dwWritten;
- BYTE byData;
+ DWORD dwAddr,dwSend,dwWritten;
+ BYTE byData[2];
hFile = CreateFile(lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file
@@ -3549,8 +3585,14 @@ static BOOL SaveMemData(LPCTSTR lpszFilename,DWORD dwStartAddr,DWORD dwEndAddr)
for (dwAddr = dwStartAddr; dwAddr <= dwEndAddr; dwAddr += 2)
{
_ASSERT(dwAddr <= 0xFFFFF);
- byData = Read2(dwAddr); // read byte in map mode
- WriteFile(hFile,&byData,sizeof(byData),&dwWritten,NULL);
+ Npeek(byData,dwAddr,2); // read two nibble in map mode
+ dwSend = 2; // send 2 nibble
+ if (uBitMode == 0) // (0=8-bit, 1=4-bit)
+ {
+ byData[0] = byData[0]|(byData[1]<<4);
+ dwSend = 1; // send 1 byte
+ }
+ WriteFile(hFile,&byData,dwSend,&dwWritten,NULL);
}
CloseHandle(hFile);
@@ -3564,9 +3606,14 @@ static INT_PTR CALLBACK DebugMemLoad(HWND hDlg, UINT message, WPARAM wParam, LPA
{
TCHAR szFilename[MAX_PATH];
DWORD dwStartAddr;
+ int nButton;
+ UINT uBitMode;
switch (message)
{
+ case WM_INITDIALOG:
+ CheckDlgButton(hDlg,IDC_DEBUG_DATA_LOAD_ABIT,BST_CHECKED);
+ return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
@@ -3586,8 +3633,14 @@ static INT_PTR CALLBACK DebugMemLoad(HWND hDlg, UINT message, WPARAM wParam, LPA
_ASSERT(dwStartAddr <= 0xFFFFF);
+ for (nButton = IDC_DEBUG_DATA_LOAD_8BIT; nButton <= IDC_DEBUG_DATA_LOAD_ABIT; ++nButton)
+ {
+ if (IsDlgButtonChecked(hDlg,nButton) == BST_CHECKED)
+ break;
+ }
+ uBitMode = (UINT) (nButton - IDC_DEBUG_DATA_LOAD_8BIT);
// load memory dump file
- if (!LoadMemData(szFilename,dwStartAddr))
+ if (!LoadMemData(szFilename,dwStartAddr,uBitMode))
return FALSE;
// update memory window
@@ -3617,9 +3670,13 @@ static INT_PTR CALLBACK DebugMemSave(HWND hDlg, UINT message, WPARAM wParam, LPA
{
TCHAR szFilename[MAX_PATH];
DWORD dwStartAddr,dwEndAddr;
+ UINT uBitMode;
switch (message)
{
+ case WM_INITDIALOG:
+ CheckDlgButton(hDlg,IDC_DEBUG_DATA_SAVE_8BIT,BST_CHECKED);
+ return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
@@ -3643,8 +3700,9 @@ static INT_PTR CALLBACK DebugMemSave(HWND hDlg, UINT message, WPARAM wParam, LPA
_ASSERT(dwStartAddr <= 0xFFFFF);
_ASSERT(dwEndAddr <= 0xFFFFF);
+ uBitMode = IsDlgButtonChecked(hDlg,IDC_DEBUG_DATA_SAVE_4BIT);
// save memory dump file
- if (!SaveMemData(szFilename,dwStartAddr,dwEndAddr))
+ if (!SaveMemData(szFilename,dwStartAddr,dwEndAddr,uBitMode))
return FALSE;
// no break
diff --git a/app/src/main/cpp/core/external.c b/app/src/main/cpp/core/external.c
deleted file mode 100644
index e548b54..0000000
--- a/app/src/main/cpp/core/external.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * external.c
- *
- * This file is part of Emu48
- *
- * Copyright (C) 1995 Sebastien Carlier
- *
- */
-#include "pch.h"
-#include "Emu48.h"
-#include "ops.h"
-
-#define SAMPLES_PER_SEC 44100 // sound sampling rate
-
-//| 38G | 39G | 40G | 48SX | 48GX | 49G | Name
-//#F0E4F #80F0F #80F0F #706D2 #80850 #80F0F =SFLAG53_56
-
-// memory address for flags -53 to -56
- // CdB for HP: add apples beep management
-#define SFLAG53_56 ( (cCurrentRomType=='6') \
- ? 0xE0E4F \
- : ( (cCurrentRomType=='A') \
- ? 0xF0E4F \
- : ( (cCurrentRomType!='E' && cCurrentRomType!='X' && cCurrentRomType!='P' && cCurrentRomType!='2' && cCurrentRomType!='Q') \
- ? ( (cCurrentRomType=='S') \
- ? 0x706D2 \
- : 0x80850 \
- ) \
- : 0x80F0F \
- ) \
- ) \
- )
-
-VOID External(CHIPSET* w) // Beep patch
-{
- BYTE fbeep;
- DWORD freq,dur;
-
- freq = Npack(w->D,5); // frequency in Hz
- dur = Npack(w->C,5); // duration in ms
- Nread(&fbeep,SFLAG53_56,1); // fetch system flags -53 to -56
-
- w->carry = TRUE; // setting of no beep
- if (!(fbeep & 0x8) && freq) // bit -56 clear and frequency > 0 Hz
- {
- if (freq > 4400) freq = 4400; // high limit of HP (SX)
-
- SoundBeep(freq,dur); // beeping
-
- // estimate cpu cycles for beeping time (2MHz / 4MHz)
- w->cycles += dur * ((cCurrentRomType=='S') ? 2000 : 4000);
-
- // original routine return with...
- w->P = 0; // P=0
- w->intk = TRUE; // INTON
- w->carry = FALSE; // RTNCC
- }
- w->pc = rstkpop();
- return;
-}
-
-VOID RCKBp(CHIPSET* w) // ROM Check Beep patch
-{
- DWORD dw2F,dwCpuFreq;
- DWORD freq,dur;
- BYTE f,d;
-
- f = w->C[1]; // f = freq ctl
- d = w->C[0]; // d = duration ctl
-
- if (cCurrentRomType == 'S') // Clarke chip with 48S ROM
- {
- // CPU strobe frequency @ RATE 14 = 1.97MHz
- dwCpuFreq = ((14 + 1) * 524288) >> 2;
-
- dw2F = f * 126 + 262; // F=f*63+131
- }
- else // York chip with 48G and later ROM
- {
- // CPU strobe frequency @ RATE 27 = 3.67MHz
- // CPU strobe frequency @ RATE 29 = 3.93MHz
- dwCpuFreq = ((27 + 1) * 524288) >> 2;
-
- dw2F = f * 180 + 367; // F=f*90+183.5
- }
-
- freq = dwCpuFreq / dw2F;
- dur = (dw2F * (256 - 16 * d)) * 1000 / 2 / dwCpuFreq;
-
- if (freq > 4400) freq = 4400; // high limit of HP
-
- SoundBeep(freq,dur); // beeping
-
- // estimate cpu cycles for beeping time (2MHz / 4MHz)
- w->cycles += dur * ((cCurrentRomType=='S') ? 2000 : 4000);
-
- w->P = 0; // P=0
- w->carry = FALSE; // RTNCC
- w->pc = rstkpop();
- return;
-}
diff --git a/app/src/main/cpp/core/fetch.c b/app/src/main/cpp/core/fetch.c
index e19cdf8..89eb246 100644
--- a/app/src/main/cpp/core/fetch.c
+++ b/app/src/main/cpp/core/fetch.c
@@ -20,742 +20,742 @@ typedef const struct
// jump tables
static JMPTAB oF_[] =
{
- (LPCVOID) oF0, F,
- (LPCVOID) oF1, F,
- (LPCVOID) oF2, F,
- (LPCVOID) oF3, F,
- (LPCVOID) oF4, F,
- (LPCVOID) oF5, F,
- (LPCVOID) oF6, F,
- (LPCVOID) oF7, F,
- (LPCVOID) oF8, F,
- (LPCVOID) oF9, F,
- (LPCVOID) oFA, F,
- (LPCVOID) oFB, F,
- (LPCVOID) oFC, F,
- (LPCVOID) oFD, F,
- (LPCVOID) oFE, F,
- (LPCVOID) oFF, F
+ { (LPCVOID) oF0, F },
+ { (LPCVOID) oF1, F },
+ { (LPCVOID) oF2, F },
+ { (LPCVOID) oF3, F },
+ { (LPCVOID) oF4, F },
+ { (LPCVOID) oF5, F },
+ { (LPCVOID) oF6, F },
+ { (LPCVOID) oF7, F },
+ { (LPCVOID) oF8, F },
+ { (LPCVOID) oF9, F },
+ { (LPCVOID) oFA, F },
+ { (LPCVOID) oFB, F },
+ { (LPCVOID) oFC, F },
+ { (LPCVOID) oFD, F },
+ { (LPCVOID) oFE, F },
+ { (LPCVOID) oFF, F }
};
static JMPTAB oE_[] =
{
- (LPCVOID) oE0, F,
- (LPCVOID) oE1, F,
- (LPCVOID) oE2, F,
- (LPCVOID) oE3, F,
- (LPCVOID) oE4, F,
- (LPCVOID) oE5, F,
- (LPCVOID) oE6, F,
- (LPCVOID) oE7, F,
- (LPCVOID) oE8, F,
- (LPCVOID) oE9, F,
- (LPCVOID) oEA, F,
- (LPCVOID) oEB, F,
- (LPCVOID) oEC, F,
- (LPCVOID) oED, F,
- (LPCVOID) oEE, F,
- (LPCVOID) oEF, F
+ { (LPCVOID) oE0, F },
+ { (LPCVOID) oE1, F },
+ { (LPCVOID) oE2, F },
+ { (LPCVOID) oE3, F },
+ { (LPCVOID) oE4, F },
+ { (LPCVOID) oE5, F },
+ { (LPCVOID) oE6, F },
+ { (LPCVOID) oE7, F },
+ { (LPCVOID) oE8, F },
+ { (LPCVOID) oE9, F },
+ { (LPCVOID) oEA, F },
+ { (LPCVOID) oEB, F },
+ { (LPCVOID) oEC, F },
+ { (LPCVOID) oED, F },
+ { (LPCVOID) oEE, F },
+ { (LPCVOID) oEF, F }
};
static JMPTAB oD_[] =
{
- (LPCVOID) oD0, F,
- (LPCVOID) oD1, F,
- (LPCVOID) oD2, F,
- (LPCVOID) oD3, F,
- (LPCVOID) oD4, F,
- (LPCVOID) oD5, F,
- (LPCVOID) oD6, F,
- (LPCVOID) oD7, F,
- (LPCVOID) oD8, F,
- (LPCVOID) oD9, F,
- (LPCVOID) oDA, F,
- (LPCVOID) oDB, F,
- (LPCVOID) oDC, F,
- (LPCVOID) oDD, F,
- (LPCVOID) oDE, F,
- (LPCVOID) oDF, F
+ { (LPCVOID) oD0, F },
+ { (LPCVOID) oD1, F },
+ { (LPCVOID) oD2, F },
+ { (LPCVOID) oD3, F },
+ { (LPCVOID) oD4, F },
+ { (LPCVOID) oD5, F },
+ { (LPCVOID) oD6, F },
+ { (LPCVOID) oD7, F },
+ { (LPCVOID) oD8, F },
+ { (LPCVOID) oD9, F },
+ { (LPCVOID) oDA, F },
+ { (LPCVOID) oDB, F },
+ { (LPCVOID) oDC, F },
+ { (LPCVOID) oDD, F },
+ { (LPCVOID) oDE, F },
+ { (LPCVOID) oDF, F }
};
static JMPTAB oC_[] =
{
- (LPCVOID) oC0, F,
- (LPCVOID) oC1, F,
- (LPCVOID) oC2, F,
- (LPCVOID) oC3, F,
- (LPCVOID) oC4, F,
- (LPCVOID) oC5, F,
- (LPCVOID) oC6, F,
- (LPCVOID) oC7, F,
- (LPCVOID) oC8, F,
- (LPCVOID) oC9, F,
- (LPCVOID) oCA, F,
- (LPCVOID) oCB, F,
- (LPCVOID) oCC, F,
- (LPCVOID) oCD, F,
- (LPCVOID) oCE, F,
- (LPCVOID) oCF, F
+ { (LPCVOID) oC0, F },
+ { (LPCVOID) oC1, F },
+ { (LPCVOID) oC2, F },
+ { (LPCVOID) oC3, F },
+ { (LPCVOID) oC4, F },
+ { (LPCVOID) oC5, F },
+ { (LPCVOID) oC6, F },
+ { (LPCVOID) oC7, F },
+ { (LPCVOID) oC8, F },
+ { (LPCVOID) oC9, F },
+ { (LPCVOID) oCA, F },
+ { (LPCVOID) oCB, F },
+ { (LPCVOID) oCC, F },
+ { (LPCVOID) oCD, F },
+ { (LPCVOID) oCE, F },
+ { (LPCVOID) oCF, F }
};
static JMPTAB oBb_[] =
{
- (LPCVOID) oBb0, F,
- (LPCVOID) oBb1, F,
- (LPCVOID) oBb2, F,
- (LPCVOID) oBb3, F,
- (LPCVOID) oBb4, F,
- (LPCVOID) oBb5, F,
- (LPCVOID) oBb6, F,
- (LPCVOID) oBb7, F,
- (LPCVOID) oBb8, F,
- (LPCVOID) oBb9, F,
- (LPCVOID) oBbA, F,
- (LPCVOID) oBbB, F,
- (LPCVOID) oBbC, F,
- (LPCVOID) oBbD, F,
- (LPCVOID) oBbE, F,
- (LPCVOID) oBbF, F
+ { (LPCVOID) oBb0, F },
+ { (LPCVOID) oBb1, F },
+ { (LPCVOID) oBb2, F },
+ { (LPCVOID) oBb3, F },
+ { (LPCVOID) oBb4, F },
+ { (LPCVOID) oBb5, F },
+ { (LPCVOID) oBb6, F },
+ { (LPCVOID) oBb7, F },
+ { (LPCVOID) oBb8, F },
+ { (LPCVOID) oBb9, F },
+ { (LPCVOID) oBbA, F },
+ { (LPCVOID) oBbB, F },
+ { (LPCVOID) oBbC, F },
+ { (LPCVOID) oBbD, F },
+ { (LPCVOID) oBbE, F },
+ { (LPCVOID) oBbF, F }
};
static JMPTAB oBa_[] =
{
- (LPCVOID) oBa0, F,
- (LPCVOID) oBa1, F,
- (LPCVOID) oBa2, F,
- (LPCVOID) oBa3, F,
- (LPCVOID) oBa4, F,
- (LPCVOID) oBa5, F,
- (LPCVOID) oBa6, F,
- (LPCVOID) oBa7, F,
- (LPCVOID) oBa8, F,
- (LPCVOID) oBa9, F,
- (LPCVOID) oBaA, F,
- (LPCVOID) oBaB, F,
- (LPCVOID) oBaC, F,
- (LPCVOID) oBaD, F,
- (LPCVOID) oBaE, F,
- (LPCVOID) oBaF, F
+ { (LPCVOID) oBa0, F },
+ { (LPCVOID) oBa1, F },
+ { (LPCVOID) oBa2, F },
+ { (LPCVOID) oBa3, F },
+ { (LPCVOID) oBa4, F },
+ { (LPCVOID) oBa5, F },
+ { (LPCVOID) oBa6, F },
+ { (LPCVOID) oBa7, F },
+ { (LPCVOID) oBa8, F },
+ { (LPCVOID) oBa9, F },
+ { (LPCVOID) oBaA, F },
+ { (LPCVOID) oBaB, F },
+ { (LPCVOID) oBaC, F },
+ { (LPCVOID) oBaD, F },
+ { (LPCVOID) oBaE, F },
+ { (LPCVOID) oBaF, F }
};
static JMPTAB oB_[] =
{
- (LPCVOID) oBa_, 2,
- (LPCVOID) oBa_, 2,
- (LPCVOID) oBa_, 2,
- (LPCVOID) oBa_, 2,
- (LPCVOID) oBa_, 2,
- (LPCVOID) oBa_, 2,
- (LPCVOID) oBa_, 2,
- (LPCVOID) oBa_, 2,
- (LPCVOID) oBb_, 2,
- (LPCVOID) oBb_, 2,
- (LPCVOID) oBb_, 2,
- (LPCVOID) oBb_, 2,
- (LPCVOID) oBb_, 2,
- (LPCVOID) oBb_, 2,
- (LPCVOID) oBb_, 2,
- (LPCVOID) oBb_, 2
+ { (LPCVOID) oBa_, 2 },
+ { (LPCVOID) oBa_, 2 },
+ { (LPCVOID) oBa_, 2 },
+ { (LPCVOID) oBa_, 2 },
+ { (LPCVOID) oBa_, 2 },
+ { (LPCVOID) oBa_, 2 },
+ { (LPCVOID) oBa_, 2 },
+ { (LPCVOID) oBa_, 2 },
+ { (LPCVOID) oBb_, 2 },
+ { (LPCVOID) oBb_, 2 },
+ { (LPCVOID) oBb_, 2 },
+ { (LPCVOID) oBb_, 2 },
+ { (LPCVOID) oBb_, 2 },
+ { (LPCVOID) oBb_, 2 },
+ { (LPCVOID) oBb_, 2 },
+ { (LPCVOID) oBb_, 2 }
};
static JMPTAB oAb_[] =
{
- (LPCVOID) oAb0, F,
- (LPCVOID) oAb1, F,
- (LPCVOID) oAb2, F,
- (LPCVOID) oAb3, F,
- (LPCVOID) oAb4, F,
- (LPCVOID) oAb5, F,
- (LPCVOID) oAb6, F,
- (LPCVOID) oAb7, F,
- (LPCVOID) oAb8, F,
- (LPCVOID) oAb9, F,
- (LPCVOID) oAbA, F,
- (LPCVOID) oAbB, F,
- (LPCVOID) oAbC, F,
- (LPCVOID) oAbD, F,
- (LPCVOID) oAbE, F,
- (LPCVOID) oAbF, F
+ { (LPCVOID) oAb0, F },
+ { (LPCVOID) oAb1, F },
+ { (LPCVOID) oAb2, F },
+ { (LPCVOID) oAb3, F },
+ { (LPCVOID) oAb4, F },
+ { (LPCVOID) oAb5, F },
+ { (LPCVOID) oAb6, F },
+ { (LPCVOID) oAb7, F },
+ { (LPCVOID) oAb8, F },
+ { (LPCVOID) oAb9, F },
+ { (LPCVOID) oAbA, F },
+ { (LPCVOID) oAbB, F },
+ { (LPCVOID) oAbC, F },
+ { (LPCVOID) oAbD, F },
+ { (LPCVOID) oAbE, F },
+ { (LPCVOID) oAbF, F }
};
static JMPTAB oAa_[] =
{
- (LPCVOID) oAa0, F,
- (LPCVOID) oAa1, F,
- (LPCVOID) oAa2, F,
- (LPCVOID) oAa3, F,
- (LPCVOID) oAa4, F,
- (LPCVOID) oAa5, F,
- (LPCVOID) oAa6, F,
- (LPCVOID) oAa7, F,
- (LPCVOID) oAa8, F,
- (LPCVOID) oAa9, F,
- (LPCVOID) oAaA, F,
- (LPCVOID) oAaB, F,
- (LPCVOID) oAaC, F,
- (LPCVOID) oAaD, F,
- (LPCVOID) oAaE, F,
- (LPCVOID) oAaF, F
+ { (LPCVOID) oAa0, F },
+ { (LPCVOID) oAa1, F },
+ { (LPCVOID) oAa2, F },
+ { (LPCVOID) oAa3, F },
+ { (LPCVOID) oAa4, F },
+ { (LPCVOID) oAa5, F },
+ { (LPCVOID) oAa6, F },
+ { (LPCVOID) oAa7, F },
+ { (LPCVOID) oAa8, F },
+ { (LPCVOID) oAa9, F },
+ { (LPCVOID) oAaA, F },
+ { (LPCVOID) oAaB, F },
+ { (LPCVOID) oAaC, F },
+ { (LPCVOID) oAaD, F },
+ { (LPCVOID) oAaE, F },
+ { (LPCVOID) oAaF, F }
};
static JMPTAB oA_[] =
{
- (LPCVOID) oAa_, 2,
- (LPCVOID) oAa_, 2,
- (LPCVOID) oAa_, 2,
- (LPCVOID) oAa_, 2,
- (LPCVOID) oAa_, 2,
- (LPCVOID) oAa_, 2,
- (LPCVOID) oAa_, 2,
- (LPCVOID) oAa_, 2,
- (LPCVOID) oAb_, 2,
- (LPCVOID) oAb_, 2,
- (LPCVOID) oAb_, 2,
- (LPCVOID) oAb_, 2,
- (LPCVOID) oAb_, 2,
- (LPCVOID) oAb_, 2,
- (LPCVOID) oAb_, 2,
- (LPCVOID) oAb_, 2
+ { (LPCVOID) oAa_, 2 },
+ { (LPCVOID) oAa_, 2 },
+ { (LPCVOID) oAa_, 2 },
+ { (LPCVOID) oAa_, 2 },
+ { (LPCVOID) oAa_, 2 },
+ { (LPCVOID) oAa_, 2 },
+ { (LPCVOID) oAa_, 2 },
+ { (LPCVOID) oAa_, 2 },
+ { (LPCVOID) oAb_, 2 },
+ { (LPCVOID) oAb_, 2 },
+ { (LPCVOID) oAb_, 2 },
+ { (LPCVOID) oAb_, 2 },
+ { (LPCVOID) oAb_, 2 },
+ { (LPCVOID) oAb_, 2 },
+ { (LPCVOID) oAb_, 2 },
+ { (LPCVOID) oAb_, 2 }
};
static JMPTAB o9b_[] =
{
- (LPCVOID) o9b0, F,
- (LPCVOID) o9b1, F,
- (LPCVOID) o9b2, F,
- (LPCVOID) o9b3, F,
- (LPCVOID) o9b4, F,
- (LPCVOID) o9b5, F,
- (LPCVOID) o9b6, F,
- (LPCVOID) o9b7, F,
- (LPCVOID) o9b8, F,
- (LPCVOID) o9b9, F,
- (LPCVOID) o9bA, F,
- (LPCVOID) o9bB, F,
- (LPCVOID) o9bC, F,
- (LPCVOID) o9bD, F,
- (LPCVOID) o9bE, F,
- (LPCVOID) o9bF, F
+ { (LPCVOID) o9b0, F },
+ { (LPCVOID) o9b1, F },
+ { (LPCVOID) o9b2, F },
+ { (LPCVOID) o9b3, F },
+ { (LPCVOID) o9b4, F },
+ { (LPCVOID) o9b5, F },
+ { (LPCVOID) o9b6, F },
+ { (LPCVOID) o9b7, F },
+ { (LPCVOID) o9b8, F },
+ { (LPCVOID) o9b9, F },
+ { (LPCVOID) o9bA, F },
+ { (LPCVOID) o9bB, F },
+ { (LPCVOID) o9bC, F },
+ { (LPCVOID) o9bD, F },
+ { (LPCVOID) o9bE, F },
+ { (LPCVOID) o9bF, F }
};
static JMPTAB o9a_[] =
{
- (LPCVOID) o9a0, F,
- (LPCVOID) o9a1, F,
- (LPCVOID) o9a2, F,
- (LPCVOID) o9a3, F,
- (LPCVOID) o9a4, F,
- (LPCVOID) o9a5, F,
- (LPCVOID) o9a6, F,
- (LPCVOID) o9a7, F,
- (LPCVOID) o9a8, F,
- (LPCVOID) o9a9, F,
- (LPCVOID) o9aA, F,
- (LPCVOID) o9aB, F,
- (LPCVOID) o9aC, F,
- (LPCVOID) o9aD, F,
- (LPCVOID) o9aE, F,
- (LPCVOID) o9aF, F
+ { (LPCVOID) o9a0, F },
+ { (LPCVOID) o9a1, F },
+ { (LPCVOID) o9a2, F },
+ { (LPCVOID) o9a3, F },
+ { (LPCVOID) o9a4, F },
+ { (LPCVOID) o9a5, F },
+ { (LPCVOID) o9a6, F },
+ { (LPCVOID) o9a7, F },
+ { (LPCVOID) o9a8, F },
+ { (LPCVOID) o9a9, F },
+ { (LPCVOID) o9aA, F },
+ { (LPCVOID) o9aB, F },
+ { (LPCVOID) o9aC, F },
+ { (LPCVOID) o9aD, F },
+ { (LPCVOID) o9aE, F },
+ { (LPCVOID) o9aF, F }
};
static JMPTAB o9_[] =
{
- (LPCVOID) o9a_, 2,
- (LPCVOID) o9a_, 2,
- (LPCVOID) o9a_, 2,
- (LPCVOID) o9a_, 2,
- (LPCVOID) o9a_, 2,
- (LPCVOID) o9a_, 2,
- (LPCVOID) o9a_, 2,
- (LPCVOID) o9a_, 2,
- (LPCVOID) o9b_, 2,
- (LPCVOID) o9b_, 2,
- (LPCVOID) o9b_, 2,
- (LPCVOID) o9b_, 2,
- (LPCVOID) o9b_, 2,
- (LPCVOID) o9b_, 2,
- (LPCVOID) o9b_, 2,
- (LPCVOID) o9b_, 2
+ { (LPCVOID) o9a_, 2 },
+ { (LPCVOID) o9a_, 2 },
+ { (LPCVOID) o9a_, 2 },
+ { (LPCVOID) o9a_, 2 },
+ { (LPCVOID) o9a_, 2 },
+ { (LPCVOID) o9a_, 2 },
+ { (LPCVOID) o9a_, 2 },
+ { (LPCVOID) o9a_, 2 },
+ { (LPCVOID) o9b_, 2 },
+ { (LPCVOID) o9b_, 2 },
+ { (LPCVOID) o9b_, 2 },
+ { (LPCVOID) o9b_, 2 },
+ { (LPCVOID) o9b_, 2 },
+ { (LPCVOID) o9b_, 2 },
+ { (LPCVOID) o9b_, 2 },
+ { (LPCVOID) o9b_, 2 }
};
static JMPTAB o8B_[] =
{
- (LPCVOID) o8B0, F,
- (LPCVOID) o8B1, F,
- (LPCVOID) o8B2, F,
- (LPCVOID) o8B3, F,
- (LPCVOID) o8B4, F,
- (LPCVOID) o8B5, F,
- (LPCVOID) o8B6, F,
- (LPCVOID) o8B7, F,
- (LPCVOID) o8B8, F,
- (LPCVOID) o8B9, F,
- (LPCVOID) o8BA, F,
- (LPCVOID) o8BB, F,
- (LPCVOID) o8BC, F,
- (LPCVOID) o8BD, F,
- (LPCVOID) o8BE, F,
- (LPCVOID) o8BF, F
+ { (LPCVOID) o8B0, F },
+ { (LPCVOID) o8B1, F },
+ { (LPCVOID) o8B2, F },
+ { (LPCVOID) o8B3, F },
+ { (LPCVOID) o8B4, F },
+ { (LPCVOID) o8B5, F },
+ { (LPCVOID) o8B6, F },
+ { (LPCVOID) o8B7, F },
+ { (LPCVOID) o8B8, F },
+ { (LPCVOID) o8B9, F },
+ { (LPCVOID) o8BA, F },
+ { (LPCVOID) o8BB, F },
+ { (LPCVOID) o8BC, F },
+ { (LPCVOID) o8BD, F },
+ { (LPCVOID) o8BE, F },
+ { (LPCVOID) o8BF, F }
};
static JMPTAB o8A_[] =
{
- (LPCVOID) o8A0, F,
- (LPCVOID) o8A1, F,
- (LPCVOID) o8A2, F,
- (LPCVOID) o8A3, F,
- (LPCVOID) o8A4, F,
- (LPCVOID) o8A5, F,
- (LPCVOID) o8A6, F,
- (LPCVOID) o8A7, F,
- (LPCVOID) o8A8, F,
- (LPCVOID) o8A9, F,
- (LPCVOID) o8AA, F,
- (LPCVOID) o8AB, F,
- (LPCVOID) o8AC, F,
- (LPCVOID) o8AD, F,
- (LPCVOID) o8AE, F,
- (LPCVOID) o8AF, F
+ { (LPCVOID) o8A0, F },
+ { (LPCVOID) o8A1, F },
+ { (LPCVOID) o8A2, F },
+ { (LPCVOID) o8A3, F },
+ { (LPCVOID) o8A4, F },
+ { (LPCVOID) o8A5, F },
+ { (LPCVOID) o8A6, F },
+ { (LPCVOID) o8A7, F },
+ { (LPCVOID) o8A8, F },
+ { (LPCVOID) o8A9, F },
+ { (LPCVOID) o8AA, F },
+ { (LPCVOID) o8AB, F },
+ { (LPCVOID) o8AC, F },
+ { (LPCVOID) o8AD, F },
+ { (LPCVOID) o8AE, F },
+ { (LPCVOID) o8AF, F }
};
static JMPTAB o81B_[] =
{
- (LPCVOID) o_invalid4, F,
- (LPCVOID) o81B1, F, // normally o_invalid4, Apple: LOOP
- (LPCVOID) o81B2, F,
- (LPCVOID) o81B3, F,
- (LPCVOID) o81B4, F,
- (LPCVOID) o81B5, F,
- (LPCVOID) o81B6, F,
- (LPCVOID) o81B7, F,
- (LPCVOID) o_invalid4, F, // Apple: SKPTOP
- (LPCVOID) o_invalid4, F, // Apple: SKBOT
- (LPCVOID) o_invalid4, F, // Apple: SKIP
- (LPCVOID) o_invalid4, F, // Apple: SKPLEN
- (LPCVOID) o_invalid4, F, // Apple: SKPID
- (LPCVOID) o_invalid4, F, // Apple: $SEMI
- (LPCVOID) o_invalid4, F, // Apple: DOCOL
- (LPCVOID) o_invalid4, F
+ { (LPCVOID) o_invalid4, F },
+ { (LPCVOID) o81B1, F }, // normally o_invalid4, Apple: LOOP
+ { (LPCVOID) o81B2, F },
+ { (LPCVOID) o81B3, F },
+ { (LPCVOID) o81B4, F },
+ { (LPCVOID) o81B5, F },
+ { (LPCVOID) o81B6, F },
+ { (LPCVOID) o81B7, F },
+ { (LPCVOID) o_invalid4, F }, // Apple: SKPTOP
+ { (LPCVOID) o_invalid4, F }, // Apple: SKBOT
+ { (LPCVOID) o_invalid4, F }, // Apple: SKIP
+ { (LPCVOID) o_invalid4, F }, // Apple: SKPLEN
+ { (LPCVOID) o_invalid4, F }, // Apple: SKPID
+ { (LPCVOID) o_invalid4, F }, // Apple: $SEMI
+ { (LPCVOID) o_invalid4, F }, // Apple: DOCOL
+ { (LPCVOID) o_invalid4, F }
};
static JMPTAB o81Af2_[] =
{
- (LPCVOID) o81Af20, F,
- (LPCVOID) o81Af21, F,
- (LPCVOID) o81Af22, F,
- (LPCVOID) o81Af23, F,
- (LPCVOID) o81Af24, F,
- (LPCVOID) o81Af21, F,
- (LPCVOID) o81Af22, F,
- (LPCVOID) o81Af23, F,
- (LPCVOID) o81Af28, F,
- (LPCVOID) o81Af29, F,
- (LPCVOID) o81Af2A, F,
- (LPCVOID) o81Af2B, F,
- (LPCVOID) o81Af2C, F,
- (LPCVOID) o81Af29, F,
- (LPCVOID) o81Af2A, F,
- (LPCVOID) o81Af2B, F
+ { (LPCVOID) o81Af20, F },
+ { (LPCVOID) o81Af21, F },
+ { (LPCVOID) o81Af22, F },
+ { (LPCVOID) o81Af23, F },
+ { (LPCVOID) o81Af24, F },
+ { (LPCVOID) o81Af21, F },
+ { (LPCVOID) o81Af22, F },
+ { (LPCVOID) o81Af23, F },
+ { (LPCVOID) o81Af28, F },
+ { (LPCVOID) o81Af29, F },
+ { (LPCVOID) o81Af2A, F },
+ { (LPCVOID) o81Af2B, F },
+ { (LPCVOID) o81Af2C, F },
+ { (LPCVOID) o81Af29, F },
+ { (LPCVOID) o81Af2A, F },
+ { (LPCVOID) o81Af2B, F }
};
static JMPTAB o81Af1_[] =
{
- (LPCVOID) o81Af10, F,
- (LPCVOID) o81Af11, F,
- (LPCVOID) o81Af12, F,
- (LPCVOID) o81Af13, F,
- (LPCVOID) o81Af14, F,
- (LPCVOID) o81Af11, F,
- (LPCVOID) o81Af12, F,
- (LPCVOID) o81Af13, F,
- (LPCVOID) o81Af18, F,
- (LPCVOID) o81Af19, F,
- (LPCVOID) o81Af1A, F,
- (LPCVOID) o81Af1B, F,
- (LPCVOID) o81Af1C, F,
- (LPCVOID) o81Af19, F,
- (LPCVOID) o81Af1A, F,
- (LPCVOID) o81Af1B, F
+ { (LPCVOID) o81Af10, F },
+ { (LPCVOID) o81Af11, F },
+ { (LPCVOID) o81Af12, F },
+ { (LPCVOID) o81Af13, F },
+ { (LPCVOID) o81Af14, F },
+ { (LPCVOID) o81Af11, F },
+ { (LPCVOID) o81Af12, F },
+ { (LPCVOID) o81Af13, F },
+ { (LPCVOID) o81Af18, F },
+ { (LPCVOID) o81Af19, F },
+ { (LPCVOID) o81Af1A, F },
+ { (LPCVOID) o81Af1B, F },
+ { (LPCVOID) o81Af1C, F },
+ { (LPCVOID) o81Af19, F },
+ { (LPCVOID) o81Af1A, F },
+ { (LPCVOID) o81Af1B, F }
};
static JMPTAB o81Af0_[] =
{
- (LPCVOID) o81Af00, F,
- (LPCVOID) o81Af01, F,
- (LPCVOID) o81Af02, F,
- (LPCVOID) o81Af03, F,
- (LPCVOID) o81Af04, F,
- (LPCVOID) o81Af01, F,
- (LPCVOID) o81Af02, F,
- (LPCVOID) o81Af03, F,
- (LPCVOID) o81Af08, F,
- (LPCVOID) o81Af09, F,
- (LPCVOID) o81Af0A, F,
- (LPCVOID) o81Af0B, F,
- (LPCVOID) o81Af0C, F,
- (LPCVOID) o81Af09, F,
- (LPCVOID) o81Af0A, F,
- (LPCVOID) o81Af0B, F
+ { (LPCVOID) o81Af00, F },
+ { (LPCVOID) o81Af01, F },
+ { (LPCVOID) o81Af02, F },
+ { (LPCVOID) o81Af03, F },
+ { (LPCVOID) o81Af04, F },
+ { (LPCVOID) o81Af01, F },
+ { (LPCVOID) o81Af02, F },
+ { (LPCVOID) o81Af03, F },
+ { (LPCVOID) o81Af08, F },
+ { (LPCVOID) o81Af09, F },
+ { (LPCVOID) o81Af0A, F },
+ { (LPCVOID) o81Af0B, F },
+ { (LPCVOID) o81Af0C, F },
+ { (LPCVOID) o81Af09, F },
+ { (LPCVOID) o81Af0A, F },
+ { (LPCVOID) o81Af0B, F }
};
static JMPTAB o81A_[] =
{
- (LPCVOID) o81Af0_, 5,
- (LPCVOID) o81Af1_, 5,
- (LPCVOID) o81Af2_, 5,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F
+ { (LPCVOID) o81Af0_, 5 },
+ { (LPCVOID) o81Af1_, 5 },
+ { (LPCVOID) o81Af2_, 5 },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F }
};
static JMPTAB o819_[] =
{
- (LPCVOID) o819f0, F,
- (LPCVOID) o819f1, F,
- (LPCVOID) o819f2, F,
- (LPCVOID) o819f3, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F
+ { (LPCVOID) o819f0, F },
+ { (LPCVOID) o819f1, F },
+ { (LPCVOID) o819f2, F },
+ { (LPCVOID) o819f3, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F }
};
static JMPTAB o818_[] =
{
- (LPCVOID) o818f0x, F,
- (LPCVOID) o818f1x, F,
- (LPCVOID) o818f2x, F,
- (LPCVOID) o818f3x, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o818f8x, F,
- (LPCVOID) o818f9x, F,
- (LPCVOID) o818fAx, F,
- (LPCVOID) o818fBx, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F,
- (LPCVOID) o_invalid6, F
+ { (LPCVOID) o818f0x, F },
+ { (LPCVOID) o818f1x, F },
+ { (LPCVOID) o818f2x, F },
+ { (LPCVOID) o818f3x, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o818f8x, F },
+ { (LPCVOID) o818f9x, F },
+ { (LPCVOID) o818fAx, F },
+ { (LPCVOID) o818fBx, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F },
+ { (LPCVOID) o_invalid6, F }
};
static JMPTAB o81_[] =
{
- (LPCVOID) o810, F,
- (LPCVOID) o811, F,
- (LPCVOID) o812, F,
- (LPCVOID) o813, F,
- (LPCVOID) o814, F,
- (LPCVOID) o815, F,
- (LPCVOID) o816, F,
- (LPCVOID) o817, F,
- (LPCVOID) o818_, 4,
- (LPCVOID) o819_, 4,
- (LPCVOID) o81A_, 4,
- (LPCVOID) o81B_, 3,
- (LPCVOID) o81C, F,
- (LPCVOID) o81D, F,
- (LPCVOID) o81E, F,
- (LPCVOID) o81F, F
+ { (LPCVOID) o810, F },
+ { (LPCVOID) o811, F },
+ { (LPCVOID) o812, F },
+ { (LPCVOID) o813, F },
+ { (LPCVOID) o814, F },
+ { (LPCVOID) o815, F },
+ { (LPCVOID) o816, F },
+ { (LPCVOID) o817, F },
+ { (LPCVOID) o818_, 4 },
+ { (LPCVOID) o819_, 4 },
+ { (LPCVOID) o81A_, 4 },
+ { (LPCVOID) o81B_, 3 },
+ { (LPCVOID) o81C, F },
+ { (LPCVOID) o81D, F },
+ { (LPCVOID) o81E, F },
+ { (LPCVOID) o81F, F }
};
static JMPTAB o8081_[] =
{
- (LPCVOID) o80810, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F,
- (LPCVOID) o_invalid5, F
+ { (LPCVOID) o80810, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F },
+ { (LPCVOID) o_invalid5, F }
};
static JMPTAB o808_[] =
{
- (LPCVOID) o8080, F,
- (LPCVOID) o8081_, 4,
- (LPCVOID) o8082X, F,
- (LPCVOID) o8083, F,
- (LPCVOID) o8084n, F,
- (LPCVOID) o8085n, F,
- (LPCVOID) o8086n, F,
- (LPCVOID) o8087n, F,
- (LPCVOID) o8088n, F,
- (LPCVOID) o8089n, F,
- (LPCVOID) o808An, F,
- (LPCVOID) o808Bn, F,
- (LPCVOID) o808C, F,
- (LPCVOID) o808D, F,
- (LPCVOID) o808E, F,
- (LPCVOID) o808F, F
+ { (LPCVOID) o8080, F },
+ { (LPCVOID) o8081_, 4 },
+ { (LPCVOID) o8082X, F },
+ { (LPCVOID) o8083, F },
+ { (LPCVOID) o8084n, F },
+ { (LPCVOID) o8085n, F },
+ { (LPCVOID) o8086n, F },
+ { (LPCVOID) o8087n, F },
+ { (LPCVOID) o8088n, F },
+ { (LPCVOID) o8089n, F },
+ { (LPCVOID) o808An, F },
+ { (LPCVOID) o808Bn, F },
+ { (LPCVOID) o808C, F },
+ { (LPCVOID) o808D, F },
+ { (LPCVOID) o808E, F },
+ { (LPCVOID) o808F, F }
};
static JMPTAB o80_[] =
{
- (LPCVOID) o800, F,
- (LPCVOID) o801, F,
- (LPCVOID) o802, F,
- (LPCVOID) o803, F,
- (LPCVOID) o804, F,
- (LPCVOID) o805, F,
- (LPCVOID) o806, F,
- (LPCVOID) o807, F,
- (LPCVOID) o808_, 3,
- (LPCVOID) o809, F,
- (LPCVOID) o80A, F,
- (LPCVOID) o80B, F,
- (LPCVOID) o80Cn, F,
- (LPCVOID) o80Dn, F,
- (LPCVOID) o80E, F,
- (LPCVOID) o80Fn, F
+ { (LPCVOID) o800, F },
+ { (LPCVOID) o801, F },
+ { (LPCVOID) o802, F },
+ { (LPCVOID) o803, F },
+ { (LPCVOID) o804, F },
+ { (LPCVOID) o805, F },
+ { (LPCVOID) o806, F },
+ { (LPCVOID) o807, F },
+ { (LPCVOID) o808_, 3 },
+ { (LPCVOID) o809, F },
+ { (LPCVOID) o80A, F },
+ { (LPCVOID) o80B, F },
+ { (LPCVOID) o80Cn, F },
+ { (LPCVOID) o80Dn, F },
+ { (LPCVOID) o80E, F },
+ { (LPCVOID) o80Fn, F }
};
static JMPTAB o8_[] =
{
- (LPCVOID) o80_, 2,
- (LPCVOID) o81_, 2,
- (LPCVOID) o82n, F,
- (LPCVOID) o83n, F,
- (LPCVOID) o84n, F,
- (LPCVOID) o85n, F,
- (LPCVOID) o86n, F,
- (LPCVOID) o87n, F,
- (LPCVOID) o88n, F,
- (LPCVOID) o89n, F,
- (LPCVOID) o8A_, 2,
- (LPCVOID) o8B_, 2,
- (LPCVOID) o8Cd4, F,
- (LPCVOID) o8Dd5, F,
- (LPCVOID) o8Ed4, F,
- (LPCVOID) o8Fd5, F
+ { (LPCVOID) o80_, 2 },
+ { (LPCVOID) o81_, 2 },
+ { (LPCVOID) o82n, F },
+ { (LPCVOID) o83n, F },
+ { (LPCVOID) o84n, F },
+ { (LPCVOID) o85n, F },
+ { (LPCVOID) o86n, F },
+ { (LPCVOID) o87n, F },
+ { (LPCVOID) o88n, F },
+ { (LPCVOID) o89n, F },
+ { (LPCVOID) o8A_, 2 },
+ { (LPCVOID) o8B_, 2 },
+ { (LPCVOID) o8Cd4, F },
+ { (LPCVOID) o8Dd5, F },
+ { (LPCVOID) o8Ed4, F },
+ { (LPCVOID) o8Fd5, F }
};
static JMPTAB o15_[] =
{
- (LPCVOID) o150a, F,
- (LPCVOID) o151a, F,
- (LPCVOID) o152a, F,
- (LPCVOID) o153a, F,
- (LPCVOID) o154a, F,
- (LPCVOID) o155a, F,
- (LPCVOID) o156a, F,
- (LPCVOID) o157a, F,
- (LPCVOID) o158x, F,
- (LPCVOID) o159x, F,
- (LPCVOID) o15Ax, F,
- (LPCVOID) o15Bx, F,
- (LPCVOID) o15Cx, F,
- (LPCVOID) o15Dx, F,
- (LPCVOID) o15Ex, F,
- (LPCVOID) o15Fx, F
+ { (LPCVOID) o150a, F },
+ { (LPCVOID) o151a, F },
+ { (LPCVOID) o152a, F },
+ { (LPCVOID) o153a, F },
+ { (LPCVOID) o154a, F },
+ { (LPCVOID) o155a, F },
+ { (LPCVOID) o156a, F },
+ { (LPCVOID) o157a, F },
+ { (LPCVOID) o158x, F },
+ { (LPCVOID) o159x, F },
+ { (LPCVOID) o15Ax, F },
+ { (LPCVOID) o15Bx, F },
+ { (LPCVOID) o15Cx, F },
+ { (LPCVOID) o15Dx, F },
+ { (LPCVOID) o15Ex, F },
+ { (LPCVOID) o15Fx, F }
};
static JMPTAB o14_[] =
{
- (LPCVOID) o140, F,
- (LPCVOID) o141, F,
- (LPCVOID) o142, F,
- (LPCVOID) o143, F,
- (LPCVOID) o144, F,
- (LPCVOID) o145, F,
- (LPCVOID) o146, F,
- (LPCVOID) o147, F,
- (LPCVOID) o148, F,
- (LPCVOID) o149, F,
- (LPCVOID) o14A, F,
- (LPCVOID) o14B, F,
- (LPCVOID) o14C, F,
- (LPCVOID) o14D, F,
- (LPCVOID) o14E, F,
- (LPCVOID) o14F, F
+ { (LPCVOID) o140, F },
+ { (LPCVOID) o141, F },
+ { (LPCVOID) o142, F },
+ { (LPCVOID) o143, F },
+ { (LPCVOID) o144, F },
+ { (LPCVOID) o145, F },
+ { (LPCVOID) o146, F },
+ { (LPCVOID) o147, F },
+ { (LPCVOID) o148, F },
+ { (LPCVOID) o149, F },
+ { (LPCVOID) o14A, F },
+ { (LPCVOID) o14B, F },
+ { (LPCVOID) o14C, F },
+ { (LPCVOID) o14D, F },
+ { (LPCVOID) o14E, F },
+ { (LPCVOID) o14F, F }
};
static JMPTAB o13_[] =
{
- (LPCVOID) o130, F,
- (LPCVOID) o131, F,
- (LPCVOID) o132, F,
- (LPCVOID) o133, F,
- (LPCVOID) o134, F,
- (LPCVOID) o135, F,
- (LPCVOID) o136, F,
- (LPCVOID) o137, F,
- (LPCVOID) o138, F,
- (LPCVOID) o139, F,
- (LPCVOID) o13A, F,
- (LPCVOID) o13B, F,
- (LPCVOID) o13C, F,
- (LPCVOID) o13D, F,
- (LPCVOID) o13E, F,
- (LPCVOID) o13F, F
+ { (LPCVOID) o130, F },
+ { (LPCVOID) o131, F },
+ { (LPCVOID) o132, F },
+ { (LPCVOID) o133, F },
+ { (LPCVOID) o134, F },
+ { (LPCVOID) o135, F },
+ { (LPCVOID) o136, F },
+ { (LPCVOID) o137, F },
+ { (LPCVOID) o138, F },
+ { (LPCVOID) o139, F },
+ { (LPCVOID) o13A, F },
+ { (LPCVOID) o13B, F },
+ { (LPCVOID) o13C, F },
+ { (LPCVOID) o13D, F },
+ { (LPCVOID) o13E, F },
+ { (LPCVOID) o13F, F }
};
static JMPTAB o12_[] =
{
- (LPCVOID) o120, F,
- (LPCVOID) o121, F,
- (LPCVOID) o122, F,
- (LPCVOID) o123, F,
- (LPCVOID) o124, F,
- (LPCVOID) o121, F,
- (LPCVOID) o122, F,
- (LPCVOID) o123, F,
- (LPCVOID) o128, F,
- (LPCVOID) o129, F,
- (LPCVOID) o12A, F,
- (LPCVOID) o12B, F,
- (LPCVOID) o12C, F,
- (LPCVOID) o129, F,
- (LPCVOID) o12A, F,
- (LPCVOID) o12B, F
+ { (LPCVOID) o120, F },
+ { (LPCVOID) o121, F },
+ { (LPCVOID) o122, F },
+ { (LPCVOID) o123, F },
+ { (LPCVOID) o124, F },
+ { (LPCVOID) o121, F },
+ { (LPCVOID) o122, F },
+ { (LPCVOID) o123, F },
+ { (LPCVOID) o128, F },
+ { (LPCVOID) o129, F },
+ { (LPCVOID) o12A, F },
+ { (LPCVOID) o12B, F },
+ { (LPCVOID) o12C, F },
+ { (LPCVOID) o129, F },
+ { (LPCVOID) o12A, F },
+ { (LPCVOID) o12B, F }
};
static JMPTAB o11_[] =
{
- (LPCVOID) o110, F,
- (LPCVOID) o111, F,
- (LPCVOID) o112, F,
- (LPCVOID) o113, F,
- (LPCVOID) o114, F,
- (LPCVOID) o111, F,
- (LPCVOID) o112, F,
- (LPCVOID) o113, F,
- (LPCVOID) o118, F,
- (LPCVOID) o119, F,
- (LPCVOID) o11A, F,
- (LPCVOID) o11B, F,
- (LPCVOID) o11C, F,
- (LPCVOID) o119, F,
- (LPCVOID) o11A, F,
- (LPCVOID) o11B, F
+ { (LPCVOID) o110, F },
+ { (LPCVOID) o111, F },
+ { (LPCVOID) o112, F },
+ { (LPCVOID) o113, F },
+ { (LPCVOID) o114, F },
+ { (LPCVOID) o111, F },
+ { (LPCVOID) o112, F },
+ { (LPCVOID) o113, F },
+ { (LPCVOID) o118, F },
+ { (LPCVOID) o119, F },
+ { (LPCVOID) o11A, F },
+ { (LPCVOID) o11B, F },
+ { (LPCVOID) o11C, F },
+ { (LPCVOID) o119, F },
+ { (LPCVOID) o11A, F },
+ { (LPCVOID) o11B, F }
};
static JMPTAB o10_[] =
{
- (LPCVOID) o100, F,
- (LPCVOID) o101, F,
- (LPCVOID) o102, F,
- (LPCVOID) o103, F,
- (LPCVOID) o104, F,
- (LPCVOID) o101, F,
- (LPCVOID) o102, F,
- (LPCVOID) o103, F,
- (LPCVOID) o108, F,
- (LPCVOID) o109, F,
- (LPCVOID) o10A, F,
- (LPCVOID) o10B, F,
- (LPCVOID) o10C, F,
- (LPCVOID) o109, F,
- (LPCVOID) o10A, F,
- (LPCVOID) o10B, F
+ { (LPCVOID) o100, F },
+ { (LPCVOID) o101, F },
+ { (LPCVOID) o102, F },
+ { (LPCVOID) o103, F },
+ { (LPCVOID) o104, F },
+ { (LPCVOID) o101, F },
+ { (LPCVOID) o102, F },
+ { (LPCVOID) o103, F },
+ { (LPCVOID) o108, F },
+ { (LPCVOID) o109, F },
+ { (LPCVOID) o10A, F },
+ { (LPCVOID) o10B, F },
+ { (LPCVOID) o10C, F },
+ { (LPCVOID) o109, F },
+ { (LPCVOID) o10A, F },
+ { (LPCVOID) o10B, F }
};
static JMPTAB o1_[] =
{
- (LPCVOID) o10_, 2,
- (LPCVOID) o11_, 2,
- (LPCVOID) o12_, 2,
- (LPCVOID) o13_, 2,
- (LPCVOID) o14_, 2,
- (LPCVOID) o15_, 2,
- (LPCVOID) o16x, F,
- (LPCVOID) o17x, F,
- (LPCVOID) o18x, F,
- (LPCVOID) o19d2, F,
- (LPCVOID) o1Ad4, F,
- (LPCVOID) o1Bd5, F,
- (LPCVOID) o1Cx, F,
- (LPCVOID) o1Dd2, F,
- (LPCVOID) o1Ed4, F,
- (LPCVOID) o1Fd5, F
+ { (LPCVOID) o10_, 2 },
+ { (LPCVOID) o11_, 2 },
+ { (LPCVOID) o12_, 2 },
+ { (LPCVOID) o13_, 2 },
+ { (LPCVOID) o14_, 2 },
+ { (LPCVOID) o15_, 2 },
+ { (LPCVOID) o16x, F },
+ { (LPCVOID) o17x, F },
+ { (LPCVOID) o18x, F },
+ { (LPCVOID) o19d2, F },
+ { (LPCVOID) o1Ad4, F },
+ { (LPCVOID) o1Bd5, F },
+ { (LPCVOID) o1Cx, F },
+ { (LPCVOID) o1Dd2, F },
+ { (LPCVOID) o1Ed4, F },
+ { (LPCVOID) o1Fd5, F }
};
static JMPTAB o0E_[] =
{
- (LPCVOID) o0Ef0, F,
- (LPCVOID) o0Ef1, F,
- (LPCVOID) o0Ef2, F,
- (LPCVOID) o0Ef3, F,
- (LPCVOID) o0Ef4, F,
- (LPCVOID) o0Ef5, F,
- (LPCVOID) o0Ef6, F,
- (LPCVOID) o0Ef7, F,
- (LPCVOID) o0Ef8, F,
- (LPCVOID) o0Ef9, F,
- (LPCVOID) o0EfA, F,
- (LPCVOID) o0EfB, F,
- (LPCVOID) o0EfC, F,
- (LPCVOID) o0EfD, F,
- (LPCVOID) o0EfE, F,
- (LPCVOID) o0EfF, F
+ { (LPCVOID) o0Ef0, F },
+ { (LPCVOID) o0Ef1, F },
+ { (LPCVOID) o0Ef2, F },
+ { (LPCVOID) o0Ef3, F },
+ { (LPCVOID) o0Ef4, F },
+ { (LPCVOID) o0Ef5, F },
+ { (LPCVOID) o0Ef6, F },
+ { (LPCVOID) o0Ef7, F },
+ { (LPCVOID) o0Ef8, F },
+ { (LPCVOID) o0Ef9, F },
+ { (LPCVOID) o0EfA, F },
+ { (LPCVOID) o0EfB, F },
+ { (LPCVOID) o0EfC, F },
+ { (LPCVOID) o0EfD, F },
+ { (LPCVOID) o0EfE, F },
+ { (LPCVOID) o0EfF, F }
};
static JMPTAB o0_[] =
{
- (LPCVOID) o00, F,
- (LPCVOID) o01, F,
- (LPCVOID) o02, F,
- (LPCVOID) o03, F,
- (LPCVOID) o04, F,
- (LPCVOID) o05, F,
- (LPCVOID) o06, F,
- (LPCVOID) o07, F,
- (LPCVOID) o08, F,
- (LPCVOID) o09, F,
- (LPCVOID) o0A, F,
- (LPCVOID) o0B, F,
- (LPCVOID) o0C, F,
- (LPCVOID) o0D, F,
- (LPCVOID) o0E_, 3,
- (LPCVOID) o0F, F
+ { (LPCVOID) o00, F },
+ { (LPCVOID) o01, F },
+ { (LPCVOID) o02, F },
+ { (LPCVOID) o03, F },
+ { (LPCVOID) o04, F },
+ { (LPCVOID) o05, F },
+ { (LPCVOID) o06, F },
+ { (LPCVOID) o07, F },
+ { (LPCVOID) o08, F },
+ { (LPCVOID) o09, F },
+ { (LPCVOID) o0A, F },
+ { (LPCVOID) o0B, F },
+ { (LPCVOID) o0C, F },
+ { (LPCVOID) o0D, F },
+ { (LPCVOID) o0E_, 3 },
+ { (LPCVOID) o0F, F }
};
static JMPTAB o_[] =
{
- (LPCVOID) o0_, 1,
- (LPCVOID) o1_, 1,
- (LPCVOID) o2n, F,
- (LPCVOID) o3X, F,
- (LPCVOID) o4d2, F,
- (LPCVOID) o5d2, F,
- (LPCVOID) o6d3, F,
- (LPCVOID) o7d3, F,
- (LPCVOID) o8_, 1,
- (LPCVOID) o9_, 1,
- (LPCVOID) oA_, 1,
- (LPCVOID) oB_, 1,
- (LPCVOID) oC_, 1,
- (LPCVOID) oD_, 1,
- (LPCVOID) oE_, 1,
- (LPCVOID) oF_, 1
+ { (LPCVOID) o0_, 1 },
+ { (LPCVOID) o1_, 1 },
+ { (LPCVOID) o2n, F },
+ { (LPCVOID) o3X, F },
+ { (LPCVOID) o4d2, F },
+ { (LPCVOID) o5d2, F },
+ { (LPCVOID) o6d3, F },
+ { (LPCVOID) o7d3, F },
+ { (LPCVOID) o8_, 1 },
+ { (LPCVOID) o9_, 1 },
+ { (LPCVOID) oA_, 1 },
+ { (LPCVOID) oB_, 1 },
+ { (LPCVOID) oC_, 1 },
+ { (LPCVOID) oD_, 1 },
+ { (LPCVOID) oE_, 1 },
+ { (LPCVOID) oF_, 1 }
};
// opcode dispatcher
diff --git a/app/src/main/cpp/core/lodepng.c b/app/src/main/cpp/core/lodepng.c
index 2c807ef..e0dcdd2 100644
--- a/app/src/main/cpp/core/lodepng.c
+++ b/app/src/main/cpp/core/lodepng.c
@@ -664,7 +664,7 @@ which is possible in case of only 0 or 1 present symbols. */
static unsigned HuffmanTree_makeTable(HuffmanTree* tree) {
static const unsigned headsize = 1u << FIRSTBITS; /*size of the first table*/
static const unsigned mask = (1u << FIRSTBITS) /*headsize*/ - 1u;
- unsigned i, numpresent, pointer, size; /*total table size*/
+ size_t i, numpresent, pointer, size; /*total table size*/
unsigned* maxlens = (unsigned*)lodepng_malloc(headsize * sizeof(unsigned));
if(!maxlens) return 83; /*alloc fail*/
@@ -683,7 +683,7 @@ static unsigned HuffmanTree_makeTable(HuffmanTree* tree) {
size = headsize;
for(i = 0; i < headsize; ++i) {
unsigned l = maxlens[i];
- if(l > FIRSTBITS) size += (1u << (l - FIRSTBITS));
+ if(l > FIRSTBITS) size += (((size_t)1) << (l - FIRSTBITS));
}
tree->table_len = (unsigned char*)lodepng_malloc(size * sizeof(*tree->table_len));
tree->table_value = (unsigned short*)lodepng_malloc(size * sizeof(*tree->table_value));
@@ -701,8 +701,8 @@ static unsigned HuffmanTree_makeTable(HuffmanTree* tree) {
unsigned l = maxlens[i];
if(l <= FIRSTBITS) continue;
tree->table_len[i] = l;
- tree->table_value[i] = pointer;
- pointer += (1u << (l - FIRSTBITS));
+ tree->table_value[i] = (unsigned short)pointer;
+ pointer += (((size_t)1) << (l - FIRSTBITS));
}
lodepng_free(maxlens);
@@ -726,7 +726,7 @@ static unsigned HuffmanTree_makeTable(HuffmanTree* tree) {
unsigned index = reverse | (j << l);
if(tree->table_len[index] != 16) return 55; /*invalid tree: long symbol shares prefix with short symbol*/
tree->table_len[index] = l;
- tree->table_value[index] = i;
+ tree->table_value[index] = (unsigned short)i;
}
} else {
/*long symbol, shares prefix with other long symbols in first lookup table, needs second lookup*/
@@ -743,7 +743,7 @@ static unsigned HuffmanTree_makeTable(HuffmanTree* tree) {
unsigned reverse2 = reverse >> FIRSTBITS; /* l - FIRSTBITS bits */
unsigned index2 = start + (reverse2 | (j << (l - FIRSTBITS)));
tree->table_len[index2] = l;
- tree->table_value[index2] = i;
+ tree->table_value[index2] = (unsigned short)i;
}
}
}
@@ -2886,7 +2886,7 @@ static unsigned lodepng_chunk_createv(ucvector* out,
}
unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize,
- unsigned length, const char* type, const unsigned char* data) {
+ size_t length, const char* type, const unsigned char* data) {
ucvector v = ucvector_init(*out, *outsize);
unsigned error = lodepng_chunk_createv(&v, length, type, data);
*out = v.data;
@@ -3363,7 +3363,7 @@ unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) {
static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) {
unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/
/*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/
- unsigned p = (unsigned)index & m;
+ unsigned p = (unsigned) index & m;
in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/
in = in << (bits * (m - p));
if(p == 0) out[index * bits / 8u] = in;
@@ -5889,7 +5889,7 @@ static size_t ilog2i(size_t i) {
l = ilog2(i);
/* approximate i*log2(i): l is integer logarithm, ((i - (1u << l)) << 1u)
linearly approximates the missing fractional part multiplied by i */
- return i * l + ((i - ((size_t) 1u << l)) << 1u);
+ return i * l + ((i - (((size_t)1) << l)) << 1u);
}
static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h,
diff --git a/app/src/main/cpp/core/lodepng.h b/app/src/main/cpp/core/lodepng.h
index 81d4985..3f3649d 100644
--- a/app/src/main/cpp/core/lodepng.h
+++ b/app/src/main/cpp/core/lodepng.h
@@ -1001,7 +1001,7 @@ and data separately. The type is a 4-letter string.
The out variable and outsize are updated to reflect the new reallocated buffer.
Returne error code (0 if it went ok)
*/
-unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length,
+unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, size_t length,
const char* type, const unsigned char* data);
diff --git a/app/src/main/cpp/core/mops.c b/app/src/main/cpp/core/mops.c
index dfbb2e0..ded208d 100644
--- a/app/src/main/cpp/core/mops.c
+++ b/app/src/main/cpp/core/mops.c
@@ -1002,9 +1002,9 @@ static DWORD ReadT2Acc(VOID)
// maybe CPU speed measurement, slow down the next 10 CPU opcodes
if (dwCycDif < 150)
{
- InitAdjustSpeed(); // init variables if necessary
EnterCriticalSection(&csSlowLock);
{
+ InitAdjustSpeed(); // init variables if necessary
nOpcSlow = 10; // slow down next 10 opcodes
}
LeaveCriticalSection(&csSlowLock);
@@ -1146,9 +1146,9 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate)
// CPU running with max. speed we may get a timeout overflow
// -> to avoid this slow down CPU speed on transmit buffer full
- InitAdjustSpeed(); // init variables if necessary
EnterCriticalSection(&csSlowLock);
{
+ InitAdjustSpeed(); // init variables if necessary
nOpcSlow = 10; // slow down next 10 opcodes
}
LeaveCriticalSection(&csSlowLock);
diff --git a/app/src/main/cpp/core/resource.h b/app/src/main/cpp/core/resource.h
index 16274ad..601e56a 100644
--- a/app/src/main/cpp/core/resource.h
+++ b/app/src/main/cpp/core/resource.h
@@ -121,62 +121,67 @@
#define IDC_DEBUG_DATA_BUT 1084
#define IDC_DEBUG_DATA_STARTADDR 1085
#define IDC_DEBUG_DATA_ENDADDR 1086
-#define IDC_DEBUG_SET_SYMB 1087
-#define IDC_DEBUG_SET_MODEL 1088
-#define IDC_DEBUG_SET_FILE 1089
-#define IDC_DEBUG_SET_BROWSE 1090
-#define IDC_DEBUG_STACK 1091
-#define IDC_STATIC_BREAKPOINT 1092
-#define IDC_BREAKEDIT_ADD 1093
-#define IDC_BREAKEDIT_DELETE 1094
-#define IDC_BREAKEDIT_WND 1095
-#define IDC_STATIC_MMU 1096
-#define IDC_MMU_IO_A 1097
-#define IDC_MMU_NCE2_A 1098
-#define IDC_MMU_CE1_A 1099
-#define IDC_MMU_CE2_A 1100
-#define IDC_MMU_NCE3_A 1101
-#define IDC_MMU_IO_S 1102
-#define IDC_MMU_CE1_S 1103
-#define IDC_MMU_CE2_S 1104
-#define IDC_MMU_NCE2_S 1105
-#define IDC_MMU_NCE3_S 1106
-#define IDC_STATIC_MISC 1107
-#define IDC_MISC_BS_TXT 1108
-#define IDC_INSTR_TEXT 1109
-#define IDC_INSTR_CODE 1110
-#define IDC_INSTR_COPY 1111
-#define IDC_INSTR_CLEAR 1112
-#define IDC_PROFILE_LASTCYCLES 1113
-#define IDC_PROFILE_LASTTIME 1114
-#define IDC_BPCODE 1115
-#define IDC_BPRPL 1116
-#define IDC_BPACCESS 1117
-#define IDC_BPREAD 1118
-#define IDC_BPWRITE 1119
-#define IDC_FIND_DATA 1120
-#define IDC_FIND_PREV 1121
-#define IDC_FIND_NEXT 1122
-#define IDC_FIND_ASCII 1123
-#define IDC_ADDR20_24 1124
-#define IDC_ADDR25_27 1125
-#define IDC_ADDR28_29 1126
-#define IDC_ADDR30_34 1127
-#define IDC_RPLVIEW_DATA 1128
-#define IDC_MACRO_SLOW 1129
-#define IDC_MACRO_FAST 1130
-#define IDC_MACRO_SLIDER 1131
-#define IDC_MACRO_REAL 1132
-#define IDC_MACRO_MANUAL 1133
-#define IDC_SOUND_SLIDER 1134
-#define IDC_SOUND_DEVICE 1135
-#define IDC_TRACE_FILE 1136
-#define IDC_TRACE_BROWSE 1137
-#define IDC_TRACE_NEW 1138
-#define IDC_TRACE_APPEND 1139
-#define IDC_TRACE_REGISTER 1140
-#define IDC_TRACE_MMU 1141
-#define IDC_TRACE_OPCODE 1142
+#define IDC_DEBUG_DATA_SAVE_8BIT 1087
+#define IDC_DEBUG_DATA_SAVE_4BIT 1088
+#define IDC_DEBUG_DATA_LOAD_8BIT 1089
+#define IDC_DEBUG_DATA_LOAD_4BIT 1090
+#define IDC_DEBUG_DATA_LOAD_ABIT 1091
+#define IDC_DEBUG_SET_SYMB 1092
+#define IDC_DEBUG_SET_MODEL 1093
+#define IDC_DEBUG_SET_FILE 1094
+#define IDC_DEBUG_SET_BROWSE 1095
+#define IDC_DEBUG_STACK 1096
+#define IDC_STATIC_BREAKPOINT 1097
+#define IDC_BREAKEDIT_ADD 1098
+#define IDC_BREAKEDIT_DELETE 1099
+#define IDC_BREAKEDIT_WND 1100
+#define IDC_STATIC_MMU 1101
+#define IDC_MMU_IO_A 1102
+#define IDC_MMU_NCE2_A 1103
+#define IDC_MMU_CE1_A 1104
+#define IDC_MMU_CE2_A 1105
+#define IDC_MMU_NCE3_A 1106
+#define IDC_MMU_IO_S 1107
+#define IDC_MMU_CE1_S 1108
+#define IDC_MMU_CE2_S 1109
+#define IDC_MMU_NCE2_S 1110
+#define IDC_MMU_NCE3_S 1111
+#define IDC_STATIC_MISC 1112
+#define IDC_MISC_BS_TXT 1113
+#define IDC_INSTR_TEXT 1114
+#define IDC_INSTR_CODE 1115
+#define IDC_INSTR_COPY 1116
+#define IDC_INSTR_CLEAR 1117
+#define IDC_PROFILE_LASTCYCLES 1118
+#define IDC_PROFILE_LASTTIME 1119
+#define IDC_BPCODE 1120
+#define IDC_BPRPL 1121
+#define IDC_BPACCESS 1122
+#define IDC_BPREAD 1123
+#define IDC_BPWRITE 1124
+#define IDC_FIND_DATA 1125
+#define IDC_FIND_PREV 1126
+#define IDC_FIND_NEXT 1127
+#define IDC_FIND_ASCII 1128
+#define IDC_ADDR20_24 1129
+#define IDC_ADDR25_27 1130
+#define IDC_ADDR28_29 1131
+#define IDC_ADDR30_34 1132
+#define IDC_RPLVIEW_DATA 1133
+#define IDC_MACRO_SLOW 1134
+#define IDC_MACRO_FAST 1135
+#define IDC_MACRO_SLIDER 1136
+#define IDC_MACRO_REAL 1137
+#define IDC_MACRO_MANUAL 1138
+#define IDC_SOUND_SLIDER 1139
+#define IDC_SOUND_DEVICE 1140
+#define IDC_TRACE_FILE 1141
+#define IDC_TRACE_BROWSE 1142
+#define IDC_TRACE_NEW 1143
+#define IDC_TRACE_APPEND 1144
+#define IDC_TRACE_REGISTER 1145
+#define IDC_TRACE_MMU 1146
+#define IDC_TRACE_OPCODE 1147
#define ID_FILE_NEW 40001
#define ID_FILE_OPEN 40002
#define ID_FILE_SAVE 40003
@@ -257,7 +262,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_COMMAND_VALUE 40074
-#define _APS_NEXT_CONTROL_VALUE 1143
+#define _APS_NEXT_CONTROL_VALUE 1148
#define _APS_NEXT_SYMED_VALUE 109
#endif
#endif
diff --git a/app/src/main/cpp/core/romcrc.c b/app/src/main/cpp/core/romcrc.c
index fd0c172..22a6891 100644
--- a/app/src/main/cpp/core/romcrc.c
+++ b/app/src/main/cpp/core/romcrc.c
@@ -241,8 +241,8 @@ VOID RebuildRomCrc(VOID)
{
// has no Crc
}
- // HP49G
- if (cCurrentRomType == 'X' && dwRomSize == _KB(2048))
+ // HP48GII/49G+/50G/49G
+ if ((strchr("2QX",cCurrentRomType)) && dwRomSize == _KB(2048))
{
CorrectAllFlashPages(); // go through all pages
}
diff --git a/app/src/main/cpp/core/serial.c b/app/src/main/cpp/core/serial.c
index 0433a06..6b5309f 100644
--- a/app/src/main/cpp/core/serial.c
+++ b/app/src/main/cpp/core/serial.c
@@ -104,7 +104,6 @@ BOOL CommOpen(LPTSTR strWirePort,LPTSTR strIrPort)
LPCTSTR strPort = (Chipset.IORam[IR_CTRL] & EIRU) ? strIrPort : strWirePort;
- _ASSERT(Chipset.IORam[IOC] & SON); // UART on
CommClose(); // close port if already open
dwBytesRead = 0L; // no bytes received
diff --git a/app/src/main/cpp/core/settings.c b/app/src/main/cpp/core/settings.c
index 6d5d539..44721ca 100644
--- a/app/src/main/cpp/core/settings.c
+++ b/app/src/main/cpp/core/settings.c
@@ -182,23 +182,24 @@ VOID ReadSettings(VOID)
disassembler_mode = ReadInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode);
disassembler_symb = ReadInt(_T("Disassembler"),_T("Symbolic"),disassembler_symb);
// Emulator
- bShowTitle = ReadInt(_T("Emulator"),_T("ShowTitle"),bShowTitle);
- bShowMenu = ReadInt(_T("Emulator"),_T("ShowMenu"),bShowMenu);
- bAlwaysOnTop = ReadInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop);
- bActFollowsMouse = ReadInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse);
- bClientWinMove = ReadInt(_T("Emulator"),_T("ClientWinMove"),bClientWinMove);
- bSingleInstance = ReadInt(_T("Emulator"),_T("SingleInstance"),bSingleInstance);
- bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
- dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
- dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
- dwGPCycles = ReadInt(_T("Emulator"),_T("GPCycles"),dwGPCycles); // CdB for HP: add apples
- dwG2Cycles = ReadInt(_T("Emulator"),_T("G2Cycles"),dwG2Cycles); // CdB for HP: add apples
- dwKeyMinDelay = ReadInt(_T("Emulator"),_T("KeyMinDelay"),dwKeyMinDelay);
- dwWakeupDelay = ReadInt(_T("Emulator"),_T("WakeupDelay"),dwWakeupDelay);
- bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale);
- uWaveDevId = ReadInt(_T("Emulator"),_T("WaveDeviceId"),uWaveDevId);
- dwWaveVol = ReadInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol);
- dwWaveTime = ReadInt(_T("Emulator"),_T("WaveTime"),dwWaveTime);
+ bShowTitle = ReadInt(_T("Emulator"),_T("ShowTitle"),bShowTitle);
+ bShowMenu = ReadInt(_T("Emulator"),_T("ShowMenu"),bShowMenu);
+ bAlwaysOnTop = ReadInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop);
+ bActFollowsMouse = ReadInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse);
+ bClientWinMove = ReadInt(_T("Emulator"),_T("ClientWinMove"),bClientWinMove);
+ bSingleInstance = ReadInt(_T("Emulator"),_T("SingleInstance"),bSingleInstance);
+ bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
+ dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
+ dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
+ dwGPCycles = ReadInt(_T("Emulator"),_T("GPCycles"),dwGPCycles); // CdB for HP: add apples
+ dwG2Cycles = ReadInt(_T("Emulator"),_T("G2Cycles"),dwG2Cycles); // CdB for HP: add apples
+ dwKeyMinDelay = ReadInt(_T("Emulator"),_T("KeyMinDelay"),dwKeyMinDelay);
+ dwWakeupDelay = ReadInt(_T("Emulator"),_T("WakeupDelay"),dwWakeupDelay);
+ bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale);
+ uWaveDevId = ReadInt(_T("Emulator"),_T("WaveDeviceId"),uWaveDevId);
+ dwWaveVol = ReadInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol);
+ dwWaveTime = ReadInt(_T("Emulator"),_T("WaveTime"),dwWaveTime);
+ bLocaleDecimalPoint = ReadInt(_T("Emulator"),_T("LocaleDecimalPoint"),bLocaleDecimalPoint);
// LowBat
bLowBatDisable = ReadInt(_T("LowBat"),_T("Disable"),bLowBatDisable);
// Macro
@@ -254,6 +255,7 @@ VOID WriteSettings(VOID)
WriteInt(_T("Emulator"),_T("WaveDeviceId"),uWaveDevId);
WriteInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol);
WriteInt(_T("Emulator"),_T("WaveTime"),dwWaveTime);
+ WriteInt(_T("Emulator"),_T("LocaleDecimalPoint"),bLocaleDecimalPoint);
// LowBat
WriteInt(_T("LowBat"),_T("Disable"),bLowBatDisable);
// Macro
diff --git a/app/src/main/cpp/core/stack.c b/app/src/main/cpp/core/stack.c
index 570dcbc..2f68478 100644
--- a/app/src/main/cpp/core/stack.c
+++ b/app/src/main/cpp/core/stack.c
@@ -19,6 +19,7 @@
#define DOCSTR 0x02A2C // String
BOOL bDetectClpObject = TRUE; // try to detect clipboard object
+BOOL bLocaleDecimalPoint = FALSE; // use decimal point character from calculator
//################
//#
@@ -26,6 +27,100 @@ BOOL bDetectClpObject = TRUE; // try to detect clipboard object
//#
//################
+//
+// check if cGroup character is thousands separator
+//
+static BOOL CheckThousandGroup(LPCTSTR cp,TCHAR cGroup)
+{
+ UINT uLastPos;
+ UINT i;
+
+ // get decimal point
+ CONST TCHAR cDecimalPoint = cGroup ^ (_T('.') ^ _T(','));
+
+ BOOL bFound = FALSE; // 1st separator not found
+ BOOL bPosOK = TRUE;
+
+ for (i = 0; bPosOK && cp[i] != cDecimalPoint && cp[i] != 0; ++i)
+ {
+ if (cp[i] == cGroup) // found separator
+ {
+ if (bFound)
+ {
+ // verify separator position
+ bPosOK = (uLastPos + 4 == i);
+ }
+
+ uLastPos = i; // last position of separator
+ bFound = TRUE; // separator found
+ }
+ }
+
+ // check last grouping
+ return bPosOK && bFound && (uLastPos + 4 == i);
+}
+
+//
+// get decimal point from clipboard
+//
+static TCHAR GetClpbrdDecimalPoint(LPCTSTR cp)
+{
+ TCHAR cDec = 0; // default for invalid decimal point detection
+
+ TCHAR cLast = 0; // last decimal point
+ UINT uPoint = 0; // no. of points
+ UINT uComma = 0; // no. of commas
+
+ LPCTSTR p;
+ for (p = cp; *p; ++p) // count '.' and ',' characters
+ {
+ if (*p == _T('.'))
+ {
+ cLast = *p; // last occurance
+ ++uPoint;
+ }
+ if (*p == _T(','))
+ {
+ cLast = *p; // last occurance
+ ++uComma;
+ }
+ }
+
+ if (uComma == 0 && uPoint == 0) // none of both
+ {
+ cDec = _T('.');
+ }
+ else if (uComma == 1 && uPoint == 0) // one single ','
+ {
+ cDec = _T(',');
+ }
+ else if (uComma == 0 && uPoint == 1) // one single '.'
+ {
+ cDec = _T('.');
+ }
+ else if (uComma == 1 && uPoint == 1) // one single ',' and '.'
+ {
+ // change from ',' to '.' or vice versa
+ const TCHAR cFirst = cLast ^ (_T('.') ^ _T(','));
+
+ if (CheckThousandGroup(cp,cFirst)) // check if 1st character is grouped
+ {
+ cDec = cLast;
+ }
+ }
+ // multiple grouped ',' and single '.'
+ else if (uComma > 1 && uPoint == 1 && CheckThousandGroup(cp,_T(',')))
+ {
+ cDec = _T('.');
+ }
+ // multiple grouped '.' and single ','
+ else if (uComma == 1 && uPoint > 1 && CheckThousandGroup(cp,_T('.')))
+ {
+ cDec = _T(',');
+ }
+ return cDec;
+}
+
static LPTSTR Trim(LPCTSTR cp)
{
LPCTSTR pcWs = _T(" \t\n\r"); // valid whitespace characters
@@ -238,22 +333,23 @@ static INT RPL_GetBcd(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cD
static __inline INT SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYTE pbyNum,INT nSize)
{
- TCHAR cVc[] = _T(".0123456789eE+-");
+ TCHAR cVc[] = _T(",.0123456789eE+-");
BYTE byNum[80];
INT i,nIp,nDp,nMaxExp;
LONG lExp;
- cVc[0] = cDec; // replace decimal char
+ // get thousand separator
+ const TCHAR cThousand = cDec ^ (_T('.') ^ _T(','));
if ( nMantLen + nExpLen >= nSize // destination buffer too small
|| !*cp // empty string
- || _tcsspn(cp,cVc) != (SIZE_T) lstrlen(cp) // real contain only these numbers
+ || _tcsspn(cp,cVc) != (SIZE_T) lstrlen(cp) // real doesn't contain only these numbers
|| (SIZE_T) lstrlen(cp) >= ARRAYSIZEOF(byNum)) // ignore too long reals
return 0;
byNum[0] = (*cp != _T('-')) ? 0 : 9; // set sign nibble
- if (*cp == _T('-') || *cp == _T('+')) // skip sign character
+ if (*cp == _T('-') || *cp == _T('+')) // skip sign nibble
cp++;
// only '.', '0' .. '9' are valid here
@@ -264,8 +360,13 @@ static __inline INT SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,
if (*cp != cDec) // no decimal point
{
// count integer part
- while (*cp >= _T('0') && *cp <= _T('9'))
- byNum[++nIp] = *cp++ - _T('0');
+ for (; (*cp >= _T('0') && *cp <= _T('9')) || *cp == cThousand; ++cp)
+ {
+ if (*cp != cThousand) // not thousand separator
+ {
+ byNum[++nIp] = *cp - _T('0');
+ }
+ }
if (!nIp) return 0;
}
@@ -376,8 +477,8 @@ static INT RPL_GetComplex(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHA
TCHAR cSep;
cSep = (cDec == _T('.')) // current separator
- ? _T(',') // radix mark '.' -> ',' separator
- : _T(';'); // radix mark ',' -> ';' separator
+ ? _T(',') // decimal point '.' -> ',' separator
+ : _T(';'); // decimal comma ',' -> ';' separator
nPos = 0; // write buffer position
@@ -420,8 +521,8 @@ static INT RPL_SetComplex(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,L
nLen = 0; // read data length
cSep = (cDec == _T('.')) // current separator
- ? _T(',') // radix mark '.' -> ',' separator
- : _T(';'); // radix mark ',' -> ';' separator
+ ? _T(',') // decimal point '.' -> ',' separator
+ : _T(';'); // decimal comma ',' -> ';' separator
if ((pszData = Trim(cp)) != NULL) // create a trimmed working copy of the string
{
@@ -468,8 +569,14 @@ static INT RPL_SetComplex(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,L
static TCHAR GetRadix(VOID)
{
- // get locale decimal point
- // GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SDECIMAL,&cDecimal,1);
+ if (bLocaleDecimalPoint) // use Windows Locale decimal point character
+ {
+ TCHAR cDecimal[2];
+
+ // get locale decimal point with zero terminator
+ GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SDECIMAL,cDecimal,2);
+ return cDecimal[0];
+ }
return RPL_GetSystemFlag(fnRadix) ? _T(',') : _T('.');
}
@@ -683,9 +790,11 @@ LRESULT OnStackPaste(VOID) // paste data to stack
if ((lpstrClipdata = (LPCTSTR) GlobalLock(hClipObj)))
{
+ TCHAR cDec;
BYTE byNumber[128];
DWORD dwAddress;
- INT s;
+
+ INT s = 0; // no valid object
do
{
@@ -715,9 +824,14 @@ LRESULT OnStackPaste(VOID) // paste data to stack
}
}
- // try to convert string to real format
- _ASSERT(16 <= ARRAYSIZEOF(byNumber));
- s = RPL_SetBcd(lpstrClipdata,12,3,GetRadix(),byNumber,sizeof(byNumber));
+ cDec = GetClpbrdDecimalPoint(lpstrClipdata);
+
+ if (cDec) // valid decimal point
+ {
+ // try to convert string to real format
+ _ASSERT(16 <= ARRAYSIZEOF(byNumber));
+ s = RPL_SetBcd(lpstrClipdata,12,3,cDec,byNumber,sizeof(byNumber));
+ }
if (s > 0) // is a real number
{
@@ -736,9 +850,14 @@ LRESULT OnStackPaste(VOID) // paste data to stack
break;
}
+ // search for ';' as separator
+ cDec = (_tcschr(lpstrClipdata,_T(';')) != NULL)
+ ? _T(',') // decimal comma
+ : _T('.'); // decimal point
+
// try to convert string to complex format
_ASSERT(32 <= ARRAYSIZEOF(byNumber));
- s = RPL_SetComplex(lpstrClipdata,12,3,GetRadix(),byNumber,sizeof(byNumber));
+ s = RPL_SetComplex(lpstrClipdata,12,3,cDec,byNumber,sizeof(byNumber));
if (s > 0) // is a real complex
{
diff --git a/app/src/main/cpp/core/timer.c b/app/src/main/cpp/core/timer.c
index 15cf9c5..7f9c733 100644
--- a/app/src/main/cpp/core/timer.c
+++ b/app/src/main/cpp/core/timer.c
@@ -247,7 +247,7 @@ VOID SetHP48Time(VOID) // set date and time
ULONGLONG ticks, time;
DWORD dw;
WORD crc, i;
- BYTE p[4];
+ LPBYTE pbyTime;
_ASSERT(sizeof(ULONGLONG) == 8); // check size of datatype
@@ -282,29 +282,23 @@ VOID SetHP48Time(VOID) // set date and time
time = ticks; // save for calc. timeout
time += OFF_TIME; // add 10 min for auto off
- dw = RPLTIME; // HP addresses for clock in port0
+ pbyTime = Port0 + RPLTIME; // HP addresses for clock in port0
crc = 0x0; // reset crc value
- for (i = 0; i < 13; ++i, ++dw) // write date and time
+ for (i = 0; i < 13; ++i) // write date and time
{
- *p = (BYTE) ticks & 0xf;
- crc = (crc >> 4) ^ (((crc ^ ((WORD) *p)) & 0xf) * 0x1081);
- Port0[dw] = *p; // always store in port0
+ *pbyTime = (BYTE) ticks & 0xf; // time
+ crc = UpCRC(crc,*pbyTime);
ticks >>= 4;
- }
- Nunpack(p,crc,4); // write crc
- memcpy(Port0+dw,p,4); // always store in port0
-
- dw += 4; // HP addresses for timeout
-
- for (i = 0; i < 13; ++i, ++dw) // write time for auto off
- {
- Port0[dw] = (BYTE) time & 0xf; // always store in port0
+ pbyTime[13+4] = (BYTE) time & 0xf; // auto off
time >>= 4;
+ ++pbyTime;
}
- Port0[dw] = 0xf; // always store in port0
+ Nunpack(pbyTime,crc,4); // write crc
+
+ pbyTime[13+4] = 0xf;
return;
}
diff --git a/app/src/main/cpp/core/udp.c b/app/src/main/cpp/core/udp.c
index 7e20930..09972f6 100644
--- a/app/src/main/cpp/core/udp.c
+++ b/app/src/main/cpp/core/udp.c
@@ -22,13 +22,10 @@ VOID ResetUdp(VOID)
BOOL SendByteUdp(BYTE byData)
{
- WSADATA wsd;
SOCKET sClient;
BOOL bErr = TRUE;
- VERIFY(WSAStartup(MAKEWORD(1,1),&wsd) == 0);
-
// IP address not specified
if (sServer.sin_addr.s_addr == INADDR_NONE)
{
@@ -72,7 +69,5 @@ BOOL SendByteUdp(BYTE byData)
bErr = sendto(sClient, (LPCCH) &byData, sizeof(byData), 0, (LPSOCKADDR) &sServer, sizeof(sServer)) == SOCKET_ERROR;
closesocket(sClient);
}
-
- WSACleanup(); // cleanup network stack
return bErr;
}
diff --git a/app/src/main/cpp/win32-layer.c b/app/src/main/cpp/win32-layer.c
index 7edb8c1..4e8cb22 100644
--- a/app/src/main/cpp/win32-layer.c
+++ b/app/src/main/cpp/win32-layer.c
@@ -36,22 +36,21 @@ extern HANDLE hWnd;
extern LPTSTR szTitle;
LPTSTR szCurrentAssetDirectory = NULL;
LPTSTR szCurrentContentDirectory = NULL;
-AAssetManager * assetManager;
-const TCHAR * assetsPrefix = _T("assets/");
+AAssetManager *assetManager;
+const TCHAR *assetsPrefix = _T("assets/");
size_t assetsPrefixLength;
-const TCHAR * contentScheme = _T("content://");
+const TCHAR *contentScheme = _T("content://");
size_t contentSchemeLength;
-const TCHAR * documentScheme = _T("document:");
+const TCHAR *documentScheme = _T("document:");
size_t documentSchemeLength;
-const TCHAR * comPrefix = _T("\\\\.\\");
+const TCHAR *comPrefix = _T("\\\\.\\");
size_t comPrefixLength;
TCHAR szFilePathTmp[MAX_PATH];
-
DWORD GetLastError(VOID) {
- //TODO
- return NO_ERROR;
+ //TODO
+ return NO_ERROR;
}
@@ -63,55 +62,55 @@ static HANDLE fileMappingHandles[MAX_FILE_MAPPING_HANDLE];
HBITMAP rootBITMAP;
void win32Init() {
- initTimer();
- for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
- fileMappingHandles[i] = NULL;
- }
+ initTimer();
+ for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
+ fileMappingHandles[i] = NULL;
+ }
- assetsPrefixLength = _tcslen(assetsPrefix);
- contentSchemeLength = _tcslen(contentScheme);
+ assetsPrefixLength = _tcslen(assetsPrefix);
+ contentSchemeLength = _tcslen(contentScheme);
documentSchemeLength = _tcslen(documentScheme);
comPrefixLength = _tcslen(comPrefix);
rootBITMAP = CreateCompatibleBitmap(NULL, 0, 0);
}
-int abs (int i) {
- return i < 0 ? -i : i;
+int abs(int i) {
+ return i < 0 ? -i : i;
}
VOID OutputDebugString(LPCSTR lpOutputString) {
- LOGD("%s", lpOutputString);
+ LOGD("%s", lpOutputString);
}
DWORD GetCurrentDirectory(DWORD nBufferLength, LPTSTR lpBuffer) {
- if(getcwd(lpBuffer, nBufferLength)) {
- return nBufferLength;
- }
- return 0;
+ if (getcwd(lpBuffer, nBufferLength)) {
+ return nBufferLength;
+ }
+ return 0;
}
BOOL SetCurrentDirectory(LPCTSTR path) {
// Set the current directory for the next calls to CreateFile() API with a relative path.
- szCurrentContentDirectory = NULL;
- szCurrentAssetDirectory = NULL;
+ szCurrentContentDirectory = NULL;
+ szCurrentAssetDirectory = NULL;
- if(path == NULL)
- return FALSE;
+ if (path == NULL)
+ return FALSE;
- if(_tcsncmp(path, contentScheme, contentSchemeLength) == 0) {
- // Set the current directory with an URL with the scheme "content://".
- szCurrentContentDirectory = (LPTSTR) path;
- return TRUE;
- } else if(_tcsncmp(path, assetsPrefix, assetsPrefixLength) == 0) {
- // Set the current directory with a path to target the Android asset folders (embedded in the app).
- szCurrentAssetDirectory = (LPTSTR) (path + assetsPrefixLength * sizeof(TCHAR));
- return TRUE;
- } else
- // Set the current directory using the file system "chdir" API. Deprecated, not supported by Android >= 10.
- return (BOOL) chdir(path);
+ if (_tcsncmp(path, contentScheme, contentSchemeLength) == 0) {
+ // Set the current directory with an URL with the scheme "content://".
+ szCurrentContentDirectory = (LPTSTR) path;
+ return TRUE;
+ } else if (_tcsncmp(path, assetsPrefix, assetsPrefixLength) == 0) {
+ // Set the current directory with a path to target the Android asset folders (embedded in the app).
+ szCurrentAssetDirectory = (LPTSTR) (path + assetsPrefixLength * sizeof(TCHAR));
+ return TRUE;
+ } else
+ // Set the current directory using the file system "chdir" API. Deprecated, not supported by Android >= 10.
+ return (BOOL) chdir(path);
}
extern BOOL settingsPort2en;
@@ -122,14 +121,16 @@ static HANDLE comms[MAX_CREATED_COMM];
static pthread_mutex_t commsLock;
-HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPVOID lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, LPVOID hTemplateFile) {
- FILE_LOGD("CreateFile(lpFileName: \"%s\", dwDesiredAccess: 0x%08x)", lpFileName, dwShareMode);
+HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
+ LPVOID lpSecurityAttributes, DWORD dwCreationDisposition,
+ DWORD dwFlagsAndAttributes, LPVOID hTemplateFile) {
+ FILE_LOGD("CreateFile(lpFileName: \"%s\", dwDesiredAccess: 0x%08x)", lpFileName, dwShareMode);
BOOL foundCOMPrefix = _tcsncmp(lpFileName, comPrefix, comPrefixLength) == 0;
- if(foundCOMPrefix) {
+ if (foundCOMPrefix) {
int serialPortId = openSerialPort(lpFileName);
- if(serialPortId > 0) {
+ if (serialPortId > 0) {
// We try to open a COM/Serial port
HANDLE handle = malloc(sizeof(struct _HANDLE));
memset(handle, 0, sizeof(struct _HANDLE));
@@ -139,8 +140,8 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
pthread_mutex_lock(&commsLock);
handle->commIndex = -1;
- for(int i = 0; i < MAX_CREATED_COMM; i++) {
- if(comms[i] == NULL) {
+ for (int i = 0; i < MAX_CREATED_COMM; i++) {
+ if (comms[i] == NULL) {
handle->commIndex = i;
comms[handle->commIndex] = handle;
break;
@@ -148,157 +149,162 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
}
pthread_mutex_unlock(&commsLock);
- SERIAL_LOGD("CreateFile(lpFileName: \"%s\", ...) commId: %d, commIndex: %d", lpFileName, handle->commId, handle->commIndex);
+ SERIAL_LOGD("CreateFile(lpFileName: \"%s\", ...) commId: %d, commIndex: %d", lpFileName,
+ handle->commId, handle->commIndex);
return handle;
} else
return (HANDLE) INVALID_HANDLE_VALUE;
}
- BOOL forceNormalFile = FALSE;
- securityExceptionOccured = FALSE;
+ BOOL forceNormalFile = FALSE;
+ securityExceptionOccured = FALSE;
#if EMUXX == 48
- if(_tcscmp(lpFileName, szPort2Filename) == 0) {
- // Special case for Port2 filename
- forceNormalFile = TRUE;
- if(!settingsPort2wr && (dwDesiredAccess & GENERIC_WRITE))
- return (HANDLE) INVALID_HANDLE_VALUE;
- }
+ if (_tcscmp(lpFileName, szPort2Filename) == 0) {
+ // Special case for Port2 filename
+ forceNormalFile = TRUE;
+ if (!settingsPort2wr && (dwDesiredAccess & GENERIC_WRITE))
+ return (HANDLE) INVALID_HANDLE_VALUE;
+ }
#endif
BOOL foundDocumentScheme = _tcsncmp(lpFileName, documentScheme, documentSchemeLength) == 0;
BOOL urlContentSchemeFound = _tcsncmp(lpFileName, contentScheme, contentSchemeLength) == 0;
- if(chooseCurrentKmlMode == ChooseKmlMode_FILE_OPEN || chooseCurrentKmlMode == ChooseKmlMode_FILE_OPEN_WITH_FOLDER) {
- // A E48 state file can contain a path to the KML script.
- if(foundDocumentScheme) {
- // Keep for compatibility:
- // When the state file is created or saved with this Android version,
- // an URL like: document:content://|content://
- // is created and saved in the state file.
- // Here we want to open a file (lpFileName) which contains the prefix "document:"
- // So, we are loading a KML script.
- // We extract the KML File URL with "content://" scheme (in the variable "filename"),
- // and we extract the folder URL with "content://" scheme (in the variable "szEmuDirectory"/"szRomDirectory" and "szCurrentContentDirectory")
- // which should contain the script and its dependencies like the includes, the images and the ROMs.
- _tcscpy(szFilePathTmp, lpFileName + _tcslen(documentScheme) * sizeof(TCHAR));
- TCHAR * filename = _tcschr(szFilePathTmp, _T('|'));
- if(filename)
- *filename = _T('\0');
- if(szFilePathTmp[0]) {
- // If szFilePathTmp is empty, this mean that the variable "szEmuDirectory", "szRomDirectory"
- // and "szCurrentContentDirectory" are set before that method, using the JSON settings embedded in the state file.
- _tcscpy(szEmuDirectory, szFilePathTmp);
+ if (chooseCurrentKmlMode == ChooseKmlMode_FILE_OPEN ||
+ chooseCurrentKmlMode == ChooseKmlMode_FILE_OPEN_WITH_FOLDER) {
+ // A E48 state file can contain a path to the KML script.
+ if (foundDocumentScheme) {
+ // Keep for compatibility:
+ // When the state file is created or saved with this Android version,
+ // an URL like: document:content://|content://
+ // is created and saved in the state file.
+ // Here we want to open a file (lpFileName) which contains the prefix "document:"
+ // So, we are loading a KML script.
+ // We extract the KML File URL with "content://" scheme (in the variable "filename"),
+ // and we extract the folder URL with "content://" scheme (in the variable "szEmuDirectory"/"szRomDirectory" and "szCurrentContentDirectory")
+ // which should contain the script and its dependencies like the includes, the images and the ROMs.
+ _tcscpy(szFilePathTmp, lpFileName + _tcslen(documentScheme) * sizeof(TCHAR));
+ TCHAR *filename = _tcschr(szFilePathTmp, _T('|'));
+ if (filename)
+ *filename = _T('\0');
+ if (szFilePathTmp[0]) {
+ // If szFilePathTmp is empty, this mean that the variable "szEmuDirectory", "szRomDirectory"
+ // and "szCurrentContentDirectory" are set before that method, using the JSON settings embedded in the state file.
+ _tcscpy(szEmuDirectory, szFilePathTmp);
#if EMUXX == 48
- _tcscpy(szRomDirectory, szFilePathTmp);
+ _tcscpy(szRomDirectory, szFilePathTmp);
#endif
- SetCurrentDirectory(szFilePathTmp);
- }
- }
- }
+ SetCurrentDirectory(szFilePathTmp);
+ }
+ }
+ }
- if(!forceNormalFile
- && (szCurrentAssetDirectory || _tcsncmp(lpFileName, assetsPrefix, assetsPrefixLength) == 0)
- && !foundDocumentScheme
- && !urlContentSchemeFound) {
- // Loading a file from the Android asset folders (embedded in the app)
- TCHAR szFileName[MAX_PATH];
- AAsset * asset = NULL;
- szFileName[0] = _T('\0');
- if(szCurrentAssetDirectory) {
- _tcscpy(szFileName, szCurrentAssetDirectory);
- _tcscat(szFileName, lpFileName);
- asset = AAssetManager_open(assetManager, szFileName, AASSET_MODE_STREAMING);
- } else {
- asset = AAssetManager_open(assetManager, lpFileName + assetsPrefixLength * sizeof(TCHAR), AASSET_MODE_STREAMING);
- }
- if(asset) {
- HANDLE handle = malloc(sizeof(struct _HANDLE));
- memset(handle, 0, sizeof(struct _HANDLE));
- handle->handleType = HANDLE_TYPE_FILE_ASSET;
- handle->fileAsset = asset;
- return handle;
- }
- } else {
- // Loading a "normal" file
- // * either a file with the scheme "content://"
- // * or a file with a simple name but within the current folder (szCurrentContentDirectory)
- // * or a file with the scheme "file://". Deprecated not supported by Android >= 10.
- BOOL useOpenFileFromContentResolver = FALSE;
- int flags = O_RDWR;
- int fd = -1;
- struct flock lock;
- mode_t perm = S_IRUSR | S_IWUSR;
+ if (!forceNormalFile
+ && (szCurrentAssetDirectory || _tcsncmp(lpFileName, assetsPrefix, assetsPrefixLength) == 0)
+ && !foundDocumentScheme
+ && !urlContentSchemeFound) {
+ // Loading a file from the Android asset folders (embedded in the app)
+ TCHAR szFileName[MAX_PATH];
+ AAsset *asset = NULL;
+ szFileName[0] = _T('\0');
+ if (szCurrentAssetDirectory) {
+ _tcscpy(szFileName, szCurrentAssetDirectory);
+ _tcscat(szFileName, lpFileName);
+ asset = AAssetManager_open(assetManager, szFileName, AASSET_MODE_STREAMING);
+ } else {
+ asset = AAssetManager_open(assetManager,
+ lpFileName + assetsPrefixLength * sizeof(TCHAR),
+ AASSET_MODE_STREAMING);
+ }
+ if (asset) {
+ HANDLE handle = malloc(sizeof(struct _HANDLE));
+ memset(handle, 0, sizeof(struct _HANDLE));
+ handle->handleType = HANDLE_TYPE_FILE_ASSET;
+ handle->fileAsset = asset;
+ return handle;
+ }
+ } else {
+ // Loading a "normal" file
+ // * either a file with the scheme "content://"
+ // * or a file with a simple name but within the current folder (szCurrentContentDirectory)
+ // * or a file with the scheme "file://". Deprecated not supported by Android >= 10.
+ BOOL useOpenFileFromContentResolver = FALSE;
+ int flags = O_RDWR;
+ int fd = -1;
+ struct flock lock;
+ mode_t perm = S_IRUSR | S_IWUSR;
- if (GENERIC_READ == dwDesiredAccess)
- flags = O_RDONLY;
- else {
- if (GENERIC_WRITE == dwDesiredAccess)
- flags = O_WRONLY;
- else if (0 != ((GENERIC_READ | GENERIC_WRITE) & dwDesiredAccess))
- flags = O_RDWR;
+ if (GENERIC_READ == dwDesiredAccess)
+ flags = O_RDONLY;
+ else {
+ if (GENERIC_WRITE == dwDesiredAccess)
+ flags = O_WRONLY;
+ else if (0 != ((GENERIC_READ | GENERIC_WRITE) & dwDesiredAccess))
+ flags = O_RDWR;
- if (CREATE_ALWAYS == dwCreationDisposition)
- flags |= O_CREAT;
- }
+ if (CREATE_ALWAYS == dwCreationDisposition)
+ flags |= O_CREAT;
+ }
- if(foundDocumentScheme) {
- TCHAR * filename = _tcsrchr(lpFileName, _T('|'));
- if(filename)
- lpFileName = filename + 1;
- }
+ if (foundDocumentScheme) {
+ TCHAR *filename = _tcsrchr(lpFileName, _T('|'));
+ if (filename)
+ lpFileName = filename + 1;
+ }
- if(urlContentSchemeFound) {
- // Case of an absolute file with the scheme "content://".
- fd = openFileFromContentResolver(lpFileName, dwDesiredAccess);
- useOpenFileFromContentResolver = TRUE;
- if(fd == -2) {
- FILE_LOGD("CreateFile() openFileFromContentResolver() %d", errno);
- securityExceptionOccured = TRUE;
- }
- } else if(szCurrentContentDirectory) {
- // Case of a relative file to a folder with the scheme "content://".
- fd = openFileInFolderFromContentResolver(lpFileName, szCurrentContentDirectory, dwDesiredAccess);
- useOpenFileFromContentResolver = TRUE;
- if(fd == -1) {
- FILE_LOGD("CreateFile() openFileFromContentResolver() %d", errno);
- }
- } else {
- // Case of an absolute file with the scheme "file://". Deprecated not supported by Android >= 10.
- TCHAR * urlFileSchemeFound = _tcsstr(lpFileName, _T("file://"));
- if(urlFileSchemeFound)
- lpFileName = urlFileSchemeFound + 7;
- fd = open(lpFileName, flags, perm);
- if(fd == -1) {
- FILE_LOGD("CreateFile() open() %d", errno);
- }
- }
- if (fd >= 0) {
- HANDLE handle = malloc(sizeof(struct _HANDLE));
- memset(handle, 0, sizeof(struct _HANDLE));
- handle->handleType = HANDLE_TYPE_FILE;
- handle->fileDescriptor = fd;
- handle->fileOpenFileFromContentResolver = useOpenFileFromContentResolver;
- return handle;
- }
- }
- FILE_LOGD("CreateFile() INVALID_HANDLE_VALUE");
- return (HANDLE) INVALID_HANDLE_VALUE;
+ if (urlContentSchemeFound) {
+ // Case of an absolute file with the scheme "content://".
+ fd = openFileFromContentResolver(lpFileName, dwDesiredAccess);
+ useOpenFileFromContentResolver = TRUE;
+ if (fd == -2) {
+ FILE_LOGD("CreateFile() openFileFromContentResolver() %d", errno);
+ securityExceptionOccured = TRUE;
+ }
+ } else if (szCurrentContentDirectory) {
+ // Case of a relative file to a folder with the scheme "content://".
+ fd = openFileInFolderFromContentResolver(lpFileName, szCurrentContentDirectory,
+ dwDesiredAccess);
+ useOpenFileFromContentResolver = TRUE;
+ if (fd == -1) {
+ FILE_LOGD("CreateFile() openFileFromContentResolver() %d", errno);
+ }
+ } else {
+ // Case of an absolute file with the scheme "file://". Deprecated not supported by Android >= 10.
+ TCHAR *urlFileSchemeFound = _tcsstr(lpFileName, _T("file://"));
+ if (urlFileSchemeFound)
+ lpFileName = urlFileSchemeFound + 7;
+ fd = open(lpFileName, flags, perm);
+ if (fd == -1) {
+ FILE_LOGD("CreateFile() open() %d", errno);
+ }
+ }
+ if (fd >= 0) {
+ HANDLE handle = malloc(sizeof(struct _HANDLE));
+ memset(handle, 0, sizeof(struct _HANDLE));
+ handle->handleType = HANDLE_TYPE_FILE;
+ handle->fileDescriptor = fd;
+ handle->fileOpenFileFromContentResolver = useOpenFileFromContentResolver;
+ return handle;
+ }
+ }
+ FILE_LOGD("CreateFile() INVALID_HANDLE_VALUE");
+ return (HANDLE) INVALID_HANDLE_VALUE;
}
-char * dumpToHexAscii(char * buffer, int inputSize, int charWidth) {
+char *dumpToHexAscii(char *buffer, int inputSize, int charWidth) {
int numLines = 1 + inputSize / charWidth;
- char * hexAsciiDump = malloc(4 * inputSize + 3 * numLines + 10);
- unsigned char * pBuff = (unsigned char *)buffer;
- char * pDump = hexAsciiDump;
+ char *hexAsciiDump = malloc(4 * inputSize + 3 * numLines + 10);
+ unsigned char *pBuff = (unsigned char *) buffer;
+ char *pDump = hexAsciiDump;
for (int l = 0, n = 0; l < numLines; ++l) {
- *pDump++ = (char)'\t';
+ *pDump++ = (char) '\t';
for (int c = 0; c < charWidth && n + c < inputSize; ++c) {
- sprintf((char *const)pDump, "%02X ", pBuff[c]);
+ sprintf((char *const) pDump, "%02X ", pBuff[c]);
pDump += 3;
}
for (int c = 0; c < charWidth && n + c < inputSize; ++c)
- *pDump++ = isprint(pBuff[c]) ? ((char *)pBuff)[c] : '.';
+ *pDump++ = isprint(pBuff[c]) ? ((char *) pBuff)[c] : '.';
*pDump++ = '\n';
pBuff += charWidth;
n += charWidth;
@@ -307,327 +313,336 @@ char * dumpToHexAscii(char * buffer, int inputSize, int charWidth) {
return hexAsciiDump;
}
-BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
- FILE_LOGD("ReadFile(hFile: %p, lpBuffer: 0x%08x, nNumberOfBytesToRead: %d)", hFile, lpBuffer, nNumberOfBytesToRead);
- DWORD readByteCount = 0;
- if(hFile->handleType == HANDLE_TYPE_FILE) {
- readByteCount = (DWORD) read(hFile->fileDescriptor, lpBuffer, nNumberOfBytesToRead);
- } else if(hFile->handleType == HANDLE_TYPE_FILE_ASSET) {
- readByteCount = (DWORD) AAsset_read(hFile->fileAsset, lpBuffer, nNumberOfBytesToRead);
- } else if(hFile->handleType == HANDLE_TYPE_COM) {
- readByteCount = (DWORD) readSerialPort(hFile->commId, lpBuffer, nNumberOfBytesToRead);
+BOOL
+ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
+ LPOVERLAPPED lpOverlapped) {
+ FILE_LOGD("ReadFile(hFile: %p, lpBuffer: 0x%08x, nNumberOfBytesToRead: %d)", hFile, lpBuffer,
+ nNumberOfBytesToRead);
+ DWORD readByteCount = 0;
+ if (hFile->handleType == HANDLE_TYPE_FILE) {
+ readByteCount = (DWORD) read(hFile->fileDescriptor, lpBuffer, nNumberOfBytesToRead);
+ } else if (hFile->handleType == HANDLE_TYPE_FILE_ASSET) {
+ readByteCount = (DWORD) AAsset_read(hFile->fileAsset, lpBuffer, nNumberOfBytesToRead);
+ } else if (hFile->handleType == HANDLE_TYPE_COM) {
+ readByteCount = (DWORD) readSerialPort(hFile->commId, lpBuffer, nNumberOfBytesToRead);
#if defined DEBUG_ANDROID_SERIAL
- char * hexAsciiDump = dumpToHexAscii(lpBuffer, readByteCount, 8);
- SERIAL_LOGD("ReadFile(hFile: %p, lpBuffer: 0x%08x, nNumberOfBytesToRead: %d) -> %d bytes\n%s", hFile, lpBuffer, nNumberOfBytesToRead, readByteCount, hexAsciiDump);
- free(hexAsciiDump);
+ char * hexAsciiDump = dumpToHexAscii(lpBuffer, readByteCount, 8);
+ SERIAL_LOGD("ReadFile(hFile: %p, lpBuffer: 0x%08x, nNumberOfBytesToRead: %d) -> %d bytes\n%s", hFile, lpBuffer, nNumberOfBytesToRead, readByteCount, hexAsciiDump);
+ free(hexAsciiDump);
#endif
- }
- if(lpNumberOfBytesRead)
- *lpNumberOfBytesRead = readByteCount;
- return readByteCount >= 0;
+ }
+ if (lpNumberOfBytesRead)
+ *lpNumberOfBytesRead = readByteCount;
+ return readByteCount >= 0;
}
-BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) {
- FILE_LOGD("WriteFile(hFile: %p, lpBuffer: 0x%08x, nNumberOfBytesToWrite: %d)", hFile, lpBuffer, nNumberOfBytesToWrite);
- if(hFile->handleType == HANDLE_TYPE_FILE) {
+BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
+ LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) {
+ FILE_LOGD("WriteFile(hFile: %p, lpBuffer: 0x%08x, nNumberOfBytesToWrite: %d)", hFile, lpBuffer,
+ nNumberOfBytesToWrite);
+ if (hFile->handleType == HANDLE_TYPE_FILE) {
ssize_t writenByteCount = write(hFile->fileDescriptor, lpBuffer, nNumberOfBytesToWrite);
- if(lpNumberOfBytesWritten)
+ if (lpNumberOfBytesWritten)
*lpNumberOfBytesWritten = (DWORD) writenByteCount;
return writenByteCount >= 0;
- } else if(hFile->handleType == HANDLE_TYPE_COM) {
+ } else if (hFile->handleType == HANDLE_TYPE_COM) {
ssize_t writenByteCount = writeSerialPort(hFile->commId, lpBuffer, nNumberOfBytesToWrite);
#if defined DEBUG_ANDROID_SERIAL
char * hexAsciiDump = dumpToHexAscii(lpBuffer, writenByteCount, 8);
SERIAL_LOGD("WriteFile(hFile: %p, lpBuffer: 0x%08x, nNumberOfBytesToWrite: %d) -> %d bytes\n%s", hFile, lpBuffer, nNumberOfBytesToWrite, writenByteCount, hexAsciiDump);
free(hexAsciiDump);
#endif
- if(serialPortSlowDown)
+ if (serialPortSlowDown)
Sleep(4); // Seems to be needed else kermit/XSend packets do not fully reach the genuine calculator.
- if(lpNumberOfBytesWritten)
+ if (lpNumberOfBytesWritten)
*lpNumberOfBytesWritten = (DWORD) writenByteCount;
return writenByteCount >= 0;
}
return FALSE;
}
-DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) {
- FILE_LOGD("SetFilePointer(hFile: %p, lDistanceToMove: %d, dwMoveMethod: %d)", hFile, lDistanceToMove, dwMoveMethod);
- int moveMode = FILE_BEGIN;
- if(dwMoveMethod == FILE_BEGIN)
- moveMode = SEEK_SET;
- else if(dwMoveMethod == FILE_CURRENT)
- moveMode = SEEK_CUR;
- else if(dwMoveMethod == FILE_END)
- moveMode = SEEK_END;
- int seekResult = -1;
- if(hFile->handleType == HANDLE_TYPE_FILE) {
- seekResult = (int) lseek(hFile->fileDescriptor, lDistanceToMove, moveMode);
- } else if(hFile->handleType == HANDLE_TYPE_FILE_ASSET) {
- seekResult = (int) AAsset_seek64(hFile->fileAsset, lDistanceToMove, moveMode);
- }
- return seekResult < 0 ? INVALID_SET_FILE_POINTER : seekResult;
+DWORD
+SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) {
+ FILE_LOGD("SetFilePointer(hFile: %p, lDistanceToMove: %d, dwMoveMethod: %d)", hFile,
+ lDistanceToMove, dwMoveMethod);
+ int moveMode = FILE_BEGIN;
+ if (dwMoveMethod == FILE_BEGIN)
+ moveMode = SEEK_SET;
+ else if (dwMoveMethod == FILE_CURRENT)
+ moveMode = SEEK_CUR;
+ else if (dwMoveMethod == FILE_END)
+ moveMode = SEEK_END;
+ int seekResult = -1;
+ if (hFile->handleType == HANDLE_TYPE_FILE) {
+ seekResult = (int) lseek(hFile->fileDescriptor, lDistanceToMove, moveMode);
+ } else if (hFile->handleType == HANDLE_TYPE_FILE_ASSET) {
+ seekResult = (int) AAsset_seek64(hFile->fileAsset, lDistanceToMove, moveMode);
+ }
+ return seekResult < 0 ? INVALID_SET_FILE_POINTER : seekResult;
}
BOOL SetEndOfFile(HANDLE hFile) {
- FILE_LOGD("SetEndOfFile(hFile: %p)", hFile);
- if(hFile->handleType == HANDLE_TYPE_FILE_ASSET)
- return FALSE;
- off_t currentPosition = lseek(hFile->fileDescriptor, 0, SEEK_CUR);
- int truncateResult = ftruncate(hFile->fileDescriptor, currentPosition);
- return truncateResult == 0;
+ FILE_LOGD("SetEndOfFile(hFile: %p)", hFile);
+ if (hFile->handleType == HANDLE_TYPE_FILE_ASSET)
+ return FALSE;
+ off_t currentPosition = lseek(hFile->fileDescriptor, 0, SEEK_CUR);
+ int truncateResult = ftruncate(hFile->fileDescriptor, currentPosition);
+ return truncateResult == 0;
}
DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) {
- FILE_LOGD("GetFileSize(hFile: %p)", hFile);
- if(lpFileSizeHigh)
- *lpFileSizeHigh = 0;
- if(hFile->handleType == HANDLE_TYPE_FILE) {
- off_t currentPosition = lseek(hFile->fileDescriptor, 0, SEEK_CUR);
- off_t fileLength = lseek(hFile->fileDescriptor, 0, SEEK_END); // + 1;
- lseek(hFile->fileDescriptor, currentPosition, SEEK_SET);
- return (DWORD) fileLength;
- } else if(hFile->handleType == HANDLE_TYPE_FILE_ASSET) {
- return (DWORD) AAsset_getLength64(hFile->fileAsset);
- }
- return 0;
+ FILE_LOGD("GetFileSize(hFile: %p)", hFile);
+ if (lpFileSizeHigh)
+ *lpFileSizeHigh = 0;
+ if (hFile->handleType == HANDLE_TYPE_FILE) {
+ off_t currentPosition = lseek(hFile->fileDescriptor, 0, SEEK_CUR);
+ off_t fileLength = lseek(hFile->fileDescriptor, 0, SEEK_END); // + 1;
+ lseek(hFile->fileDescriptor, currentPosition, SEEK_SET);
+ return (DWORD) fileLength;
+ } else if (hFile->handleType == HANDLE_TYPE_FILE_ASSET) {
+ return (DWORD) AAsset_getLength64(hFile->fileAsset);
+ }
+ return 0;
}
//** https://www.ibm.com/developerworks/systems/library/es-MigratingWin32toLinux.html
//https://www.ibm.com/developerworks/systems/library/es-win32linux.html
//https://www.ibm.com/developerworks/systems/library/es-win32linux-sem.html
-HANDLE CreateFileMapping(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName) {
- FILE_LOGD("CreateFileMapping(hFile: %p, flProtect: 0x08x, dwMaximumSizeLow: %d)", hFile, flProtect, dwMaximumSizeLow);
- HANDLE handle = malloc(sizeof(struct _HANDLE));
- memset(handle, 0, sizeof(struct _HANDLE));
- if(hFile->handleType == HANDLE_TYPE_FILE) {
- if(hFile->fileOpenFileFromContentResolver)
- handle->handleType = HANDLE_TYPE_FILE_MAPPING_CONTENT;
- else
- handle->handleType = HANDLE_TYPE_FILE_MAPPING;
- handle->fileDescriptor = hFile->fileDescriptor;
- } else if(hFile->handleType == HANDLE_TYPE_FILE_ASSET) {
- handle->handleType = HANDLE_TYPE_FILE_MAPPING_ASSET;
- handle->fileAsset = hFile->fileAsset;
- }
- if(dwMaximumSizeHigh == 0 && dwMaximumSizeLow == 0) {
- dwMaximumSizeLow = GetFileSize(hFile, &dwMaximumSizeHigh);
- }
- handle->fileMappingSize = /*(dwMaximumSizeHigh << 32) |*/ dwMaximumSizeLow;
- handle->fileMappingAddress = NULL;
- handle->fileMappingProtect = flProtect;
- return handle;
+HANDLE
+CreateFileMapping(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect,
+ DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName) {
+ FILE_LOGD("CreateFileMapping(hFile: %p, flProtect: 0x08x, dwMaximumSizeLow: %d)", hFile,
+ flProtect, dwMaximumSizeLow);
+ HANDLE handle = malloc(sizeof(struct _HANDLE));
+ memset(handle, 0, sizeof(struct _HANDLE));
+ if (hFile->handleType == HANDLE_TYPE_FILE) {
+ if (hFile->fileOpenFileFromContentResolver)
+ handle->handleType = HANDLE_TYPE_FILE_MAPPING_CONTENT;
+ else
+ handle->handleType = HANDLE_TYPE_FILE_MAPPING;
+ handle->fileDescriptor = hFile->fileDescriptor;
+ } else if (hFile->handleType == HANDLE_TYPE_FILE_ASSET) {
+ handle->handleType = HANDLE_TYPE_FILE_MAPPING_ASSET;
+ handle->fileAsset = hFile->fileAsset;
+ }
+ if (dwMaximumSizeHigh == 0 && dwMaximumSizeLow == 0) {
+ dwMaximumSizeLow = GetFileSize(hFile, &dwMaximumSizeHigh);
+ }
+ handle->fileMappingSize = /*(dwMaximumSizeHigh << 32) |*/ dwMaximumSizeLow;
+ handle->fileMappingAddress = NULL;
+ handle->fileMappingProtect = flProtect;
+ return handle;
}
//https://msdn.microsoft.com/en-us/library/Aa366761(v=VS.85).aspx
-LPVOID MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) {
- FILE_LOGD("MapViewOfFile(hFileMappingObject: %p, dwDesiredAccess: 0x%08x, dwFileOffsetLow: %d)", hFileMappingObject, dwDesiredAccess, dwFileOffsetLow);
- hFileMappingObject->fileMappingOffset = /*(dwFileOffsetHigh << 32) |*/ dwFileOffsetLow;
- LPVOID result = NULL;
- if(hFileMappingObject->handleType == HANDLE_TYPE_FILE_MAPPING) {
- int prot = PROT_NONE;
- if (dwDesiredAccess & FILE_MAP_READ)
- prot |= PROT_READ;
- if (dwDesiredAccess & FILE_MAP_WRITE)
- prot |= PROT_WRITE;
- hFileMappingObject->fileMappingAddress = mmap(NULL, hFileMappingObject->fileMappingSize,
- prot, MAP_PRIVATE,
- hFileMappingObject->fileDescriptor, hFileMappingObject->fileMappingOffset);
- } else if(hFileMappingObject->handleType == HANDLE_TYPE_FILE_MAPPING_CONTENT) {
- size_t numberOfBytesToRead = hFileMappingObject->fileMappingSize - hFileMappingObject->fileMappingOffset;
- hFileMappingObject->fileMappingAddress = malloc(numberOfBytesToRead);
- off_t currentPosition = lseek(hFileMappingObject->fileDescriptor, 0, SEEK_CUR);
- lseek(hFileMappingObject->fileDescriptor, hFileMappingObject->fileMappingOffset, SEEK_SET);
- DWORD readByteCount = (DWORD) read(hFileMappingObject->fileDescriptor, hFileMappingObject->fileMappingAddress, numberOfBytesToRead);
- lseek(hFileMappingObject->fileDescriptor, currentPosition, SEEK_SET);
- } else if(hFileMappingObject->handleType == HANDLE_TYPE_FILE_MAPPING_ASSET) {
- if (dwDesiredAccess & FILE_MAP_WRITE)
- return NULL;
- hFileMappingObject->fileMappingAddress = (LPVOID) (AAsset_getBuffer(hFileMappingObject->fileAsset) + hFileMappingObject->fileMappingOffset);
- }
- if(hFileMappingObject->fileMappingAddress) {
- for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
- if(!fileMappingHandles[i]) {
- fileMappingHandles[i] = hFileMappingObject;
- break;
- }
- }
- }
- result = hFileMappingObject->fileMappingAddress;
- return result;
+LPVOID MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,
+ DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) {
+ FILE_LOGD("MapViewOfFile(hFileMappingObject: %p, dwDesiredAccess: 0x%08x, dwFileOffsetLow: %d)",
+ hFileMappingObject, dwDesiredAccess, dwFileOffsetLow);
+ hFileMappingObject->fileMappingOffset = /*(dwFileOffsetHigh << 32) |*/ dwFileOffsetLow;
+ LPVOID result = NULL;
+ if (hFileMappingObject->handleType == HANDLE_TYPE_FILE_MAPPING) {
+ int prot = PROT_NONE;
+ if (dwDesiredAccess & FILE_MAP_READ)
+ prot |= PROT_READ;
+ if (dwDesiredAccess & FILE_MAP_WRITE)
+ prot |= PROT_WRITE;
+ hFileMappingObject->fileMappingAddress = mmap(NULL, hFileMappingObject->fileMappingSize,
+ prot, MAP_PRIVATE,
+ hFileMappingObject->fileDescriptor,
+ hFileMappingObject->fileMappingOffset);
+ } else if (hFileMappingObject->handleType == HANDLE_TYPE_FILE_MAPPING_CONTENT) {
+ size_t numberOfBytesToRead =
+ hFileMappingObject->fileMappingSize - hFileMappingObject->fileMappingOffset;
+ hFileMappingObject->fileMappingAddress = malloc(numberOfBytesToRead);
+ off_t currentPosition = lseek(hFileMappingObject->fileDescriptor, 0, SEEK_CUR);
+ lseek(hFileMappingObject->fileDescriptor, hFileMappingObject->fileMappingOffset, SEEK_SET);
+ DWORD readByteCount = (DWORD) read(hFileMappingObject->fileDescriptor,
+ hFileMappingObject->fileMappingAddress,
+ numberOfBytesToRead);
+ lseek(hFileMappingObject->fileDescriptor, currentPosition, SEEK_SET);
+ } else if (hFileMappingObject->handleType == HANDLE_TYPE_FILE_MAPPING_ASSET) {
+ if (dwDesiredAccess & FILE_MAP_WRITE)
+ return NULL;
+ hFileMappingObject->fileMappingAddress = (LPVOID) (
+ AAsset_getBuffer(hFileMappingObject->fileAsset) +
+ hFileMappingObject->fileMappingOffset);
+ }
+ if (hFileMappingObject->fileMappingAddress) {
+ for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
+ if (!fileMappingHandles[i]) {
+ fileMappingHandles[i] = hFileMappingObject;
+ break;
+ }
+ }
+ }
+ result = hFileMappingObject->fileMappingAddress;
+ return result;
}
// https://msdn.microsoft.com/en-us/library/aa366882(v=vs.85).aspx
BOOL UnmapViewOfFile(LPCVOID lpBaseAddress) {
- FILE_LOGD("UnmapViewOfFile(lpBaseAddress: %p)", lpBaseAddress);
- int result = -1;
- for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
- HANDLE fileMappingHandle = fileMappingHandles[i];
- if(fileMappingHandle && lpBaseAddress == fileMappingHandle->fileMappingAddress) {
- // Only save the file manually (for Port2 actually)
- fileMappingHandles[i] = NULL;
- break;
- }
- }
+ FILE_LOGD("UnmapViewOfFile(lpBaseAddress: %p)", lpBaseAddress);
+ int result = -1;
+ for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
+ HANDLE fileMappingHandle = fileMappingHandles[i];
+ if (fileMappingHandle && lpBaseAddress == fileMappingHandle->fileMappingAddress) {
+ // Only save the file manually (for Port2 actually)
+ fileMappingHandles[i] = NULL;
+ break;
+ }
+ }
- return result == 0;
+ return result == 0;
}
// This is not a Win32 function
BOOL SaveMapViewToFile(LPCVOID lpBaseAddress) {
- FILE_LOGD("SaveMapViewToFile(lpBaseAddress: %p)", lpBaseAddress);
- int result = -1;
- for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
- HANDLE fileMappingHandle = fileMappingHandles[i];
- if(fileMappingHandle && lpBaseAddress == fileMappingHandle->fileMappingAddress) {
- if(fileMappingHandle->handleType == HANDLE_TYPE_FILE_MAPPING
- || fileMappingHandle->handleType == HANDLE_TYPE_FILE_MAPPING_CONTENT) {
- //size_t numberOfBytesToWrite = fileMappingHandle->fileMappingSize - fileMappingHandle->fileMappingOffset;
- size_t numberOfBytesToWrite = fileMappingHandle->fileMappingSize;
- if(numberOfBytesToWrite > 0) {
- off_t currentPosition = lseek(fileMappingHandle->fileDescriptor, 0, SEEK_CUR);
- //lseek(fileMappingHandle->fileDescriptor, fileMappingHandle->fileMappingOffset, SEEK_SET);
- lseek(fileMappingHandle->fileDescriptor, 0, SEEK_SET);
- write(fileMappingHandle->fileDescriptor, fileMappingHandle->fileMappingAddress, numberOfBytesToWrite);
- lseek(fileMappingHandle->fileDescriptor, currentPosition, SEEK_SET);
- } else {
- // BUG
- }
- } else if(fileMappingHandle->handleType == HANDLE_TYPE_FILE_MAPPING_ASSET) {
- // No need to unmap
- result = 0;
- }
- break;
- }
- }
+ FILE_LOGD("SaveMapViewToFile(lpBaseAddress: %p)", lpBaseAddress);
+ int result = -1;
+ for (int i = 0; i < MAX_FILE_MAPPING_HANDLE; ++i) {
+ HANDLE fileMappingHandle = fileMappingHandles[i];
+ if (fileMappingHandle && lpBaseAddress == fileMappingHandle->fileMappingAddress) {
+ if (fileMappingHandle->handleType == HANDLE_TYPE_FILE_MAPPING
+ || fileMappingHandle->handleType == HANDLE_TYPE_FILE_MAPPING_CONTENT) {
+ //size_t numberOfBytesToWrite = fileMappingHandle->fileMappingSize - fileMappingHandle->fileMappingOffset;
+ size_t numberOfBytesToWrite = fileMappingHandle->fileMappingSize;
+ if (numberOfBytesToWrite > 0) {
+ off_t currentPosition = lseek(fileMappingHandle->fileDescriptor, 0, SEEK_CUR);
+ //lseek(fileMappingHandle->fileDescriptor, fileMappingHandle->fileMappingOffset, SEEK_SET);
+ lseek(fileMappingHandle->fileDescriptor, 0, SEEK_SET);
+ write(fileMappingHandle->fileDescriptor, fileMappingHandle->fileMappingAddress,
+ numberOfBytesToWrite);
+ lseek(fileMappingHandle->fileDescriptor, currentPosition, SEEK_SET);
+ } else {
+ // BUG
+ }
+ } else if (fileMappingHandle->handleType == HANDLE_TYPE_FILE_MAPPING_ASSET) {
+ // No need to unmap
+ result = 0;
+ }
+ break;
+ }
+ }
- return result == 0;
+ return result == 0;
}
//https://github.com/neosmart/pevents/blob/master/src/pevents.cpp
HANDLE CreateEvent(LPVOID lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR name) {
- HANDLE handle = malloc(sizeof(struct _HANDLE));
- memset(handle, 0, sizeof(struct _HANDLE));
- handle->handleType = HANDLE_TYPE_EVENT;
+ HANDLE handle = malloc(sizeof(struct _HANDLE));
+ memset(handle, 0, sizeof(struct _HANDLE));
+ handle->handleType = HANDLE_TYPE_EVENT;
- int result = pthread_cond_init(&(handle->eventCVariable), 0);
- _ASSERT(result == 0);
+ int result = pthread_cond_init(&(handle->eventCVariable), 0);
+ _ASSERT(result == 0);
- result = pthread_mutex_init(&(handle->eventMutex), 0);
- _ASSERT(result == 0);
+ result = pthread_mutex_init(&(handle->eventMutex), 0);
+ _ASSERT(result == 0);
- handle->eventState = FALSE;
- handle->eventAutoReset = bManualReset ? FALSE : TRUE;
+ handle->eventState = FALSE;
+ handle->eventAutoReset = bManualReset ? FALSE : TRUE;
- if (bInitialState)
- {
- result = SetEvent(handle);
- _ASSERT(result == 0);
- }
+ if (bInitialState) {
+ result = SetEvent(handle);
+ _ASSERT(result == 0);
+ }
- return handle;
+ return handle;
}
BOOL SetEvent(HANDLE hEvent) {
- int result = pthread_mutex_lock(&hEvent->eventMutex);
- _ASSERT(result == 0);
+ int result = pthread_mutex_lock(&hEvent->eventMutex);
+ _ASSERT(result == 0);
- hEvent->eventState = TRUE;
+ hEvent->eventState = TRUE;
- //Depending on the event type, we either trigger everyone or only one
- if (hEvent->eventAutoReset)
- {
- //hEvent->eventState can be false if compiled with WFMO support
- if (hEvent->eventState)
- {
- result = pthread_mutex_unlock(&hEvent->eventMutex);
- _ASSERT(result == 0);
- result = pthread_cond_signal(&hEvent->eventCVariable);
- _ASSERT(result == 0);
- return 0;
- }
- }
- else
- {
- result = pthread_mutex_unlock(&hEvent->eventMutex);
- _ASSERT(result == 0);
- result = pthread_cond_broadcast(&hEvent->eventCVariable);
- _ASSERT(result == 0);
- }
+ //Depending on the event type, we either trigger everyone or only one
+ if (hEvent->eventAutoReset) {
+ //hEvent->eventState can be false if compiled with WFMO support
+ if (hEvent->eventState) {
+ result = pthread_mutex_unlock(&hEvent->eventMutex);
+ _ASSERT(result == 0);
+ result = pthread_cond_signal(&hEvent->eventCVariable);
+ _ASSERT(result == 0);
+ return 0;
+ }
+ } else {
+ result = pthread_mutex_unlock(&hEvent->eventMutex);
+ _ASSERT(result == 0);
+ result = pthread_cond_broadcast(&hEvent->eventCVariable);
+ _ASSERT(result == 0);
+ }
- return 0;
+ return 0;
}
BOOL ResetEvent(HANDLE hEvent) {
- if(hEvent) {
- int result = pthread_mutex_lock(&hEvent->eventMutex);
- _ASSERT(result == 0);
+ if (hEvent) {
+ int result = pthread_mutex_lock(&hEvent->eventMutex);
+ _ASSERT(result == 0);
- hEvent->eventState = FALSE;
+ hEvent->eventState = FALSE;
- result = pthread_mutex_unlock(&hEvent->eventMutex);
- _ASSERT(result == 0);
+ result = pthread_mutex_unlock(&hEvent->eventMutex);
+ _ASSERT(result == 0);
- return TRUE;
- }
- return FALSE;
+ return TRUE;
+ }
+ return FALSE;
}
int UnlockedWaitForEvent(HANDLE hHandle, uint64_t milliseconds) {
- int result = 0;
- if (!hHandle->eventState)
- {
- //Zero-timeout event state check optimization
- if (milliseconds == 0)
- {
- return WAIT_TIMEOUT;
- }
+ int result = 0;
+ if (!hHandle->eventState) {
+ //Zero-timeout event state check optimization
+ if (milliseconds == 0) {
+ return WAIT_TIMEOUT;
+ }
- struct timespec ts;
- if (milliseconds != (uint64_t) -1)
- {
- struct timeval tv;
- gettimeofday(&tv, NULL);
+ struct timespec ts;
+ if (milliseconds != (uint64_t) -1) {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
- uint64_t nanoseconds = ((uint64_t) tv.tv_sec) * 1000 * 1000 * 1000 + milliseconds * 1000 * 1000 + ((uint64_t) tv.tv_usec) * 1000;
+ uint64_t nanoseconds =
+ ((uint64_t) tv.tv_sec) * 1000 * 1000 * 1000 + milliseconds * 1000 * 1000 +
+ ((uint64_t) tv.tv_usec) * 1000;
- ts.tv_sec = nanoseconds / 1000 / 1000 / 1000;
- ts.tv_nsec = (nanoseconds - ((uint64_t) ts.tv_sec) * 1000 * 1000 * 1000);
- }
+ ts.tv_sec = nanoseconds / 1000 / 1000 / 1000;
+ ts.tv_nsec = (nanoseconds - ((uint64_t) ts.tv_sec) * 1000 * 1000 * 1000);
+ }
- do
- {
- //Regardless of whether it's an auto-reset or manual-reset event:
- //wait to obtain the event, then lock anyone else out
- if (milliseconds != (uint64_t) -1)
- {
- result = pthread_cond_timedwait(&hHandle->eventCVariable, &hHandle->eventMutex, &ts);
- THREAD_LOGD("UnlockedWaitForEvent() pthread_cond_timedwait() for event %x return %d", hHandle, result);
- if(result == ETIMEDOUT)
- result = WAIT_TIMEOUT;
- }
- else
- {
- result = pthread_cond_wait(&hHandle->eventCVariable, &hHandle->eventMutex);
- }
- } while (result == 0 && !hHandle->eventState);
+ do {
+ //Regardless of whether it's an auto-reset or manual-reset event:
+ //wait to obtain the event, then lock anyone else out
+ if (milliseconds != (uint64_t) -1) {
+ result = pthread_cond_timedwait(&hHandle->eventCVariable, &hHandle->eventMutex,
+ &ts);
+ THREAD_LOGD(
+ "UnlockedWaitForEvent() pthread_cond_timedwait() for event %x return %d",
+ hHandle, result);
+ if (result == ETIMEDOUT)
+ result = WAIT_TIMEOUT;
+ } else {
+ result = pthread_cond_wait(&hHandle->eventCVariable, &hHandle->eventMutex);
+ }
+ } while (result == 0 && !hHandle->eventState);
- if (result == 0 && hHandle->eventAutoReset)
- {
- //We've only accquired the event if the wait succeeded
- hHandle->eventState = FALSE;
- }
- }
- else if (hHandle->eventAutoReset)
- {
- //It's an auto-reset event that's currently available;
- //we need to stop anyone else from using it
- result = 0;
- hHandle->eventState = FALSE;
- }
- //Else we're trying to obtain a manual reset event with a signaled state;
- //don't do anything
+ if (result == 0 && hHandle->eventAutoReset) {
+ //We've only accquired the event if the wait succeeded
+ hHandle->eventState = FALSE;
+ }
+ } else if (hHandle->eventAutoReset) {
+ //It's an auto-reset event that's currently available;
+ //we need to stop anyone else from using it
+ result = 0;
+ hHandle->eventState = FALSE;
+ }
+ //Else we're trying to obtain a manual reset event with a signaled state;
+ //don't do anything
- return result;
+ return result;
}
extern int jniDetachCurrentThread();
@@ -637,64 +652,68 @@ extern int jniDetachCurrentThread();
static HANDLE threads[MAX_CREATED_THREAD];
static void ThreadStart(LPVOID lpThreadParameter) {
- HANDLE handle = (HANDLE)lpThreadParameter;
- if(handle) {
- handle->threadStartAddress(handle->threadParameter);
- }
+ HANDLE handle = (HANDLE) lpThreadParameter;
+ if (handle) {
+ handle->threadStartAddress(handle->threadParameter);
+ }
- threads[handle->threadIndex] = NULL;
- jniDetachCurrentThread();
- CloseHandle(handle->threadEventMessage);
+ threads[handle->threadIndex] = NULL;
+ jniDetachCurrentThread();
+ CloseHandle(handle->threadEventMessage);
}
-HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) {
- THREAD_LOGD("CreateThread()");
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- if(dwStackSize)
- pthread_attr_setstacksize(&attr, dwStackSize);
+HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter,
+ DWORD dwCreationFlags, LPDWORD lpThreadId) {
+ THREAD_LOGD("CreateThread()");
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ if (dwStackSize)
+ pthread_attr_setstacksize(&attr, dwStackSize);
- HANDLE handle = malloc(sizeof(struct _HANDLE));
- memset(handle, 0, sizeof(struct _HANDLE));
- handle->handleType = HANDLE_TYPE_THREAD;
- handle->threadStartAddress = lpStartAddress;
- handle->threadParameter = lpParameter;
- handle->threadEventMessage = CreateEvent(NULL, FALSE, FALSE, NULL);
- for(int i = 0; i < MAX_CREATED_THREAD; i++) {
- if(threads[i] == NULL) {
- handle->threadIndex = i;
- threads[handle->threadIndex] = handle;
- break;
- }
- }
+ HANDLE handle = malloc(sizeof(struct _HANDLE));
+ memset(handle, 0, sizeof(struct _HANDLE));
+ handle->handleType = HANDLE_TYPE_THREAD;
+ handle->threadStartAddress = lpStartAddress;
+ handle->threadParameter = lpParameter;
+ handle->threadEventMessage = CreateEvent(NULL, FALSE, FALSE, NULL);
+ for (int i = 0; i < MAX_CREATED_THREAD; i++) {
+ if (threads[i] == NULL) {
+ handle->threadIndex = i;
+ threads[handle->threadIndex] = handle;
+ break;
+ }
+ }
- //Suspended
- //https://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition
- //https://stackoverflow.com/questions/7953917/create-thread-in-suspended-mode-using-pthreads
- //http://man7.org/linux/man-pages/man3/pthread_create.3.html
- int pthreadResult = pthread_create(&handle->threadId, &attr, (void *(*)(void *)) ThreadStart, handle);
- if(pthreadResult == 0) {
- if(lpThreadId)
- *lpThreadId = (DWORD) handle->threadIndex; //handle->threadId;
- THREAD_LOGD("CreateThread() threadId: 0x%lx, threadIndex: %d", handle->threadId, handle->threadIndex);
- return handle;
- } else {
- threads[handle->threadIndex] = NULL;
- if(handle->threadEventMessage)
- CloseHandle(handle->threadEventMessage);
- free(handle);
- }
- return NULL;
+ //Suspended
+ //https://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition
+ //https://stackoverflow.com/questions/7953917/create-thread-in-suspended-mode-using-pthreads
+ //http://man7.org/linux/man-pages/man3/pthread_create.3.html
+ int pthreadResult = pthread_create(&handle->threadId, &attr, (void *(*)(void *)) ThreadStart,
+ handle);
+ if (pthreadResult == 0) {
+ if (lpThreadId)
+ *lpThreadId = (DWORD) handle->threadIndex; //handle->threadId;
+ THREAD_LOGD("CreateThread() threadId: 0x%lx, threadIndex: %d", handle->threadId,
+ handle->threadIndex);
+ return handle;
+ } else {
+ threads[handle->threadIndex] = NULL;
+ if (handle->threadEventMessage)
+ CloseHandle(handle->threadEventMessage);
+ free(handle);
+ }
+ return NULL;
}
DWORD ResumeThread(HANDLE hThread) {
- THREAD_LOGD("ResumeThread()");
- //TODO
- return 0;
+ THREAD_LOGD("ResumeThread()");
+ //TODO
+ return 0;
}
BOOL SetThreadPriority(HANDLE hThread, int nPriority) {
- THREAD_LOGD("SetThreadPriority()");
+ THREAD_LOGD("SetThreadPriority()");
// if(hThread->handleType == HANDLE_TYPE_THREAD) {
// int policy;
// struct sched_param param;
@@ -707,153 +726,149 @@ BOOL SetThreadPriority(HANDLE hThread, int nPriority) {
// // THIS DOES NOT WORK WITH ANDROID!
// return TRUE;
// }
- return FALSE;
+ return FALSE;
}
//https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject
-DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
-{
- if(hHandle->handleType == HANDLE_TYPE_THREAD) {
- _ASSERT(dwMilliseconds == INFINITE)
- if(dwMilliseconds == INFINITE) {
- pthread_join(hHandle->threadId, NULL);
- }
- //TODO for dwMilliseconds != INFINITE
- //https://stackoverflow.com/questions/2719580/waitforsingleobject-and-waitformultipleobjects-equivalent-in-linux
- } else if(hHandle->handleType == HANDLE_TYPE_EVENT) {
+DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
+ if (hHandle->handleType == HANDLE_TYPE_THREAD) {
+ _ASSERT(dwMilliseconds == INFINITE)
+ if (dwMilliseconds == INFINITE) {
+ pthread_join(hHandle->threadId, NULL);
+ }
+ //TODO for dwMilliseconds != INFINITE
+ //https://stackoverflow.com/questions/2719580/waitforsingleobject-and-waitformultipleobjects-equivalent-in-linux
+ } else if (hHandle->handleType == HANDLE_TYPE_EVENT) {
- int tempResult;
- if (dwMilliseconds == 0)
- {
- tempResult = pthread_mutex_trylock(&hHandle->eventMutex);
- if (tempResult == EBUSY)
- {
- return WAIT_TIMEOUT;
- }
- }
- else
- {
- tempResult = pthread_mutex_lock(&hHandle->eventMutex);
- }
+ int tempResult;
+ if (dwMilliseconds == 0) {
+ tempResult = pthread_mutex_trylock(&hHandle->eventMutex);
+ if (tempResult == EBUSY) {
+ return WAIT_TIMEOUT;
+ }
+ } else {
+ tempResult = pthread_mutex_lock(&hHandle->eventMutex);
+ }
- _ASSERT(tempResult == 0);
+ _ASSERT(tempResult == 0);
- int result = UnlockedWaitForEvent(hHandle, dwMilliseconds);
+ int result = UnlockedWaitForEvent(hHandle, dwMilliseconds);
- tempResult = pthread_mutex_unlock(&hHandle->eventMutex);
- _ASSERT(tempResult == 0);
+ tempResult = pthread_mutex_unlock(&hHandle->eventMutex);
+ _ASSERT(tempResult == 0);
- return (DWORD) result;
- }
+ return (DWORD) result;
+ }
- DWORD result = WAIT_OBJECT_0;
- return result;
+ DWORD result = WAIT_OBJECT_0;
+ return result;
}
BOOL WINAPI CloseHandle(HANDLE hObject) {
- FILE_LOGD("CloseHandle(hObject: %p)", hObject);
- if(!hObject)
- return FALSE;
- //https://msdn.microsoft.com/en-us/9b84891d-62ca-4ddc-97b7-c4c79482abd9
- // Can be a thread/event/file handle!
- switch(hObject->handleType) {
- case HANDLE_TYPE_FILE: {
- FILE_LOGD("CloseHandle() HANDLE_TYPE_FILE");
- int closeResult;
- if(hObject->fileOpenFileFromContentResolver) {
- closeResult = closeFileFromContentResolver(hObject->fileDescriptor);
- } else {
- closeResult = close(hObject->fileDescriptor);
- if(closeResult == -1) {
- LOGD("close() %d", errno); //9 -> EBADF
- }
- }
- if(closeResult >= 0) {
- hObject->handleType = HANDLE_TYPE_INVALID;
- hObject->fileDescriptor = 0;
- free(hObject);
- return TRUE;
- }
+ FILE_LOGD("CloseHandle(hObject: %p)", hObject);
+ if (!hObject)
+ return FALSE;
+ //https://msdn.microsoft.com/en-us/9b84891d-62ca-4ddc-97b7-c4c79482abd9
+ // Can be a thread/event/file handle!
+ switch (hObject->handleType) {
+ case HANDLE_TYPE_FILE: {
+ FILE_LOGD("CloseHandle() HANDLE_TYPE_FILE");
+ int closeResult;
+ if (hObject->fileOpenFileFromContentResolver) {
+ closeResult = closeFileFromContentResolver(hObject->fileDescriptor);
+ } else {
+ closeResult = close(hObject->fileDescriptor);
+ if (closeResult == -1) {
+ LOGD("close() %d", errno); //9 -> EBADF
+ }
+ }
+ if (closeResult >= 0) {
+ hObject->handleType = HANDLE_TYPE_INVALID;
+ hObject->fileDescriptor = 0;
+ free(hObject);
+ return TRUE;
+ }
- break;
- }
- case HANDLE_TYPE_FILE_ASSET: {
- FILE_LOGD("CloseHandle() HANDLE_TYPE_FILE_ASSET");
- AAsset_close(hObject->fileAsset);
- hObject->handleType = HANDLE_TYPE_INVALID;
- hObject->fileAsset = NULL;
- free(hObject);
- return TRUE;
- }
- case HANDLE_TYPE_FILE_MAPPING:
- case HANDLE_TYPE_FILE_MAPPING_CONTENT:
- case HANDLE_TYPE_FILE_MAPPING_ASSET: {
- FILE_LOGD("CloseHandle() HANDLE_TYPE_FILE_MAPPING");
- hObject->handleType = HANDLE_TYPE_INVALID;
- hObject->fileDescriptor = 0;
- hObject->fileAsset = NULL;
- hObject->fileMappingSize = 0;
- hObject->fileMappingAddress = NULL;
- free(hObject);
- return TRUE;
- }
- case HANDLE_TYPE_EVENT: {
- FILE_LOGD("CloseHandle() HANDLE_TYPE_EVENT");
- hObject->handleType = HANDLE_TYPE_INVALID;
- int result = 0;
- result = pthread_cond_destroy(&hObject->eventCVariable);
- _ASSERT(result == 0);
- result = pthread_mutex_destroy(&hObject->eventMutex);
- _ASSERT(result == 0);
- hObject->eventAutoReset = FALSE;
- hObject->eventState = FALSE;
- free(hObject);
- return TRUE;
- }
- case HANDLE_TYPE_THREAD:
- THREAD_LOGD("CloseHandle() THREAD 0x%lx", hObject->threadId);
- if(hObject->threadEventMessage && hObject->threadEventMessage->handleType == HANDLE_TYPE_EVENT) {
- CloseHandle(hObject->threadEventMessage);
- hObject->threadEventMessage = NULL;
- }
- hObject->handleType = HANDLE_TYPE_INVALID;
- hObject->threadId = 0;
- hObject->threadStartAddress = NULL;
- hObject->threadParameter = NULL;
- free(hObject);
- return TRUE;
- case HANDLE_TYPE_COM: {
- SERIAL_LOGD("CloseHandle(hObject: %p) for HANDLE_TYPE_COM", hObject);
+ break;
+ }
+ case HANDLE_TYPE_FILE_ASSET: {
+ FILE_LOGD("CloseHandle() HANDLE_TYPE_FILE_ASSET");
+ AAsset_close(hObject->fileAsset);
+ hObject->handleType = HANDLE_TYPE_INVALID;
+ hObject->fileAsset = NULL;
+ free(hObject);
+ return TRUE;
+ }
+ case HANDLE_TYPE_FILE_MAPPING:
+ case HANDLE_TYPE_FILE_MAPPING_CONTENT:
+ case HANDLE_TYPE_FILE_MAPPING_ASSET: {
+ FILE_LOGD("CloseHandle() HANDLE_TYPE_FILE_MAPPING");
+ hObject->handleType = HANDLE_TYPE_INVALID;
+ hObject->fileDescriptor = 0;
+ hObject->fileAsset = NULL;
+ hObject->fileMappingSize = 0;
+ hObject->fileMappingAddress = NULL;
+ free(hObject);
+ return TRUE;
+ }
+ case HANDLE_TYPE_EVENT: {
+ FILE_LOGD("CloseHandle() HANDLE_TYPE_EVENT");
+ hObject->handleType = HANDLE_TYPE_INVALID;
+ int result = 0;
+ result = pthread_cond_destroy(&hObject->eventCVariable);
+ _ASSERT(result == 0);
+ result = pthread_mutex_destroy(&hObject->eventMutex);
+ _ASSERT(result == 0);
+ hObject->eventAutoReset = FALSE;
+ hObject->eventState = FALSE;
+ free(hObject);
+ return TRUE;
+ }
+ case HANDLE_TYPE_THREAD:
+ THREAD_LOGD("CloseHandle() THREAD 0x%lx", hObject->threadId);
+ if (hObject->threadEventMessage &&
+ hObject->threadEventMessage->handleType == HANDLE_TYPE_EVENT) {
+ CloseHandle(hObject->threadEventMessage);
+ hObject->threadEventMessage = NULL;
+ }
+ hObject->handleType = HANDLE_TYPE_INVALID;
+ hObject->threadId = 0;
+ hObject->threadStartAddress = NULL;
+ hObject->threadParameter = NULL;
+ free(hObject);
+ return TRUE;
+ case HANDLE_TYPE_COM: {
+ SERIAL_LOGD("CloseHandle(hObject: %p) for HANDLE_TYPE_COM", hObject);
- closeSerialPort(hObject->commId);
- hObject->commId = 0;
+ closeSerialPort(hObject->commId);
+ hObject->commId = 0;
- hObject->handleType = HANDLE_TYPE_INVALID;
- if(hObject->commState) {
- free(hObject->commState);
- hObject->commState = NULL;
- }
- if(hObject->commEvent) {
- CloseHandle(hObject->commEvent);
- hObject->commEvent = NULL;
- }
- if(hObject->commIndex != -1) {
- pthread_mutex_lock(&commsLock);
- comms[hObject->commIndex] = NULL;
- pthread_mutex_unlock(&commsLock);
- }
- free(hObject);
- return TRUE;
- }
- default:
- break;
- }
- return FALSE;
+ hObject->handleType = HANDLE_TYPE_INVALID;
+ if (hObject->commState) {
+ free(hObject->commState);
+ hObject->commState = NULL;
+ }
+ if (hObject->commEvent) {
+ CloseHandle(hObject->commEvent);
+ hObject->commEvent = NULL;
+ }
+ if (hObject->commIndex != -1) {
+ pthread_mutex_lock(&commsLock);
+ comms[hObject->commIndex] = NULL;
+ pthread_mutex_unlock(&commsLock);
+ }
+ free(hObject);
+ return TRUE;
+ }
+ default:
+ break;
+ }
+ return FALSE;
}
void Sleep(int ms) {
- if(ms == 0) {
+ if (ms == 0) {
// Because sched_yield() does not seem to work with Android, try to increase the pause duration,
// hoping to switch to the others thread (WorkerThread).
ms = 1;
@@ -868,295 +883,305 @@ void Sleep(int ms) {
}
BOOL QueryPerformanceFrequency(PLARGE_INTEGER l) {
- //https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
- l->QuadPart = 10000000;
- return TRUE;
+ //https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
+ l->QuadPart = 10000000;
+ return TRUE;
}
-BOOL QueryPerformanceCounter(PLARGE_INTEGER l)
-{
- struct timespec /*{
+BOOL QueryPerformanceCounter(PLARGE_INTEGER l) {
+ struct timespec /*{
time_t tv_sec;
long tv_nsec;
} */ time;
- clock_gettime(CLOCK_MONOTONIC, &time);
- l->QuadPart = (uint64_t) ((1e9 * time.tv_sec + time.tv_nsec) / 100);
- return TRUE;
-}
-void InitializeCriticalSection(CRITICAL_SECTION * lpCriticalSection) {
- pthread_mutexattr_t Attr;
- pthread_mutexattr_init(&Attr);
- pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(lpCriticalSection, &Attr);
-}
-void DeleteCriticalSection(CRITICAL_SECTION * lpCriticalSection) {
- pthread_mutex_destroy(lpCriticalSection);
+ clock_gettime(CLOCK_MONOTONIC, &time);
+ l->QuadPart = (uint64_t) ((1e9 * time.tv_sec + time.tv_nsec) / 100);
+ return TRUE;
}
-void EnterCriticalSection(CRITICAL_SECTION *lock)
-{
- pthread_mutex_lock(lock);
+void InitializeCriticalSection(CRITICAL_SECTION *lpCriticalSection) {
+ pthread_mutexattr_t Attr;
+ pthread_mutexattr_init(&Attr);
+ pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(lpCriticalSection, &Attr);
}
-void LeaveCriticalSection(CRITICAL_SECTION *lock)
-{
- pthread_mutex_unlock(lock);
+void DeleteCriticalSection(CRITICAL_SECTION *lpCriticalSection) {
+ pthread_mutex_destroy(lpCriticalSection);
}
-DWORD GetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName) {
- //TODO
+void EnterCriticalSection(CRITICAL_SECTION *lock) {
+ pthread_mutex_lock(lock);
+}
+
+void LeaveCriticalSection(CRITICAL_SECTION *lock) {
+ pthread_mutex_unlock(lock);
+}
+
+DWORD GetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault,
+ LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName) {
+ //TODO
#ifdef UNICODE
- wcsncpy(lpReturnedString, lpDefault, nSize);
+ wcsncpy(lpReturnedString, lpDefault, nSize);
#else
- strncpy(lpReturnedString, lpDefault, nSize);
+ strncpy(lpReturnedString, lpDefault, nSize);
#endif
- return 0;
+ return 0;
}
+
UINT GetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName) {
- //TODO
- return (UINT) nDefault;
+ //TODO
+ return (UINT) nDefault;
}
-BOOL WritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName) {
- //TODO
- return 0;
+
+BOOL WritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString,
+ LPCTSTR lpFileName) {
+ //TODO
+ return 0;
}
HGLOBAL WINAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes) {
- return malloc(dwBytes);
+ return malloc(dwBytes);
}
-LPVOID WINAPI GlobalLock (HGLOBAL hMem) {
- return hMem;
+
+LPVOID WINAPI GlobalLock(HGLOBAL hMem) {
+ return hMem;
}
BOOL WINAPI GlobalUnlock(HGLOBAL hMem) {
- return TRUE;
+ return TRUE;
}
HGLOBAL WINAPI GlobalFree(HGLOBAL hMem) {
- free(hMem);
- return NULL;
+ free(hMem);
+ return NULL;
}
BOOL GetOpenFileName(LPOPENFILENAME openFilename) {
- if(openFilename) {
- if(currentDialogBoxMode == DialogBoxMode_OPEN_MACRO) {
- openFilename->nMaxFile = MAX_PATH;
- openFilename->nFileExtension = 1;
- //openFilename->lpstrFile = getSaveObjectFilenameResult;
- _tcsncpy(openFilename->lpstrFile, getSaveObjectFilenameResult, openFilename->nMaxFile);
- return TRUE;
- }
- }
- return FALSE;
+ if (openFilename) {
+ if (currentDialogBoxMode == DialogBoxMode_OPEN_MACRO) {
+ openFilename->nMaxFile = MAX_PATH;
+ openFilename->nFileExtension = 1;
+ //openFilename->lpstrFile = getSaveObjectFilenameResult;
+ _tcsncpy(openFilename->lpstrFile, getSaveObjectFilenameResult, openFilename->nMaxFile);
+ return TRUE;
+ }
+ }
+ return FALSE;
}
TCHAR getSaveObjectFilenameResult[MAX_PATH];
+
BOOL GetSaveFileName(LPOPENFILENAME openFilename) {
- if(openFilename) {
- if(currentDialogBoxMode == DialogBoxMode_SET_USRPRG32
- || currentDialogBoxMode == DialogBoxMode_SET_USRPRG42
- || currentDialogBoxMode == DialogBoxMode_SAVE_MACRO) {
- openFilename->nMaxFile = MAX_PATH;
- openFilename->nFileExtension = 1;
- //openFilename->lpstrFile = getSaveObjectFilenameResult;
- _tcsncpy(openFilename->lpstrFile, getSaveObjectFilenameResult, openFilename->nMaxFile);
- return TRUE;
- }
- }
- return FALSE;
+ if (openFilename) {
+ if (currentDialogBoxMode == DialogBoxMode_SET_USRPRG32
+ || currentDialogBoxMode == DialogBoxMode_SET_USRPRG42
+ || currentDialogBoxMode == DialogBoxMode_SAVE_MACRO) {
+ openFilename->nMaxFile = MAX_PATH;
+ openFilename->nFileExtension = 1;
+ //openFilename->lpstrFile = getSaveObjectFilenameResult;
+ _tcsncpy(openFilename->lpstrFile, getSaveObjectFilenameResult, openFilename->nMaxFile);
+ return TRUE;
+ }
+ }
+ return FALSE;
}
// Almost the same function as the private core function DibNumColors()
-static __inline WORD DibNumColors(BITMAPINFOHEADER CONST *lpbi)
-{
- if (lpbi->biClrUsed != 0) return (WORD) lpbi->biClrUsed;
+static __inline WORD DibNumColors(BITMAPINFOHEADER CONST *lpbi) {
+ if (lpbi->biClrUsed != 0) return (WORD) lpbi->biClrUsed;
- /* a 24 bitcount DIB has no color table */
- return (lpbi->biBitCount <= 8) ? (1 << lpbi->biBitCount) : 0;
+ /* a 24 bitcount DIB has no color table */
+ return (lpbi->biBitCount <= 8) ? (1 << lpbi->biBitCount) : 0;
}
static HBITMAP DecodeBMPIcon(LPBYTE imageBuffer, size_t imageSize) {
- // size of bitmap header information
- DWORD dwFileSize = sizeof(BITMAPINFOHEADER);
- if (imageSize < dwFileSize)
- return NULL;
+ // size of bitmap header information
+ DWORD dwFileSize = sizeof(BITMAPINFOHEADER);
+ if (imageSize < dwFileSize)
+ return NULL;
- LPBITMAPINFO pBmi = (LPBITMAPINFO)imageBuffer;
+ LPBITMAPINFO pBmi = (LPBITMAPINFO) imageBuffer;
- // size with color table
- if (pBmi->bmiHeader.biCompression == BI_BITFIELDS)
- dwFileSize += 3 * sizeof(DWORD);
- else
- dwFileSize += DibNumColors(&pBmi->bmiHeader) * sizeof(RGBQUAD);
+ // size with color table
+ if (pBmi->bmiHeader.biCompression == BI_BITFIELDS)
+ dwFileSize += 3 * sizeof(DWORD);
+ else
+ dwFileSize += DibNumColors(&pBmi->bmiHeader) * sizeof(RGBQUAD);
- pBmi->bmiHeader.biHeight /= 2;
+ pBmi->bmiHeader.biHeight /= 2;
- DWORD stride = (((pBmi->bmiHeader.biWidth * (DWORD)pBmi->bmiHeader.biBitCount) + 31) / 32 * 4);
- DWORD height = (DWORD) abs(pBmi->bmiHeader.biHeight);
+ DWORD stride = (((pBmi->bmiHeader.biWidth * (DWORD) pBmi->bmiHeader.biBitCount) + 31) / 32 * 4);
+ DWORD height = (DWORD) abs(pBmi->bmiHeader.biHeight);
- // size with bitmap data
- if (pBmi->bmiHeader.biCompression != BI_RGB)
- dwFileSize += pBmi->bmiHeader.biSizeImage;
- else {
- pBmi->bmiHeader.biSizeImage = stride * height;
- dwFileSize += pBmi->bmiHeader.biSizeImage;
- }
- if (imageSize < dwFileSize)
- return NULL;
+ // size with bitmap data
+ if (pBmi->bmiHeader.biCompression != BI_RGB)
+ dwFileSize += pBmi->bmiHeader.biSizeImage;
+ else {
+ pBmi->bmiHeader.biSizeImage = stride * height;
+ dwFileSize += pBmi->bmiHeader.biSizeImage;
+ }
+ if (imageSize < dwFileSize)
+ return NULL;
- HBITMAP hBitmap = CreateDIBitmap(hWindowDC, &pBmi->bmiHeader, CBM_INIT, imageBuffer, pBmi, DIB_RGB_COLORS);
- if(hBitmap) {
- // Inverse the height
- BYTE *source = imageBuffer + dwFileSize - stride;
- BYTE *destination = hBitmap->bitmapBits;
- DWORD width = pBmi->bmiHeader.biWidth;
- for (unsigned int y = 0; y < height; ++y) {
- for (unsigned int x = 0; x < width; ++x) {
- BYTE * sourcePixel = source + (x << 2);
- BYTE * destinationPixel = destination + (x << 2);
- destinationPixel[0] = sourcePixel[2];
- destinationPixel[1] = sourcePixel[1];
- destinationPixel[2] = sourcePixel[0];
- destinationPixel[3] = sourcePixel[3];
- }
- source -= stride;
- destination += stride;
- }
- }
- // Only support 32bits RGBA BMP for now.
- return hBitmap;
+ HBITMAP hBitmap = CreateDIBitmap(hWindowDC, &pBmi->bmiHeader, CBM_INIT, imageBuffer, pBmi,
+ DIB_RGB_COLORS);
+ if (hBitmap) {
+ // Inverse the height
+ BYTE *source = imageBuffer + dwFileSize - stride;
+ BYTE *destination = hBitmap->bitmapBits;
+ DWORD width = pBmi->bmiHeader.biWidth;
+ for (unsigned int y = 0; y < height; ++y) {
+ for (unsigned int x = 0; x < width; ++x) {
+ BYTE *sourcePixel = source + (x << 2);
+ BYTE *destinationPixel = destination + (x << 2);
+ destinationPixel[0] = sourcePixel[2];
+ destinationPixel[1] = sourcePixel[1];
+ destinationPixel[2] = sourcePixel[0];
+ destinationPixel[3] = sourcePixel[3];
+ }
+ source -= stride;
+ destination += stride;
+ }
+ }
+ // Only support 32bits RGBA BMP for now.
+ return hBitmap;
}
static HBITMAP DecodePNGIcon(LPBYTE imageBuffer, size_t imageSize) {
- HBITMAP hBitmap = NULL;
- UINT uWidth,uHeight;
- LPBYTE pbyImage = NULL;
- UINT uError = lodepng_decode_memory(&pbyImage, &uWidth, &uHeight, imageBuffer, imageSize, LCT_RGBA, 8);
- if (uError == 0) {
- BITMAPINFO bmi;
- ZeroMemory(&bmi, sizeof(bmi)); // init bitmap info
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = (LONG) uWidth;
- bmi.bmiHeader.biHeight = (LONG) uHeight;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32; // create a true color DIB
- bmi.bmiHeader.biCompression = BI_RGB;
+ HBITMAP hBitmap = NULL;
+ UINT uWidth, uHeight;
+ LPBYTE pbyImage = NULL;
+ UINT uError = lodepng_decode_memory(&pbyImage, &uWidth, &uHeight, imageBuffer, imageSize,
+ LCT_RGBA, 8);
+ if (uError == 0) {
+ BITMAPINFO bmi;
+ ZeroMemory(&bmi, sizeof(bmi)); // init bitmap info
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = (LONG) uWidth;
+ bmi.bmiHeader.biHeight = (LONG) uHeight;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32; // create a true color DIB
+ bmi.bmiHeader.biCompression = BI_RGB;
- // bitmap dimensions
- LONG stride = (((bmi.bmiHeader.biWidth * bmi.bmiHeader.biBitCount) + 31) / 32 * 4);
- bmi.bmiHeader.biSizeImage = (DWORD) (stride * bmi.bmiHeader.biHeight);
+ // bitmap dimensions
+ LONG stride = (((bmi.bmiHeader.biWidth * bmi.bmiHeader.biBitCount) + 31) / 32 * 4);
+ bmi.bmiHeader.biSizeImage = (DWORD) (stride * bmi.bmiHeader.biHeight);
- // allocate buffer for pixels
- LPBYTE pbyPixels; // BMP buffer
- hBitmap = CreateDIBSection(hWindowDC, &bmi, DIB_RGB_COLORS, (VOID **)&pbyPixels, NULL, 0);
- if (hBitmap)
- memcpy(pbyPixels, pbyImage, bmi.bmiHeader.biSizeImage);
- }
+ // allocate buffer for pixels
+ LPBYTE pbyPixels; // BMP buffer
+ hBitmap = CreateDIBSection(hWindowDC, &bmi, DIB_RGB_COLORS, (VOID **) &pbyPixels, NULL, 0);
+ if (hBitmap)
+ memcpy(pbyPixels, pbyImage, bmi.bmiHeader.biSizeImage);
+ }
- if (pbyImage != NULL)
- free(pbyImage);
- return hBitmap;
+ if (pbyImage != NULL)
+ free(pbyImage);
+ return hBitmap;
}
// ICO (file format) https://en.wikipedia.org/wiki/ICO_(file_format)
// https://docs.microsoft.com/en-us/previous-versions/ms997538(v=msdn.10)
typedef struct {
- WORD idReserved;
- WORD idType;
- WORD idCount;
+ WORD idReserved;
+ WORD idType;
+ WORD idCount;
} ICONDIR, *LPICONDIR;
typedef struct ICONDIRENTRY {
- BYTE bWidth; // Specifies image width in pixels. Can be any number between 0 and 255. Value 0 means image width is 256 pixels.
- BYTE bHeight; // Specifies image height in pixels. Can be any number between 0 and 255. Value 0 means image height is 256 pixels.
- BYTE bColorCount; // Specifies number of colors in the color palette. Should be 0 if the image does not use a color palette.
- BYTE bReserved; // Reserved. Should be 0.
- WORD wPlanes; // In ICO format: Specifies color planes. Should be 0 or 1.
- WORD wBitCount; // In ICO format: Specifies bits per pixel.
- DWORD dwBytesInRes; // Specifies the size of the image's data in bytes
- DWORD dwImageOffset; // Specifies the offset of BMP or PNG data from the beginning of the ICO/CUR file
+ BYTE bWidth; // Specifies image width in pixels. Can be any number between 0 and 255. Value 0 means image width is 256 pixels.
+ BYTE bHeight; // Specifies image height in pixels. Can be any number between 0 and 255. Value 0 means image height is 256 pixels.
+ BYTE bColorCount; // Specifies number of colors in the color palette. Should be 0 if the image does not use a color palette.
+ BYTE bReserved; // Reserved. Should be 0.
+ WORD wPlanes; // In ICO format: Specifies color planes. Should be 0 or 1.
+ WORD wBitCount; // In ICO format: Specifies bits per pixel.
+ DWORD dwBytesInRes; // Specifies the size of the image's data in bytes
+ DWORD dwImageOffset; // Specifies the offset of BMP or PNG data from the beginning of the ICO/CUR file
} ICONDIRENTRY, *LPICONDIRENTRY;
typedef struct {
- BITMAPINFOHEADER icHeader; // DIB header
- RGBQUAD icColors[1]; // Color table
- BYTE icXOR[1]; // DIB bits for XOR mask
- BYTE icAND[1]; // DIB bits for AND mask
+ BITMAPINFOHEADER icHeader; // DIB header
+ RGBQUAD icColors[1]; // Color table
+ BYTE icXOR[1]; // DIB bits for XOR mask
+ BYTE icAND[1]; // DIB bits for AND mask
} ICONIMAGE, *LPICONIMAGE;
HANDLE LoadImage(HINSTANCE hInst, LPCSTR name, UINT type, int cx, int cy, UINT fuLoad) {
- HANDLE hIconFile = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if (hIconFile == INVALID_HANDLE_VALUE)
- return NULL;
+ HANDLE hIconFile = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0,
+ NULL);
+ if (hIconFile == INVALID_HANDLE_VALUE)
+ return NULL;
- ICONDIR fileHeader;
- DWORD nNumberOfBytesToRead = 0;
- if(ReadFile(hIconFile, &fileHeader, sizeof(ICONDIR), &nNumberOfBytesToRead, NULL) == FALSE || sizeof(ICONDIR) != nNumberOfBytesToRead) {
- CloseHandle(hIconFile);
- return NULL;
- }
+ ICONDIR fileHeader;
+ DWORD nNumberOfBytesToRead = 0;
+ if (ReadFile(hIconFile, &fileHeader, sizeof(ICONDIR), &nNumberOfBytesToRead, NULL) == FALSE ||
+ sizeof(ICONDIR) != nNumberOfBytesToRead) {
+ CloseHandle(hIconFile);
+ return NULL;
+ }
- size_t iconsBufferSize = fileHeader.idCount * sizeof(ICONDIRENTRY);
- ICONDIRENTRY * iconHeaderArray = malloc(iconsBufferSize);
- nNumberOfBytesToRead = 0;
- if(ReadFile(hIconFile, iconHeaderArray, iconsBufferSize, &nNumberOfBytesToRead, NULL) == FALSE || iconsBufferSize != nNumberOfBytesToRead) {
- CloseHandle(hIconFile);
- return NULL;
- }
+ size_t iconsBufferSize = fileHeader.idCount * sizeof(ICONDIRENTRY);
+ ICONDIRENTRY *iconHeaderArray = malloc(iconsBufferSize);
+ nNumberOfBytesToRead = 0;
+ if (ReadFile(hIconFile, iconHeaderArray, iconsBufferSize, &nNumberOfBytesToRead, NULL) ==
+ FALSE || iconsBufferSize != nNumberOfBytesToRead) {
+ CloseHandle(hIconFile);
+ return NULL;
+ }
- int maxWidth = -1;
- int maxHeight = -1;
- int maxBitPerPixel = -1;
- int maxIconIndex = -1;
- for (int i = 0; i < fileHeader.idCount; ++i) {
- ICONDIRENTRY * iconHeader = &(iconHeaderArray[i]);
- int width = iconHeader->bWidth == 0 ? 256 : iconHeader->bWidth;
- int height = iconHeader->bHeight == 0 ? 256 : iconHeader->bHeight;
- if(width >= maxWidth && height >= maxHeight && iconHeader->wBitCount > maxBitPerPixel) {
- maxWidth = width;
- maxHeight = height;
- maxBitPerPixel = iconHeader->wBitCount;
- maxIconIndex = i;
- }
- }
- maxIconIndex = 1; // To test BMP
- if(maxIconIndex == -1) {
- CloseHandle(hIconFile);
- return NULL;
- }
+ int maxWidth = -1;
+ int maxHeight = -1;
+ int maxBitPerPixel = -1;
+ int maxIconIndex = -1;
+ for (int i = 0; i < fileHeader.idCount; ++i) {
+ ICONDIRENTRY *iconHeader = &(iconHeaderArray[i]);
+ int width = iconHeader->bWidth == 0 ? 256 : iconHeader->bWidth;
+ int height = iconHeader->bHeight == 0 ? 256 : iconHeader->bHeight;
+ if (width >= maxWidth && height >= maxHeight && iconHeader->wBitCount > maxBitPerPixel) {
+ maxWidth = width;
+ maxHeight = height;
+ maxBitPerPixel = iconHeader->wBitCount;
+ maxIconIndex = i;
+ }
+ }
+ maxIconIndex = 1; // To test BMP
+ if (maxIconIndex == -1) {
+ CloseHandle(hIconFile);
+ return NULL;
+ }
- DWORD dwBytesInRes = iconHeaderArray[maxIconIndex].dwBytesInRes;
- LPBYTE iconBuffer = malloc(dwBytesInRes);
+ DWORD dwBytesInRes = iconHeaderArray[maxIconIndex].dwBytesInRes;
+ LPBYTE iconBuffer = malloc(dwBytesInRes);
- SetFilePointer(hIconFile, iconHeaderArray[maxIconIndex].dwImageOffset, 0, FILE_BEGIN);
- if(ReadFile(hIconFile, iconBuffer, dwBytesInRes, &nNumberOfBytesToRead, NULL) == FALSE || dwBytesInRes != nNumberOfBytesToRead) {
- CloseHandle(hIconFile);
- free(iconHeaderArray);
- free(iconBuffer);
- return NULL;
- }
- CloseHandle(hIconFile);
+ SetFilePointer(hIconFile, iconHeaderArray[maxIconIndex].dwImageOffset, 0, FILE_BEGIN);
+ if (ReadFile(hIconFile, iconBuffer, dwBytesInRes, &nNumberOfBytesToRead, NULL) == FALSE ||
+ dwBytesInRes != nNumberOfBytesToRead) {
+ CloseHandle(hIconFile);
+ free(iconHeaderArray);
+ free(iconBuffer);
+ return NULL;
+ }
+ CloseHandle(hIconFile);
- HBITMAP icon = NULL;
- if (dwBytesInRes >= 8 && memcmp(iconBuffer, "\x89PNG\r\n\x1a\n", 8) == 0)
- // It is a PNG image
- icon = DecodePNGIcon(iconBuffer, dwBytesInRes);
- else
- // It is a BMP image
- icon = DecodeBMPIcon(iconBuffer, dwBytesInRes);
+ HBITMAP icon = NULL;
+ if (dwBytesInRes >= 8 && memcmp(iconBuffer, "\x89PNG\r\n\x1a\n", 8) == 0)
+ // It is a PNG image
+ icon = DecodePNGIcon(iconBuffer, dwBytesInRes);
+ else
+ // It is a BMP image
+ icon = DecodeBMPIcon(iconBuffer, dwBytesInRes);
- free(iconHeaderArray);
- free(iconBuffer);
+ free(iconHeaderArray);
+ free(iconBuffer);
- if(!icon)
- return NULL;
+ if (!icon)
+ return NULL;
- HANDLE handle = malloc(sizeof(struct _HANDLE));
- memset(handle, 0, sizeof(struct _HANDLE));
- handle->handleType = HANDLE_TYPE_ICON;
- handle->icon = icon;
- return handle;
+ HANDLE handle = malloc(sizeof(struct _HANDLE));
+ memset(handle, 0, sizeof(struct _HANDLE));
+ handle->handleType = HANDLE_TYPE_ICON;
+ handle->icon = icon;
+ return handle;
}
@@ -1168,70 +1193,69 @@ int selItemDataCount = 0;
TCHAR labels[MAX_LABEL_SIZE];
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
- //TODO
- if(currentDialogBoxMode == DialogBoxMode_GET_USRPRG32
- || currentDialogBoxMode == DialogBoxMode_GET_USRPRG42
- || currentDialogBoxMode == DialogBoxMode_SET_USRPRG32
- || currentDialogBoxMode == DialogBoxMode_SET_USRPRG42) {
- if (Msg == LB_ADDSTRING && itemDataCount < MAX_ITEMDATA) {
- itemString[itemDataCount] = (TCHAR *)lParam;
- return itemDataCount++;
- } else if (Msg == LB_SETITEMDATA && wParam < MAX_ITEMDATA) {
- itemData[wParam] = lParam;
- } else if (Msg == LB_GETITEMDATA && wParam < MAX_ITEMDATA) {
- return itemData[wParam];
- } else if (Msg == LB_GETCOUNT) {
- return itemDataCount;
- } else if (Msg == LB_GETSELCOUNT) {
- return selItemDataCount;
- } else if (Msg == LB_GETSEL && wParam < itemDataCount && wParam < MAX_ITEMDATA) {
- return selItemDataIndex[wParam];
- }
- }
- if(Msg == WM_SETICON && wParam == ICON_BIG) {
- if(lParam != NULL) {
- HANDLE hIcon = (HANDLE)lParam;
- if(hIcon->handleType == HANDLE_TYPE_ICON && hIcon->icon != NULL) {
- HBITMAP icon = hIcon->icon;
- if(icon && icon->bitmapInfoHeader && icon->bitmapBits)
- setKMLIcon(icon->bitmapInfoHeader->biWidth, icon->bitmapInfoHeader->biHeight, icon->bitmapBits, icon->bitmapInfoHeader->biSizeImage);
- }
- } else {
- setKMLIcon(0, 0, NULL, 0);
- }
- }
- return NULL;
+ //TODO
+ if (currentDialogBoxMode == DialogBoxMode_GET_USRPRG32
+ || currentDialogBoxMode == DialogBoxMode_GET_USRPRG42
+ || currentDialogBoxMode == DialogBoxMode_SET_USRPRG32
+ || currentDialogBoxMode == DialogBoxMode_SET_USRPRG42) {
+ if (Msg == LB_ADDSTRING && itemDataCount < MAX_ITEMDATA) {
+ itemString[itemDataCount] = (TCHAR *) lParam;
+ return itemDataCount++;
+ } else if (Msg == LB_SETITEMDATA && wParam < MAX_ITEMDATA) {
+ itemData[wParam] = lParam;
+ } else if (Msg == LB_GETITEMDATA && wParam < MAX_ITEMDATA) {
+ return itemData[wParam];
+ } else if (Msg == LB_GETCOUNT) {
+ return itemDataCount;
+ } else if (Msg == LB_GETSELCOUNT) {
+ return selItemDataCount;
+ } else if (Msg == LB_GETSEL && wParam < itemDataCount && wParam < MAX_ITEMDATA) {
+ return selItemDataIndex[wParam];
+ }
+ }
+ if (Msg == WM_SETICON && wParam == ICON_BIG) {
+ if (lParam != NULL) {
+ HANDLE hIcon = (HANDLE) lParam;
+ if (hIcon->handleType == HANDLE_TYPE_ICON && hIcon->icon != NULL) {
+ HBITMAP icon = hIcon->icon;
+ if (icon && icon->bitmapInfoHeader && icon->bitmapBits)
+ setKMLIcon(icon->bitmapInfoHeader->biWidth, icon->bitmapInfoHeader->biHeight,
+ icon->bitmapBits, icon->bitmapInfoHeader->biSizeImage);
+ }
+ } else {
+ setKMLIcon(0, 0, NULL, 0);
+ }
+ }
+ return NULL;
}
+
BOOL PostMessage(HWND handleWindow, UINT Msg, WPARAM wParam, LPARAM lParam) {
- //TODO
- if(handleWindow == hWnd && Msg == WM_COMMAND) {
- int menuCommand = (int) ((wParam & 0xffff) - 40000);
- LOGD("Menu Item %d", menuCommand);
- sendMenuItemCommand(menuCommand);
- }
- return NULL;
+ //TODO
+ if (handleWindow == hWnd && Msg == WM_COMMAND) {
+ int menuCommand = (int) ((wParam & 0xffff) - 40000);
+ LOGD("Menu Item %d", menuCommand);
+ sendMenuItemCommand(menuCommand);
+ }
+ return NULL;
}
-int MessageBox(HANDLE h, LPCTSTR szMessage, LPCTSTR title, int flags)
-{
- if(flags & MB_YESNO) {
- return IDOK;
- }
+int MessageBox(HANDLE h, LPCTSTR szMessage, LPCTSTR title, int flags) {
+ if (flags & MB_YESNO) {
+ return IDOK;
+ }
- return showAlert(szMessage, flags);
+ return showAlert(szMessage, flags);
}
-DWORD timeGetTime(void)
-{
- time_t t = time(NULL);
- return (DWORD)(t * 1000);
+DWORD timeGetTime(void) {
+ time_t t = time(NULL);
+ return (DWORD) (t * 1000);
}
-BOOL GetSystemPowerStatus(LPSYSTEM_POWER_STATUS status)
-{
- status->ACLineStatus = AC_LINE_ONLINE;
- return TRUE;
+BOOL GetSystemPowerStatus(LPSYSTEM_POWER_STATUS status) {
+ status->ACLineStatus = AC_LINE_ONLINE;
+ return TRUE;
}
@@ -1240,745 +1264,789 @@ BOOL GetSystemPowerStatus(LPSYSTEM_POWER_STATUS status)
#if defined NEW_WIN32_SOUND_ENGINE
// this callback handler is called every time a buffer finishes playing
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
- WAVE_OUT_LOGD("waveOut bqPlayerCallback()");
+ WAVE_OUT_LOGD("waveOut bqPlayerCallback()");
- HWAVEOUT hwo = context;
- LPWAVEHDR pWaveHeaderNextToRead = NULL;
+ HWAVEOUT hwo = context;
+ LPWAVEHDR pWaveHeaderNextToRead = NULL;
- pthread_mutex_lock(&hwo->audioEngineLock);
- if (hwo->pWaveHeaderNextToRead) {
- pWaveHeaderNextToRead = hwo->pWaveHeaderNextToRead;
- hwo->pWaveHeaderNextToRead = hwo->pWaveHeaderNextToRead->lpNext;
- if(!hwo->pWaveHeaderNextToRead) {
- hwo->pWaveHeaderNextToWrite = NULL;
- }
- }
- pthread_mutex_unlock(&hwo->audioEngineLock);
+ pthread_mutex_lock(&hwo->audioEngineLock);
+ if (hwo->pWaveHeaderNextToRead) {
+ pWaveHeaderNextToRead = hwo->pWaveHeaderNextToRead;
+ hwo->pWaveHeaderNextToRead = hwo->pWaveHeaderNextToRead->lpNext;
+ if(!hwo->pWaveHeaderNextToRead) {
+ hwo->pWaveHeaderNextToWrite = NULL;
+ }
+ }
+ pthread_mutex_unlock(&hwo->audioEngineLock);
- if(pWaveHeaderNextToRead) {
- PostThreadMessage(1, MM_WOM_DONE, hwo, pWaveHeaderNextToRead);
- } else {
- WAVE_OUT_LOGD("waveOut bqPlayerCallback() Nothing to play?");
- }
+ if(pWaveHeaderNextToRead) {
+ PostThreadMessage(1, MM_WOM_DONE, hwo, pWaveHeaderNextToRead);
+ } else {
+ WAVE_OUT_LOGD("waveOut bqPlayerCallback() Nothing to play?");
+ }
- WAVE_OUT_LOGD("bqPlayerCallback() before sem_post() +1");
- sem_post(&hwo->waveOutLock); // Increment
- WAVE_OUT_LOGD("bqPlayerCallback() after sem_post() +1");
+ WAVE_OUT_LOGD("bqPlayerCallback() before sem_post() +1");
+ sem_post(&hwo->waveOutLock); // Increment
+ WAVE_OUT_LOGD("bqPlayerCallback() after sem_post() +1");
}
#else
void onPlayerDone(HWAVEOUT hwo) {
- WAVE_OUT_LOGD("waveOut onPlayerDone()");
- //PostThreadMessage(0, MM_WOM_DONE, hwo, hwo->pWaveHeaderNext);
- // Artificially replace the post message MM_WOM_DONE
- bSoundSlow = FALSE; // no sound slow down
- bEnableSlow = TRUE; // reenable CPU slow down possibility
+ WAVE_OUT_LOGD("waveOut onPlayerDone()");
+ //PostThreadMessage(0, MM_WOM_DONE, hwo, hwo->pWaveHeaderNext);
+ // Artificially replace the post message MM_WOM_DONE
+ bSoundSlow = FALSE; // no sound slow down
+ bEnableSlow = TRUE; // reenable CPU slow down possibility
}
// this callback handler is called every time a buffer finishes playing
void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
- WAVE_OUT_LOGD("waveOut bqPlayerCallback()");
- HWAVEOUT hwo = context;
- if (hwo->pWaveHeaderNext != NULL) {
- LPWAVEHDR pWaveHeaderNext = hwo->pWaveHeaderNext->lpNext;
- free(hwo->pWaveHeaderNext->lpData);
- free(hwo->pWaveHeaderNext);
- hwo->pWaveHeaderNext = pWaveHeaderNext;
- if(pWaveHeaderNext != NULL) {
- WAVE_OUT_LOGD("waveOut bqPlayerCallback() bqPlayerBufferQueue->Enqueue");
- SLresult result = (*hwo->bqPlayerBufferQueue)->Enqueue(hwo->bqPlayerBufferQueue, pWaveHeaderNext->lpData, pWaveHeaderNext->dwBufferLength);
- if (SL_RESULT_SUCCESS != result) {
- WAVE_OUT_LOGD("waveOut bqPlayerCallback() Enqueue Error %d", result);
- onPlayerDone(hwo);
- // Error
- //pthread_mutex_unlock(&hwo->audioEngineLock);
+ WAVE_OUT_LOGD("waveOut bqPlayerCallback()");
+ HWAVEOUT hwo = context;
+ if (hwo->pWaveHeaderNext != NULL) {
+ LPWAVEHDR pWaveHeaderNext = hwo->pWaveHeaderNext->lpNext;
+ free(hwo->pWaveHeaderNext->lpData);
+ free(hwo->pWaveHeaderNext);
+ hwo->pWaveHeaderNext = pWaveHeaderNext;
+ if (pWaveHeaderNext != NULL) {
+ WAVE_OUT_LOGD("waveOut bqPlayerCallback() bqPlayerBufferQueue->Enqueue");
+ SLresult result = (*hwo->bqPlayerBufferQueue)->Enqueue(hwo->bqPlayerBufferQueue,
+ pWaveHeaderNext->lpData,
+ pWaveHeaderNext->dwBufferLength);
+ if (SL_RESULT_SUCCESS != result) {
+ WAVE_OUT_LOGD("waveOut bqPlayerCallback() Enqueue Error %d", result);
+ onPlayerDone(hwo);
+ // Error
+ //pthread_mutex_unlock(&hwo->audioEngineLock);
// return;
- }
+ }
// return;
- } else {
- WAVE_OUT_LOGD("waveOut bqPlayerCallback() Nothing next, so, this is the end");
- onPlayerDone(hwo);
- }
- } else {
- WAVE_OUT_LOGD("waveOut bqPlayerCallback() Nothing to play? So, this is the end");
- onPlayerDone(hwo);
- }
+ } else {
+ WAVE_OUT_LOGD("waveOut bqPlayerCallback() Nothing next, so, this is the end");
+ onPlayerDone(hwo);
+ }
+ } else {
+ WAVE_OUT_LOGD("waveOut bqPlayerCallback() Nothing to play? So, this is the end");
+ onPlayerDone(hwo);
+ }
}
// Timer to replace the missing bqPlayerCallback
void onPlayerDoneTimerCallback(void *context) {
- WAVE_OUT_LOGD("waveOut onPlayerDoneTimerCallback()");
- HWAVEOUT hwo = context;
- onPlayerDone(hwo);
+ WAVE_OUT_LOGD("waveOut onPlayerDoneTimerCallback()");
+ HWAVEOUT hwo = context;
+ onPlayerDone(hwo);
- //TODO May be needed if an attached occurs in the future
- //jniDetachCurrentThread();
+ //TODO May be needed if an attached occurs in the future
+ //jniDetachCurrentThread();
}
#endif
-MMRESULT waveOutOpen(LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) {
- WAVE_OUT_LOGD("waveOutOpen()");
+MMRESULT waveOutOpen(LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback,
+ DWORD_PTR dwInstance, DWORD fdwOpen) {
+ WAVE_OUT_LOGD("waveOutOpen()");
- HWAVEOUT handle = (HWAVEOUT)malloc(sizeof(struct _HWAVEOUT));
- memset(handle, 0, sizeof(struct _HWAVEOUT));
- handle->pwfx = (WAVEFORMATEX *) pwfx;
- handle->uDeviceID = uDeviceID;
+ HWAVEOUT handle = (HWAVEOUT) malloc(sizeof(struct _HWAVEOUT));
+ memset(handle, 0, sizeof(struct _HWAVEOUT));
+ handle->pwfx = (WAVEFORMATEX *) pwfx;
+ handle->uDeviceID = uDeviceID;
- SLresult result;
+ SLresult result;
- // create engine
- result = slCreateEngine(&handle->engineObject, 0, NULL, 0, NULL, NULL);
- //_ASSERT(SL_RESULT_SUCCESS == result);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() slCreateEngine error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // create engine
+ result = slCreateEngine(&handle->engineObject, 0, NULL, 0, NULL, NULL);
+ //_ASSERT(SL_RESULT_SUCCESS == result);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() slCreateEngine error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // realize the engine
- result = (*handle->engineObject)->Realize(handle->engineObject, SL_BOOLEAN_FALSE);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() engineObject->Realize error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // realize the engine
+ result = (*handle->engineObject)->Realize(handle->engineObject, SL_BOOLEAN_FALSE);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() engineObject->Realize error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // get the engine interface, which is needed in order to create other objects
- result = (*handle->engineObject)->GetInterface(handle->engineObject, SL_IID_ENGINE, &handle->engineEngine);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() engineObject->GetInterface error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // get the engine interface, which is needed in order to create other objects
+ result = (*handle->engineObject)->GetInterface(handle->engineObject, SL_IID_ENGINE,
+ &handle->engineEngine);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() engineObject->GetInterface error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // create output mix, with environmental reverb specified as a non-required interface
- const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB };
- const SLboolean req[1] = { SL_BOOLEAN_FALSE };
- result = (*handle->engineEngine)->CreateOutputMix(handle->engineEngine, &handle->outputMixObject, 1, ids, req);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() engineObject->CreateOutputMix error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
- // realize the output mix
- result = (*handle->outputMixObject)->Realize(handle->outputMixObject, SL_BOOLEAN_FALSE);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() outputMixObject->Realize error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
- // configure audio source
- SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
- SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locatorType
+ // create output mix, with environmental reverb specified as a non-required interface
+ const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
+ const SLboolean req[1] = {SL_BOOLEAN_FALSE};
+ result = (*handle->engineEngine)->CreateOutputMix(handle->engineEngine,
+ &handle->outputMixObject, 1, ids, req);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() engineObject->CreateOutputMix error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
+ // realize the output mix
+ result = (*handle->outputMixObject)->Realize(handle->outputMixObject, SL_BOOLEAN_FALSE);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() outputMixObject->Realize error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
+ // configure audio source
+ SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
+ SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locatorType
#if defined NEW_WIN32_SOUND_ENGINE
- //1 // numBuffers
- //2 // numBuffers
- 20 // numBuffers
+ //1 // numBuffers
+ //2 // numBuffers
+ 20 // numBuffers
#else
- 20 // numBuffers
+ 20 // numBuffers
#endif
- };
- SLDataFormat_PCM format_pcm = {
- SL_DATAFORMAT_PCM, // formatType
- 1, // numChannels
- SL_SAMPLINGRATE_8, // samplesPerSec
- SL_PCMSAMPLEFORMAT_FIXED_16, // bitsPerSample
- SL_PCMSAMPLEFORMAT_FIXED_16, // containerSize
- SL_SPEAKER_FRONT_CENTER, // channelMask
- SL_BYTEORDER_LITTLEENDIAN // endianness
- };
- /*
- * Enable Fast Audio when possible: once we set the same rate to be the native, fast audio path
- * will be triggered
- */
- format_pcm.samplesPerSec = pwfx->nSamplesPerSec * 1000; //sample rate in mili second
- format_pcm.bitsPerSample = pwfx->wBitsPerSample;
- format_pcm.containerSize = pwfx->wBitsPerSample;
- format_pcm.numChannels = pwfx->nChannels;
+ };
+ SLDataFormat_PCM format_pcm = {
+ SL_DATAFORMAT_PCM, // formatType
+ 1, // numChannels
+ SL_SAMPLINGRATE_8, // samplesPerSec
+ SL_PCMSAMPLEFORMAT_FIXED_16, // bitsPerSample
+ SL_PCMSAMPLEFORMAT_FIXED_16, // containerSize
+ SL_SPEAKER_FRONT_CENTER, // channelMask
+ SL_BYTEORDER_LITTLEENDIAN // endianness
+ };
+ /*
+ * Enable Fast Audio when possible: once we set the same rate to be the native, fast audio path
+ * will be triggered
+ */
+ format_pcm.samplesPerSec = pwfx->nSamplesPerSec * 1000; //sample rate in mili second
+ format_pcm.bitsPerSample = pwfx->wBitsPerSample;
+ format_pcm.containerSize = pwfx->wBitsPerSample;
+ format_pcm.numChannels = pwfx->nChannels;
- SLDataSource audioSrc = {
- &loc_bufq, // pLocator
- &format_pcm // pFormat
- };
+ SLDataSource audioSrc = {
+ &loc_bufq, // pLocator
+ &format_pcm // pFormat
+ };
- // configure audio sink
- SLDataLocator_OutputMix loc_outmix = {
- SL_DATALOCATOR_OUTPUTMIX, // locatorType
- handle->outputMixObject // outputMix
- };
- SLDataSink audioSnk = {
- &loc_outmix, // pLocator
- NULL // pFormat
- };
+ // configure audio sink
+ SLDataLocator_OutputMix loc_outmix = {
+ SL_DATALOCATOR_OUTPUTMIX, // locatorType
+ handle->outputMixObject // outputMix
+ };
+ SLDataSink audioSnk = {
+ &loc_outmix, // pLocator
+ NULL // pFormat
+ };
- /*
- * create audio player:
- * fast audio does not support when SL_IID_EFFECTSEND is required, skip it
- * for fast audio case
- */
- const SLInterfaceID ids2[3] = {
- SL_IID_BUFFERQUEUE,
- SL_IID_VOLUME,
- //SL_IID_EFFECTSEND,
- //SL_IID_MUTESOLO,
- };
- const SLboolean req2[3] = {
- SL_BOOLEAN_TRUE,
- SL_BOOLEAN_TRUE,
- //SL_BOOLEAN_TRUE,
- //SL_BOOLEAN_TRUE,
- };
+ /*
+ * create audio player:
+ * fast audio does not support when SL_IID_EFFECTSEND is required, skip it
+ * for fast audio case
+ */
+ const SLInterfaceID ids2[3] = {
+ SL_IID_BUFFERQUEUE,
+ SL_IID_VOLUME,
+ //SL_IID_EFFECTSEND,
+ //SL_IID_MUTESOLO,
+ };
+ const SLboolean req2[3] = {
+ SL_BOOLEAN_TRUE,
+ SL_BOOLEAN_TRUE,
+ //SL_BOOLEAN_TRUE,
+ //SL_BOOLEAN_TRUE,
+ };
- result = (*handle->engineEngine)->CreateAudioPlayer(handle->engineEngine, &handle->bqPlayerObject, &audioSrc, &audioSnk, 2, ids2, req2);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() engineEngine->CreateAudioPlayer error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ result = (*handle->engineEngine)->CreateAudioPlayer(handle->engineEngine,
+ &handle->bqPlayerObject, &audioSrc,
+ &audioSnk, 2, ids2, req2);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() engineEngine->CreateAudioPlayer error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // realize the player
- result = (*handle->bqPlayerObject)->Realize(handle->bqPlayerObject, SL_BOOLEAN_FALSE);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->Realize error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // realize the player
+ result = (*handle->bqPlayerObject)->Realize(handle->bqPlayerObject, SL_BOOLEAN_FALSE);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->Realize error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // get the play interface
- result = (*handle->bqPlayerObject)->GetInterface(handle->bqPlayerObject, SL_IID_PLAY, &handle->bqPlayerPlay);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->GetInterface SL_IID_PLAY error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // get the play interface
+ result = (*handle->bqPlayerObject)->GetInterface(handle->bqPlayerObject, SL_IID_PLAY,
+ &handle->bqPlayerPlay);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->GetInterface SL_IID_PLAY error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // get the buffer queue interface
- result = (*handle->bqPlayerObject)->GetInterface(handle->bqPlayerObject, SL_IID_BUFFERQUEUE, &handle->bqPlayerBufferQueue);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->GetInterface SL_IID_BUFFERQUEUE error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // get the buffer queue interface
+ result = (*handle->bqPlayerObject)->GetInterface(handle->bqPlayerObject, SL_IID_BUFFERQUEUE,
+ &handle->bqPlayerBufferQueue);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->GetInterface SL_IID_BUFFERQUEUE error: %d",
+ result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // register callback on the buffer queue
- result = (*handle->bqPlayerBufferQueue)->RegisterCallback(handle->bqPlayerBufferQueue, bqPlayerCallback, handle);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() bqPlayerBufferQueue->RegisterCallback error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // register callback on the buffer queue
+ result = (*handle->bqPlayerBufferQueue)->RegisterCallback(handle->bqPlayerBufferQueue,
+ bqPlayerCallback, handle);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() bqPlayerBufferQueue->RegisterCallback error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // get the volume interface
- result = (*handle->bqPlayerObject)->GetInterface(handle->bqPlayerObject, SL_IID_VOLUME, &handle->bqPlayerVolume);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->GetInterface SL_IID_VOLUME error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // get the volume interface
+ result = (*handle->bqPlayerObject)->GetInterface(handle->bqPlayerObject, SL_IID_VOLUME,
+ &handle->bqPlayerVolume);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->GetInterface SL_IID_VOLUME error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
- // set the player's state to playing
- result = (*handle->bqPlayerPlay)->SetPlayState(handle->bqPlayerPlay, SL_PLAYSTATE_PLAYING);
- if(result != SL_RESULT_SUCCESS) {
- WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->SetPlayState error: %d", result);
- waveOutClose(handle);
- return MMSYSERR_ERROR;
- }
+ // set the player's state to playing
+ result = (*handle->bqPlayerPlay)->SetPlayState(handle->bqPlayerPlay, SL_PLAYSTATE_PLAYING);
+ if (result != SL_RESULT_SUCCESS) {
+ WAVE_OUT_LOGD("waveOutOpen() bqPlayerObject->SetPlayState error: %d", result);
+ waveOutClose(handle);
+ return MMSYSERR_ERROR;
+ }
#if defined NEW_WIN32_SOUND_ENGINE
- sem_init(&handle->waveOutLock, 0, 1);
+ sem_init(&handle->waveOutLock, 0, 1);
#else
- struct sigevent sev;
- sev.sigev_notify = SIGEV_THREAD;
- sev.sigev_notify_function = (void (*)(sigval_t)) onPlayerDoneTimerCallback; //this function will be called when timer expires
- sev.sigev_value.sival_ptr = handle; //this argument will be passed to cbf
- sev.sigev_notify_attributes = NULL;
- timer_t * timer = &(handle->playerDoneTimer);
- if (timer_create(CLOCK_MONOTONIC, &sev, timer) == -1) {
- WAVE_OUT_LOGD("waveOutOpen() ERROR in timer_create");
- return NULL;
- }
+ struct sigevent sev;
+ sev.sigev_notify = SIGEV_THREAD;
+ sev.sigev_notify_function = (void (*)(
+ sigval_t)) onPlayerDoneTimerCallback; //this function will be called when timer expires
+ sev.sigev_value.sival_ptr = handle; //this argument will be passed to cbf
+ sev.sigev_notify_attributes = NULL;
+ timer_t *timer = &(handle->playerDoneTimer);
+ if (timer_create(CLOCK_MONOTONIC, &sev, timer) == -1) {
+ WAVE_OUT_LOGD("waveOutOpen() ERROR in timer_create");
+ return NULL;
+ }
- long delayInMilliseconds = 1000; // msecs
- handle->playerDoneTimerSetTimes.it_value.tv_sec = delayInMilliseconds / 1000;
- handle->playerDoneTimerSetTimes.it_value.tv_nsec = (delayInMilliseconds % 1000) * 1000000;
- handle->playerDoneTimerSetTimes.it_interval.tv_sec = 0;
- handle->playerDoneTimerSetTimes.it_interval.tv_nsec = 0;
+ long delayInMilliseconds = 1000; // msecs
+ handle->playerDoneTimerSetTimes.it_value.tv_sec = delayInMilliseconds / 1000;
+ handle->playerDoneTimerSetTimes.it_value.tv_nsec = (delayInMilliseconds % 1000) * 1000000;
+ handle->playerDoneTimerSetTimes.it_interval.tv_sec = 0;
+ handle->playerDoneTimerSetTimes.it_interval.tv_nsec = 0;
#endif
- *phwo = handle;
- return MMSYSERR_NOERROR;
+ *phwo = handle;
+ return MMSYSERR_NOERROR;
}
MMRESULT waveOutReset(HWAVEOUT hwo) {
- WAVE_OUT_LOGD("waveOutReset()");
- //TODO
- return 0;
+ WAVE_OUT_LOGD("waveOutReset()");
+ //TODO
+ return 0;
}
MMRESULT waveOutClose(HWAVEOUT handle) {
- WAVE_OUT_LOGD("waveOutClose()");
+ WAVE_OUT_LOGD("waveOutClose()");
- // destroy buffer queue audio player object, and invalidate all associated interfaces
- if (handle->bqPlayerObject != NULL) {
- (*handle->bqPlayerObject)->Destroy(handle->bqPlayerObject);
- handle->bqPlayerObject = NULL;
- handle->bqPlayerPlay = NULL;
- handle->bqPlayerBufferQueue = NULL;
- handle->bqPlayerVolume = NULL;
- }
+ // destroy buffer queue audio player object, and invalidate all associated interfaces
+ if (handle->bqPlayerObject != NULL) {
+ (*handle->bqPlayerObject)->Destroy(handle->bqPlayerObject);
+ handle->bqPlayerObject = NULL;
+ handle->bqPlayerPlay = NULL;
+ handle->bqPlayerBufferQueue = NULL;
+ handle->bqPlayerVolume = NULL;
+ }
- // destroy output mix object, and invalidate all associated interfaces
- if (handle->outputMixObject != NULL) {
- (*handle->outputMixObject)->Destroy(handle->outputMixObject);
- handle->outputMixObject = NULL;
- }
+ // destroy output mix object, and invalidate all associated interfaces
+ if (handle->outputMixObject != NULL) {
+ (*handle->outputMixObject)->Destroy(handle->outputMixObject);
+ handle->outputMixObject = NULL;
+ }
- // destroy engine object, and invalidate all associated interfaces
- if (handle->engineObject != NULL) {
- (*handle->engineObject)->Destroy(handle->engineObject);
- handle->engineObject = NULL;
- handle->engineEngine = NULL;
- }
+ // destroy engine object, and invalidate all associated interfaces
+ if (handle->engineObject != NULL) {
+ (*handle->engineObject)->Destroy(handle->engineObject);
+ handle->engineObject = NULL;
+ handle->engineEngine = NULL;
+ }
- pthread_mutex_destroy(&handle->audioEngineLock);
+ pthread_mutex_destroy(&handle->audioEngineLock);
#if defined NEW_WIN32_SOUND_ENGINE
- sem_destroy(&handle->waveOutLock);
+ sem_destroy(&handle->waveOutLock);
#else
- onPlayerDone(handle);
- if(handle->playerDoneTimer)
- timer_delete(handle->playerDoneTimer);
+ onPlayerDone(handle);
+ if (handle->playerDoneTimer)
+ timer_delete(handle->playerDoneTimer);
#endif
- memset(handle, 0, sizeof(struct _HWAVEOUT));
- free(handle);
- return 0;
+ memset(handle, 0, sizeof(struct _HWAVEOUT));
+ free(handle);
+ return 0;
}
MMRESULT waveOutPrepareHeader(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) {
- WAVE_OUT_LOGD("waveOutPrepareHeader()");
- //TODO
- return 0;
+ WAVE_OUT_LOGD("waveOutPrepareHeader()");
+ //TODO
+ return 0;
}
MMRESULT waveOutUnprepareHeader(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) {
- WAVE_OUT_LOGD("waveOutUnprepareHeader()");
- //TODO
- return 0;
+ WAVE_OUT_LOGD("waveOutUnprepareHeader()");
+ //TODO
+ return 0;
}
MMRESULT waveOutWrite(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) {
- WAVE_OUT_LOGD("waveOutWrite()");
+ WAVE_OUT_LOGD("waveOutWrite()");
#if defined NEW_WIN32_SOUND_ENGINE
- WAVE_OUT_LOGD("waveOutWrite() before sem_wait() -1");
- sem_wait(&hwo->waveOutLock); // Decrement, lock if 0
- WAVE_OUT_LOGD("waveOutWrite() after sem_wait() -1");
+ WAVE_OUT_LOGD("waveOutWrite() before sem_wait() -1");
+ sem_wait(&hwo->waveOutLock); // Decrement, lock if 0
+ WAVE_OUT_LOGD("waveOutWrite() after sem_wait() -1");
- LPWAVEHDR pWaveHeaderNextToWriteBackup = hwo->pWaveHeaderNextToWrite;
+ LPWAVEHDR pWaveHeaderNextToWriteBackup = hwo->pWaveHeaderNextToWrite;
- pthread_mutex_lock(&hwo->audioEngineLock);
- if(hwo->pWaveHeaderNextToWrite) {
- hwo->pWaveHeaderNextToWrite->lpNext = pwh;
- } else {
- hwo->pWaveHeaderNextToRead = pwh;
- }
- hwo->pWaveHeaderNextToWrite = pwh;
- pwh->lpNext = NULL;
- pthread_mutex_unlock(&hwo->audioEngineLock);
+ pthread_mutex_lock(&hwo->audioEngineLock);
+ if(hwo->pWaveHeaderNextToWrite) {
+ hwo->pWaveHeaderNextToWrite->lpNext = pwh;
+ } else {
+ hwo->pWaveHeaderNextToRead = pwh;
+ }
+ hwo->pWaveHeaderNextToWrite = pwh;
+ pwh->lpNext = NULL;
+ pthread_mutex_unlock(&hwo->audioEngineLock);
- WAVE_OUT_LOGD("waveOutWrite() bqPlayerBufferQueue->Enqueue() play right now");
- SLresult result = (*hwo->bqPlayerBufferQueue)->Enqueue(hwo->bqPlayerBufferQueue, pwh->lpData, pwh->dwBufferLength);
- if (SL_RESULT_SUCCESS != result) {
- WAVE_OUT_LOGD("waveOutWrite() bqPlayerBufferQueue->Enqueue() error: %d (SL_RESULT_BUFFER_INSUFFICIENT=7)", result);
+ WAVE_OUT_LOGD("waveOutWrite() bqPlayerBufferQueue->Enqueue() play right now");
+ SLresult result = (*hwo->bqPlayerBufferQueue)->Enqueue(hwo->bqPlayerBufferQueue, pwh->lpData, pwh->dwBufferLength);
+ if (SL_RESULT_SUCCESS != result) {
+ WAVE_OUT_LOGD("waveOutWrite() bqPlayerBufferQueue->Enqueue() error: %d (SL_RESULT_BUFFER_INSUFFICIENT=7)", result);
- pthread_mutex_lock(&hwo->audioEngineLock);
- if(pWaveHeaderNextToWriteBackup) {
- hwo->pWaveHeaderNextToWrite = pWaveHeaderNextToWriteBackup;
- hwo->pWaveHeaderNextToWrite->lpNext = NULL;
- if(hwo->pWaveHeaderNextToRead == pwh) {
- hwo->pWaveHeaderNextToRead = pWaveHeaderNextToWriteBackup;
- }
- } else {
- hwo->pWaveHeaderNextToWrite = NULL;
- hwo->pWaveHeaderNextToRead = NULL;
- }
- pthread_mutex_unlock(&hwo->audioEngineLock);
+ pthread_mutex_lock(&hwo->audioEngineLock);
+ if(pWaveHeaderNextToWriteBackup) {
+ hwo->pWaveHeaderNextToWrite = pWaveHeaderNextToWriteBackup;
+ hwo->pWaveHeaderNextToWrite->lpNext = NULL;
+ if(hwo->pWaveHeaderNextToRead == pwh) {
+ hwo->pWaveHeaderNextToRead = pWaveHeaderNextToWriteBackup;
+ }
+ } else {
+ hwo->pWaveHeaderNextToWrite = NULL;
+ hwo->pWaveHeaderNextToRead = NULL;
+ }
+ pthread_mutex_unlock(&hwo->audioEngineLock);
- PostThreadMessage(1, MM_WOM_DONE, hwo, pwh);
+ PostThreadMessage(1, MM_WOM_DONE, hwo, pwh);
- return MMSYSERR_ERROR;
- }
+ return MMSYSERR_ERROR;
+ }
#else
- pwh->lpNext = NULL;
- if(hwo->pWaveHeaderNext == NULL) {
- hwo->pWaveHeaderNext = pwh;
- WAVE_OUT_LOGD("waveOutWrite() bqPlayerBufferQueue->Enqueue() play right now");
- SLresult result = (*hwo->bqPlayerBufferQueue)->Enqueue(hwo->bqPlayerBufferQueue, pwh->lpData, pwh->dwBufferLength);
- if (SL_RESULT_SUCCESS != result) {
- WAVE_OUT_LOGD("waveOutWrite() bqPlayerBufferQueue->Enqueue() error: %d (SL_RESULT_BUFFER_INSUFFICIENT=7)", result);
- //onPlayerDone(hwo);
- //pthread_mutex_unlock(&hwo->audioEngineLock);
- return MMSYSERR_ERROR;
- }
- } else {
- LPWAVEHDR pWaveHeaderNext = hwo->pWaveHeaderNext;
- while (pWaveHeaderNext->lpNext)
- pWaveHeaderNext = pWaveHeaderNext->lpNext;
- WAVE_OUT_LOGD("waveOutWrite() play when finishing the current one");
- pWaveHeaderNext->lpNext = pwh;
- }
+ pwh->lpNext = NULL;
+ if (hwo->pWaveHeaderNext == NULL) {
+ hwo->pWaveHeaderNext = pwh;
+ WAVE_OUT_LOGD("waveOutWrite() bqPlayerBufferQueue->Enqueue() play right now");
+ SLresult result = (*hwo->bqPlayerBufferQueue)->Enqueue(hwo->bqPlayerBufferQueue,
+ pwh->lpData, pwh->dwBufferLength);
+ if (SL_RESULT_SUCCESS != result) {
+ WAVE_OUT_LOGD(
+ "waveOutWrite() bqPlayerBufferQueue->Enqueue() error: %d (SL_RESULT_BUFFER_INSUFFICIENT=7)",
+ result);
+ //onPlayerDone(hwo);
+ //pthread_mutex_unlock(&hwo->audioEngineLock);
+ return MMSYSERR_ERROR;
+ }
+ } else {
+ LPWAVEHDR pWaveHeaderNext = hwo->pWaveHeaderNext;
+ while (pWaveHeaderNext->lpNext)
+ pWaveHeaderNext = pWaveHeaderNext->lpNext;
+ WAVE_OUT_LOGD("waveOutWrite() play when finishing the current one");
+ pWaveHeaderNext->lpNext = pwh;
+ }
- if (timer_settime(hwo->playerDoneTimer, 0, &(hwo->playerDoneTimerSetTimes), NULL) == -1) {
- WAVE_OUT_LOGD("waveOutWrite() ERROR in timer_settime (playerDoneTimerSetTimes)");
- }
+ if (timer_settime(hwo->playerDoneTimer, 0, &(hwo->playerDoneTimerSetTimes), NULL) == -1) {
+ WAVE_OUT_LOGD("waveOutWrite() ERROR in timer_settime (playerDoneTimerSetTimes)");
+ }
#endif
- return MMSYSERR_NOERROR;
+ return MMSYSERR_NOERROR;
}
MMRESULT waveOutGetDevCaps(UINT_PTR uDeviceID, LPWAVEOUTCAPS pwoc, UINT cbwoc) {
- WAVE_OUT_LOGD("waveOutGetDevCaps()");
- if(pwoc) {
- pwoc->dwFormats = WAVE_FORMAT_4M08;
- }
- return MMSYSERR_NOERROR;
+ WAVE_OUT_LOGD("waveOutGetDevCaps()");
+ if (pwoc) {
+ pwoc->dwFormats = WAVE_FORMAT_4M08;
+ }
+ return MMSYSERR_NOERROR;
}
MMRESULT waveOutGetID(HWAVEOUT hwo, LPUINT puDeviceID) {
- WAVE_OUT_LOGD("waveOutGetID()");
- //TODO
- return 0;
+ WAVE_OUT_LOGD("waveOutGetID()");
+ //TODO
+ return 0;
}
-
-
BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) {
#if defined NEW_WIN32_SOUND_ENGINE
- pthread_t thId = pthread_self();
- for(int i = 0; i < MAX_CREATED_THREAD; i++) {
- HANDLE threadHandle = threads[i];
- if(threadHandle && threadHandle->threadId == thId) {
- WaitForSingleObject(threadHandle->threadEventMessage, INFINITE);
- if(lpMsg)
- memcpy(lpMsg, &threadHandle->threadMessage, sizeof(MSG));
- if(lpMsg->message == WM_QUIT)
- return FALSE;
- return TRUE;
- }
- }
+ pthread_t thId = pthread_self();
+ for(int i = 0; i < MAX_CREATED_THREAD; i++) {
+ HANDLE threadHandle = threads[i];
+ if(threadHandle && threadHandle->threadId == thId) {
+ WaitForSingleObject(threadHandle->threadEventMessage, INFINITE);
+ if(lpMsg)
+ memcpy(lpMsg, &threadHandle->threadMessage, sizeof(MSG));
+ if(lpMsg->message == WM_QUIT)
+ return FALSE;
+ return TRUE;
+ }
+ }
- return FALSE;
+ return FALSE;
#else
- return FALSE;
+ return FALSE;
#endif
}
BOOL PostThreadMessage(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam) {
- WAVE_OUT_LOGD("waveOut PostThreadMessage()");
+ WAVE_OUT_LOGD("waveOut PostThreadMessage()");
#if defined NEW_WIN32_SOUND_ENGINE
- for(int i = 0; i < MAX_CREATED_THREAD; i++) {
- HANDLE threadHandle = threads[i];
- if(threadHandle && threadHandle->threadIndex == idThread) {
- threadHandle->threadMessage.hwnd = NULL;
- threadHandle->threadMessage.message = Msg;
- threadHandle->threadMessage.wParam = wParam;
- threadHandle->threadMessage.lParam = lParam;
- WAVE_OUT_LOGD("waveOut SetEvent()");
- SetEvent(threadHandle->threadEventMessage);
- return TRUE;
- }
- }
- return TRUE;
- //return FALSE;
+ for(int i = 0; i < MAX_CREATED_THREAD; i++) {
+ HANDLE threadHandle = threads[i];
+ if(threadHandle && threadHandle->threadIndex == idThread) {
+ threadHandle->threadMessage.hwnd = NULL;
+ threadHandle->threadMessage.message = Msg;
+ threadHandle->threadMessage.wParam = wParam;
+ threadHandle->threadMessage.lParam = lParam;
+ WAVE_OUT_LOGD("waveOut SetEvent()");
+ SetEvent(threadHandle->threadEventMessage);
+ return TRUE;
+ }
+ }
+ return TRUE;
+ //return FALSE;
#else
- return TRUE;
+ return TRUE;
#endif
}
HWND CreateWindow() {
- HANDLE handle = malloc(sizeof(struct _HANDLE));
- memset(handle, 0, sizeof(struct _HANDLE));
- handle->handleType = HANDLE_TYPE_WINDOW;
- handle->windowDC = CreateCompatibleDC(NULL);
- return handle;
+ HANDLE handle = malloc(sizeof(struct _HANDLE));
+ memset(handle, 0, sizeof(struct _HANDLE));
+ handle->handleType = HANDLE_TYPE_WINDOW;
+ handle->windowDC = CreateCompatibleDC(NULL);
+ return handle;
}
BOOL DestroyWindow(HWND hWnd) {
- memset(hWnd, 0, sizeof(struct _HANDLE));
- free(hWnd);
- return TRUE;
+ memset(hWnd, 0, sizeof(struct _HANDLE));
+ free(hWnd);
+ return TRUE;
}
BOOL GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT *lpwndpl) {
- if(lpwndpl) {
- lpwndpl->rcNormalPosition.left = 0;
- lpwndpl->rcNormalPosition.top = 0;
- }
- return TRUE;
+ if (lpwndpl) {
+ lpwndpl->rcNormalPosition.left = 0;
+ lpwndpl->rcNormalPosition.top = 0;
+ }
+ return TRUE;
}
-BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl) { return 0; }
-extern void draw();
-BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase) {
- // Update when switch the screen off
- draw(); //TODO Need a true WM_PAINT event!
- return 0;
-}
-BOOL AdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu) { return 0; }
-LONG GetWindowLong(HWND hWnd, int nIndex) { return 0; }
-HMENU GetMenu(HWND hWnd) { return NULL; }
-int GetMenuItemCount(HMENU hMenu) { return 0; }
-UINT GetMenuItemID(HMENU hMenu, int nPos) { return 0; }
-HMENU GetSubMenu(HMENU hMenu, int nPos) { return NULL; }
-int GetMenuString(HMENU hMenu, UINT uIDItem, LPTSTR lpString,int cchMax, UINT flags) { return 0; }
-BOOL DeleteMenu(HMENU hMenu, UINT uPosition, UINT uFlags) { return FALSE; }
-BOOL InsertMenu(HMENU hMenu, UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR lpNewItem) { return FALSE; }
-BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) { return 0; }
+BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl) { return 0; }
+
+extern void draw();
+
+BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase) {
+ // Update when switch the screen off
+ draw(); //TODO Need a true WM_PAINT event!
+ return 0;
+}
+
+BOOL AdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu) { return 0; }
+
+LONG GetWindowLong(HWND hWnd, int nIndex) { return 0; }
+
+HMENU GetMenu(HWND hWnd) { return NULL; }
+
+int GetMenuItemCount(HMENU hMenu) { return 0; }
+
+UINT GetMenuItemID(HMENU hMenu, int nPos) { return 0; }
+
+HMENU GetSubMenu(HMENU hMenu, int nPos) { return NULL; }
+
+int GetMenuString(HMENU hMenu, UINT uIDItem, LPTSTR lpString, int cchMax, UINT flags) { return 0; }
+
+BOOL DeleteMenu(HMENU hMenu, UINT uPosition, UINT uFlags) { return FALSE; }
+
+BOOL InsertMenu(HMENU hMenu, UINT uPosition, UINT uFlags, UINT_PTR uIDNewItem,
+ LPCTSTR lpNewItem) { return FALSE; }
+
+BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy,
+ UINT uFlags) { return 0; }
BOOL WINAPI SetWindowOrgEx(HDC hdc, int x, int y, LPPOINT lppt) {
- if(lppt) {
- lppt->x = hdc->windowOriginX;
- lppt->y = hdc->windowOriginY;
- }
- hdc->windowOriginX = x;
- hdc->windowOriginY = y;
- return TRUE;
+ if (lppt) {
+ lppt->x = hdc->windowOriginX;
+ lppt->y = hdc->windowOriginY;
+ }
+ hdc->windowOriginX = x;
+ hdc->windowOriginY = y;
+ return TRUE;
}
// GDI
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h) {
- if(h) {
- switch (h->handleType) {
- case HGDIOBJ_TYPE_PEN:
- break;
- case HGDIOBJ_TYPE_BRUSH: {
- HBRUSH oldSelectedBrushColor = hdc->selectedBrushColor;
- hdc->selectedBrushColor = h;
- return oldSelectedBrushColor;
- }
- case HGDIOBJ_TYPE_FONT:
- break;
- case HGDIOBJ_TYPE_BITMAP: {
- HBITMAP oldSelectedBitmap = hdc->selectedBitmap;
- hdc->selectedBitmap = h;
- return oldSelectedBitmap;
- }
- case HGDIOBJ_TYPE_REGION:
- break;
- case HGDIOBJ_TYPE_PALETTE: {
- HPALETTE oldSelectedPalette = hdc->selectedPalette;
- hdc->selectedPalette = h;
- return oldSelectedPalette;
- }
- default:
- break;
- }
- }
- return NULL;
+ if (h) {
+ switch (h->handleType) {
+ case HGDIOBJ_TYPE_PEN:
+ break;
+ case HGDIOBJ_TYPE_BRUSH: {
+ HBRUSH oldSelectedBrushColor = hdc->selectedBrushColor;
+ hdc->selectedBrushColor = h;
+ return oldSelectedBrushColor;
+ }
+ case HGDIOBJ_TYPE_FONT:
+ break;
+ case HGDIOBJ_TYPE_BITMAP: {
+ HBITMAP oldSelectedBitmap = hdc->selectedBitmap;
+ hdc->selectedBitmap = h;
+ return oldSelectedBitmap;
+ }
+ case HGDIOBJ_TYPE_REGION:
+ break;
+ case HGDIOBJ_TYPE_PALETTE: {
+ HPALETTE oldSelectedPalette = hdc->selectedPalette;
+ hdc->selectedPalette = h;
+ return oldSelectedPalette;
+ }
+ default:
+ break;
+ }
+ }
+ return NULL;
}
+
int GetObject(HGDIOBJ h, int c, LPVOID pv) {
- if(h) {
- switch (h->handleType) {
- case HGDIOBJ_TYPE_PEN:
- break;
- case HGDIOBJ_TYPE_BRUSH:
- break;
- case HGDIOBJ_TYPE_FONT:
- break;
- case HGDIOBJ_TYPE_BITMAP:
- if(h && c == sizeof(BITMAP) && pv) {
- BITMAP * pBITMAP = (BITMAP *)pv;
- HBITMAP hBITMAP = (HBITMAP)h;
- pBITMAP->bmType = 0;
- pBITMAP->bmWidth = hBITMAP->bitmapInfoHeader->biWidth;
- pBITMAP->bmHeight = hBITMAP->bitmapInfoHeader->biWidth;
- pBITMAP->bmWidthBytes = (4 * ((hBITMAP->bitmapInfoHeader->biWidth * hBITMAP->bitmapInfoHeader->biBitCount + 31) / 32));
- pBITMAP->bmPlanes = hBITMAP->bitmapInfoHeader->biPlanes;
- pBITMAP->bmBitsPixel = hBITMAP->bitmapInfoHeader->biBitCount;
- pBITMAP->bmBits = (LPVOID)hBITMAP->bitmapBits;
- return sizeof(BITMAP);
- }
- break;
- case HGDIOBJ_TYPE_REGION:
- break;
- case HGDIOBJ_TYPE_PALETTE:
- break;
- default:
- break;
- }
- } return 0;
+ if (h) {
+ switch (h->handleType) {
+ case HGDIOBJ_TYPE_PEN:
+ break;
+ case HGDIOBJ_TYPE_BRUSH:
+ break;
+ case HGDIOBJ_TYPE_FONT:
+ break;
+ case HGDIOBJ_TYPE_BITMAP:
+ if (h && c == sizeof(BITMAP) && pv) {
+ BITMAP *pBITMAP = (BITMAP *) pv;
+ HBITMAP hBITMAP = (HBITMAP) h;
+ pBITMAP->bmType = 0;
+ pBITMAP->bmWidth = hBITMAP->bitmapInfoHeader->biWidth;
+ pBITMAP->bmHeight = hBITMAP->bitmapInfoHeader->biWidth;
+ pBITMAP->bmWidthBytes = (4 * ((hBITMAP->bitmapInfoHeader->biWidth *
+ hBITMAP->bitmapInfoHeader->biBitCount + 31) /
+ 32));
+ pBITMAP->bmPlanes = hBITMAP->bitmapInfoHeader->biPlanes;
+ pBITMAP->bmBitsPixel = hBITMAP->bitmapInfoHeader->biBitCount;
+ pBITMAP->bmBits = (LPVOID) hBITMAP->bitmapBits;
+ return sizeof(BITMAP);
+ }
+ break;
+ case HGDIOBJ_TYPE_REGION:
+ break;
+ case HGDIOBJ_TYPE_PALETTE:
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
}
+
HGDIOBJ GetCurrentObject(HDC hdc, UINT type) {
- if(hdc)
- return hdc->selectedBitmap;
- return NULL;
+ if (hdc)
+ return hdc->selectedBitmap;
+ return NULL;
}
+
BOOL DeleteObject(HGDIOBJ ho) {
- PAINT_LOGD("PAINT DeleteObject(ho: %p)", ho);
- if(ho) {
- switch(ho->handleType) {
- case HGDIOBJ_TYPE_PALETTE: {
- PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_PALETTE");
- ho->handleType = HGDIOBJ_TYPE_INVALID;
- if(ho->paletteLog)
- free(ho->paletteLog);
- ho->paletteLog = NULL;
- free(ho);
- return TRUE;
- }
- case HGDIOBJ_TYPE_BITMAP: {
- PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_BITMAP");
- if(ho == rootBITMAP)
- return FALSE;
- ho->handleType = HGDIOBJ_TYPE_INVALID;
- if(ho->bitmapInfo)
- free((void *) ho->bitmapInfo);
- ho->bitmapInfo = NULL;
- ho->bitmapInfoHeader = NULL;
- if(ho->bitmapBits)
- free((void *) ho->bitmapBits);
- ho->bitmapBits = NULL;
- free(ho);
- return TRUE;
- }
- case HGDIOBJ_TYPE_BRUSH: {
- PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_BRUSH");
- ho->handleType = HGDIOBJ_TYPE_INVALID;
- ho->brushColor = 0;
- free(ho);
- return TRUE;
- }
- default:
- break;
- }
- }
- return FALSE;
+ PAINT_LOGD("PAINT DeleteObject(ho: %p)", ho);
+ if (ho) {
+ switch (ho->handleType) {
+ case HGDIOBJ_TYPE_PALETTE: {
+ PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_PALETTE");
+ ho->handleType = HGDIOBJ_TYPE_INVALID;
+ if (ho->paletteLog)
+ free(ho->paletteLog);
+ ho->paletteLog = NULL;
+ free(ho);
+ return TRUE;
+ }
+ case HGDIOBJ_TYPE_BITMAP: {
+ PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_BITMAP");
+ if (ho == rootBITMAP)
+ return FALSE;
+ ho->handleType = HGDIOBJ_TYPE_INVALID;
+ if (ho->bitmapInfo)
+ free((void *) ho->bitmapInfo);
+ ho->bitmapInfo = NULL;
+ ho->bitmapInfoHeader = NULL;
+ if (ho->bitmapBits)
+ free((void *) ho->bitmapBits);
+ ho->bitmapBits = NULL;
+ free(ho);
+ return TRUE;
+ }
+ case HGDIOBJ_TYPE_BRUSH: {
+ PAINT_LOGD("PAINT DeleteObject() HGDIOBJ_TYPE_BRUSH");
+ ho->handleType = HGDIOBJ_TYPE_INVALID;
+ ho->brushColor = 0;
+ free(ho);
+ return TRUE;
+ }
+ default:
+ break;
+ }
+ }
+ return FALSE;
}
+
HGDIOBJ GetStockObject(int i) {
- //TODO
- return NULL;
+ //TODO
+ return NULL;
}
-HPALETTE CreatePalette(CONST LOGPALETTE * plpal) {
- HGDIOBJ handle = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
- memset(handle, 0, sizeof(_HGDIOBJ));
- handle->handleType = HGDIOBJ_TYPE_PALETTE;
- if(plpal && plpal->palNumEntries >= 0 && plpal->palNumEntries <= 256) {
- size_t structSize = sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * (size_t)(plpal->palNumEntries - 1);
- handle->paletteLog = malloc(structSize);
- memcpy(handle->paletteLog, plpal, structSize);
- }
- return handle;
+
+HPALETTE CreatePalette(CONST LOGPALETTE *plpal) {
+ HGDIOBJ handle = (HGDIOBJ) malloc(sizeof(_HGDIOBJ));
+ memset(handle, 0, sizeof(_HGDIOBJ));
+ handle->handleType = HGDIOBJ_TYPE_PALETTE;
+ if (plpal && plpal->palNumEntries >= 0 && plpal->palNumEntries <= 256) {
+ size_t structSize =
+ sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * (size_t) (plpal->palNumEntries - 1);
+ handle->paletteLog = malloc(structSize);
+ memcpy(handle->paletteLog, plpal, structSize);
+ }
+ return handle;
}
+
HPALETTE SelectPalette(HDC hdc, HPALETTE hPal, BOOL bForceBkgd) {
- if(!hdc)
+ if (!hdc)
return NULL;
- HPALETTE hOldPal = hdc->selectedPalette;
- hdc->selectedPalette = hPal;
- return hOldPal;
+ HPALETTE hOldPal = hdc->selectedPalette;
+ hdc->selectedPalette = hPal;
+ return hOldPal;
}
+
UINT RealizePalette(HDC hdc) {
- if(hdc && hdc->selectedPalette) {
- PLOGPALETTE paletteLog = hdc->selectedPalette->paletteLog;
- if (paletteLog) {
- HPALETTE oldRealizedPalette = hdc->realizedPalette;
- hdc->realizedPalette = CreatePalette(paletteLog);
- if(oldRealizedPalette)
- DeleteObject(oldRealizedPalette);
- }
- }
- return 0;
+ if (hdc && hdc->selectedPalette) {
+ PLOGPALETTE paletteLog = hdc->selectedPalette->paletteLog;
+ if (paletteLog) {
+ HPALETTE oldRealizedPalette = hdc->realizedPalette;
+ hdc->realizedPalette = CreatePalette(paletteLog);
+ if (oldRealizedPalette)
+ DeleteObject(oldRealizedPalette);
+ }
+ }
+ return 0;
}
COLORREF SetBkColor(HDC hdc, COLORREF color) {
- COLORREF backgroundColorBackup = hdc->backgroundColor;
- hdc->backgroundColor = color;
- hdc->isBackgroundColorSet = TRUE;
- return backgroundColorBackup;
+ COLORREF backgroundColorBackup = hdc->backgroundColor;
+ hdc->backgroundColor = color;
+ hdc->isBackgroundColorSet = TRUE;
+ return backgroundColorBackup;
}
// DC
HDC CreateCompatibleDC(HDC hdc) {
- HDC handle = (HDC)malloc(sizeof(struct _HDC));
- memset(handle, 0, sizeof(struct _HDC));
- handle->handleType = HDC_TYPE_DC;
- handle->hdcCompatible = hdc;
+ HDC handle = (HDC) malloc(sizeof(struct _HDC));
+ memset(handle, 0, sizeof(struct _HDC));
+ handle->handleType = HDC_TYPE_DC;
+ handle->hdcCompatible = hdc;
handle->selectedBitmap = rootBITMAP;
- return handle;
+ return handle;
}
+
HDC GetDC(HWND hWnd) {
- if(!hWnd)
- return NULL;
- return hWnd->windowDC;
+ if (!hWnd)
+ return NULL;
+ return hWnd->windowDC;
}
+
int ReleaseDC(HWND hWnd, HDC hDC) {
- if(!hWnd)
- return NULL;
- hWnd->windowDC = NULL; //?
- return TRUE;
+ if (!hWnd)
+ return NULL;
+ hWnd->windowDC = NULL; //?
+ return TRUE;
}
BOOL DeleteDC(HDC hdc) {
- memset(hdc, 0, sizeof(struct _HDC));
- free(hdc);
- return TRUE;
+ memset(hdc, 0, sizeof(struct _HDC));
+ free(hdc);
+ return TRUE;
}
HBRUSH WINAPI CreateSolidBrush(COLORREF color) {
- HGDIOBJ handle = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
- memset(handle, 0, sizeof(_HGDIOBJ));
- handle->handleType = HGDIOBJ_TYPE_BRUSH;
- handle->brushColor = color;
- return handle;
+ HGDIOBJ handle = (HGDIOBJ) malloc(sizeof(_HGDIOBJ));
+ memset(handle, 0, sizeof(_HGDIOBJ));
+ handle->handleType = HGDIOBJ_TYPE_BRUSH;
+ handle->brushColor = color;
+ return handle;
}
BOOL MoveToEx(HDC hdc, int x, int y, LPPOINT lppt) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
BOOL LineTo(HDC hdc, int x, int y) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) {
- PAINT_LOGD("PAINT PatBlt(hdcDest: %p, x: %d, y: %d, w: %d, h: %d, rop: 0x%08x)", hdcDest, x, y, w, h, rop);
+ PAINT_LOGD("PAINT PatBlt(hdcDest: %p, x: %d, y: %d, w: %d, h: %d, rop: 0x%08x)", hdcDest, x, y,
+ w, h, rop);
- if((hdcDest->selectedBitmap || hdcDest->hdcCompatible == NULL) && w && h) {
- HBITMAP hBitmapDestination = NULL;
- void * pixelsDestination = NULL;
- int destinationWidth = 0;
- int destinationHeight = 0;
- float destinationStride = 0;
+ if ((hdcDest->selectedBitmap || hdcDest->hdcCompatible == NULL) && w && h) {
+ HBITMAP hBitmapDestination = NULL;
+ void *pixelsDestination = NULL;
+ int destinationWidth = 0;
+ int destinationHeight = 0;
+ float destinationStride = 0;
- JNIEnv * jniEnv = NULL;
+ JNIEnv *jniEnv = NULL;
- if(hdcDest->hdcCompatible == NULL) {
- // We update the main window
+ if (hdcDest->hdcCompatible == NULL) {
+ // We update the main window
- jint ret;
- BOOL needDetach = FALSE;
- ret = (*java_machine)->GetEnv(java_machine, (void **) &jniEnv, JNI_VERSION_1_6);
- if (ret == JNI_EDETACHED) {
- // GetEnv: not attached
- ret = (*java_machine)->AttachCurrentThread(java_machine, &jniEnv, NULL);
- if (ret == JNI_OK) {
- needDetach = TRUE;
- }
- }
+ jint ret;
+ BOOL needDetach = FALSE;
+ ret = (*java_machine)->GetEnv(java_machine, (void **) &jniEnv, JNI_VERSION_1_6);
+ if (ret == JNI_EDETACHED) {
+ // GetEnv: not attached
+ ret = (*java_machine)->AttachCurrentThread(java_machine, &jniEnv, NULL);
+ if (ret == JNI_OK) {
+ needDetach = TRUE;
+ }
+ }
- destinationWidth = androidBitmapInfo.width;
- destinationHeight = androidBitmapInfo.height;
+ destinationWidth = androidBitmapInfo.width;
+ destinationHeight = androidBitmapInfo.height;
- destinationStride = androidBitmapInfo.stride;
+ destinationStride = androidBitmapInfo.stride;
// RECT newRectangleToUpdate;
// newRectangleToUpdate.left = x;
@@ -1987,139 +2055,152 @@ BOOL PatBlt(HDC hdcDest, int x, int y, int w, int h, DWORD rop) {
// newRectangleToUpdate.bottom = y + h;
// UnionRect(&mainViewRectangleToUpdate, &mainViewRectangleToUpdate, &newRectangleToUpdate);
- if ((ret = AndroidBitmap_lockPixels(jniEnv, bitmapMainScreen, &pixelsDestination)) < 0) {
- LOGD("AndroidBitmap_lockPixels() failed ! error=%d", ret);
- return FALSE;
- }
- } else {
- hBitmapDestination = hdcDest->selectedBitmap;
- pixelsDestination = (void *) hBitmapDestination->bitmapBits;
+ if ((ret = AndroidBitmap_lockPixels(jniEnv, bitmapMainScreen, &pixelsDestination)) <
+ 0) {
+ LOGD("AndroidBitmap_lockPixels() failed ! error=%d", ret);
+ return FALSE;
+ }
+ } else {
+ hBitmapDestination = hdcDest->selectedBitmap;
+ pixelsDestination = (void *) hBitmapDestination->bitmapBits;
- destinationWidth = hBitmapDestination->bitmapInfoHeader->biWidth;
- destinationHeight = abs(hBitmapDestination->bitmapInfoHeader->biHeight);
- //TODO destinationTopDown = hBitmapDestination->bitmapInfoHeader->biHeight < 0;
+ destinationWidth = hBitmapDestination->bitmapInfoHeader->biWidth;
+ destinationHeight = abs(hBitmapDestination->bitmapInfoHeader->biHeight);
+ //TODO destinationTopDown = hBitmapDestination->bitmapInfoHeader->biHeight < 0;
- destinationStride = (float)(4 * ((destinationWidth * hBitmapDestination->bitmapInfoHeader->biBitCount + 31) / 32));
- }
+ destinationStride = (float) (4 * ((destinationWidth *
+ hBitmapDestination->bitmapInfoHeader->biBitCount +
+ 31) / 32));
+ }
- x -= hdcDest->windowOriginX;
- y -= hdcDest->windowOriginY;
+ x -= hdcDest->windowOriginX;
+ y -= hdcDest->windowOriginY;
- HPALETTE palette = hdcDest->realizedPalette;
- if(!palette)
- palette = hdcDest->selectedPalette;
- PALETTEENTRY * palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ?
- palette->paletteLog->palPalEntry : NULL;
+ HPALETTE palette = hdcDest->realizedPalette;
+ if (!palette)
+ palette = hdcDest->selectedPalette;
+ PALETTEENTRY *palPalEntry =
+ palette && palette->paletteLog && palette->paletteLog->palPalEntry ?
+ palette->paletteLog->palPalEntry : NULL;
- COLORREF brushColor = 0xFF000000; // 0xAABBGGRR
- if(hdcDest->selectedBrushColor) {
- brushColor = hdcDest->selectedBrushColor->brushColor;
- }
+ COLORREF brushColor = 0xFF000000; // 0xAABBGGRR
+ if (hdcDest->selectedBrushColor) {
+ brushColor = hdcDest->selectedBrushColor->brushColor;
+ }
- for (int currentY = y; currentY < y + h; currentY++) {
- for (int currentX = x; currentX < x + w; currentX++) {
- BYTE * destinationPixel = pixelsDestination + (int)(destinationStride * currentY + 4.0 * currentX);
+ for (int currentY = y; currentY < y + h; currentY++) {
+ for (int currentX = x; currentX < x + w; currentX++) {
+ BYTE *destinationPixel =
+ pixelsDestination + (int) (destinationStride * currentY + 4.0 * currentX);
- // -> ARGB_8888
- switch (rop) {
- case DSTINVERT:
- destinationPixel[0] = (BYTE) (255 - destinationPixel[0]);
- destinationPixel[1] = (BYTE) (255 - destinationPixel[1]);
- destinationPixel[2] = (BYTE) (255 - destinationPixel[2]);
- destinationPixel[3] = 255;
- break;
- case BLACKNESS:
- destinationPixel[0] = palPalEntry[0].peRed;
- destinationPixel[1] = palPalEntry[0].peGreen;
- destinationPixel[2] = palPalEntry[0].peBlue;
- destinationPixel[3] = 255;
- break;
- case WHITENESS:
- destinationPixel[0] = 255; //palPalEntry[1].peRed;
- destinationPixel[1] = 255; //palPalEntry[1].peGreen;
- destinationPixel[2] = 255; //palPalEntry[1].peBlue;
- destinationPixel[3] = 255;
- break;
- case PATCOPY:
- // 0xAABBGGRR
- *((UINT *)destinationPixel) = brushColor;
- break;
- default:
- break;
- }
- }
- }
+ // -> ARGB_8888
+ switch (rop) {
+ case DSTINVERT:
+ destinationPixel[0] = (BYTE) (255 - destinationPixel[0]);
+ destinationPixel[1] = (BYTE) (255 - destinationPixel[1]);
+ destinationPixel[2] = (BYTE) (255 - destinationPixel[2]);
+ destinationPixel[3] = 255;
+ break;
+ case BLACKNESS:
+ destinationPixel[0] = palPalEntry[0].peRed;
+ destinationPixel[1] = palPalEntry[0].peGreen;
+ destinationPixel[2] = palPalEntry[0].peBlue;
+ destinationPixel[3] = 255;
+ break;
+ case WHITENESS:
+ destinationPixel[0] = 255; //palPalEntry[1].peRed;
+ destinationPixel[1] = 255; //palPalEntry[1].peGreen;
+ destinationPixel[2] = 255; //palPalEntry[1].peBlue;
+ destinationPixel[3] = 255;
+ break;
+ case PATCOPY:
+ // 0xAABBGGRR
+ *((UINT *) destinationPixel) = brushColor;
+ break;
+ default:
+ break;
+ }
+ }
+ }
- if(jniEnv)
- AndroidBitmap_unlockPixels(jniEnv, bitmapMainScreen);
- }
- return 0;
+ if (jniEnv)
+ AndroidBitmap_unlockPixels(jniEnv, bitmapMainScreen);
+ }
+ return 0;
}
-#define ROP_PSDPxax 0x00B8074A // ternary ROP
+
+#define ROP_PSDPxax 0x00B8074A // ternary ROP
#define ROP_PDSPxax 0x00D80745
+
BOOL BitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
- if(hdcSrc && hdcSrc->selectedBitmap) {
- HBITMAP hBitmap = hdcSrc->selectedBitmap;
- int sourceWidth = hBitmap->bitmapInfoHeader->biWidth;
- int sourceHeight = abs(hBitmap->bitmapInfoHeader->biHeight);
- return StretchBlt(hdc, x, y, cx, cy, hdcSrc, x1, y1, min(cx, sourceWidth), min(cy, sourceHeight), rop);
- }
- return FALSE;
+ if (hdcSrc && hdcSrc->selectedBitmap) {
+ HBITMAP hBitmap = hdcSrc->selectedBitmap;
+ int sourceWidth = hBitmap->bitmapInfoHeader->biWidth;
+ int sourceHeight = abs(hBitmap->bitmapInfoHeader->biHeight);
+ return StretchBlt(hdc, x, y, cx, cy, hdcSrc, x1, y1, min(cx, sourceWidth),
+ min(cy, sourceHeight), rop);
+ }
+ return FALSE;
}
+
int SetStretchBltMode(HDC hdc, int mode) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
-BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, DWORD rop) {
- PAINT_LOGD("PAINT StretchBlt(hdcDest: %p, xDest: %d, yDest: %d, wDest: %d, hDest: %d, hdcSrc: %p, xSrc: %d, ySrc: %d, wSrc: %d, hSrc: %d, rop: 0x%08x)",
- hdcDest, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, rop);
+BOOL
+StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdcSrc, int xSrc, int ySrc,
+ int wSrc, int hSrc, DWORD rop) {
+ PAINT_LOGD(
+ "PAINT StretchBlt(hdcDest: %p, xDest: %d, yDest: %d, wDest: %d, hDest: %d, hdcSrc: %p, xSrc: %d, ySrc: %d, wSrc: %d, hSrc: %d, rop: 0x%08x)",
+ hdcDest, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, rop);
- if(hdcDest && hdcSrc
- && (hdcDest->selectedBitmap || hdcDest->hdcCompatible == NULL)
- && hdcSrc->selectedBitmap && hDest && hSrc) {
+ if (hdcDest && hdcSrc
+ && (hdcDest->selectedBitmap || hdcDest->hdcCompatible == NULL)
+ && hdcSrc->selectedBitmap && hDest && hSrc) {
- HBITMAP hBitmapSource = hdcSrc->selectedBitmap;
- void * pixelsSource = (void *) hBitmapSource->bitmapBits;
+ HBITMAP hBitmapSource = hdcSrc->selectedBitmap;
+ void *pixelsSource = (void *) hBitmapSource->bitmapBits;
- HBITMAP hBitmapDestination = NULL;
- void * pixelsDestination = NULL;
- int destinationBitCount = 8;
+ HBITMAP hBitmapDestination = NULL;
+ void *pixelsDestination = NULL;
+ int destinationBitCount = 8;
- BOOL sourceTopDown = hBitmapSource->bitmapInfoHeader->biHeight < 0;
- BOOL destinationTopDown = FALSE;
+ BOOL sourceTopDown = hBitmapSource->bitmapInfoHeader->biHeight < 0;
+ BOOL destinationTopDown = FALSE;
- int sourceWidth = hBitmapSource->bitmapInfoHeader->biWidth;
- int sourceHeight = abs(hBitmapSource->bitmapInfoHeader->biHeight); // Can be < 0
- int destinationWidth = 0;
- int destinationHeight = 0;
+ int sourceWidth = hBitmapSource->bitmapInfoHeader->biWidth;
+ int sourceHeight = abs(hBitmapSource->bitmapInfoHeader->biHeight); // Can be < 0
+ int destinationWidth = 0;
+ int destinationHeight = 0;
- UINT sourceBitCount = hBitmapSource->bitmapInfoHeader->biBitCount;
- int sourceStride = 4 * ((sourceWidth * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32);
- int destinationStride = 0;
+ UINT sourceBitCount = hBitmapSource->bitmapInfoHeader->biBitCount;
+ int sourceStride =
+ 4 * ((sourceWidth * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32);
+ int destinationStride = 0;
- JNIEnv * jniEnv = NULL;
- jint ret;
+ JNIEnv *jniEnv = NULL;
+ jint ret;
- if(hdcDest->hdcCompatible == NULL) {
- // We update the main window
+ if (hdcDest->hdcCompatible == NULL) {
+ // We update the main window
- BOOL needDetach = FALSE;
- ret = (*java_machine)->GetEnv(java_machine, (void **) &jniEnv, JNI_VERSION_1_6);
- if (ret == JNI_EDETACHED) {
- // GetEnv: not attached
- ret = (*java_machine)->AttachCurrentThread(java_machine, &jniEnv, NULL);
- if (ret == JNI_OK) {
- needDetach = TRUE;
- }
- }
+ BOOL needDetach = FALSE;
+ ret = (*java_machine)->GetEnv(java_machine, (void **) &jniEnv, JNI_VERSION_1_6);
+ if (ret == JNI_EDETACHED) {
+ // GetEnv: not attached
+ ret = (*java_machine)->AttachCurrentThread(java_machine, &jniEnv, NULL);
+ if (ret == JNI_OK) {
+ needDetach = TRUE;
+ }
+ }
- destinationWidth = androidBitmapInfo.width;
- destinationHeight = androidBitmapInfo.height;
- destinationBitCount = 32;
- destinationStride = androidBitmapInfo.stride;
+ destinationWidth = androidBitmapInfo.width;
+ destinationHeight = androidBitmapInfo.height;
+ destinationBitCount = 32;
+ destinationStride = androidBitmapInfo.stride;
- destinationTopDown = TRUE;
+ destinationTopDown = TRUE;
// RECT newRectangleToUpdate;
// newRectangleToUpdate.left = xDest;
@@ -2128,291 +2209,306 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc
// newRectangleToUpdate.bottom = yDest + hDest;
// UnionRect(&mainViewRectangleToUpdate, &mainViewRectangleToUpdate, &newRectangleToUpdate);
- if ((ret = AndroidBitmap_lockPixels(jniEnv, bitmapMainScreen, &pixelsDestination)) < 0) {
- LOGD("AndroidBitmap_lockPixels() failed ! error=%d", ret);
- return FALSE;
- }
- } else {
- hBitmapDestination = hdcDest->selectedBitmap;
- pixelsDestination = (void *) hBitmapDestination->bitmapBits;
+ if ((ret = AndroidBitmap_lockPixels(jniEnv, bitmapMainScreen, &pixelsDestination)) <
+ 0) {
+ LOGD("AndroidBitmap_lockPixels() failed ! error=%d", ret);
+ return FALSE;
+ }
+ } else {
+ hBitmapDestination = hdcDest->selectedBitmap;
+ pixelsDestination = (void *) hBitmapDestination->bitmapBits;
- destinationWidth = hBitmapDestination->bitmapInfoHeader->biWidth;
- destinationHeight = abs(hBitmapDestination->bitmapInfoHeader->biHeight);
- destinationTopDown = hBitmapDestination->bitmapInfoHeader->biHeight < 0;
- destinationBitCount = hBitmapDestination->bitmapInfoHeader->biBitCount;
- destinationStride = 4 * ((destinationWidth * hBitmapDestination->bitmapInfoHeader->biBitCount + 31) / 32);
- }
+ destinationWidth = hBitmapDestination->bitmapInfoHeader->biWidth;
+ destinationHeight = abs(hBitmapDestination->bitmapInfoHeader->biHeight);
+ destinationTopDown = hBitmapDestination->bitmapInfoHeader->biHeight < 0;
+ destinationBitCount = hBitmapDestination->bitmapInfoHeader->biBitCount;
+ destinationStride = 4 * ((destinationWidth *
+ hBitmapDestination->bitmapInfoHeader->biBitCount + 31) / 32);
+ }
- xDest -= hdcDest->windowOriginX;
- yDest -= hdcDest->windowOriginY;
+ xDest -= hdcDest->windowOriginX;
+ yDest -= hdcDest->windowOriginY;
- //LOGD("StretchBlt(%p, x:%d, y:%d, w:%d, h:%d, %08x, x:%d, y:%d, w:%d, h:%d) -> sourceBitCount: %d", hdcDest->hdcCompatible, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, sourceBitCount);
+ //LOGD("StretchBlt(%p, x:%d, y:%d, w:%d, h:%d, %08x, x:%d, y:%d, w:%d, h:%d) -> sourceBitCount: %d", hdcDest->hdcCompatible, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, sourceBitCount);
- HPALETTE palette = hdcSrc->realizedPalette;
- if(!palette)
- palette = hdcSrc->selectedPalette;
- PALETTEENTRY * palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ?
- palette->paletteLog->palPalEntry : NULL;
- if(!palPalEntry && sourceBitCount <= 8 && hBitmapSource->bitmapInfoHeader->biClrUsed > 0) {
- palPalEntry = (PALETTEENTRY *)hBitmapSource->bitmapInfo->bmiColors;
- }
- COLORREF brushColor = 0xFF000000; // 0xAABBGGRR
- if(hdcDest->selectedBrushColor) {
- brushColor = hdcDest->selectedBrushColor->brushColor;
- }
- COLORREF backgroundColor = 0xFF000000; // 0xAABBGGRR
- if(sourceBitCount > 1 && destinationBitCount == 1 && hdcSrc->isBackgroundColorSet)
- {
- backgroundColor = hdcSrc->backgroundColor;
- }
- else if(sourceBitCount == 1 && destinationBitCount > 1 && hdcDest->isBackgroundColorSet)
- {
- backgroundColor = hdcDest->backgroundColor;
- }
+ HPALETTE palette = hdcSrc->realizedPalette;
+ if (!palette)
+ palette = hdcSrc->selectedPalette;
+ PALETTEENTRY *palPalEntry =
+ palette && palette->paletteLog && palette->paletteLog->palPalEntry ?
+ palette->paletteLog->palPalEntry : NULL;
+ if (!palPalEntry && sourceBitCount <= 8 && hBitmapSource->bitmapInfoHeader->biClrUsed > 0) {
+ palPalEntry = (PALETTEENTRY *) hBitmapSource->bitmapInfo->bmiColors;
+ }
+ COLORREF brushColor = 0xFF000000; // 0xAABBGGRR
+ if (hdcDest->selectedBrushColor) {
+ brushColor = hdcDest->selectedBrushColor->brushColor;
+ }
+ COLORREF backgroundColor = 0xFF000000; // 0xAABBGGRR
+ if (sourceBitCount > 1 && destinationBitCount == 1 && hdcSrc->isBackgroundColorSet) {
+ backgroundColor = hdcSrc->backgroundColor;
+ } else if (sourceBitCount == 1 && destinationBitCount > 1 &&
+ hdcDest->isBackgroundColorSet) {
+ backgroundColor = hdcDest->backgroundColor;
+ }
- StretchBltInternal(xDest, yDest, wDest, hDest,
- pixelsDestination, destinationBitCount, destinationStride, destinationWidth, destinationHeight,
- xSrc, ySrc, wSrc, hSrc,
- pixelsSource, sourceBitCount, sourceStride, sourceWidth, sourceHeight,
- rop, sourceTopDown, destinationTopDown, palPalEntry, brushColor, backgroundColor);
+ StretchBltInternal(xDest, yDest, wDest, hDest,
+ pixelsDestination, destinationBitCount, destinationStride,
+ destinationWidth, destinationHeight,
+ xSrc, ySrc, wSrc, hSrc,
+ pixelsSource, sourceBitCount, sourceStride, sourceWidth, sourceHeight,
+ rop, sourceTopDown, destinationTopDown, palPalEntry, brushColor,
+ backgroundColor);
- if(jniEnv && hdcDest->hdcCompatible == NULL && (ret = AndroidBitmap_unlockPixels(jniEnv, bitmapMainScreen)) < 0) {
- LOGD("AndroidBitmap_unlockPixels() failed ! error=%d", ret);
- return FALSE;
- }
+ if (jniEnv && hdcDest->hdcCompatible == NULL &&
+ (ret = AndroidBitmap_unlockPixels(jniEnv, bitmapMainScreen)) < 0) {
+ LOGD("AndroidBitmap_unlockPixels() failed ! error=%d", ret);
+ return FALSE;
+ }
- return TRUE;
- }
- return FALSE;
+ return TRUE;
+ }
+ return FALSE;
}
void StretchBltInternal(int xDest, int yDest, int wDest, int hDest,
- const void *pixelsDestination, int destinationBitCount, int destinationStride, int destinationWidth, int destinationHeight,
+ const void *pixelsDestination, int destinationBitCount,
+ int destinationStride, int destinationWidth, int destinationHeight,
int xSrc, int ySrc, int wSrc, int hSrc,
- const void *pixelsSource, UINT sourceBitCount, int sourceStride, int sourceWidth, int sourceHeight,
- DWORD rop, BOOL sourceTopDown, BOOL destinationTopDown, const PALETTEENTRY *palPalEntry, COLORREF brushColor, COLORREF backgroundColor) {
- int dst_maxx = xDest + wDest;
- int dst_maxy = yDest + hDest;
+ const void *pixelsSource, UINT sourceBitCount, int sourceStride,
+ int sourceWidth, int sourceHeight,
+ DWORD rop, BOOL sourceTopDown, BOOL destinationTopDown,
+ const PALETTEENTRY *palPalEntry, COLORREF brushColor,
+ COLORREF backgroundColor) {
+ int dst_maxx = xDest + wDest;
+ int dst_maxy = yDest + hDest;
- if(xDest < 0) {
- wDest += xDest;
- xDest = 0;
- }
- if(yDest < 0) {
- hDest += yDest;
- yDest = 0;
- }
- if(dst_maxx > destinationWidth)
- dst_maxx = destinationWidth;
- if(dst_maxy > destinationHeight)
- dst_maxy = destinationHeight;
+ if (xDest < 0) {
+ wDest += xDest;
+ xDest = 0;
+ }
+ if (yDest < 0) {
+ hDest += yDest;
+ yDest = 0;
+ }
+ if (dst_maxx > destinationWidth)
+ dst_maxx = destinationWidth;
+ if (dst_maxy > destinationHeight)
+ dst_maxy = destinationHeight;
- int src_cury, dst_cury;
- for (int y = yDest; y < dst_maxy; y++) {
- if(sourceTopDown)
+ int src_cury, dst_cury;
+ for (int y = yDest; y < dst_maxy; y++) {
+ if (sourceTopDown)
src_cury = ySrc + (y - yDest) * hSrc / hDest; // Source top-down
else
src_cury = sourceHeight - 1 - (ySrc + (y - yDest) * hSrc / hDest); // Source bottom-up
- if (src_cury < 0 || src_cury >= sourceHeight)
- continue;
- if(destinationTopDown)
- dst_cury = y; // Destination top-down
- else
- dst_cury = destinationHeight - 1 - y; // Destination bottom-up
+ if (src_cury < 0 || src_cury >= sourceHeight)
+ continue;
+ if (destinationTopDown)
+ dst_cury = y; // Destination top-down
+ else
+ dst_cury = destinationHeight - 1 - y; // Destination bottom-up
- BYTE parity = (BYTE) xSrc;
- for (int x = xDest; x < dst_maxx; x++, parity++) {
- int src_curx = xSrc + (x - xDest) * wSrc / wDest;
- if (src_curx < 0 || src_curx >= sourceWidth)
- continue;
+ BYTE parity = (BYTE) xSrc;
+ for (int x = xDest; x < dst_maxx; x++, parity++) {
+ int src_curx = xSrc + (x - xDest) * wSrc / wDest;
+ if (src_curx < 0 || src_curx >= sourceWidth)
+ continue;
- BYTE * sourcePixelBase = pixelsSource + sourceStride * src_cury;
- BYTE * destinationPixelBase = pixelsDestination + destinationStride * dst_cury;
+ BYTE *sourcePixelBase = pixelsSource + sourceStride * src_cury;
+ BYTE *destinationPixelBase = pixelsDestination + destinationStride * dst_cury;
- COLORREF sourceColor = 0xFF000000;
- BYTE * sourceColorPointer = (BYTE *) &sourceColor;
+ COLORREF sourceColor = 0xFF000000;
+ BYTE *sourceColorPointer = (BYTE *) &sourceColor;
- switch (sourceBitCount) {
- case 1: {
- //TODO https://devblogs.microsoft.com/oldnewthing/?p=29013
- // When blitting from a monochrome DC to a color DC,
- // the color black in the source turns into the destination’s text color,
- // and the color white in the source turns into the destination’s background
- // color.
- BYTE * sourcePixel = sourcePixelBase + ((UINT)src_curx >> (UINT)3);
- UINT bitNumber = (UINT) (7 - (src_curx % 8));
- if(*sourcePixel & ((UINT)1 << bitNumber)) {
- // Monochrome 1=White
- sourceColorPointer[0] = 255;
- sourceColorPointer[1] = 255;
- sourceColorPointer[2] = 255;
- } else {
- // Monochrome 0=Black
- sourceColorPointer[0] = 0;
- sourceColorPointer[1] = 0;
- sourceColorPointer[2] = 0;
- }
- sourceColorPointer[3] = 255;
- break;
- }
- case 4: {
- int currentXBytes = ((sourceBitCount >> (UINT)2) * src_curx) >> (UINT)1;
- BYTE * sourcePixel = sourcePixelBase + currentXBytes;
- BYTE colorIndex = (parity & (BYTE)0x1 ? sourcePixel[0] & (BYTE)0x0F : sourcePixel[0] >> (UINT)4);
- if (palPalEntry) {
- sourceColorPointer[0] = palPalEntry[colorIndex].peBlue;
- sourceColorPointer[1] = palPalEntry[colorIndex].peGreen;
- sourceColorPointer[2] = palPalEntry[colorIndex].peRed;
- sourceColorPointer[3] = 255;
- } else {
- sourceColorPointer[0] = colorIndex;
- sourceColorPointer[1] = colorIndex;
- sourceColorPointer[2] = colorIndex;
- sourceColorPointer[3] = 255;
- }
- break;
- }
- case 8: {
- BYTE * sourcePixel = sourcePixelBase + src_curx;
- BYTE colorIndex = sourcePixel[0];
- if (palPalEntry) {
- sourceColorPointer[0] = palPalEntry[colorIndex].peBlue;
- sourceColorPointer[1] = palPalEntry[colorIndex].peGreen;
- sourceColorPointer[2] = palPalEntry[colorIndex].peRed;
- sourceColorPointer[3] = 255;
- } else {
- sourceColorPointer[0] = colorIndex;
- sourceColorPointer[1] = colorIndex;
- sourceColorPointer[2] = colorIndex;
- sourceColorPointer[3] = 255;
- }
- break;
- }
- case 24: {
- BYTE * sourcePixel = sourcePixelBase + 3 * src_curx;
- sourceColorPointer[0] = sourcePixel[2];
- sourceColorPointer[1] = sourcePixel[1];
- sourceColorPointer[2] = sourcePixel[0];
- sourceColorPointer[3] = 255;
- break;
- }
- case 32: {
- BYTE *sourcePixel = sourcePixelBase + 4 * src_curx;
- memcpy(sourceColorPointer, sourcePixel, 4);
- break;
- }
- default:
- break;
- }
+ switch (sourceBitCount) {
+ case 1: {
+ //TODO https://devblogs.microsoft.com/oldnewthing/?p=29013
+ // When blitting from a monochrome DC to a color DC,
+ // the color black in the source turns into the destination’s text color,
+ // and the color white in the source turns into the destination’s background
+ // color.
+ BYTE *sourcePixel = sourcePixelBase + ((UINT) src_curx >> (UINT) 3);
+ UINT bitNumber = (UINT) (7 - (src_curx % 8));
+ if (*sourcePixel & ((UINT) 1 << bitNumber)) {
+ // Monochrome 1=White
+ sourceColorPointer[0] = 255;
+ sourceColorPointer[1] = 255;
+ sourceColorPointer[2] = 255;
+ } else {
+ // Monochrome 0=Black
+ sourceColorPointer[0] = 0;
+ sourceColorPointer[1] = 0;
+ sourceColorPointer[2] = 0;
+ }
+ sourceColorPointer[3] = 255;
+ break;
+ }
+ case 4: {
+ int currentXBytes = ((sourceBitCount >> (UINT) 2) * src_curx) >> (UINT) 1;
+ BYTE *sourcePixel = sourcePixelBase + currentXBytes;
+ BYTE colorIndex = (parity & (BYTE) 0x1 ? sourcePixel[0] & (BYTE) 0x0F :
+ sourcePixel[0] >> (UINT) 4);
+ if (palPalEntry) {
+ sourceColorPointer[0] = palPalEntry[colorIndex].peBlue;
+ sourceColorPointer[1] = palPalEntry[colorIndex].peGreen;
+ sourceColorPointer[2] = palPalEntry[colorIndex].peRed;
+ sourceColorPointer[3] = 255;
+ } else {
+ sourceColorPointer[0] = colorIndex;
+ sourceColorPointer[1] = colorIndex;
+ sourceColorPointer[2] = colorIndex;
+ sourceColorPointer[3] = 255;
+ }
+ break;
+ }
+ case 8: {
+ BYTE *sourcePixel = sourcePixelBase + src_curx;
+ BYTE colorIndex = sourcePixel[0];
+ if (palPalEntry) {
+ sourceColorPointer[0] = palPalEntry[colorIndex].peBlue;
+ sourceColorPointer[1] = palPalEntry[colorIndex].peGreen;
+ sourceColorPointer[2] = palPalEntry[colorIndex].peRed;
+ sourceColorPointer[3] = 255;
+ } else {
+ sourceColorPointer[0] = colorIndex;
+ sourceColorPointer[1] = colorIndex;
+ sourceColorPointer[2] = colorIndex;
+ sourceColorPointer[3] = 255;
+ }
+ break;
+ }
+ case 24: {
+ BYTE *sourcePixel = sourcePixelBase + 3 * src_curx;
+ sourceColorPointer[0] = sourcePixel[2];
+ sourceColorPointer[1] = sourcePixel[1];
+ sourceColorPointer[2] = sourcePixel[0];
+ sourceColorPointer[3] = 255;
+ break;
+ }
+ case 32: {
+ BYTE *sourcePixel = sourcePixelBase + 4 * src_curx;
+ memcpy(sourceColorPointer, sourcePixel, 4);
+ break;
+ }
+ default:
+ break;
+ }
- switch (destinationBitCount) {
- case 1: {
- //TODO https://devblogs.microsoft.com/oldnewthing/?p=29013
- // If you blit from a color DC to a monochrome DC,
- // then all pixels in the source that are equal to the background color
- // will turn white, and all other pixels will turn black.
- // In other words, GDI considers a monochrome bitmap to be
- // black pixels on a white background.
- BYTE * destinationPixel = destinationPixelBase + (x >> 3);
- UINT bitNumber = (UINT) (7 - (x % 8));
- if((backgroundColor & 0xFFFFFF) == (sourceColor & 0xFFFFFF)) {
- *destinationPixel |= (1 << bitNumber); // 1 White
- } else {
- *destinationPixel &= ~(1 << bitNumber); // 0 Black
- }
- break;
- }
- case 4: {
- //TODO
- break;
- }
- case 8: {
- //TODO
- break;
- }
- case 24: {
- BYTE * destinationPixel = destinationPixelBase + 3 * x;
- destinationPixel[0] = sourceColorPointer[0];
- destinationPixel[1] = sourceColorPointer[1];
- destinationPixel[2] = sourceColorPointer[2];
- break;
- }
- case 32: {
- BYTE * destinationPixel = destinationPixelBase + 4 * x;
- // https://docs.microsoft.com/en-us/windows/desktop/gdi/ternary-raster-operations
- // http://www.qnx.com/developers/docs/6.4.1/gf/dev_guide/api/gf_context_set_rop.html
- if (rop == ROP_PDSPxax) { // P ^ (D & (S ^ P))
- UINT destination = *((UINT *) destinationPixel);
- *((UINT *)destinationPixel) = (brushColor ^ (destination & (sourceColor ^ brushColor))) | 0xFF000000;
- } else if (rop == ROP_PSDPxax) { // P ^ (S & (D ^ P))
- UINT destination = *((UINT *) destinationPixel);
- *((UINT *)destinationPixel) = (brushColor ^ (sourceColor & (destination ^ brushColor))) | 0xFF000000;
- } else if (rop == SRCAND) { // dest = source AND dest
- UINT destination = *((UINT *) destinationPixel);
- *((UINT *)destinationPixel) = (sourceColor & destination) | 0xFF000000;
- } else
- *((UINT *)destinationPixel) = sourceColor;
- break;
- }
- default:
- break;
- }
- }
- }
+ switch (destinationBitCount) {
+ case 1: {
+ //TODO https://devblogs.microsoft.com/oldnewthing/?p=29013
+ // If you blit from a color DC to a monochrome DC,
+ // then all pixels in the source that are equal to the background color
+ // will turn white, and all other pixels will turn black.
+ // In other words, GDI considers a monochrome bitmap to be
+ // black pixels on a white background.
+ BYTE *destinationPixel = destinationPixelBase + (x >> 3);
+ UINT bitNumber = (UINT) (7 - (x % 8));
+ if ((backgroundColor & 0xFFFFFF) == (sourceColor & 0xFFFFFF)) {
+ *destinationPixel |= (1 << bitNumber); // 1 White
+ } else {
+ *destinationPixel &= ~(1 << bitNumber); // 0 Black
+ }
+ break;
+ }
+ case 4: {
+ //TODO
+ break;
+ }
+ case 8: {
+ //TODO
+ break;
+ }
+ case 24: {
+ BYTE *destinationPixel = destinationPixelBase + 3 * x;
+ destinationPixel[0] = sourceColorPointer[0];
+ destinationPixel[1] = sourceColorPointer[1];
+ destinationPixel[2] = sourceColorPointer[2];
+ break;
+ }
+ case 32: {
+ BYTE *destinationPixel = destinationPixelBase + 4 * x;
+ // https://docs.microsoft.com/en-us/windows/desktop/gdi/ternary-raster-operations
+ // http://www.qnx.com/developers/docs/6.4.1/gf/dev_guide/api/gf_context_set_rop.html
+ if (rop == ROP_PDSPxax) { // P ^ (D & (S ^ P))
+ UINT destination = *((UINT *) destinationPixel);
+ *((UINT *) destinationPixel) =
+ (brushColor ^ (destination & (sourceColor ^ brushColor))) |
+ 0xFF000000;
+ } else if (rop == ROP_PSDPxax) { // P ^ (S & (D ^ P))
+ UINT destination = *((UINT *) destinationPixel);
+ *((UINT *) destinationPixel) =
+ (brushColor ^ (sourceColor & (destination ^ brushColor))) |
+ 0xFF000000;
+ } else if (rop == SRCAND) { // dest = source AND dest
+ UINT destination = *((UINT *) destinationPixel);
+ *((UINT *) destinationPixel) = (sourceColor & destination) | 0xFF000000;
+ } else
+ *((UINT *) destinationPixel) = sourceColor;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
}
-UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq) {
- if(prgbq
- && hdc && hdc->realizedPalette && hdc->realizedPalette->paletteLog && hdc->realizedPalette->paletteLog->palPalEntry
- && hdc->realizedPalette->paletteLog->palNumEntries > 0 && iStart < hdc->realizedPalette->paletteLog->palNumEntries) {
- PALETTEENTRY * palPalEntry = hdc->realizedPalette->paletteLog->palPalEntry;
- for (int i = iStart, j = 0; i < cEntries; i++, j++) {
- palPalEntry[i].peRed = prgbq[j].rgbRed;
- palPalEntry[i].peGreen = prgbq[j].rgbGreen;
- palPalEntry[i].peBlue = prgbq[j].rgbBlue;
- palPalEntry[i].peFlags = 0;
- }
- }
- return 0;
+UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq) {
+ if (prgbq
+ && hdc && hdc->realizedPalette && hdc->realizedPalette->paletteLog &&
+ hdc->realizedPalette->paletteLog->palPalEntry
+ && hdc->realizedPalette->paletteLog->palNumEntries > 0 &&
+ iStart < hdc->realizedPalette->paletteLog->palNumEntries) {
+ PALETTEENTRY *palPalEntry = hdc->realizedPalette->paletteLog->palPalEntry;
+ for (int i = iStart, j = 0; i < cEntries; i++, j++) {
+ palPalEntry[i].peRed = prgbq[j].rgbRed;
+ palPalEntry[i].peGreen = prgbq[j].rgbGreen;
+ palPalEntry[i].peBlue = prgbq[j].rgbBlue;
+ palPalEntry[i].peFlags = 0;
+ }
+ }
+ return 0;
}
-HBITMAP CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitCount, CONST VOID *lpBits) {
- PAINT_LOGD("PAINT CreateBitmap()");
- HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
- memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
- newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
+HBITMAP CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitCount, CONST VOID *lpBits) {
+ PAINT_LOGD("PAINT CreateBitmap()");
- BITMAPINFO * newBitmapInfo = malloc(sizeof(BITMAPINFO));
- memset(newBitmapInfo, 0, sizeof(BITMAPINFO));
- newBitmapInfo->bmiHeader.biBitCount = (WORD) nBitCount;
- newBitmapInfo->bmiHeader.biClrUsed = 0;
- newBitmapInfo->bmiHeader.biWidth = nWidth;
+ HGDIOBJ newHBITMAP = (HGDIOBJ) malloc(sizeof(_HGDIOBJ));
+ memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
+ newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
+
+ BITMAPINFO *newBitmapInfo = malloc(sizeof(BITMAPINFO));
+ memset(newBitmapInfo, 0, sizeof(BITMAPINFO));
+ newBitmapInfo->bmiHeader.biBitCount = (WORD) nBitCount;
+ newBitmapInfo->bmiHeader.biClrUsed = 0;
+ newBitmapInfo->bmiHeader.biWidth = nWidth;
newBitmapInfo->bmiHeader.biHeight = nHeight;
- newBitmapInfo->bmiHeader.biPlanes = (WORD) nPlanes;
- newHBITMAP->bitmapInfo = newBitmapInfo;
- newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *)newBitmapInfo;
+ newBitmapInfo->bmiHeader.biPlanes = (WORD) nPlanes;
+ newHBITMAP->bitmapInfo = newBitmapInfo;
+ newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *) newBitmapInfo;
- size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
- size_t size = abs(newBitmapInfo->bmiHeader.biHeight) * stride;
- newBitmapInfo->bmiHeader.biSizeImage = (DWORD) size;
- VOID * bitmapBits = malloc(size);
- memset(bitmapBits, 0, size);
- newHBITMAP->bitmapBits = bitmapBits;
- return newHBITMAP;
+ size_t stride = (size_t) (4 * ((newBitmapInfo->bmiHeader.biWidth *
+ newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
+ size_t size = abs(newBitmapInfo->bmiHeader.biHeight) * stride;
+ newBitmapInfo->bmiHeader.biSizeImage = (DWORD) size;
+ VOID *bitmapBits = malloc(size);
+ memset(bitmapBits, 0, size);
+ newHBITMAP->bitmapBits = bitmapBits;
+ return newHBITMAP;
}
// RLE decode from Christoph Giesselink in FILES.C from Emu48forPocketPC v125
#define WIDTHBYTES(bits) ((((bits) + 31) / 32) * 4)
-typedef struct _BmpFile
-{
- DWORD dwPos; // actual reading pos
- DWORD dwFileSize; // file size
- LPBYTE pbyFile; // buffer
+typedef struct _BmpFile {
+ DWORD dwPos; // actual reading pos
+ DWORD dwFileSize; // file size
+ LPBYTE pbyFile; // buffer
} BMPFILE, FAR *LPBMPFILE, *PBMPFILE;
-static BOOL ReadRleBmpByte(LPBMPFILE pBmp, BYTE *n)
-{
+static BOOL ReadRleBmpByte(LPBMPFILE pBmp, BYTE *n) {
// outside BMP file
if (pBmp->dwPos >= pBmp->dwFileSize)
return TRUE;
@@ -2421,15 +2517,14 @@ static BOOL ReadRleBmpByte(LPBMPFILE pBmp, BYTE *n)
return FALSE;
}
-static BOOL DecodeRleBmp(LPBYTE ppvBits,BITMAPINFOHEADER CONST *lpbi, LPBMPFILE pBmp)
-{
- BYTE byLength,byColorIndex;
- DWORD dwPos,dwRow,dwSizeImage,dwPixelPerLine;
- BOOL bDecoding;
+static BOOL DecodeRleBmp(LPBYTE ppvBits, BITMAPINFOHEADER CONST *lpbi, LPBMPFILE pBmp) {
+ BYTE byLength, byColorIndex;
+ DWORD dwPos, dwRow, dwSizeImage, dwPixelPerLine;
+ BOOL bDecoding;
- _ASSERT(ppvBits != NULL); // destination
- _ASSERT(lpbi != NULL); // BITMAPINFOHEADER
- _ASSERT(pBmp != NULL); // bitmap data
+ _ASSERT(ppvBits != NULL); // destination
+ _ASSERT(lpbi != NULL); // BITMAPINFOHEADER
+ _ASSERT(pBmp != NULL); // bitmap data
// valid bit count for RLE bitmaps
_ASSERT(lpbi->biBitCount == 4 || lpbi->biBitCount == 8);
@@ -2438,14 +2533,14 @@ static BOOL DecodeRleBmp(LPBYTE ppvBits,BITMAPINFOHEADER CONST *lpbi, LPBMPFILE
if ((lpbi->biBitCount != 4 && lpbi->biBitCount != 8) || lpbi->biHeight < 0)
return TRUE;
- bDecoding = TRUE; // RLE decoder running
- dwPos = dwRow = 0; // reset absolute position and row counter
+ bDecoding = TRUE; // RLE decoder running
+ dwPos = dwRow = 0; // reset absolute position and row counter
// image size
_ASSERT(lpbi->biHeight >= 0);
- dwSizeImage = WIDTHBYTES((DWORD)lpbi->biWidth * lpbi->biBitCount) * lpbi->biHeight;
+ dwSizeImage = WIDTHBYTES((DWORD) lpbi->biWidth * lpbi->biBitCount) * lpbi->biHeight;
- ZeroMemory(ppvBits,dwSizeImage); // clear bitmap
+ ZeroMemory(ppvBits, dwSizeImage); // clear bitmap
// image size in pixel
dwSizeImage *= (8 / lpbi->biBitCount);
@@ -2453,54 +2548,48 @@ static BOOL DecodeRleBmp(LPBYTE ppvBits,BITMAPINFOHEADER CONST *lpbi, LPBMPFILE
// no. of pixels per line
dwPixelPerLine = dwSizeImage / lpbi->biHeight;
- do
- {
+ do {
// length information is WORD aligned
_ASSERT(((DWORD) &pBmp->pbyFile[pBmp->dwPos] % sizeof(WORD)) == 0);
- if (ReadRleBmpByte(pBmp,&byLength)) return TRUE;
- if (ReadRleBmpByte(pBmp,&byColorIndex)) return TRUE;
+ if (ReadRleBmpByte(pBmp, &byLength)) return TRUE;
+ if (ReadRleBmpByte(pBmp, &byColorIndex)) return TRUE;
- if (byLength) // length information
+ if (byLength) // length information
{
// check for buffer overflow
- if (dwPos + byLength > dwSizeImage)
- {
+ if (dwPos + byLength > dwSizeImage) {
// write rest of data until buffer full
byLength = (dwPos > dwSizeImage) ? 0 : (BYTE) (dwSizeImage - dwPos);
- bDecoding = FALSE; // abort
+ bDecoding = FALSE; // abort
}
- if (lpbi->biBitCount == 4) // RLE4
+ if (lpbi->biBitCount == 4) // RLE4
{
BYTE byColor[2];
- UINT s,d;
+ UINT s, d;
// split into upper/lower nibble
byColor[0] = byColorIndex >> 4;
byColor[1] = byColorIndex & 0x0F;
- s = 0; // source nibble selector [0/1]
- d = (~dwPos & 1) * 4; // destination shift [0/4]
+ s = 0; // source nibble selector [0/1]
+ d = (~dwPos & 1) * 4; // destination shift [0/4]
- while (byLength-- > 0)
- {
+ while (byLength-- > 0) {
// write nibble to memory
_ASSERT((byColor[s] & 0xF0) == 0);
- ppvBits[dwPos++/2] |= (byColor[s] << d);
- s ^= 1; // next source nibble
- d ^= 4; // next destination shift
+ ppvBits[dwPos++ / 2] |= (byColor[s] << d);
+ s ^= 1; // next source nibble
+ d ^= 4; // next destination shift
}
- }
- else // RLE8
+ } else // RLE8
{
while (byLength-- > 0)
ppvBits[dwPos++] = byColorIndex;
}
- }
- else // escape sequence
+ } else // escape sequence
{
- switch (byColorIndex)
- {
+ switch (byColorIndex) {
case 0: // End of Line
dwPos = ++dwRow * dwPixelPerLine;
break;
@@ -2509,40 +2598,37 @@ static BOOL DecodeRleBmp(LPBYTE ppvBits,BITMAPINFOHEADER CONST *lpbi, LPBMPFILE
break;
case 2: // Delta
// column offset
- if (ReadRleBmpByte(pBmp,&byColorIndex)) return TRUE;
+ if (ReadRleBmpByte(pBmp, &byColorIndex)) return TRUE;
dwPos += byColorIndex;
// row offset
- if (ReadRleBmpByte(pBmp,&byColorIndex)) return TRUE;
+ if (ReadRleBmpByte(pBmp, &byColorIndex)) return TRUE;
dwRow += byColorIndex;
dwPos += dwPixelPerLine * byColorIndex;
break;
default: // absolute mode
// check for buffer overflow
- if (dwPos + byColorIndex > dwSizeImage)
- {
+ if (dwPos + byColorIndex > dwSizeImage) {
// write rest of data until buffer full
byColorIndex = (dwPos > dwSizeImage) ? 0 : (BYTE) (dwSizeImage - dwPos);
- bDecoding = FALSE; // abort
+ bDecoding = FALSE; // abort
}
- if (lpbi->biBitCount == 4) // RLE4
+ if (lpbi->biBitCount == 4) // RLE4
{
- BYTE byColor,byColorPair;
- UINT s,d;
+ BYTE byColor, byColorPair;
+ UINT s, d;
- d = (~dwPos & 1) * 4; // destination shift [0/4]
+ d = (~dwPos & 1) * 4; // destination shift [0/4]
- for (s = 0; s < byColorIndex; ++s)
- {
- if ((s & 1) == 0) // upper nibble
+ for (s = 0; s < byColorIndex; ++s) {
+ if ((s & 1) == 0) // upper nibble
{
// fetch color pair
- if (ReadRleBmpByte(pBmp,&byColorPair)) return TRUE;
+ if (ReadRleBmpByte(pBmp, &byColorPair)) return TRUE;
// get upper nibble
byColor = (byColorPair >> 4);
- }
- else // lower nibble
+ } else // lower nibble
{
// get lower nibble
byColor = (byColorPair & 0x0F);
@@ -2550,17 +2636,16 @@ static BOOL DecodeRleBmp(LPBYTE ppvBits,BITMAPINFOHEADER CONST *lpbi, LPBMPFILE
// write nibble to memory
_ASSERT((byColor & 0xF0) == 0);
- ppvBits[dwPos++/2] |= (byColor << d);
- d ^= 4; // next destination shift
+ ppvBits[dwPos++ / 2] |= (byColor << d);
+ d ^= 4; // next destination shift
}
// for odd byte length detection
byColorIndex = (++byColorIndex) >> 1;
- }
- else // RLE8
+ } else // RLE8
{
if (pBmp->dwPos + byColorIndex > pBmp->dwFileSize) return TRUE;
- CopyMemory(ppvBits+dwPos,&pBmp->pbyFile[pBmp->dwPos],byColorIndex);
+ CopyMemory(ppvBits + dwPos, &pBmp->pbyFile[pBmp->dwPos], byColorIndex);
dwPos += byColorIndex;
pBmp->dwPos += byColorIndex;
}
@@ -2569,26 +2654,26 @@ static BOOL DecodeRleBmp(LPBYTE ppvBits,BITMAPINFOHEADER CONST *lpbi, LPBMPFILE
break;
}
}
- }
- while (bDecoding);
+ } while (bDecoding);
return FALSE;
}
-HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CONST VOID *pjBits, CONST BITMAPINFO *pbmi, UINT iUsage) {
- PAINT_LOGD("PAINT CreateDIBitmap()");
+HBITMAP CreateDIBitmap(HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CONST VOID *pjBits,
+ CONST BITMAPINFO *pbmi, UINT iUsage) {
+ PAINT_LOGD("PAINT CreateDIBitmap()");
- HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
+ HGDIOBJ newHBITMAP = (HGDIOBJ) malloc(sizeof(_HGDIOBJ));
memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
- BITMAPINFO * newBitmapInfo = malloc(sizeof(BITMAPINFO));
+ BITMAPINFO *newBitmapInfo = malloc(sizeof(BITMAPINFO));
memcpy(newBitmapInfo, pbmi, sizeof(BITMAPINFO));
newHBITMAP->bitmapInfo = newBitmapInfo;
- newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *)newBitmapInfo;
+ newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *) newBitmapInfo;
- if(flInit == CBM_INIT && pjBits) {
- VOID * bitmapBits = NULL;
- if(iUsage == DIB_RGB_COLORS) {
+ if (flInit == CBM_INIT && pjBits) {
+ VOID *bitmapBits = NULL;
+ if (iUsage == DIB_RGB_COLORS) {
switch (pbmi->bmiHeader.biCompression) {
case BI_RLE4:
case BI_RLE8: {
@@ -2596,13 +2681,18 @@ HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CO
// Destination
BOOL bErr;
newBitmapInfo->bmiHeader.biCompression = BI_RGB;
- size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
+ size_t stride = (size_t) (4 * ((newBitmapInfo->bmiHeader.biWidth *
+ newBitmapInfo->bmiHeader.biBitCount + 31) /
+ 32));
size_t size = abs(newBitmapInfo->bmiHeader.biHeight) * stride;
bitmapBits = malloc(size);
BMPFILE Bmp;
- int bitOffset = sizeof(BITMAPINFOHEADER) + (pbmi->bmiHeader.biCompression == BI_BITFIELDS ? 3 * sizeof(DWORD) : DibNumColors(&pbmi->bmiHeader) * sizeof(RGBQUAD));
+ int bitOffset = sizeof(BITMAPINFOHEADER) +
+ (pbmi->bmiHeader.biCompression == BI_BITFIELDS ? 3 *
+ sizeof(DWORD) :
+ DibNumColors(&pbmi->bmiHeader) * sizeof(RGBQUAD));
- Bmp.pbyFile = ((LPBYTE)&pbmi->bmiHeader) + bitOffset;
+ Bmp.pbyFile = ((LPBYTE) &pbmi->bmiHeader) + bitOffset;
Bmp.dwPos = 0;
Bmp.dwFileSize = -1; //size;
@@ -2615,7 +2705,9 @@ HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CO
case BI_RGB:
case BI_BITFIELDS: {
// We consider the source and destination dib with the same format
- size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
+ size_t stride = (size_t) (4 * ((newBitmapInfo->bmiHeader.biWidth *
+ newBitmapInfo->bmiHeader.biBitCount + 31) /
+ 32));
size_t size = newBitmapInfo->bmiHeader.biSizeImage ?
newBitmapInfo->bmiHeader.biSizeImage :
abs(newBitmapInfo->bmiHeader.biHeight) * stride;
@@ -2629,165 +2721,182 @@ HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CO
}
return newHBITMAP;
}
-HBITMAP CreateDIBSection(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppvBits, HANDLE hSection, DWORD offset) {
- PAINT_LOGD("PAINT CreateDIBSection()");
- HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
- memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
- newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
+HBITMAP
+CreateDIBSection(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppvBits, HANDLE hSection,
+ DWORD offset) {
+ PAINT_LOGD("PAINT CreateDIBSection()");
- size_t bitmapInfoSize = sizeof(BITMAPINFO);
- if(pbmi->bmiHeader.biClrUsed > 0)
- bitmapInfoSize += sizeof(RGBQUAD) * min(pbmi->bmiHeader.biClrUsed, 2^16);
- BITMAPINFO * newBitmapInfo = malloc(bitmapInfoSize);
- memcpy(newBitmapInfo, pbmi, bitmapInfoSize);
- newHBITMAP->bitmapInfo = newBitmapInfo;
- newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *)newBitmapInfo;
+ HGDIOBJ newHBITMAP = (HGDIOBJ) malloc(sizeof(_HGDIOBJ));
+ memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
+ newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
- // For DIB_RGB_COLORS only
- size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
- size_t size = newBitmapInfo->bmiHeader.biSizeImage ?
- newBitmapInfo->bmiHeader.biSizeImage :
- abs(newBitmapInfo->bmiHeader.biHeight) * stride;
- newHBITMAP->bitmapBits = malloc(size);
+ size_t bitmapInfoSize = sizeof(BITMAPINFO);
+ if (pbmi->bmiHeader.biClrUsed > 0)
+ bitmapInfoSize += sizeof(RGBQUAD) * min(pbmi->bmiHeader.biClrUsed, 2 ^ 16);
+ BITMAPINFO *newBitmapInfo = malloc(bitmapInfoSize);
+ memcpy(newBitmapInfo, pbmi, bitmapInfoSize);
+ newHBITMAP->bitmapInfo = newBitmapInfo;
+ newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *) newBitmapInfo;
- memset((void *) newHBITMAP->bitmapBits, 0, size);
- *ppvBits = (void *) newHBITMAP->bitmapBits;
- return newHBITMAP;
+ // For DIB_RGB_COLORS only
+ size_t stride = (size_t) (4 * ((newBitmapInfo->bmiHeader.biWidth *
+ newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
+ size_t size = newBitmapInfo->bmiHeader.biSizeImage ?
+ newBitmapInfo->bmiHeader.biSizeImage :
+ abs(newBitmapInfo->bmiHeader.biHeight) * stride;
+ newHBITMAP->bitmapBits = malloc(size);
+
+ memset((void *) newHBITMAP->bitmapBits, 0, size);
+ *ppvBits = (void *) newHBITMAP->bitmapBits;
+ return newHBITMAP;
}
-HBITMAP CreateCompatibleBitmap( HDC hdc, int cx, int cy) {
- PAINT_LOGD("PAINT CreateCompatibleBitmap()");
- HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
- memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
- newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
+HBITMAP CreateCompatibleBitmap(HDC hdc, int cx, int cy) {
+ PAINT_LOGD("PAINT CreateCompatibleBitmap()");
- BITMAPINFO * newBitmapInfo = malloc(sizeof(BITMAPINFO));
- memset(newBitmapInfo, 0, sizeof(BITMAPINFO));
- newHBITMAP->bitmapInfo = newBitmapInfo;
- newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *)newBitmapInfo;
+ HGDIOBJ newHBITMAP = (HGDIOBJ) malloc(sizeof(_HGDIOBJ));
+ memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
+ newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
- newBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- newBitmapInfo->bmiHeader.biWidth = cx;
- newBitmapInfo->bmiHeader.biHeight = cy;
- newBitmapInfo->bmiHeader.biBitCount = 32;
+ BITMAPINFO *newBitmapInfo = malloc(sizeof(BITMAPINFO));
+ memset(newBitmapInfo, 0, sizeof(BITMAPINFO));
+ newHBITMAP->bitmapInfo = newBitmapInfo;
+ newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *) newBitmapInfo;
- size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
- size_t size = abs(newBitmapInfo->bmiHeader.biHeight) * stride;
- newBitmapInfo->bmiHeader.biSizeImage = (DWORD) size;
- newHBITMAP->bitmapBits = malloc(size);
- memset((void *) newHBITMAP->bitmapBits, 0, size);
- return newHBITMAP;
+ newBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ newBitmapInfo->bmiHeader.biWidth = cx;
+ newBitmapInfo->bmiHeader.biHeight = cy;
+ newBitmapInfo->bmiHeader.biBitCount = 32;
+
+ size_t stride = (size_t) (4 * ((newBitmapInfo->bmiHeader.biWidth *
+ newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
+ size_t size = abs(newBitmapInfo->bmiHeader.biHeight) * stride;
+ newBitmapInfo->bmiHeader.biSizeImage = (DWORD) size;
+ newHBITMAP->bitmapBits = malloc(size);
+ memset((void *) newHBITMAP->bitmapBits, 0, size);
+ return newHBITMAP;
}
-int GetDIBits(HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT usage) {
+
+int GetDIBits(HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPBITMAPINFO lpbmi,
+ UINT usage) {
PAINT_LOGD("PAINT GetDIBits()");
- //TODO Not sure at all for this function
- if(hbm && lpbmi) {
- CONST BITMAPINFO *pbmi = hbm->bitmapInfo;
- if(!lpvBits) {
- size_t bitmapInfoSize = sizeof(BITMAPINFOHEADER);
- memcpy(lpbmi, pbmi, bitmapInfoSize);
- } else {
- // We consider the source and destination dib with the same format
- size_t stride = (size_t)(4 * ((pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount + 31) / 32));
- VOID * sourceDibBits = (VOID *)hbm->bitmapBits;
- VOID * destinationDibBits = lpvBits;
- for(int y = 0; y < cLines; y++) {
- size_t lineSize = (start + y) * stride;
- memcpy(destinationDibBits + lineSize, sourceDibBits + lineSize, stride);
- }
- }
- }
- return 0;
+ //TODO Not sure at all for this function
+ if (hbm && lpbmi) {
+ CONST BITMAPINFO *pbmi = hbm->bitmapInfo;
+ if (!lpvBits) {
+ size_t bitmapInfoSize = sizeof(BITMAPINFOHEADER);
+ memcpy(lpbmi, pbmi, bitmapInfoSize);
+ } else {
+ // We consider the source and destination dib with the same format
+ size_t stride = (size_t) (4 *
+ ((pbmi->bmiHeader.biWidth * pbmi->bmiHeader.biBitCount + 31) /
+ 32));
+ VOID *sourceDibBits = (VOID *) hbm->bitmapBits;
+ VOID *destinationDibBits = lpvBits;
+ for (int y = 0; y < cLines; y++) {
+ size_t lineSize = (start + y) * stride;
+ memcpy(destinationDibBits + lineSize, sourceDibBits + lineSize, stride);
+ }
+ }
+ }
+ return 0;
}
-COLORREF GetPixel(HDC hdc, int x ,int y) {
- HBITMAP hBitmapSource = hdc->selectedBitmap;
- void * pixelsSource = (void *) hBitmapSource->bitmapBits;
- BOOL reverseHeight = hBitmapSource->bitmapInfoHeader->biHeight < 0;
+COLORREF GetPixel(HDC hdc, int x, int y) {
+ HBITMAP hBitmapSource = hdc->selectedBitmap;
+ void *pixelsSource = (void *) hBitmapSource->bitmapBits;
- int sourceWidth = hBitmapSource->bitmapInfoHeader->biWidth;
- int sourceHeight = abs(hBitmapSource->bitmapInfoHeader->biHeight); // Can be < 0
+ BOOL reverseHeight = hBitmapSource->bitmapInfoHeader->biHeight < 0;
- int sourceBitCount = hBitmapSource->bitmapInfoHeader->biBitCount;
- int sourceStride = 4 * ((sourceWidth * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32);
+ int sourceWidth = hBitmapSource->bitmapInfoHeader->biWidth;
+ int sourceHeight = abs(hBitmapSource->bitmapInfoHeader->biHeight); // Can be < 0
- x -= hdc->windowOriginX;
- y -= hdc->windowOriginY;
+ int sourceBitCount = hBitmapSource->bitmapInfoHeader->biBitCount;
+ int sourceStride = 4 * ((sourceWidth * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32);
- if(!reverseHeight)
- y = sourceHeight - 1 - y;
+ x -= hdc->windowOriginX;
+ y -= hdc->windowOriginY;
- HPALETTE palette = hdc->realizedPalette;
- if(!palette)
- palette = hdc->selectedPalette;
- PALETTEENTRY * palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ?
- palette->paletteLog->palPalEntry : NULL;
- if(!palPalEntry && sourceBitCount <= 8 && hBitmapSource->bitmapInfoHeader->biClrUsed > 0) {
- palPalEntry = (PALETTEENTRY *)hBitmapSource->bitmapInfo->bmiColors;
- }
- COLORREF resultColor = CLR_INVALID; // 0xAABBGGRR
+ if (!reverseHeight)
+ y = sourceHeight - 1 - y;
- if(x >= 0 && y >= 0 && x < sourceWidth && y < sourceHeight) {
- BYTE * sourcePixel = pixelsSource + sourceStride * y;
+ HPALETTE palette = hdc->realizedPalette;
+ if (!palette)
+ palette = hdc->selectedPalette;
+ PALETTEENTRY *palPalEntry = palette && palette->paletteLog && palette->paletteLog->palPalEntry ?
+ palette->paletteLog->palPalEntry : NULL;
+ if (!palPalEntry && sourceBitCount <= 8 && hBitmapSource->bitmapInfoHeader->biClrUsed > 0) {
+ palPalEntry = (PALETTEENTRY *) hBitmapSource->bitmapInfo->bmiColors;
+ }
+ COLORREF resultColor = CLR_INVALID; // 0xAABBGGRR
- // -> ARGB_8888
- switch (sourceBitCount) {
- case 1:
- //TODO
- break;
- case 4: {
- sourcePixel += x >> 2;
- BYTE colorIndex = (x & 0x1 ? sourcePixel[0] & (BYTE)0x0F : sourcePixel[0] >> 4);
- if (palPalEntry) {
- resultColor = 0xFF000000 | RGB(palPalEntry[colorIndex].peRed, palPalEntry[colorIndex].peGreen, palPalEntry[colorIndex].peBlue);
- } else {
- resultColor = 0xFF000000 | RGB(colorIndex, colorIndex, colorIndex);
- }
- break;
- }
- case 8: {
- sourcePixel += x;
- BYTE colorIndex = sourcePixel[0];
- if (palPalEntry) {
- resultColor = 0xFF000000 | RGB(palPalEntry[colorIndex].peRed, palPalEntry[colorIndex].peGreen, palPalEntry[colorIndex].peBlue);
- } else {
- resultColor = 0xFF000000 | RGB(sourcePixel[0], sourcePixel[0], sourcePixel[0]);
- }
- break;
- }
- case 24:
- sourcePixel += 3 * x;
- resultColor = 0xFF000000 | RGB(sourcePixel[2], sourcePixel[1], sourcePixel[0]);
- break;
- case 32:
- sourcePixel += 4 * x;
- resultColor = 0xFF000000 | RGB(sourcePixel[2], sourcePixel[1], sourcePixel[0]);
- break;
- default:
- break;
- }
- }
+ if (x >= 0 && y >= 0 && x < sourceWidth && y < sourceHeight) {
+ BYTE *sourcePixel = pixelsSource + sourceStride * y;
- return resultColor;
+ // -> ARGB_8888
+ switch (sourceBitCount) {
+ case 1:
+ //TODO
+ break;
+ case 4: {
+ sourcePixel += x >> 2;
+ BYTE colorIndex = (x & 0x1 ? sourcePixel[0] & (BYTE) 0x0F : sourcePixel[0] >> 4);
+ if (palPalEntry) {
+ resultColor = 0xFF000000 | RGB(palPalEntry[colorIndex].peRed,
+ palPalEntry[colorIndex].peGreen,
+ palPalEntry[colorIndex].peBlue);
+ } else {
+ resultColor = 0xFF000000 | RGB(colorIndex, colorIndex, colorIndex);
+ }
+ break;
+ }
+ case 8: {
+ sourcePixel += x;
+ BYTE colorIndex = sourcePixel[0];
+ if (palPalEntry) {
+ resultColor = 0xFF000000 | RGB(palPalEntry[colorIndex].peRed,
+ palPalEntry[colorIndex].peGreen,
+ palPalEntry[colorIndex].peBlue);
+ } else {
+ resultColor = 0xFF000000 | RGB(sourcePixel[0], sourcePixel[0], sourcePixel[0]);
+ }
+ break;
+ }
+ case 24:
+ sourcePixel += 3 * x;
+ resultColor = 0xFF000000 | RGB(sourcePixel[2], sourcePixel[1], sourcePixel[0]);
+ break;
+ case 32:
+ sourcePixel += 4 * x;
+ resultColor = 0xFF000000 | RGB(sourcePixel[2], sourcePixel[1], sourcePixel[0]);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return resultColor;
}
+
BOOL SetRect(LPRECT lprc, int xLeft, int yTop, int xRight, int yBottom) {
if (!lprc) return FALSE;
- lprc->left = xLeft;
- lprc->right = xRight;
- lprc->top = yTop;
+ lprc->left = xLeft;
+ lprc->right = xRight;
+ lprc->top = yTop;
lprc->bottom = yBottom;
return TRUE;
}
+
BOOL SetRectEmpty(LPRECT lprc) {
- if(lprc) {
- lprc->top = 0;
- lprc->bottom = 0;
- lprc->left = 0;
- lprc->right = 0;
- return TRUE;
- }
- return FALSE;
+ if (lprc) {
+ lprc->top = 0;
+ lprc->bottom = 0;
+ lprc->left = 0;
+ lprc->right = 0;
+ return TRUE;
+ }
+ return FALSE;
}
BOOL IsRectEmpty(CONST RECT *lprc) {
@@ -2799,108 +2908,108 @@ BOOL IsRectEmpty(CONST RECT *lprc) {
// This comes from Wine source code
BOOL UnionRect(LPRECT dest, CONST RECT *src1, CONST RECT *src2) {
if (!dest) return FALSE;
- if (IsRectEmpty(src1))
- {
- if (IsRectEmpty(src2))
- {
- SetRectEmpty( dest );
+ if (IsRectEmpty(src1)) {
+ if (IsRectEmpty(src2)) {
+ SetRectEmpty(dest);
return FALSE;
- }
- else *dest = *src2;
- }
- else
- {
+ } else *dest = *src2;
+ } else {
if (IsRectEmpty(src2)) *dest = *src1;
- else
- {
- dest->left = min( src1->left, src2->left );
- dest->right = max( src1->right, src2->right );
- dest->top = min( src1->top, src2->top );
- dest->bottom = max( src1->bottom, src2->bottom );
+ else {
+ dest->left = min(src1->left, src2->left);
+ dest->right = max(src1->right, src2->right);
+ dest->top = min(src1->top, src2->top);
+ dest->bottom = max(src1->bottom, src2->bottom);
}
}
return TRUE;
}
+
int SetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
-HRGN ExtCreateRegion(CONST XFORM * lpx, DWORD nCount, CONST RGNDATA * lpData) {
- //TODO
- return NULL;
+
+HRGN ExtCreateRegion(CONST XFORM *lpx, DWORD nCount, CONST RGNDATA *lpData) {
+ //TODO
+ return NULL;
}
+
BOOL GdiFlush(void) {
- mainViewUpdateCallback();
- return 0;
+ mainViewUpdateCallback();
+ return 0;
}
+
HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint) {
- if(lpPaint) {
- memset(lpPaint, 0, sizeof(PAINTSTRUCT));
- lpPaint->fErase = TRUE;
- lpPaint->hdc = CreateCompatibleDC(NULL); //hWnd->windowDC);
- lpPaint->rcPaint.right = (short) nBackgroundW;
- lpPaint->rcPaint.bottom = (short) nBackgroundH;
- return lpPaint->hdc;
- }
- return NULL;
+ if (lpPaint) {
+ memset(lpPaint, 0, sizeof(PAINTSTRUCT));
+ lpPaint->fErase = TRUE;
+ lpPaint->hdc = CreateCompatibleDC(NULL); //hWnd->windowDC);
+ lpPaint->rcPaint.right = (short) nBackgroundW;
+ lpPaint->rcPaint.bottom = (short) nBackgroundH;
+ return lpPaint->hdc;
+ }
+ return NULL;
}
+
BOOL EndPaint(HWND hWnd, CONST PAINTSTRUCT *lpPaint) {
- //mainViewUpdateCallback(); //TODO May be not needed
- DeleteDC(lpPaint->hdc);
- return 0;
+ //mainViewUpdateCallback(); //TODO May be not needed
+ DeleteDC(lpPaint->hdc);
+ return 0;
}
// Window
BOOL WINAPI MessageBeep(UINT uType) {
- //TODO System beep
- return 1;
+ //TODO System beep
+ return 1;
}
BOOL WINAPI OpenClipboard(HWND hWndNewOwner) {
- return TRUE;
+ return TRUE;
}
+
BOOL WINAPI CloseClipboard(VOID) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
BOOL WINAPI EmptyClipboard(VOID) {
- return TRUE;
+ return TRUE;
}
-HANDLE WINAPI SetClipboardData(UINT uFormat,HANDLE hMem) {
- if(CF_TEXT) {
- clipboardCopyText((const TCHAR *)hMem);
- }
- GlobalFree(hMem);
- return NULL;
+HANDLE WINAPI SetClipboardData(UINT uFormat, HANDLE hMem) {
+ if (CF_TEXT) {
+ clipboardCopyText((const TCHAR *) hMem);
+ }
+ GlobalFree(hMem);
+ return NULL;
}
BOOL WINAPI IsClipboardFormatAvailable(UINT format) {
- TCHAR * szText = clipboardPasteText();
- BOOL result = szText != NULL;
- GlobalFree(szText);
- return result;
+ TCHAR *szText = clipboardPasteText();
+ BOOL result = szText != NULL;
+ GlobalFree(szText);
+ return result;
}
HANDLE WINAPI GetClipboardData(UINT uFormat) {
- TCHAR * szText = clipboardPasteText();
- return szText;
+ TCHAR *szText = clipboardPasteText();
+ return szText;
}
struct timerEvent {
- int timerId;
- UINT uDelay;
- UINT uResolution;
- LPTIMECALLBACK fptc;
- DWORD_PTR dwUser;
- UINT fuEvent;
+ int timerId;
+ UINT uDelay;
+ UINT uResolution;
+ LPTIMECALLBACK fptc;
+ DWORD_PTR dwUser;
+ UINT fuEvent;
- ULONGLONG triggerTime;
+ ULONGLONG triggerTime;
- struct timerEvent * next;
- struct timerEvent * prev;
+ struct timerEvent *next;
+ struct timerEvent *prev;
};
static struct timerEvent timersList;
static int lastTimerId;
@@ -2909,66 +3018,68 @@ static pthread_t timerThreadId;
static BOOL timerThreadToEnd;
static void initTimer() {
- timersList.next = &timersList;
- timersList.prev = &timersList;
- timerThreadId = 0;
- timerThreadToEnd = TRUE;
- lastTimerId = 0;
+ timersList.next = &timersList;
+ timersList.prev = &timersList;
+ timerThreadId = 0;
+ timerThreadToEnd = TRUE;
+ lastTimerId = 0;
}
static void dumpTimers() {
TIMER_LOGD("dumpTimers()");
- for (struct timerEvent * nextTimer = timersList.next; nextTimer != &timersList; nextTimer = nextTimer->next) {
+ for (struct timerEvent *nextTimer = timersList.next;
+ nextTimer != &timersList; nextTimer = nextTimer->next) {
TIMER_LOGD("\ttimerId: %d (%x), uDelay: %d, dwUser: %d, fuEvent: %d, triggerTime: %ld)",
- nextTimer->timerId, nextTimer, nextTimer->uDelay, nextTimer->dwUser, nextTimer->fuEvent, nextTimer->triggerTime);
+ nextTimer->timerId, nextTimer, nextTimer->uDelay, nextTimer->dwUser,
+ nextTimer->fuEvent, nextTimer->triggerTime);
}
}
MMRESULT timeKillEvent(UINT uTimerID) {
- TIMER_LOGD("timeKillEvent(uTimerID: [%d])", uTimerID);
+ TIMER_LOGD("timeKillEvent(uTimerID: [%d])", uTimerID);
- pthread_mutex_lock(&timerEventsLock);
+ pthread_mutex_lock(&timerEventsLock);
- struct timerEvent * nextTimer, * timerToFree = NULL;
- // Search the timer by id
- for (nextTimer = timersList.next; nextTimer != &timersList; nextTimer = nextTimer->next) {
- if(uTimerID == nextTimer->timerId) {
- // Remove the timer
- nextTimer->next->prev = nextTimer->prev;
- nextTimer->prev->next = nextTimer->next;
- timerToFree = nextTimer;
- break;
- }
- }
+ struct timerEvent *nextTimer, *timerToFree = NULL;
+ // Search the timer by id
+ for (nextTimer = timersList.next; nextTimer != &timersList; nextTimer = nextTimer->next) {
+ if (uTimerID == nextTimer->timerId) {
+ // Remove the timer
+ nextTimer->next->prev = nextTimer->prev;
+ nextTimer->prev->next = nextTimer->next;
+ timerToFree = nextTimer;
+ break;
+ }
+ }
#if defined(TIMER_LOGD)
dumpTimers();
#endif
- if(timersList.next == &timersList) {
- // The list is empty
- // Leave the thread?
- timerThreadToEnd = TRUE;
- TIMER_LOGD("timeKillEvent(uTimerID: [%d]) timerThreadToEnd = TRUE ", uTimerID);
- }
- pthread_mutex_unlock(&timerEventsLock);
+ if (timersList.next == &timersList) {
+ // The list is empty
+ // Leave the thread?
+ timerThreadToEnd = TRUE;
+ TIMER_LOGD("timeKillEvent(uTimerID: [%d]) timerThreadToEnd = TRUE ", uTimerID);
+ }
+ pthread_mutex_unlock(&timerEventsLock);
- if(timerToFree)
- free(timerToFree);
+ if (timerToFree)
+ free(timerToFree);
- return 0; //No error
+ return 0; //No error
}
-static void insertTimer(struct timerEvent * newTimer) {
- struct timerEvent * nextTimer;
- // Search where to insert this new timer
- for (nextTimer = timersList.next; nextTimer != &timersList; nextTimer = nextTimer->next) {
- if(newTimer->triggerTime < nextTimer->triggerTime)
- break;
- }
- // Insert this new timer
- newTimer->next = nextTimer;
- newTimer->prev = nextTimer->prev;
- nextTimer->prev->next = newTimer;
- nextTimer->prev = newTimer;
+static void insertTimer(struct timerEvent *newTimer) {
+ struct timerEvent *nextTimer;
+ // Search where to insert this new timer
+ for (nextTimer = timersList.next; nextTimer != &timersList; nextTimer = nextTimer->next) {
+ if (newTimer->triggerTime < nextTimer->triggerTime)
+ break;
+ }
+ // Insert this new timer
+ newTimer->next = nextTimer;
+ newTimer->prev = nextTimer->prev;
+ nextTimer->prev->next = newTimer;
+ nextTimer->prev = newTimer;
#if defined(TIMER_LOGD)
dumpTimers();
@@ -2978,518 +3089,559 @@ static void insertTimer(struct timerEvent * newTimer) {
static void timerThreadStart(LPVOID lpThreadParameter) {
TIMER_LOGD("timerThreadStart() START");
pthread_mutex_lock(&timerEventsLock);
- while (!timerThreadToEnd) {
- TIMER_LOGD("timerThreadStart() %ld", GetTickCount64());
+ while (!timerThreadToEnd) {
+ TIMER_LOGD("timerThreadStart() %ld", GetTickCount64());
- int sleep_time;
- for (;;) {
- struct timerEvent *timer = (timersList.next == &timersList ? NULL : timersList.next);
- if (!timer) {
- sleep_time = -1;
- break;
- }
+ int sleep_time;
+ for (;;) {
+ struct timerEvent *timer = (timersList.next == &timersList ? NULL : timersList.next);
+ if (!timer) {
+ sleep_time = -1;
+ break;
+ }
- sleep_time = timer->triggerTime - GetTickCount64();
- if (sleep_time > 0)
- break;
+ sleep_time = timer->triggerTime - GetTickCount64();
+ if (sleep_time > 0)
+ break;
- // Remove this timer from the linked list
- timer->next->prev = timer->prev;
- timer->prev->next = timer->next;
+ // Remove this timer from the linked list
+ timer->next->prev = timer->prev;
+ timer->prev->next = timer->next;
- struct timerEvent *timerToFree;
- if(timer->fuEvent == TIME_PERIODIC) {
- timer->triggerTime += timer->uDelay;
- /* Re-insert the timer */
- insertTimer(timer);
- timerToFree = NULL;
- } else
- timerToFree = timer;
+ struct timerEvent *timerToFree;
+ if (timer->fuEvent == TIME_PERIODIC) {
+ timer->triggerTime += timer->uDelay;
+ /* Re-insert the timer */
+ insertTimer(timer);
+ timerToFree = NULL;
+ } else
+ timerToFree = timer;
- // Copy the timer data because we unlock the mutex!
- int timerId = timer->timerId;
- LPTIMECALLBACK fptc = timer->fptc;
- DWORD_PTR dwUser = timer->dwUser;
+ // Copy the timer data because we unlock the mutex!
+ int timerId = timer->timerId;
+ LPTIMECALLBACK fptc = timer->fptc;
+ DWORD_PTR dwUser = timer->dwUser;
- pthread_mutex_unlock(&timerEventsLock);
+ pthread_mutex_unlock(&timerEventsLock);
- // Call the timer callback now!
- fptc((UINT)timerId, 0, (DWORD) dwUser, 0, 0);
+ // Call the timer callback now!
+ fptc((UINT) timerId, 0, (DWORD) dwUser, 0, 0);
- pthread_mutex_lock(&timerEventsLock);
- if(timerToFree)
- free(timerToFree);
- }
+ pthread_mutex_lock(&timerEventsLock);
+ if (timerToFree)
+ free(timerToFree);
+ }
#if defined(TIMER_LOGD)
- dumpTimers();
+ dumpTimers();
#endif
- if (sleep_time < 0)
- break;
- if (sleep_time == 0)
- continue;
+ if (sleep_time < 0)
+ break;
+ if (sleep_time == 0)
+ continue;
- pthread_mutex_unlock(&timerEventsLock);
- Sleep(sleep_time > 100 ? 100 : sleep_time);
- pthread_mutex_lock(&timerEventsLock);
- }
- timerThreadId = 0;
- pthread_mutex_unlock(&timerEventsLock);
- jniDetachCurrentThread();
+ pthread_mutex_unlock(&timerEventsLock);
+ Sleep(sleep_time > 100 ? 100 : sleep_time);
+ pthread_mutex_lock(&timerEventsLock);
+ }
+ timerThreadId = 0;
+ pthread_mutex_unlock(&timerEventsLock);
+ jniDetachCurrentThread();
TIMER_LOGD("timerThreadStart() END");
}
-MMRESULT timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent) {
- TIMER_LOGD("timeSetEvent(uDelay: %d, fuEvent: %d)", uDelay, fuEvent);
+MMRESULT
+timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent) {
+ TIMER_LOGD("timeSetEvent(uDelay: %d, fuEvent: %d)", uDelay, fuEvent);
- struct timerEvent * newTimer = (struct timerEvent *)malloc(sizeof(struct timerEvent));
+ struct timerEvent *newTimer = (struct timerEvent *) malloc(sizeof(struct timerEvent));
- pthread_mutex_lock(&timerEventsLock);
+ pthread_mutex_lock(&timerEventsLock);
- newTimer->timerId = ++lastTimerId;
- newTimer->uDelay = uDelay; // In ms
- newTimer->uResolution = uResolution;
- newTimer->fptc = fptc;
- newTimer->dwUser = dwUser;
- newTimer->fuEvent = fuEvent; // TIME_ONESHOT / TIME_PERIODIC
+ newTimer->timerId = ++lastTimerId;
+ newTimer->uDelay = uDelay; // In ms
+ newTimer->uResolution = uResolution;
+ newTimer->fptc = fptc;
+ newTimer->dwUser = dwUser;
+ newTimer->fuEvent = fuEvent; // TIME_ONESHOT / TIME_PERIODIC
- newTimer->triggerTime = GetTickCount64() + (ULONGLONG)uDelay;
+ newTimer->triggerTime = GetTickCount64() + (ULONGLONG) uDelay;
- insertTimer(newTimer);
+ insertTimer(newTimer);
- timerThreadToEnd = FALSE;
+ timerThreadToEnd = FALSE;
- if(!timerThreadId) {
- // If not yet created, create the thread which will handle all the timers
- TIMER_LOGD("timeSetEvent() pthread_create");
- if (pthread_create(&timerThreadId, NULL, (void *(*)(void *)) timerThreadStart, NULL) != 0) {
- TIMER_LOGD("timeSetEvent() ERROR in pthread_create, errno: %d (EAGAIN 11 / EINVAL 22 / EPERM 1)", errno);
- // EAGAIN Insufficient resources to create another thread.
- // EINVAL Invalid settings in attr.
- // ENOMEM No permission to set the scheduling policy and parameters specified in attr.
- pthread_mutex_unlock(&timerEventsLock);
- return NULL;
- }
- }
+ if (!timerThreadId) {
+ // If not yet created, create the thread which will handle all the timers
+ TIMER_LOGD("timeSetEvent() pthread_create");
+ if (pthread_create(&timerThreadId, NULL, (void *(*)(void *)) timerThreadStart, NULL) != 0) {
+ TIMER_LOGD(
+ "timeSetEvent() ERROR in pthread_create, errno: %d (EAGAIN 11 / EINVAL 22 / EPERM 1)",
+ errno);
+ // EAGAIN Insufficient resources to create another thread.
+ // EINVAL Invalid settings in attr.
+ // ENOMEM No permission to set the scheduling policy and parameters specified in attr.
+ pthread_mutex_unlock(&timerEventsLock);
+ return NULL;
+ }
+ }
- TIMER_LOGD("timeSetEvent() -> timerId: [%d]", newTimer->timerId);
- pthread_mutex_unlock(&timerEventsLock);
- return (MMRESULT) newTimer->timerId; // No error
+ TIMER_LOGD("timeSetEvent() -> timerId: [%d]", newTimer->timerId);
+ pthread_mutex_unlock(&timerEventsLock);
+ return (MMRESULT) newTimer->timerId; // No error
}
MMRESULT timeGetDevCaps(LPTIMECAPS ptc, UINT cbtc) {
- if(ptc) {
- ptc->wPeriodMin = 1; // ms
- ptc->wPeriodMax = 1000000; // ms -> 1000s
- }
- return 0; //No error
+ if (ptc) {
+ ptc->wPeriodMin = 1; // ms
+ ptc->wPeriodMax = 1000000; // ms -> 1000s
+ }
+ return 0; //No error
}
+
MMRESULT timeBeginPeriod(UINT uPeriod) {
- //TODO
- return 0; //No error
+ //TODO
+ return 0; //No error
}
+
MMRESULT timeEndPeriod(UINT uPeriod) {
- //TODO
- return 0; //No error
+ //TODO
+ return 0; //No error
}
+
VOID GetLocalTime(LPSYSTEMTIME lpSystemTime) {
- if(lpSystemTime) {
- struct timespec ts = {0, 0};
- struct tm tm = {};
- clock_gettime(CLOCK_REALTIME, &ts);
- time_t tim = ts.tv_sec;
- localtime_r(&tim, &tm);
- lpSystemTime->wYear = (WORD) (1900 + tm.tm_year);
- lpSystemTime->wMonth = (WORD) (1 + tm.tm_mon);
- lpSystemTime->wDayOfWeek = (WORD) (tm.tm_wday);
- lpSystemTime->wDay = (WORD) (tm.tm_mday);
- lpSystemTime->wHour = (WORD) (tm.tm_hour);
- lpSystemTime->wMinute = (WORD) (tm.tm_min);
- lpSystemTime->wSecond = (WORD) (tm.tm_sec);
- lpSystemTime->wMilliseconds = (WORD) (ts.tv_nsec / 1e6);
- }
+ if (lpSystemTime) {
+ struct timespec ts = {0, 0};
+ struct tm tm = {};
+ clock_gettime(CLOCK_REALTIME, &ts);
+ time_t tim = ts.tv_sec;
+ localtime_r(&tim, &tm);
+ lpSystemTime->wYear = (WORD) (1900 + tm.tm_year);
+ lpSystemTime->wMonth = (WORD) (1 + tm.tm_mon);
+ lpSystemTime->wDayOfWeek = (WORD) (tm.tm_wday);
+ lpSystemTime->wDay = (WORD) (tm.tm_mday);
+ lpSystemTime->wHour = (WORD) (tm.tm_hour);
+ lpSystemTime->wMinute = (WORD) (tm.tm_min);
+ lpSystemTime->wSecond = (WORD) (tm.tm_sec);
+ lpSystemTime->wMilliseconds = (WORD) (ts.tv_nsec / 1e6);
+ }
}
+
ULONGLONG GetTickCount64(VOID) {
- struct timespec now;
- if (clock_gettime(CLOCK_MONOTONIC, &now))
- return 0;
- return (ULONGLONG) ((ULONGLONG)now.tv_sec * 1000UL + (ULONGLONG)now.tv_nsec / 1000000UL);
+ struct timespec now;
+ if (clock_gettime(CLOCK_MONOTONIC, &now))
+ return 0;
+ return (ULONGLONG) ((ULONGLONG) now.tv_sec * 1000UL + (ULONGLONG) now.tv_nsec / 1000000UL);
}
+
DWORD GetTickCount(VOID) {
- return (DWORD)GetTickCount64();
+ return (DWORD) GetTickCount64();
}
BOOL EnableWindow(HWND hWnd, BOOL bEnable) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
HWND GetDlgItem(HWND hDlg, int nIDDlgItem) {
- //TODO
- return NULL;
+ //TODO
+ return NULL;
}
-UINT GetDlgItemTextA(HWND hDlg, int nIDDlgItem, LPSTR lpString,int cchMax) {
- //TODO
- return 0;
+
+UINT GetDlgItemTextA(HWND hDlg, int nIDDlgItem, LPSTR lpString, int cchMax) {
+ //TODO
+ return 0;
}
extern TCHAR szKmlLog[10240];
extern TCHAR szKmlTitle[10240];
BOOL SetDlgItemText(HWND hDlg, int nIDDlgItem, LPCTSTR lpString) {
- if(nIDDlgItem == IDC_KMLLOG) {
- //LOGD("KML log:\r\n%s", lpString);
- _tcsncpy(szKmlLog, lpString, sizeof(szKmlLog)/sizeof(TCHAR));
- } if(nIDDlgItem == IDC_TITLE) {
- _tcsncpy(szKmlTitle, lpString, sizeof(szKmlTitle)/sizeof(TCHAR));
- }
- //TODO
- return 0;
+ if (nIDDlgItem == IDC_KMLLOG) {
+ //LOGD("KML log:\r\n%s", lpString);
+ _tcsncpy(szKmlLog, lpString, sizeof(szKmlLog) / sizeof(TCHAR));
+ }
+ if (nIDDlgItem == IDC_TITLE) {
+ _tcsncpy(szKmlTitle, lpString, sizeof(szKmlTitle) / sizeof(TCHAR));
+ }
+ //TODO
+ return 0;
}
+
LRESULT SendDlgItemMessage(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
BOOL CheckDlgButton(HWND hDlg, int nIDButton, UINT uCheck) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
UINT IsDlgButtonChecked(HWND hDlg, int nIDButton) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
BOOL EndDialog(HWND hDlg, INT_PTR nResult) {
- //TODO
- if(currentDialogBoxMode == DialogBoxMode_GET_USRPRG32
- || currentDialogBoxMode == DialogBoxMode_GET_USRPRG42
- || currentDialogBoxMode == DialogBoxMode_SET_USRPRG32
- || currentDialogBoxMode == DialogBoxMode_SET_USRPRG42) {
- itemDataCount = 0;
- selItemDataCount = 0;
- }
- return 0;
+ //TODO
+ if (currentDialogBoxMode == DialogBoxMode_GET_USRPRG32
+ || currentDialogBoxMode == DialogBoxMode_GET_USRPRG42
+ || currentDialogBoxMode == DialogBoxMode_SET_USRPRG32
+ || currentDialogBoxMode == DialogBoxMode_SET_USRPRG42) {
+ itemDataCount = 0;
+ selItemDataCount = 0;
+ }
+ return 0;
}
-HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) {
- //TODO
- return INVALID_HANDLE_VALUE;
+
+HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) {
+ //TODO
+ return INVALID_HANDLE_VALUE;
}
+
BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
BOOL FindClose(HANDLE hFindFile) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
BOOL SHGetPathFromIDListA(PCIDLIST_ABSOLUTE pidl, LPSTR pszPath) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
HRESULT SHGetMalloc(IMalloc **ppMalloc) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
+
PIDLIST_ABSOLUTE SHBrowseForFolderA(LPBROWSEINFOA lpbi) {
- //TODO
- return NULL;
+ //TODO
+ return NULL;
}
+
#ifndef IDD_USERCODE
- #define IDD_USERCODE 121
+#define IDD_USERCODE 121
#endif
-INT_PTR DialogBoxParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) {
- if(lpTemplateName == MAKEINTRESOURCE(IDD_CHOOSEKML)) {
- if(chooseCurrentKmlMode == ChooseKmlMode_UNKNOWN) {
- } else if(chooseCurrentKmlMode == ChooseKmlMode_FILE_NEW) {
- lstrcpy(szCurrentKml, szChosenCurrentKml);
- } else if(chooseCurrentKmlMode == ChooseKmlMode_FILE_OPEN || chooseCurrentKmlMode == ChooseKmlMode_FILE_OPEN_WITH_FOLDER) {
- // We are here because we open a state file and the embedded KML path is not reachable.
- // So, we try to find a correct KML file in the current Custom KML scripts folder.
- if(!getFirstKMLFilenameForType(Chipset.type)) {
- kmlFileNotFound = TRUE;
- return -1;
- }
- }
- } else if(lpTemplateName == MAKEINTRESOURCE(IDD_KMLLOG)) {
- lpDialogFunc(NULL, WM_INITDIALOG, 0, 0);
- } else if(lpTemplateName == MAKEINTRESOURCE(IDD_USERCODE)) {
- if(currentDialogBoxMode == DialogBoxMode_GET_USRPRG32
- || currentDialogBoxMode == DialogBoxMode_GET_USRPRG42) {
- itemDataCount = 0;
- selItemDataCount = 0;
- lpDialogFunc(NULL, WM_INITDIALOG, 0, 0);
- LPTSTR lpLabel = labels;
- for(int i = 0; i < itemDataCount; i++) {
- _tcscpy(lpLabel, itemString[i]);
- lpLabel += _tcslen(itemString[i]) * sizeof(TCHAR);
- *lpLabel = 9; // Separator (TAB)
- lpLabel++;
- }
- *lpLabel = 0; // End of string
- lpDialogFunc(NULL, WM_COMMAND, IDCANCEL, 0);
- } else if(currentDialogBoxMode == DialogBoxMode_SET_USRPRG32
- || currentDialogBoxMode == DialogBoxMode_SET_USRPRG42) {
- itemDataCount = 0;
- lpDialogFunc(NULL, WM_INITDIALOG, 0, 0);
- lpDialogFunc(NULL, WM_COMMAND, IDOK, 0);
- }
- }
- return IDOK;
+
+INT_PTR
+DialogBoxParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc,
+ LPARAM dwInitParam) {
+ if (lpTemplateName == MAKEINTRESOURCE(IDD_CHOOSEKML)) {
+ if (chooseCurrentKmlMode == ChooseKmlMode_UNKNOWN) {
+ } else if (chooseCurrentKmlMode == ChooseKmlMode_FILE_NEW) {
+ lstrcpy(szCurrentKml, szChosenCurrentKml);
+ } else if (chooseCurrentKmlMode == ChooseKmlMode_FILE_OPEN ||
+ chooseCurrentKmlMode == ChooseKmlMode_FILE_OPEN_WITH_FOLDER) {
+ // We are here because we open a state file and the embedded KML path is not reachable.
+ // So, we try to find a correct KML file in the current Custom KML scripts folder.
+ if (!getFirstKMLFilenameForType(Chipset.type)) {
+ kmlFileNotFound = TRUE;
+ return -1;
+ }
+ }
+ } else if (lpTemplateName == MAKEINTRESOURCE(IDD_KMLLOG)) {
+ lpDialogFunc(NULL, WM_INITDIALOG, 0, 0);
+ } else if (lpTemplateName == MAKEINTRESOURCE(IDD_USERCODE)) {
+ if (currentDialogBoxMode == DialogBoxMode_GET_USRPRG32
+ || currentDialogBoxMode == DialogBoxMode_GET_USRPRG42) {
+ itemDataCount = 0;
+ selItemDataCount = 0;
+ lpDialogFunc(NULL, WM_INITDIALOG, 0, 0);
+ LPTSTR lpLabel = labels;
+ for (int i = 0; i < itemDataCount; i++) {
+ _tcscpy(lpLabel, itemString[i]);
+ lpLabel += _tcslen(itemString[i]) * sizeof(TCHAR);
+ *lpLabel = 9; // Separator (TAB)
+ lpLabel++;
+ }
+ *lpLabel = 0; // End of string
+ lpDialogFunc(NULL, WM_COMMAND, IDCANCEL, 0);
+ } else if (currentDialogBoxMode == DialogBoxMode_SET_USRPRG32
+ || currentDialogBoxMode == DialogBoxMode_SET_USRPRG42) {
+ itemDataCount = 0;
+ lpDialogFunc(NULL, WM_INITDIALOG, 0, 0);
+ lpDialogFunc(NULL, WM_COMMAND, IDOK, 0);
+ }
+ }
+ return IDOK;
}
+
HCURSOR SetCursor(HCURSOR hCursor) {
- //TODO
- return NULL;
+ //TODO
+ return NULL;
}
+
int MulDiv(int nNumber, int nNumerator, int nDenominator) {
- //TODO
- return 0;
+ //TODO
+ return 0;
}
BOOL GetKeyboardLayoutName(LPSTR pwszKLID) {
- //TODO
- //Trick to bypass UnmapROM in KillKML
- if(pbyRom == NULL && pbyRomBackup)
+ //TODO
+ //Trick to bypass UnmapROM in KillKML
+ if (pbyRom == NULL && pbyRomBackup)
pbyRom = pbyRomBackup;
- return 0;
+ return 0;
}
void DragAcceptFiles(HWND hWnd, BOOL fAccept) {
- //TODO
+ //TODO
}
+int GetLocaleInfo(LCID Locale, LCTYPE LCType, LPSTR lpLCData, int cchData) {
+ //TODO
+ return 0;
+}
#ifdef UNICODE
-int WINAPI wvsprintf(LPWSTR, LPCWSTR, va_list arglist) {
- return vswprintf(arg1, MAX_PATH, arg2, arglist);
-}
-DWORD GetFullPathName(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR* lpFilePart) { return 0; }
-LPWSTR lstrcpyn(LPWSTR lpString1, LPCWSTR lpString2,int iMaxLength) {
- return strcpy(lpString1, lpString2);
-}
-LPWSTR lstrcat(LPWSTR lpString1, LPCWSTR lpString2) {
- return NULL;
-}
-void __cdecl _wsplitpath(wchar_t const* _FullPath, wchar_t* _Drive, wchar_t* _Dir, wchar_t* _Filename, wchar_t* _Ext) {}
-int WINAPI lstrcmp(LPCWSTR lpString1, LPCWSTR lpString2) {
- return wcscmp(lpString1, lpString2);
-}
-int lstrcmpi(LPCWSTR lpString1, LPCWSTR lpString2) {
- return wcscasecmp(lpString1, lpString2);
-}
-void _wmakepath(wchar_t _Buffer, wchar_t const* _Drive, wchar_t const* _Dir, wchar_t const* _Filename, wchar_t const* _Ext)
-{
-}
+ int WINAPI wvsprintf(LPWSTR, LPCWSTR, va_list arglist) {
+ return vswprintf(arg1, MAX_PATH, arg2, arglist);
+ }
+ DWORD GetFullPathName(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR* lpFilePart) { return 0; }
+ LPWSTR lstrcpyn(LPWSTR lpString1, LPCWSTR lpString2,int iMaxLength) {
+ return strcpy(lpString1, lpString2);
+ }
+ LPWSTR lstrcat(LPWSTR lpString1, LPCWSTR lpString2) {
+ return NULL;
+ }
+ void __cdecl _wsplitpath(wchar_t const* _FullPath, wchar_t* _Drive, wchar_t* _Dir, wchar_t* _Filename, wchar_t* _Ext) {}
+ int WINAPI lstrcmp(LPCWSTR lpString1, LPCWSTR lpString2) {
+ return wcscmp(lpString1, lpString2);
+ }
+ int lstrcmpi(LPCWSTR lpString1, LPCWSTR lpString2) {
+ return wcscasecmp(lpString1, lpString2);
+ }
+ void _wmakepath(wchar_t _Buffer, wchar_t const* _Drive, wchar_t const* _Dir, wchar_t const* _Filename, wchar_t const* _Ext)
+ {
+ }
#else
-int WINAPI wvsprintf(LPSTR arg1, LPCSTR arg2, va_list arglist) {
- return vsprintf(arg1, arg2, arglist);
-}
-const char pathSeparator =
+ int WINAPI wvsprintf(LPSTR arg1, LPCSTR arg2, va_list arglist) {
+ return vsprintf(arg1, arg2, arglist);
+ }
+ const char pathSeparator =
#ifdef _WIN32
- '\\';
+ '\\';
#else
- '/';
+ '/';
#endif
-DWORD GetFullPathName(LPCSTR lpFileName, DWORD nBufferLength, LPSTR lpBuffer, LPSTR* lpFilePart) {
- lstrcpyn(lpBuffer, lpFileName, nBufferLength);
- if(lpFilePart != NULL) {
- *lpFilePart = strrchr(lpBuffer, pathSeparator);
- if(*lpFilePart != NULL)
- (*lpFilePart)++;
- }
- return lstrlen(lpBuffer);
-}
-LPSTR lstrcpyn(LPSTR lpString1, LPCSTR lpString2,int iMaxLength) {
- return strcpy(lpString1, lpString2);
-}
-LPSTR lstrcat(LPSTR lpString1, LPCSTR lpString2) {
- return strcat(lpString1, lpString2);
-}
-void __cdecl _splitpath(const char * _FullPath, char* _Drive, char* _Dir, char* _Filename, char* _Ext) {
- if (_Drive)
- _Drive[0] = 0;
- char * filePart = strrchr(_FullPath, pathSeparator);
- if(_Dir) {
- if(filePart != NULL) {
- strncpy(_Dir, _FullPath, (int)(filePart - _FullPath));
- } else
- _Dir[0] = 0;
- }
- if(_Filename) {
- if(filePart != NULL) {
- strcpy(_Filename, filePart + 1);
- } else
- _Filename[0] = 0;
- }
- if(_Ext) {
- _Ext[0] = 0;
- if(_Filename) {
- char * extPart = strrchr(_Filename, '.');
- if (extPart != NULL) {
- strcpy(_Ext, extPart + 1);
- }
- }
- }
-}
-int WINAPI lstrcmp(LPCSTR lpString1, LPCSTR lpString2) {
- return strcmp(lpString1, lpString2);
-}
-int lstrcmpi(LPCSTR lpString1, LPCSTR lpString2) {
- return strcasecmp(lpString1, lpString2);
-}
+ DWORD
+ GetFullPathName(LPCSTR lpFileName, DWORD nBufferLength, LPSTR lpBuffer, LPSTR *lpFilePart) {
+ lstrcpyn(lpBuffer, lpFileName, nBufferLength);
+ if (lpFilePart != NULL) {
+ *lpFilePart = strrchr(lpBuffer, pathSeparator);
+ if (*lpFilePart != NULL)
+ (*lpFilePart)++;
+ }
+ return lstrlen(lpBuffer);
+ }
+ LPSTR lstrcpyn(LPSTR lpString1, LPCSTR lpString2, int iMaxLength) {
+ return strcpy(lpString1, lpString2);
+ }
+ LPSTR lstrcat(LPSTR lpString1, LPCSTR lpString2) {
+ return strcat(lpString1, lpString2);
+ }
+ void __cdecl
+ _splitpath(const char *_FullPath, char *_Drive, char *_Dir, char *_Filename, char *_Ext) {
+ if (_Drive)
+ _Drive[0] = 0;
+ char *filePart = strrchr(_FullPath, pathSeparator);
+ if (_Dir) {
+ if (filePart != NULL) {
+ strncpy(_Dir, _FullPath, (int) (filePart - _FullPath));
+ } else
+ _Dir[0] = 0;
+ }
+ if (_Filename) {
+ if (filePart != NULL) {
+ strcpy(_Filename, filePart + 1);
+ } else
+ _Filename[0] = 0;
+ }
+ if (_Ext) {
+ _Ext[0] = 0;
+ if (_Filename) {
+ char *extPart = strrchr(_Filename, '.');
+ if (extPart != NULL) {
+ strcpy(_Ext, extPart + 1);
+ }
+ }
+ }
+ }
+ int WINAPI lstrcmp(LPCSTR lpString1, LPCSTR lpString2) {
+ return strcmp(lpString1, lpString2);
+ }
+ int lstrcmpi(LPCSTR lpString1, LPCSTR lpString2) {
+ return strcasecmp(lpString1, lpString2);
+ }
-void _makepath(char _Buffer, char const* _Drive, char const* _Dir, char const* _Filename, char const* _Ext)
-{
-}
+ void _makepath(char _Buffer, char const *_Drive, char const *_Dir, char const *_Filename,
+ char const *_Ext) {
+ }
#endif // !UNICODE
-
-
-BOOL GetClientRect(HWND hWnd, LPRECT lpRect)
-{
- return 0;
-}
+ BOOL GetClientRect(HWND hWnd, LPRECT lpRect) {
+ return 0;
+ }
// IO
-BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait) {
- //TODO
- return FALSE;
-}
+ BOOL
+ GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred,
+ BOOL bWait) {
+ //TODO
+ return FALSE;
+ }
// This is not a win32 API
-void commEvent(int commId, int eventMask) {
- SERIAL_LOGD("commEvent(commId: %d, eventMask: 0x%08x)", commId, eventMask);
+ void commEvent(int commId, int eventMask) {
+ SERIAL_LOGD("commEvent(commId: %d, eventMask: 0x%08x)", commId, eventMask);
- HANDLE commHandleFound = NULL;
- pthread_mutex_lock(&commsLock);
- for(int i = 0; i < MAX_CREATED_COMM; i++) {
- HANDLE commHandle = comms[i];
- if (commHandle && commHandle->commId == commId) {
- commHandleFound = commHandle;
- break;
- }
- }
- pthread_mutex_unlock(&commsLock);
- if(commHandleFound) {
- commHandleFound->commEventMask = eventMask;
- SetEvent(commHandleFound->commEvent);
- }
-}
-
-BOOL WaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
- SERIAL_LOGD("WaitCommEvent(hFile: %p, lpEvtMask: %p)", hFile, lpEvtMask);
- if(hFile && hFile->handleType == HANDLE_TYPE_COM) {
- SERIAL_LOGD("WaitCommEvent(hFile: %p, lpEvtMask: %p) -> WaitForSingleObject locking", hFile, lpEvtMask);
- WaitForSingleObject(hFile->commEvent, INFINITE);
- SERIAL_LOGD("WaitCommEvent(hFile: %p, lpEvtMask: %p) -> WaitForSingleObject unlocked", hFile, lpEvtMask);
+ HANDLE commHandleFound = NULL;
pthread_mutex_lock(&commsLock);
- if(lpEvtMask && hFile->commEventMask) {
- *lpEvtMask = hFile->commEventMask; //EV_RXCHAR | EV_TXEMPTY | EV_ERR
- hFile->commEventMask = 0;
+ for (int i = 0; i < MAX_CREATED_COMM; i++) {
+ HANDLE commHandle = comms[i];
+ if (commHandle && commHandle->commId == commId) {
+ commHandleFound = commHandle;
+ break;
+ }
}
pthread_mutex_unlock(&commsLock);
- SERIAL_LOGD("WaitCommEvent(hFile: %p, lpEvtMask: %p) -> *lpEvtMask=%d", hFile, lpEvtMask, *lpEvtMask);
- return TRUE;
- }
- return FALSE;
-}
-BOOL ClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) {
- SERIAL_LOGD("ClearCommError(hFile: %p, lpErrors: %p, lpStat: %p) TODO", hFile, lpErrors, lpStat);
- //TODO
- return FALSE;
-}
-BOOL SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
- SERIAL_LOGD("SetCommTimeouts(hFile: %p, lpCommTimeouts: %p) TODO", hFile, lpCommTimeouts);
- //TODO
- return FALSE;
-}
-BOOL SetCommMask(HANDLE hFile, DWORD dwEvtMask) {
- SERIAL_LOGD("SetCommMask(hFile: %p, dwEvtMask: 0x%08X) TODO", hFile, dwEvtMask);
- //TODO
- if(hFile && hFile->handleType == HANDLE_TYPE_COM) {
- if(dwEvtMask == 0) {
- // When 0, clear all events and force WaitCommEvent to return.
- SERIAL_LOGD("SetCommMask(hFile: %p, dwEvtMask: 0x%08X) SetEvent(hEvent: %p)", hFile, dwEvtMask, hFile->commEvent);
- SetEvent(hFile->commEvent);
- return TRUE;
+ if (commHandleFound) {
+ commHandleFound->commEventMask = eventMask;
+ SetEvent(commHandleFound->commEvent);
}
}
- return FALSE;
-}
-BOOL SetCommState(HANDLE hFile, LPDCB lpDCB) {
- SERIAL_LOGD("SetCommState(hFile: %p, lpDCB: %p)", hFile, lpDCB);
- if(hFile && hFile->handleType == HANDLE_TYPE_COM && lpDCB) {
- int result = setSerialPortParameters(hFile->commId, lpDCB->BaudRate); //TODO 2 stop bits?
- if(result > 0) {
- if (hFile->commState)
- free(hFile->commState);
- hFile->commState = malloc(sizeof(struct _DCB));
- memcpy(hFile->commState, lpDCB, sizeof(struct _DCB));
- }
- return TRUE;
- }
- return FALSE;
-}
-BOOL PurgeComm(HANDLE hFile, DWORD dwFlags) {
- SERIAL_LOGD("PurgeComm(hFile: %p, dwFlags: 0x%08X) TODO", hFile, dwFlags);
- if(hFile && hFile->handleType == HANDLE_TYPE_COM)
- return serialPortPurgeComm(hFile->commId, dwFlags);
- return FALSE;
-}
-BOOL SetCommBreak(HANDLE hFile) {
- SERIAL_LOGD("SetCommBreak(hFile: %p)", hFile);
- if(hFile && hFile->handleType == HANDLE_TYPE_COM)
- return serialPortSetBreak(hFile->commId);
- return FALSE;
-}
-BOOL ClearCommBreak(HANDLE hFile) {
- SERIAL_LOGD("ClearCommBreak(hFile: %p)", hFile);
- if(hFile && hFile->handleType == HANDLE_TYPE_COM)
- return serialPortClearBreak(hFile->commId);
- return FALSE;
-}
+
+ BOOL WaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
+ SERIAL_LOGD("WaitCommEvent(hFile: %p, lpEvtMask: %p)", hFile, lpEvtMask);
+ if (hFile && hFile->handleType == HANDLE_TYPE_COM) {
+ SERIAL_LOGD("WaitCommEvent(hFile: %p, lpEvtMask: %p) -> WaitForSingleObject locking",
+ hFile, lpEvtMask);
+ WaitForSingleObject(hFile->commEvent, INFINITE);
+ SERIAL_LOGD("WaitCommEvent(hFile: %p, lpEvtMask: %p) -> WaitForSingleObject unlocked",
+ hFile, lpEvtMask);
+ pthread_mutex_lock(&commsLock);
+ if (lpEvtMask && hFile->commEventMask) {
+ *lpEvtMask = hFile->commEventMask; //EV_RXCHAR | EV_TXEMPTY | EV_ERR
+ hFile->commEventMask = 0;
+ }
+ pthread_mutex_unlock(&commsLock);
+ SERIAL_LOGD("WaitCommEvent(hFile: %p, lpEvtMask: %p) -> *lpEvtMask=%d", hFile,
+ lpEvtMask, *lpEvtMask);
+ return TRUE;
+ }
+ return FALSE;
+ }
+ BOOL ClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) {
+ SERIAL_LOGD("ClearCommError(hFile: %p, lpErrors: %p, lpStat: %p) TODO", hFile, lpErrors,
+ lpStat);
+ //TODO
+ return FALSE;
+ }
+ BOOL SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
+ SERIAL_LOGD("SetCommTimeouts(hFile: %p, lpCommTimeouts: %p) TODO", hFile, lpCommTimeouts);
+ //TODO
+ return FALSE;
+ }
+ BOOL SetCommMask(HANDLE hFile, DWORD dwEvtMask) {
+ SERIAL_LOGD("SetCommMask(hFile: %p, dwEvtMask: 0x%08X) TODO", hFile, dwEvtMask);
+ //TODO
+ if (hFile && hFile->handleType == HANDLE_TYPE_COM) {
+ if (dwEvtMask == 0) {
+ // When 0, clear all events and force WaitCommEvent to return.
+ SERIAL_LOGD("SetCommMask(hFile: %p, dwEvtMask: 0x%08X) SetEvent(hEvent: %p)", hFile,
+ dwEvtMask, hFile->commEvent);
+ SetEvent(hFile->commEvent);
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ BOOL SetCommState(HANDLE hFile, LPDCB lpDCB) {
+ SERIAL_LOGD("SetCommState(hFile: %p, lpDCB: %p)", hFile, lpDCB);
+ if (hFile && hFile->handleType == HANDLE_TYPE_COM && lpDCB) {
+ int result = setSerialPortParameters(hFile->commId,
+ lpDCB->BaudRate); //TODO 2 stop bits?
+ if (result > 0) {
+ if (hFile->commState)
+ free(hFile->commState);
+ hFile->commState = malloc(sizeof(struct _DCB));
+ memcpy(hFile->commState, lpDCB, sizeof(struct _DCB));
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+ BOOL PurgeComm(HANDLE hFile, DWORD dwFlags) {
+ SERIAL_LOGD("PurgeComm(hFile: %p, dwFlags: 0x%08X) TODO", hFile, dwFlags);
+ if (hFile && hFile->handleType == HANDLE_TYPE_COM)
+ return serialPortPurgeComm(hFile->commId, dwFlags);
+ return FALSE;
+ }
+ BOOL SetCommBreak(HANDLE hFile) {
+ SERIAL_LOGD("SetCommBreak(hFile: %p)", hFile);
+ if (hFile && hFile->handleType == HANDLE_TYPE_COM)
+ return serialPortSetBreak(hFile->commId);
+ return FALSE;
+ }
+ BOOL ClearCommBreak(HANDLE hFile) {
+ SERIAL_LOGD("ClearCommBreak(hFile: %p)", hFile);
+ if (hFile && hFile->handleType == HANDLE_TYPE_COM)
+ return serialPortClearBreak(hFile->commId);
+ return FALSE;
+ }
-int WSAGetLastError() {
- //TODO
- // Win9x break with WSAEINTR (a blocking socket call was canceled)
+ int WSAGetLastError() {
+ //TODO
+ // Win9x break with WSAEINTR (a blocking socket call was canceled)
// if(errno == ECANCELED)
// return WSAEINTR;
- return 0;
-}
+ return 0;
+ }
-int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
- return 0;
-}
+ int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
+ return 0;
+ }
-int WSACleanup() {
- return 0;
-}
+ int WSACleanup() {
+ return 0;
+ }
-int closesocket(SOCKET s) {
- int err = shutdown(s, SHUT_RDWR);
- err = close(s);
-}
+ int closesocket(SOCKET s) {
+ int err = shutdown(s, SHUT_RDWR);
+ err = close(s);
+ }
-int win32_select(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, struct timeval* __timeout) {
- struct timeval timeout;
- if(__timeout == NULL) {
- timeout.tv_sec = 1; //0;
- timeout.tv_usec = 0; //500000;
- __timeout = &timeout;
- }
- return select(__fd_count, __read_fds, __write_fds, __exception_fds, __timeout);
-}
+ int
+ win32_select(int __fd_count, fd_set *__read_fds, fd_set *__write_fds, fd_set *__exception_fds,
+ struct timeval *__timeout) {
+ struct timeval timeout;
+ if (__timeout == NULL) {
+ timeout.tv_sec = 1; //0;
+ timeout.tv_usec = 0; //500000;
+ __timeout = &timeout;
+ }
+ return select(__fd_count, __read_fds, __write_fds, __exception_fds, __timeout);
+ }
-int win32_ioctlsocket(SOCKET s, long cmd, u_long FAR * argp) {
- //TODO
- return 0;
-}
+ int win32_ioctlsocket(SOCKET s, long cmd, u_long FAR *argp) {
+ //TODO
+ return 0;
+ }
diff --git a/app/src/main/cpp/win32-layer.h b/app/src/main/cpp/win32-layer.h
index 28d524c..0a6b3fe 100644
--- a/app/src/main/cpp/win32-layer.h
+++ b/app/src/main/cpp/win32-layer.h
@@ -1199,9 +1199,12 @@ typedef struct tagCOPYDATASTRUCT {
PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
-
-
-
+// Locale info
+#define LOCALE_USER_DEFAULT 1024
+#define LOCALE_SDECIMAL 0x0000000E // decimal separator, eg "." for 1,234.00
+typedef DWORD LCID;
+typedef DWORD LCTYPE;
+extern int GetLocaleInfo(LCID Locale, LCTYPE LCType, LPSTR lpLCData, int cchData);
#ifdef UNICODE
diff --git a/app/src/main/java/org/emulator/calculator/Serial.java b/app/src/main/java/org/emulator/calculator/Serial.java
index 5d351a1..9e6c018 100644
--- a/app/src/main/java/org/emulator/calculator/Serial.java
+++ b/app/src/main/java/org/emulator/calculator/Serial.java
@@ -158,7 +158,9 @@ public class Serial {
if(usbConnection == null && usbPermission == UsbPermission.Unknown && !usbManager.hasPermission(driver.getDevice())) {
usbPermission = UsbPermission.Requested;
int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_MUTABLE : 0;
- PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(INTENT_ACTION_GRANT_USB), flags);
+ Intent intent = new Intent(INTENT_ACTION_GRANT_USB);
+ intent.setPackage(context.getPackageName());
+ PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(context, 0, intent, flags);
usbManager.requestPermission(driver.getDevice(), usbPermissionIntent);
if(debug) Log.d(TAG, "Request permission");
connectionStatus = "serial_connection_failed_user_has_not_given_permission";
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/CdcAcmSerialDriver.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/CdcAcmSerialDriver.java
index 1dde5a0..df4d081 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/CdcAcmSerialDriver.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/CdcAcmSerialDriver.java
@@ -8,13 +8,11 @@ package org.emulator.calculator.usbserial.driver;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.util.Log;
-import org.emulator.calculator.usbserial.util.HexDump;
-import org.emulator.calculator.usbserial.util.UsbUtils;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
@@ -32,8 +30,6 @@ import java.util.Map;
*/
public class CdcAcmSerialDriver implements UsbSerialDriver {
- public static final int USB_SUBCLASS_ACM = 2;
-
private final String TAG = CdcAcmSerialDriver.class.getSimpleName();
private final UsbDevice mDevice;
@@ -42,31 +38,21 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
public CdcAcmSerialDriver(UsbDevice device) {
mDevice = device;
mPorts = new ArrayList<>();
- int ports = countPorts(device);
- for (int port = 0; port < ports; port++) {
- mPorts.add(new CdcAcmSerialPort(mDevice, port));
- }
- if (mPorts.size() == 0) {
- mPorts.add(new CdcAcmSerialPort(mDevice, -1));
- }
- }
- @SuppressWarnings({"unused"})
- public static boolean probe(UsbDevice device) {
- return countPorts(device) > 0;
- }
-
- private static int countPorts(UsbDevice device) {
int controlInterfaceCount = 0;
int dataInterfaceCount = 0;
- for (int i = 0; i < device.getInterfaceCount(); i++) {
- if (device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_COMM &&
- device.getInterface(i).getInterfaceSubclass() == USB_SUBCLASS_ACM)
+ for( int i = 0; i < device.getInterfaceCount(); i++) {
+ if(device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_COMM)
controlInterfaceCount++;
- if (device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA)
+ if(device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA)
dataInterfaceCount++;
}
- return Math.min(controlInterfaceCount, dataInterfaceCount);
+ for( int port = 0; port < Math.min(controlInterfaceCount, dataInterfaceCount); port++) {
+ mPorts.add(new CdcAcmSerialPort(mDevice, port));
+ }
+ if(mPorts.size() == 0) {
+ mPorts.add(new CdcAcmSerialPort(mDevice, -1));
+ }
}
@Override
@@ -109,11 +95,7 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
}
@Override
- protected void openInt() throws IOException {
- Log.d(TAG, "interfaces:");
- for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
- Log.d(TAG, mDevice.getInterface(i).toString());
- }
+ protected void openInt(UsbDeviceConnection connection) throws IOException {
if (mPortNumber == -1) {
Log.d(TAG,"device might be castrated ACM device, trying single interface logic");
openSingleInterface();
@@ -149,57 +131,38 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
}
private void openInterface() throws IOException {
+ Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
+ int controlInterfaceCount = 0;
+ int dataInterfaceCount = 0;
mControlInterface = null;
mDataInterface = null;
- int j = getInterfaceIdFromDescriptors();
- Log.d(TAG, "interface count=" + mDevice.getInterfaceCount() + ", IAD=" + j);
- if (j >= 0) {
- for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
- UsbInterface usbInterface = mDevice.getInterface(i);
- if (usbInterface.getId() == j || usbInterface.getId() == j+1) {
- if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_COMM &&
- usbInterface.getInterfaceSubclass() == USB_SUBCLASS_ACM) {
- mControlIndex = usbInterface.getId();
- mControlInterface = usbInterface;
- }
- if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
- mDataInterface = usbInterface;
- }
+ for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
+ UsbInterface usbInterface = mDevice.getInterface(i);
+ if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_COMM) {
+ if(controlInterfaceCount == mPortNumber) {
+ mControlIndex = i;
+ mControlInterface = usbInterface;
}
+ controlInterfaceCount++;
}
- }
- if (mControlInterface == null || mDataInterface == null) {
- Log.d(TAG, "no IAD fallback");
- int controlInterfaceCount = 0;
- int dataInterfaceCount = 0;
- for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
- UsbInterface usbInterface = mDevice.getInterface(i);
- if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_COMM &&
- usbInterface.getInterfaceSubclass() == USB_SUBCLASS_ACM) {
- if (controlInterfaceCount == mPortNumber) {
- mControlIndex = usbInterface.getId();
- mControlInterface = usbInterface;
- }
- controlInterfaceCount++;
- }
- if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
- if (dataInterfaceCount == mPortNumber) {
- mDataInterface = usbInterface;
- }
- dataInterfaceCount++;
+ if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {
+ if(dataInterfaceCount == mPortNumber) {
+ mDataInterface = usbInterface;
}
+ dataInterfaceCount++;
}
}
if(mControlInterface == null) {
throw new IOException("No control interface");
}
- Log.d(TAG, "Control interface id " + mControlInterface.getId());
+ Log.d(TAG, "Control iface=" + mControlInterface);
if (!mConnection.claimInterface(mControlInterface, true)) {
throw new IOException("Could not claim control interface");
}
+
mControlEndpoint = mControlInterface.getEndpoint(0);
if (mControlEndpoint.getDirection() != UsbConstants.USB_DIR_IN || mControlEndpoint.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
throw new IOException("Invalid control endpoint");
@@ -208,10 +171,12 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
if(mDataInterface == null) {
throw new IOException("No data interface");
}
- Log.d(TAG, "data interface id " + mDataInterface.getId());
+ Log.d(TAG, "data iface=" + mDataInterface);
+
if (!mConnection.claimInterface(mDataInterface, true)) {
throw new IOException("Could not claim data interface");
}
+
for (int i = 0; i < mDataInterface.getEndpointCount(); i++) {
UsbEndpoint ep = mDataInterface.getEndpoint(i);
if (ep.getDirection() == UsbConstants.USB_DIR_IN && ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
@@ -221,36 +186,6 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
}
}
- private int getInterfaceIdFromDescriptors() {
- ArrayList descriptors = UsbUtils.getDescriptors(mConnection);
- Log.d(TAG, "USB descriptor:");
- for(byte[] descriptor : descriptors)
- Log.d(TAG, HexDump.toHexString(descriptor));
-
- if (descriptors.size() > 0 &&
- descriptors.get(0).length == 18 &&
- descriptors.get(0)[1] == 1 && // bDescriptorType
- descriptors.get(0)[4] == (byte)(UsbConstants.USB_CLASS_MISC) && //bDeviceClass
- descriptors.get(0)[5] == 2 && // bDeviceSubClass
- descriptors.get(0)[6] == 1) { // bDeviceProtocol
- // is IAD device, see https://www.usb.org/sites/default/files/iadclasscode_r10.pdf
- int port = -1;
- for (int d = 1; d < descriptors.size(); d++) {
- if (descriptors.get(d).length == 8 &&
- descriptors.get(d)[1] == 0x0b && // bDescriptorType == IAD
- descriptors.get(d)[4] == UsbConstants.USB_CLASS_COMM && // bFunctionClass == CDC
- descriptors.get(d)[5] == USB_SUBCLASS_ACM) { // bFunctionSubClass == ACM
- port++;
- if (port == mPortNumber &&
- descriptors.get(d)[3] == 2) { // bInterfaceCount
- return descriptors.get(d)[2]; // bFirstInterface
- }
- }
- }
- }
- return -1;
- }
-
private int sendAcmControlMessage(int request, int value, byte[] buf) throws IOException {
int len = mConnection.controlTransfer(
USB_RT_ACM, request, value, mControlIndex, buf, buf != null ? buf.length : 0, 5000);
@@ -351,9 +286,42 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
}
- @SuppressWarnings({"unused"})
public static Map getSupportedDevices() {
- return new LinkedHashMap<>();
+ final Map supportedDevices = new LinkedHashMap<>();
+ supportedDevices.put(UsbId.VENDOR_ARDUINO,
+ new int[] {
+ UsbId.ARDUINO_UNO,
+ UsbId.ARDUINO_UNO_R3,
+ UsbId.ARDUINO_MEGA_2560,
+ UsbId.ARDUINO_MEGA_2560_R3,
+ UsbId.ARDUINO_SERIAL_ADAPTER,
+ UsbId.ARDUINO_SERIAL_ADAPTER_R3,
+ UsbId.ARDUINO_MEGA_ADK,
+ UsbId.ARDUINO_MEGA_ADK_R3,
+ UsbId.ARDUINO_LEONARDO,
+ UsbId.ARDUINO_MICRO,
+ });
+ supportedDevices.put(UsbId.VENDOR_VAN_OOIJEN_TECH,
+ new int[] {
+ UsbId.VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL,
+ });
+ supportedDevices.put(UsbId.VENDOR_ATMEL,
+ new int[] {
+ UsbId.ATMEL_LUFA_CDC_DEMO_APP,
+ });
+ supportedDevices.put(UsbId.VENDOR_LEAFLABS,
+ new int[] {
+ UsbId.LEAFLABS_MAPLE,
+ });
+ supportedDevices.put(UsbId.VENDOR_ARM,
+ new int[] {
+ UsbId.ARM_MBED,
+ });
+ supportedDevices.put(UsbId.VENDOR_ST,
+ new int[] {
+ UsbId.ST_CDC,
+ });
+ return supportedDevices;
}
}
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/Ch34xSerialDriver.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/Ch34xSerialDriver.java
index 415acee..dd09763 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/Ch34xSerialDriver.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/Ch34xSerialDriver.java
@@ -7,11 +7,9 @@ package org.emulator.calculator.usbserial.driver;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
-import android.util.Log;
-
-//import org.emulator.calculator.usbserial.BuildConfig;
import java.io.IOException;
import java.util.Collections;
@@ -22,366 +20,355 @@ import java.util.Map;
public class Ch34xSerialDriver implements UsbSerialDriver {
- private static final String TAG = Ch34xSerialDriver.class.getSimpleName();
+ private static final String TAG = Ch34xSerialDriver.class.getSimpleName();
- private final UsbDevice mDevice;
- private final UsbSerialPort mPort;
+ private final UsbDevice mDevice;
+ private final UsbSerialPort mPort;
- private static final int LCR_ENABLE_RX = 0x80;
- private static final int LCR_ENABLE_TX = 0x40;
- private static final int LCR_MARK_SPACE = 0x20;
- private static final int LCR_PAR_EVEN = 0x10;
- private static final int LCR_ENABLE_PAR = 0x08;
- private static final int LCR_STOP_BITS_2 = 0x04;
- private static final int LCR_CS8 = 0x03;
- private static final int LCR_CS7 = 0x02;
- private static final int LCR_CS6 = 0x01;
- private static final int LCR_CS5 = 0x00;
+ private static final int LCR_ENABLE_RX = 0x80;
+ private static final int LCR_ENABLE_TX = 0x40;
+ private static final int LCR_MARK_SPACE = 0x20;
+ private static final int LCR_PAR_EVEN = 0x10;
+ private static final int LCR_ENABLE_PAR = 0x08;
+ private static final int LCR_STOP_BITS_2 = 0x04;
+ private static final int LCR_CS8 = 0x03;
+ private static final int LCR_CS7 = 0x02;
+ private static final int LCR_CS6 = 0x01;
+ private static final int LCR_CS5 = 0x00;
- private static final int GCL_CTS = 0x01;
- private static final int GCL_DSR = 0x02;
- private static final int GCL_RI = 0x04;
- private static final int GCL_CD = 0x08;
- private static final int SCL_DTR = 0x20;
- private static final int SCL_RTS = 0x40;
+ private static final int GCL_CTS = 0x01;
+ private static final int GCL_DSR = 0x02;
+ private static final int GCL_RI = 0x04;
+ private static final int GCL_CD = 0x08;
+ private static final int SCL_DTR = 0x20;
+ private static final int SCL_RTS = 0x40;
- public Ch34xSerialDriver(UsbDevice device) {
- mDevice = device;
- mPort = new Ch340SerialPort(mDevice, 0);
- }
+ public Ch34xSerialDriver(UsbDevice device) {
+ mDevice = device;
+ mPort = new Ch340SerialPort(mDevice, 0);
+ }
- @Override
- public UsbDevice getDevice() {
- return mDevice;
- }
+ @Override
+ public UsbDevice getDevice() {
+ return mDevice;
+ }
- @Override
- public List getPorts() {
- return Collections.singletonList(mPort);
- }
+ @Override
+ public List getPorts() {
+ return Collections.singletonList(mPort);
+ }
- public class Ch340SerialPort extends CommonUsbSerialPort {
+ public class Ch340SerialPort extends CommonUsbSerialPort {
- private static final int USB_TIMEOUT_MILLIS = 5000;
+ private static final int USB_TIMEOUT_MILLIS = 5000;
- private final int DEFAULT_BAUD_RATE = 9600;
+ private final int DEFAULT_BAUD_RATE = 9600;
- private boolean dtr = false;
- private boolean rts = false;
+ private boolean dtr = false;
+ private boolean rts = false;
- public Ch340SerialPort(UsbDevice device, int portNumber) {
- super(device, portNumber);
- }
+ public Ch340SerialPort(UsbDevice device, int portNumber) {
+ super(device, portNumber);
+ }
- @Override
- public UsbSerialDriver getDriver() {
- return Ch34xSerialDriver.this;
- }
+ @Override
+ public UsbSerialDriver getDriver() {
+ return Ch34xSerialDriver.this;
+ }
- @Override
- protected void openInt() throws IOException {
- for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
- UsbInterface usbIface = mDevice.getInterface(i);
- if (!mConnection.claimInterface(usbIface, true)) {
- throw new IOException("Could not claim data interface");
- }
- }
+ @Override
+ protected void openInt(UsbDeviceConnection connection) throws IOException {
+ for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
+ UsbInterface usbIface = mDevice.getInterface(i);
+ if (!mConnection.claimInterface(usbIface, true)) {
+ throw new IOException("Could not claim data interface");
+ }
+ }
- UsbInterface dataIface = mDevice.getInterface(mDevice.getInterfaceCount() - 1);
- for (int i = 0; i < dataIface.getEndpointCount(); i++) {
- UsbEndpoint ep = dataIface.getEndpoint(i);
- if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
- if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
- mReadEndpoint = ep;
- } else {
- mWriteEndpoint = ep;
- }
- }
- }
+ UsbInterface dataIface = mDevice.getInterface(mDevice.getInterfaceCount() - 1);
+ for (int i = 0; i < dataIface.getEndpointCount(); i++) {
+ UsbEndpoint ep = dataIface.getEndpoint(i);
+ if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
+ if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
+ mReadEndpoint = ep;
+ } else {
+ mWriteEndpoint = ep;
+ }
+ }
+ }
- initialize();
- setBaudRate(DEFAULT_BAUD_RATE);
- }
+ initialize();
+ setBaudRate(DEFAULT_BAUD_RATE);
+ }
- @Override
- protected void closeInt() {
- try {
- for (int i = 0; i < mDevice.getInterfaceCount(); i++)
- mConnection.releaseInterface(mDevice.getInterface(i));
- } catch(Exception ignored) {}
- }
+ @Override
+ protected void closeInt() {
+ try {
+ for (int i = 0; i < mDevice.getInterfaceCount(); i++)
+ mConnection.releaseInterface(mDevice.getInterface(i));
+ } catch(Exception ignored) {}
+ }
- private int controlOut(int request, int value, int index) {
- final int REQTYPE_HOST_TO_DEVICE = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT;
- return mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, request,
- value, index, null, 0, USB_TIMEOUT_MILLIS);
- }
+ private int controlOut(int request, int value, int index) {
+ final int REQTYPE_HOST_TO_DEVICE = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT;
+ return mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, request,
+ value, index, null, 0, USB_TIMEOUT_MILLIS);
+ }
- private int controlIn(int request, int value, int index, byte[] buffer) {
- final int REQTYPE_DEVICE_TO_HOST = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN;
- return mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, request,
- value, index, buffer, buffer.length, USB_TIMEOUT_MILLIS);
- }
+ private int controlIn(int request, int value, int index, byte[] buffer) {
+ final int REQTYPE_DEVICE_TO_HOST = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN;
+ return mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, request,
+ value, index, buffer, buffer.length, USB_TIMEOUT_MILLIS);
+ }
- private void checkState(String msg, int request, int value, int[] expected) throws IOException {
- byte[] buffer = new byte[expected.length];
- int ret = controlIn(request, value, 0, buffer);
+ private void checkState(String msg, int request, int value, int[] expected) throws IOException {
+ byte[] buffer = new byte[expected.length];
+ int ret = controlIn(request, value, 0, buffer);
- if (ret < 0) {
- throw new IOException("Failed send cmd [" + msg + "]");
- }
+ if (ret < 0) {
+ throw new IOException("Failed send cmd [" + msg + "]");
+ }
- if (ret != expected.length) {
- throw new IOException("Expected " + expected.length + " bytes, but get " + ret + " [" + msg + "]");
- }
+ if (ret != expected.length) {
+ throw new IOException("Expected " + expected.length + " bytes, but get " + ret + " [" + msg + "]");
+ }
- for (int i = 0; i < expected.length; i++) {
- if (expected[i] == -1) {
- continue;
- }
+ for (int i = 0; i < expected.length; i++) {
+ if (expected[i] == -1) {
+ continue;
+ }
- int current = buffer[i] & 0xff;
- if (expected[i] != current) {
- throw new IOException("Expected 0x" + Integer.toHexString(expected[i]) + " byte, but get 0x" + Integer.toHexString(current) + " [" + msg + "]");
- }
- }
- }
+ int current = buffer[i] & 0xff;
+ if (expected[i] != current) {
+ throw new IOException("Expected 0x" + Integer.toHexString(expected[i]) + " byte, but get 0x" + Integer.toHexString(current) + " [" + msg + "]");
+ }
+ }
+ }
- private void setControlLines() throws IOException {
- if (controlOut(0xa4, ~((dtr ? SCL_DTR : 0) | (rts ? SCL_RTS : 0)), 0) < 0) {
- throw new IOException("Failed to set control lines");
- }
- }
+ private void setControlLines() throws IOException {
+ if (controlOut(0xa4, ~((dtr ? SCL_DTR : 0) | (rts ? SCL_RTS : 0)), 0) < 0) {
+ throw new IOException("Failed to set control lines");
+ }
+ }
- private byte getStatus() throws IOException {
- byte[] buffer = new byte[2];
- int ret = controlIn(0x95, 0x0706, 0, buffer);
- if (ret < 0)
- throw new IOException("Error getting control lines");
- return buffer[0];
- }
+ private byte getStatus() throws IOException {
+ byte[] buffer = new byte[2];
+ int ret = controlIn(0x95, 0x0706, 0, buffer);
+ if (ret < 0)
+ throw new IOException("Error getting control lines");
+ return buffer[0];
+ }
- private void initialize() throws IOException {
- checkState("init #1", 0x5f, 0, new int[]{-1 /* 0x27, 0x30 */, 0x00});
+ private void initialize() throws IOException {
+ checkState("init #1", 0x5f, 0, new int[]{-1 /* 0x27, 0x30 */, 0x00});
- if (controlOut(0xa1, 0, 0) < 0) {
- throw new IOException("Init failed: #2");
- }
+ if (controlOut(0xa1, 0, 0) < 0) {
+ throw new IOException("Init failed: #2");
+ }
- setBaudRate(DEFAULT_BAUD_RATE);
+ setBaudRate(DEFAULT_BAUD_RATE);
- checkState("init #4", 0x95, 0x2518, new int[]{-1 /* 0x56, c3*/, 0x00});
+ checkState("init #4", 0x95, 0x2518, new int[]{-1 /* 0x56, c3*/, 0x00});
- if (controlOut(0x9a, 0x2518, LCR_ENABLE_RX | LCR_ENABLE_TX | LCR_CS8) < 0) {
- throw new IOException("Init failed: #5");
- }
+ if (controlOut(0x9a, 0x2518, LCR_ENABLE_RX | LCR_ENABLE_TX | LCR_CS8) < 0) {
+ throw new IOException("Init failed: #5");
+ }
- checkState("init #6", 0x95, 0x0706, new int[]{-1/*0xf?*/, -1/*0xec,0xee*/});
+ checkState("init #6", 0x95, 0x0706, new int[]{-1/*0xf?*/, -1/*0xec,0xee*/});
- if (controlOut(0xa1, 0x501f, 0xd90a) < 0) {
- throw new IOException("Init failed: #7");
- }
+ if (controlOut(0xa1, 0x501f, 0xd90a) < 0) {
+ throw new IOException("Init failed: #7");
+ }
- setBaudRate(DEFAULT_BAUD_RATE);
+ setBaudRate(DEFAULT_BAUD_RATE);
- setControlLines();
+ setControlLines();
- checkState("init #10", 0x95, 0x0706, new int[]{-1/* 0x9f, 0xff*/, -1/*0xec,0xee*/});
- }
+ checkState("init #10", 0x95, 0x0706, new int[]{-1/* 0x9f, 0xff*/, -1/*0xec,0xee*/});
+ }
- private void setBaudRate(int baudRate) throws IOException {
- long factor;
- long divisor;
+ private void setBaudRate(int baudRate) throws IOException {
+ final long CH341_BAUDBASE_FACTOR = 1532620800;
+ final int CH341_BAUDBASE_DIVMAX = 3;
- if (baudRate == 921600) {
- divisor = 7;
- factor = 0xf300;
- } else {
- final long BAUDBASE_FACTOR = 1532620800;
- final int BAUDBASE_DIVMAX = 3;
+ long factor = CH341_BAUDBASE_FACTOR / baudRate;
+ int divisor = CH341_BAUDBASE_DIVMAX;
-// if(BuildConfig.DEBUG && (baudRate & (3<<29)) == (1<<29))
-// baudRate &= ~(1<<29); // for testing purpose bypass dedicated baud rate handling
- factor = BAUDBASE_FACTOR / baudRate;
- divisor = BAUDBASE_DIVMAX;
- while ((factor > 0xfff0) && divisor > 0) {
- factor >>= 3;
- divisor--;
- }
- if (factor > 0xfff0) {
- throw new UnsupportedOperationException("Unsupported baud rate: " + baudRate);
- }
- factor = 0x10000 - factor;
- }
+ while ((factor > 0xfff0) && divisor > 0) {
+ factor >>= 3;
+ divisor--;
+ }
- divisor |= 0x0080; // else ch341a waits until buffer full
- int val1 = (int) ((factor & 0xff00) | divisor);
- int val2 = (int) (factor & 0xff);
- Log.d(TAG, String.format("baud rate=%d, 0x1312=0x%04x, 0x0f2c=0x%04x", baudRate, val1, val2));
- int ret = controlOut(0x9a, 0x1312, val1);
- if (ret < 0) {
- throw new IOException("Error setting baud rate: #1)");
- }
- ret = controlOut(0x9a, 0x0f2c, val2);
- if (ret < 0) {
- throw new IOException("Error setting baud rate: #2");
- }
- }
+ if (factor > 0xfff0) {
+ throw new UnsupportedOperationException("Unsupported baud rate: " + baudRate);
+ }
- @Override
- public void setParameters(int baudRate, int dataBits, int stopBits, @Parity int parity) throws IOException {
- if(baudRate <= 0) {
- throw new IllegalArgumentException("Invalid baud rate: " + baudRate);
- }
- setBaudRate(baudRate);
+ factor = 0x10000 - factor;
+ divisor |= 0x0080; // else ch341a waits until buffer full
+ int ret = controlOut(0x9a, 0x1312, (int) ((factor & 0xff00) | divisor));
+ if (ret < 0) {
+ throw new IOException("Error setting baud rate: #1)");
+ }
- int lcr = LCR_ENABLE_RX | LCR_ENABLE_TX;
+ ret = controlOut(0x9a, 0x0f2c, (int) (factor & 0xff));
+ if (ret < 0) {
+ throw new IOException("Error setting baud rate: #2");
+ }
+ }
- switch (dataBits) {
- case DATABITS_5:
- lcr |= LCR_CS5;
- break;
- case DATABITS_6:
- lcr |= LCR_CS6;
- break;
- case DATABITS_7:
- lcr |= LCR_CS7;
- break;
- case DATABITS_8:
- lcr |= LCR_CS8;
- break;
- default:
- throw new IllegalArgumentException("Invalid data bits: " + dataBits);
- }
+ @Override
+ public void setParameters(int baudRate, int dataBits, int stopBits, @Parity int parity) throws IOException {
+ if(baudRate <= 0) {
+ throw new IllegalArgumentException("Invalid baud rate: " + baudRate);
+ }
+ setBaudRate(baudRate);
- switch (parity) {
- case PARITY_NONE:
- break;
- case PARITY_ODD:
- lcr |= LCR_ENABLE_PAR;
- break;
- case PARITY_EVEN:
- lcr |= LCR_ENABLE_PAR | LCR_PAR_EVEN;
- break;
- case PARITY_MARK:
- lcr |= LCR_ENABLE_PAR | LCR_MARK_SPACE;
- break;
- case PARITY_SPACE:
- lcr |= LCR_ENABLE_PAR | LCR_MARK_SPACE | LCR_PAR_EVEN;
- break;
- default:
- throw new IllegalArgumentException("Invalid parity: " + parity);
- }
+ int lcr = LCR_ENABLE_RX | LCR_ENABLE_TX;
- switch (stopBits) {
- case STOPBITS_1:
- break;
- case STOPBITS_1_5:
- throw new UnsupportedOperationException("Unsupported stop bits: 1.5");
- case STOPBITS_2:
- lcr |= LCR_STOP_BITS_2;
- break;
- default:
- throw new IllegalArgumentException("Invalid stop bits: " + stopBits);
- }
+ switch (dataBits) {
+ case DATABITS_5:
+ lcr |= LCR_CS5;
+ break;
+ case DATABITS_6:
+ lcr |= LCR_CS6;
+ break;
+ case DATABITS_7:
+ lcr |= LCR_CS7;
+ break;
+ case DATABITS_8:
+ lcr |= LCR_CS8;
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid data bits: " + dataBits);
+ }
- int ret = controlOut(0x9a, 0x2518, lcr);
- if (ret < 0) {
- throw new IOException("Error setting control byte");
- }
- }
+ switch (parity) {
+ case PARITY_NONE:
+ break;
+ case PARITY_ODD:
+ lcr |= LCR_ENABLE_PAR;
+ break;
+ case PARITY_EVEN:
+ lcr |= LCR_ENABLE_PAR | LCR_PAR_EVEN;
+ break;
+ case PARITY_MARK:
+ lcr |= LCR_ENABLE_PAR | LCR_MARK_SPACE;
+ break;
+ case PARITY_SPACE:
+ lcr |= LCR_ENABLE_PAR | LCR_MARK_SPACE | LCR_PAR_EVEN;
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid parity: " + parity);
+ }
- @Override
- public boolean getCD() throws IOException {
- return (getStatus() & GCL_CD) == 0;
- }
+ switch (stopBits) {
+ case STOPBITS_1:
+ break;
+ case STOPBITS_1_5:
+ throw new UnsupportedOperationException("Unsupported stop bits: 1.5");
+ case STOPBITS_2:
+ lcr |= LCR_STOP_BITS_2;
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid stop bits: " + stopBits);
+ }
- @Override
- public boolean getCTS() throws IOException {
- return (getStatus() & GCL_CTS) == 0;
- }
+ int ret = controlOut(0x9a, 0x2518, lcr);
+ if (ret < 0) {
+ throw new IOException("Error setting control byte");
+ }
+ }
- @Override
- public boolean getDSR() throws IOException {
- return (getStatus() & GCL_DSR) == 0;
- }
+ @Override
+ public boolean getCD() throws IOException {
+ return (getStatus() & GCL_CD) == 0;
+ }
- @Override
- public boolean getDTR() throws IOException {
- return dtr;
- }
+ @Override
+ public boolean getCTS() throws IOException {
+ return (getStatus() & GCL_CTS) == 0;
+ }
- @Override
- public void setDTR(boolean value) throws IOException {
- dtr = value;
- setControlLines();
- }
+ @Override
+ public boolean getDSR() throws IOException {
+ return (getStatus() & GCL_DSR) == 0;
+ }
- @Override
- public boolean getRI() throws IOException {
- return (getStatus() & GCL_RI) == 0;
- }
+ @Override
+ public boolean getDTR() throws IOException {
+ return dtr;
+ }
- @Override
- public boolean getRTS() throws IOException {
- return rts;
- }
+ @Override
+ public void setDTR(boolean value) throws IOException {
+ dtr = value;
+ setControlLines();
+ }
- @Override
- public void setRTS(boolean value) throws IOException {
- rts = value;
- setControlLines();
- }
+ @Override
+ public boolean getRI() throws IOException {
+ return (getStatus() & GCL_RI) == 0;
+ }
- @Override
- public EnumSet getControlLines() throws IOException {
- int status = getStatus();
- EnumSet set = EnumSet.noneOf(ControlLine.class);
- if(rts) set.add(ControlLine.RTS);
- if((status & GCL_CTS) == 0) set.add(ControlLine.CTS);
- if(dtr) set.add(ControlLine.DTR);
- if((status & GCL_DSR) == 0) set.add(ControlLine.DSR);
- if((status & GCL_CD) == 0) set.add(ControlLine.CD);
- if((status & GCL_RI) == 0) set.add(ControlLine.RI);
- return set;
- }
+ @Override
+ public boolean getRTS() throws IOException {
+ return rts;
+ }
- @Override
- public EnumSet getSupportedControlLines() throws IOException {
- return EnumSet.allOf(ControlLine.class);
- }
+ @Override
+ public void setRTS(boolean value) throws IOException {
+ rts = value;
+ setControlLines();
+ }
- @Override
- public void setBreak(boolean value) throws IOException {
- byte[] req = new byte[2];
- if(controlIn(0x95, 0x1805, 0, req) < 0) {
- throw new IOException("Error getting BREAK condition");
- }
- if(value) {
- req[0] &= ~1;
- req[1] &= ~0x40;
- } else {
- req[0] |= 1;
- req[1] |= 0x40;
- }
- int val = (req[1] & 0xff) << 8 | (req[0] & 0xff);
- if(controlOut(0x9a, 0x1805, val) < 0) {
- throw new IOException("Error setting BREAK condition");
- }
- }
- }
+ @Override
+ public EnumSet getControlLines() throws IOException {
+ int status = getStatus();
+ EnumSet set = EnumSet.noneOf(ControlLine.class);
+ if(rts) set.add(ControlLine.RTS);
+ if((status & GCL_CTS) == 0) set.add(ControlLine.CTS);
+ if(dtr) set.add(ControlLine.DTR);
+ if((status & GCL_DSR) == 0) set.add(ControlLine.DSR);
+ if((status & GCL_CD) == 0) set.add(ControlLine.CD);
+ if((status & GCL_RI) == 0) set.add(ControlLine.RI);
+ return set;
+ }
- @SuppressWarnings({"unused"})
- public static Map getSupportedDevices() {
- final Map supportedDevices = new LinkedHashMap<>();
- supportedDevices.put(UsbId.VENDOR_QINHENG, new int[]{
- UsbId.QINHENG_CH340,
- UsbId.QINHENG_CH341A,
- });
- return supportedDevices;
- }
+ @Override
+ public EnumSet getSupportedControlLines() throws IOException {
+ return EnumSet.allOf(ControlLine.class);
+ }
+
+ @Override
+ public void setBreak(boolean value) throws IOException {
+ byte[] req = new byte[2];
+ if(controlIn(0x95, 0x1805, 0, req) < 0) {
+ throw new IOException("Error getting BREAK condition");
+ }
+ if(value) {
+ req[0] &= ~1;
+ req[1] &= ~0x40;
+ } else {
+ req[0] |= 1;
+ req[1] |= 0x40;
+ }
+ int val = (req[1] & 0xff) << 8 | (req[0] & 0xff);
+ if(controlOut(0x9a, 0x1805, val) < 0) {
+ throw new IOException("Error setting BREAK condition");
+ }
+ }
+ }
+
+ public static Map getSupportedDevices() {
+ final Map supportedDevices = new LinkedHashMap<>();
+ supportedDevices.put(UsbId.VENDOR_QINHENG, new int[]{
+ UsbId.QINHENG_CH340,
+ UsbId.QINHENG_CH341A,
+ });
+ return supportedDevices;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/ChromeCcdSerialDriver.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/ChromeCcdSerialDriver.java
deleted file mode 100644
index ef93042..0000000
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/ChromeCcdSerialDriver.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package org.emulator.calculator.usbserial.driver;
-
-import android.hardware.usb.UsbConstants;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbEndpoint;
-import android.hardware.usb.UsbInterface;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.ArrayList;
-
-public class ChromeCcdSerialDriver implements UsbSerialDriver{
-
- private final String TAG = ChromeCcdSerialDriver.class.getSimpleName();
-
- private final UsbDevice mDevice;
- private final List mPorts;
-
- @Override
- public UsbDevice getDevice() {
- return mDevice;
- }
-
- @Override
- public List getPorts() {
- return mPorts;
- }
-
- public ChromeCcdSerialDriver(UsbDevice mDevice) {
- this.mDevice = mDevice;
- mPorts = new ArrayList();
- for (int i = 0; i < 3; i++)
- mPorts.add(new ChromeCcdSerialPort(mDevice, i));
- }
-
- public class ChromeCcdSerialPort extends CommonUsbSerialPort {
- private UsbInterface mDataInterface;
-
- public ChromeCcdSerialPort(UsbDevice device, int portNumber) {
- super(device, portNumber);
- }
-
- @Override
- protected void openInt() throws IOException {
- Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
- mDataInterface = mDevice.getInterface(mPortNumber);
- if (!mConnection.claimInterface(mDataInterface, true)) {
- throw new IOException("Could not claim shared control/data interface");
- }
- Log.d(TAG, "endpoint count=" + mDataInterface.getEndpointCount());
- for (int i = 0; i < mDataInterface.getEndpointCount(); ++i) {
- UsbEndpoint ep = mDataInterface.getEndpoint(i);
- if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)) {
- mReadEndpoint = ep;
- } else if ((ep.getDirection() == UsbConstants.USB_DIR_OUT) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)) {
- mWriteEndpoint = ep;
- }
- }
- }
-
- @Override
- protected void closeInt() {
- try {
- mConnection.releaseInterface(mDataInterface);
- } catch(Exception ignored) {}
- }
-
- @Override
- public UsbSerialDriver getDriver() {
- return ChromeCcdSerialDriver.this;
- }
-
- @Override
- public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public EnumSet getSupportedControlLines() throws IOException {
- return EnumSet.noneOf(ControlLine.class);
- }
- }
-
- public static Map getSupportedDevices() {
- final Map supportedDevices = new LinkedHashMap<>();
- supportedDevices.put(UsbId.VENDOR_GOOGLE, new int[]{
- UsbId.GOOGLE_CR50,
- });
- return supportedDevices;
- }
-}
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/CommonUsbSerialPort.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/CommonUsbSerialPort.java
index d9faa34..0a7e93b 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/CommonUsbSerialPort.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/CommonUsbSerialPort.java
@@ -25,32 +25,28 @@ import java.util.EnumSet;
*/
public abstract class CommonUsbSerialPort implements UsbSerialPort {
- public static boolean DEBUG = false;
-
private static final String TAG = CommonUsbSerialPort.class.getSimpleName();
+ private static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
private static final int MAX_READ_SIZE = 16 * 1024; // = old bulkTransfer limit
protected final UsbDevice mDevice;
protected final int mPortNumber;
// non-null when open()
- protected UsbDeviceConnection mConnection;
+ protected UsbDeviceConnection mConnection = null;
protected UsbEndpoint mReadEndpoint;
protected UsbEndpoint mWriteEndpoint;
protected UsbRequest mUsbRequest;
- /**
- * Internal write buffer.
- * Guarded by {@link #mWriteBufferLock}.
- * Default length = mReadEndpoint.getMaxPacketSize()
- **/
- protected byte[] mWriteBuffer;
protected final Object mWriteBufferLock = new Object();
-
+ /** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
+ protected byte[] mWriteBuffer;
public CommonUsbSerialPort(UsbDevice device, int portNumber) {
mDevice = device;
mPortNumber = portNumber;
+
+ mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
}
@Override
@@ -89,19 +85,11 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
* Sets the size of the internal buffer used to exchange data with the USB
* stack for write operations. Most users should not need to change this.
*
- * @param bufferSize the size in bytes, <= 0 resets original size
+ * @param bufferSize the size in bytes
*/
public final void setWriteBufferSize(int bufferSize) {
synchronized (mWriteBufferLock) {
- if (bufferSize <= 0) {
- if (mWriteEndpoint != null) {
- bufferSize = mWriteEndpoint.getMaxPacketSize();
- } else {
- mWriteBuffer = null;
- return;
- }
- }
- if (mWriteBuffer != null && bufferSize == mWriteBuffer.length) {
+ if (bufferSize == mWriteBuffer.length) {
return;
}
mWriteBuffer = new byte[bufferSize];
@@ -118,7 +106,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
}
mConnection = connection;
try {
- openInt();
+ openInt(connection);
if (mReadEndpoint == null || mWriteEndpoint == null) {
throw new IOException("Could not get read & write endpoints");
}
@@ -132,18 +120,17 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
}
}
- protected abstract void openInt() throws IOException;
+ protected abstract void openInt(UsbDeviceConnection connection) throws IOException;
@Override
public void close() throws IOException {
if (mConnection == null) {
throw new IOException("Already closed");
}
- UsbRequest usbRequest = mUsbRequest;
- mUsbRequest = null;
try {
- usbRequest.cancel();
+ mUsbRequest.cancel();
} catch(Exception ignored) {}
+ mUsbRequest = null;
try {
closeInt();
} catch(Exception ignored) {}
@@ -158,40 +145,25 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
/**
* use simple USB request supported by all devices to test if connection is still valid
*/
- protected void testConnection(boolean full) throws IOException {
- testConnection(full, "USB get_status request failed");
- }
-
- protected void testConnection(boolean full, String msg) throws IOException {
- if(mUsbRequest == null) {
- throw new IOException("Connection closed");
- }
- if(!full) {
- return;
- }
+ protected void testConnection() throws IOException {
byte[] buf = new byte[2];
int len = mConnection.controlTransfer(0x80 /*DEVICE*/, 0 /*GET_STATUS*/, 0, 0, buf, buf.length, 200);
if(len < 0)
- throw new IOException(msg);
+ throw new IOException("USB get_status request failed");
}
@Override
public int read(final byte[] dest, final int timeout) throws IOException {
- if(dest.length == 0) {
- throw new IllegalArgumentException("Read buffer too small");
- }
- return read(dest, dest.length, timeout);
+ return read(dest, timeout, true);
}
- @Override
- public int read(final byte[] dest, final int length, final int timeout) throws IOException {return read(dest, length, timeout, true);}
-
- protected int read(final byte[] dest, int length, final int timeout, boolean testConnection) throws IOException {
- testConnection(false);
- if(length <= 0) {
- throw new IllegalArgumentException("Read length too small");
+ protected int read(final byte[] dest, final int timeout, boolean testConnection) throws IOException {
+ if(mConnection == null) {
+ throw new IOException("Connection closed");
+ }
+ if(dest.length <= 0) {
+ throw new IllegalArgumentException("Read buffer to small");
}
- length = Math.min(length, dest.length);
final int nread;
if (timeout != 0) {
// bulkTransfer will cause data loss with short timeout + high baud rates + continuous transfer
@@ -203,16 +175,16 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
// /system/lib64/libandroid_runtime.so (android_hardware_UsbDeviceConnection_request_wait(_JNIEnv*, _jobject*, long)+84)
// data loss / crashes were observed with timeout up to 200 msec
long endTime = testConnection ? MonotonicClock.millis() + timeout : 0;
- int readMax = Math.min(length, MAX_READ_SIZE);
+ int readMax = Math.min(dest.length, MAX_READ_SIZE);
nread = mConnection.bulkTransfer(mReadEndpoint, dest, readMax, timeout);
// Android error propagation is improvable:
// nread == -1 can be: timeout, connection lost, buffer to small, ???
- if(nread == -1 && testConnection)
- testConnection(MonotonicClock.millis() < endTime);
+ if(nread == -1 && testConnection && MonotonicClock.millis() < endTime)
+ testConnection();
} else {
- final ByteBuffer buf = ByteBuffer.wrap(dest, 0, length);
- if (!mUsbRequest.queue(buf, length)) {
+ final ByteBuffer buf = ByteBuffer.wrap(dest);
+ if (!mUsbRequest.queue(buf, dest.length)) {
throw new IOException("Queueing USB request failed");
}
final UsbRequest response = mConnection.requestWait();
@@ -223,23 +195,21 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
// Android error propagation is improvable:
// response != null & nread == 0 can be: connection lost, buffer to small, ???
if(nread == 0) {
- testConnection(true);
+ testConnection();
}
}
return Math.max(nread, 0);
}
@Override
- public void write(byte[] src, int timeout) throws IOException {write(src, src.length, timeout);}
-
- @Override
- public void write(final byte[] src, int length, final int timeout) throws IOException {
+ public void write(final byte[] src, final int timeout) throws IOException {
int offset = 0;
- long startTime = MonotonicClock.millis();
- length = Math.min(length, src.length);
+ final long endTime = (timeout == 0) ? 0 : (MonotonicClock.millis() + timeout);
- testConnection(false);
- while (offset < length) {
+ if(mConnection == null) {
+ throw new IOException("Connection closed");
+ }
+ while (offset < src.length) {
int requestTimeout;
final int requestLength;
final int actualLength;
@@ -247,10 +217,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
synchronized (mWriteBufferLock) {
final byte[] writeBuffer;
- if (mWriteBuffer == null) {
- mWriteBuffer = new byte[mWriteEndpoint.getMaxPacketSize()];
- }
- requestLength = Math.min(length - offset, mWriteBuffer.length);
+ requestLength = Math.min(src.length - offset, mWriteBuffer.length);
if (offset == 0) {
writeBuffer = src;
} else {
@@ -261,7 +228,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
if (timeout == 0 || offset == 0) {
requestTimeout = timeout;
} else {
- requestTimeout = (int)(startTime + timeout - MonotonicClock.millis());
+ requestTimeout = (int)(endTime - MonotonicClock.millis());
if(requestTimeout == 0)
requestTimeout = -1;
}
@@ -271,18 +238,14 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
actualLength = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, requestLength, requestTimeout);
}
}
- long elapsed = MonotonicClock.millis() - startTime;
- if (DEBUG) {
- Log.d(TAG, "Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + length + " time " + elapsed + "/" + requestTimeout);
- }
+ Log.d(TAG, "Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + src.length + " timeout " + requestTimeout);
if (actualLength <= 0) {
- String msg = "Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length + " after " + elapsed + "msec, rc=" + actualLength;
- if (timeout != 0) {
- testConnection(elapsed < timeout, msg);
- throw new SerialTimeoutException(msg, offset);
+ if (timeout != 0 && MonotonicClock.millis() >= endTime) {
+ SerialTimeoutException ex = new SerialTimeoutException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length + ", rc=" + actualLength);
+ ex.bytesTransferred = offset;
+ throw ex;
} else {
- throw new IOException(msg);
-
+ throw new IOException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length);
}
}
offset += actualLength;
@@ -291,7 +254,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
@Override
public boolean isOpen() {
- return mUsbRequest != null;
+ return mConnection != null;
}
@Override
@@ -322,7 +285,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
public void setRTS(boolean value) throws IOException { throw new UnsupportedOperationException(); }
@Override
- public EnumSet getControlLines() throws IOException { throw new UnsupportedOperationException(); }
+ public abstract EnumSet getControlLines() throws IOException;
@Override
public abstract EnumSet getSupportedControlLines() throws IOException;
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/Cp21xxSerialDriver.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/Cp21xxSerialDriver.java
index 906486c..c8f02c0 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/Cp21xxSerialDriver.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/Cp21xxSerialDriver.java
@@ -8,6 +8,7 @@ package org.emulator.calculator.usbserial.driver;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
@@ -118,14 +119,14 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
byte[] buffer = new byte[1];
int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, SILABSER_GET_MDMSTS_REQUEST_CODE, 0,
mPortNumber, buffer, buffer.length, USB_WRITE_TIMEOUT_MILLIS);
- if (result != buffer.length) {
+ if (result != 1) {
throw new IOException("Control transfer failed: " + SILABSER_GET_MDMSTS_REQUEST_CODE + " / " + 0 + " -> " + result);
}
return buffer[0];
}
@Override
- protected void openInt() throws IOException {
+ protected void openInt(UsbDeviceConnection connection) throws IOException {
mIsRestrictedPort = mDevice.getInterfaceCount() == 2 && mPortNumber == 1;
if(mPortNumber >= mDevice.getInterfaceCount()) {
throw new IOException("Unknown port number");
@@ -320,7 +321,6 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
}
}
- @SuppressWarnings({"unused"})
public static Map getSupportedDevices() {
final Map supportedDevices = new LinkedHashMap<>();
supportedDevices.put(UsbId.VENDOR_SILABS,
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/FtdiSerialDriver.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/FtdiSerialDriver.java
index d28e729..4fa50e0 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/FtdiSerialDriver.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/FtdiSerialDriver.java
@@ -9,6 +9,7 @@ package org.emulator.calculator.usbserial.driver;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
import android.util.Log;
import org.emulator.calculator.usbserial.util.MonotonicClock;
@@ -98,8 +99,8 @@ public class FtdiSerialDriver implements UsbSerialDriver {
@Override
- protected void openInt() throws IOException {
- if (!mConnection.claimInterface(mDevice.getInterface(mPortNumber), true)) {
+ protected void openInt(UsbDeviceConnection connection) throws IOException {
+ if (!connection.claimInterface(mDevice.getInterface(mPortNumber), true)) {
throw new IOException("Could not claim interface " + mPortNumber);
}
if (mDevice.getInterface(mPortNumber).getEndpointCount() < 2) {
@@ -122,13 +123,12 @@ public class FtdiSerialDriver implements UsbSerialDriver {
}
// mDevice.getVersion() would require API 23
- byte[] rawDescriptors = mConnection.getRawDescriptors();
+ byte[] rawDescriptors = connection.getRawDescriptors();
if(rawDescriptors == null || rawDescriptors.length < 14) {
throw new IOException("Could not get device descriptors");
}
int deviceType = rawDescriptors[13];
- baudRateWithPort = deviceType == 7 || deviceType == 8 || deviceType == 9 // ...H devices
- || mDevice.getInterfaceCount() > 1; // FT2232C
+ baudRateWithPort = deviceType == 7 || deviceType == 8 || deviceType == 9; // ...H devices
}
@Override
@@ -139,37 +139,24 @@ public class FtdiSerialDriver implements UsbSerialDriver {
}
@Override
- public int read(final byte[] dest, final int timeout) throws IOException
- {
+ public int read(final byte[] dest, final int timeout) throws IOException {
if(dest.length <= READ_HEADER_LENGTH) {
- throw new IllegalArgumentException("Read buffer too small");
+ throw new IllegalArgumentException("Read buffer to small");
// could allocate larger buffer, including space for 2 header bytes, but this would
// result in buffers not being 64 byte aligned any more, causing data loss at continuous
// data transfer at high baud rates when buffers are fully filled.
}
- return read(dest, dest.length, timeout);
- }
-
- @Override
- public int read(final byte[] dest, int length, final int timeout) throws IOException {
- if(length <= READ_HEADER_LENGTH) {
- throw new IllegalArgumentException("Read length too small");
- // could allocate larger buffer, including space for 2 header bytes, but this would
- // result in buffers not being 64 byte aligned any more, causing data loss at continuous
- // data transfer at high baud rates when buffers are fully filled.
- }
- length = Math.min(length, dest.length);
int nread;
if (timeout != 0) {
long endTime = MonotonicClock.millis() + timeout;
do {
- nread = super.read(dest, length, Math.max(1, (int)(endTime - MonotonicClock.millis())), false);
+ nread = super.read(dest, Math.max(1, (int)(endTime - MonotonicClock.millis())), false);
} while (nread == READ_HEADER_LENGTH && MonotonicClock.millis() < endTime);
- if(nread <= 0)
- testConnection(MonotonicClock.millis() < endTime);
+ if(nread <= 0 && MonotonicClock.millis() < endTime)
+ testConnection();
} else {
do {
- nread = super.read(dest, length, timeout);
+ nread = super.read(dest, timeout, false);
} while (nread == READ_HEADER_LENGTH);
}
return readFilter(dest, nread);
@@ -303,7 +290,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
byte[] data = new byte[2];
int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, GET_MODEM_STATUS_REQUEST,
0, mPortNumber+1, data, data.length, USB_WRITE_TIMEOUT_MILLIS);
- if (result != data.length) {
+ if (result != 2) {
throw new IOException("Get modem status failed: result=" + result);
}
return data[0];
@@ -419,7 +406,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
byte[] data = new byte[1];
int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, GET_LATENCY_TIMER_REQUEST,
0, mPortNumber+1, data, data.length, USB_WRITE_TIMEOUT_MILLIS);
- if (result != data.length) {
+ if (result != 1) {
throw new IOException("Get latency timer failed: result=" + result);
}
return data[0];
@@ -427,7 +414,6 @@ public class FtdiSerialDriver implements UsbSerialDriver {
}
- @SuppressWarnings({"unused"})
public static Map getSupportedDevices() {
final Map supportedDevices = new LinkedHashMap<>();
supportedDevices.put(UsbId.VENDOR_FTDI,
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/GsmModemSerialDriver.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/GsmModemSerialDriver.java
deleted file mode 100644
index c180401..0000000
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/GsmModemSerialDriver.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.emulator.calculator.usbserial.driver;
-
-import android.hardware.usb.UsbConstants;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbEndpoint;
-import android.hardware.usb.UsbInterface;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-public class GsmModemSerialDriver implements UsbSerialDriver{
-
- private final String TAG = GsmModemSerialDriver.class.getSimpleName();
-
- private final UsbDevice mDevice;
- private final UsbSerialPort mPort;
-
- @Override
- public UsbDevice getDevice() {
- return mDevice;
- }
-
- @Override
- public List getPorts() {
- return Collections.singletonList(mPort);
- }
-
- public GsmModemSerialDriver(UsbDevice mDevice) {
- this.mDevice = mDevice;
- mPort = new GsmModemSerialPort(mDevice, 0);
- }
-
- public class GsmModemSerialPort extends CommonUsbSerialPort {
-
- private UsbInterface mDataInterface;
-
- public GsmModemSerialPort(UsbDevice device, int portNumber) {
- super(device, portNumber);
- }
-
- @Override
- protected void openInt() throws IOException {
- Log.d(TAG, "claiming interfaces, count=" + mDevice.getInterfaceCount());
- mDataInterface = mDevice.getInterface(0);
- if (!mConnection.claimInterface(mDataInterface, true)) {
- throw new IOException("Could not claim shared control/data interface");
- }
- Log.d(TAG, "endpoint count=" + mDataInterface.getEndpointCount());
- for (int i = 0; i < mDataInterface.getEndpointCount(); ++i) {
- UsbEndpoint ep = mDataInterface.getEndpoint(i);
- if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)) {
- mReadEndpoint = ep;
- } else if ((ep.getDirection() == UsbConstants.USB_DIR_OUT) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)) {
- mWriteEndpoint = ep;
- }
- }
- initGsmModem();
- }
-
- @Override
- protected void closeInt() {
- try {
- mConnection.releaseInterface(mDataInterface);
- } catch(Exception ignored) {}
-
- }
-
- private int initGsmModem() throws IOException {
- int len = mConnection.controlTransfer(
- 0x21, 0x22, 0x01, 0, null, 0, 5000);
- if(len < 0) {
- throw new IOException("init failed");
- }
- return len;
- }
-
- @Override
- public UsbSerialDriver getDriver() {
- return GsmModemSerialDriver.this;
- }
-
- @Override
- public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public EnumSet getSupportedControlLines() throws IOException {
- return EnumSet.noneOf(ControlLine.class);
- }
- }
-
- public static Map getSupportedDevices() {
- final Map supportedDevices = new LinkedHashMap<>();
- supportedDevices.put(UsbId.VENDOR_UNISOC, new int[]{
- UsbId.FIBOCOM_L610,
- UsbId.FIBOCOM_L612,
- });
- return supportedDevices;
- }
-}
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/ProbeTable.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/ProbeTable.java
index bcf6e0d..b64918e 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/ProbeTable.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/ProbeTable.java
@@ -6,7 +6,6 @@
package org.emulator.calculator.usbserial.driver;
-import android.hardware.usb.UsbDevice;
import android.util.Pair;
import java.lang.reflect.InvocationTargetException;
@@ -15,14 +14,14 @@ import java.util.LinkedHashMap;
import java.util.Map;
/**
- * Maps (vendor id, product id) pairs to the corresponding serial driver,
- * or invoke 'probe' method to check actual USB devices for matching interfaces.
+ * Maps (vendor id, product id) pairs to the corresponding serial driver.
+ *
+ * @author mike wakerly (opensource@hoho.com)
*/
public class ProbeTable {
- private final Map, Class extends UsbSerialDriver>> mVidPidProbeTable =
+ private final Map, Class extends UsbSerialDriver>> mProbeTable =
new LinkedHashMap<>();
- private final Map> mMethodProbeTable = new LinkedHashMap<>();
/**
* Adds or updates a (vendor, product) pair in the table.
@@ -34,7 +33,7 @@ public class ProbeTable {
*/
public ProbeTable addProduct(int vendorId, int productId,
Class extends UsbSerialDriver> driverClass) {
- mVidPidProbeTable.put(Pair.create(vendorId, productId), driverClass);
+ mProbeTable.put(Pair.create(vendorId, productId), driverClass);
return this;
}
@@ -42,11 +41,12 @@ public class ProbeTable {
* Internal method to add all supported products from
* {@code getSupportedProducts} static method.
*
- * @param driverClass to be added
+ * @param driverClass
+ * @return
*/
@SuppressWarnings("unchecked")
- void addDriver(Class extends UsbSerialDriver> driverClass) {
- Method method;
+ ProbeTable addDriver(Class extends UsbSerialDriver> driverClass) {
+ final Method method;
try {
method = driverClass.getMethod("getSupportedDevices");
@@ -68,35 +68,20 @@ public class ProbeTable {
}
}
- try {
- method = driverClass.getMethod("probe", UsbDevice.class);
- mMethodProbeTable.put(method, driverClass);
- } catch (SecurityException | NoSuchMethodException ignored) {
- }
+ return this;
}
/**
- * Returns the driver for the given USB device, or {@code null} if no match.
+ * Returns the driver for the given (vendor, product) pair, or {@code null}
+ * if no match.
*
- * @param usbDevice the USB device to be probed
+ * @param vendorId the USB vendor id
+ * @param productId the USB product id
* @return the driver class matching this pair, or {@code null}
*/
- public Class extends UsbSerialDriver> findDriver(final UsbDevice usbDevice) {
- final Pair pair = Pair.create(usbDevice.getVendorId(), usbDevice.getProductId());
- Class extends UsbSerialDriver> driverClass = mVidPidProbeTable.get(pair);
- if (driverClass != null)
- return driverClass;
- for (Map.Entry> entry : mMethodProbeTable.entrySet()) {
- try {
- Method method = entry.getKey();
- Object o = method.invoke(null, usbDevice);
- if((boolean)o)
- return entry.getValue();
- } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
- throw new RuntimeException(e);
- }
- }
- return null;
+ public Class extends UsbSerialDriver> findDriver(int vendorId, int productId) {
+ final Pair pair = Pair.create(vendorId, productId);
+ return mProbeTable.get(pair);
}
}
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/ProlificSerialDriver.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/ProlificSerialDriver.java
index 2ae4968..234215c 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/ProlificSerialDriver.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/ProlificSerialDriver.java
@@ -11,6 +11,7 @@ package org.emulator.calculator.usbserial.driver;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.util.Log;
@@ -34,7 +35,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
28800, 38400, 57600, 115200, 128000, 134400, 161280, 201600, 230400, 268800,
403200, 460800, 614400, 806400, 921600, 1228800, 2457600, 3000000, 6000000
};
- protected enum DeviceType { DEVICE_TYPE_01, DEVICE_TYPE_T, DEVICE_TYPE_HX, DEVICE_TYPE_HXN }
+ protected enum DeviceType { DEVICE_TYPE_01, DEVICE_TYPE_T, DEVICE_TYPE_HX, DEVICE_TYPE_HXN}
private final UsbDevice mDevice;
private final UsbSerialPort mPort;
@@ -122,7 +123,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
private volatile Thread mReadStatusThread = null;
private final Object mReadStatusThreadLock = new Object();
private boolean mStopReadStatusThread = false;
- private Exception mReadStatusException = null;
+ private IOException mReadStatusException = null;
public ProlificSerialPort(UsbDevice device, int portNumber) {
@@ -138,7 +139,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
byte[] buffer = new byte[length];
int result = mConnection.controlTransfer(requestType, request, value, index, buffer, length, USB_READ_TIMEOUT_MILLIS);
if (result != length) {
- throw new IOException(String.format("ControlTransfer %s 0x%x failed: %d",mDeviceType.name(), value, result));
+ throw new IOException(String.format("ControlTransfer 0x%x failed: %d",value, result));
}
return buffer;
}
@@ -147,7 +148,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
int length = (data == null) ? 0 : data.length;
int result = mConnection.controlTransfer(requestType, request, value, index, data, length, USB_WRITE_TIMEOUT_MILLIS);
if (result != length) {
- throw new IOException( String.format("ControlTransfer %s 0x%x failed: %d", mDeviceType.name(), value, result));
+ throw new IOException( String.format("ControlTransfer 0x%x failed: %d", value, result));
}
}
@@ -201,12 +202,12 @@ public class ProlificSerialDriver implements UsbSerialDriver {
private void readStatusThreadFunction() {
try {
- byte[] buffer = new byte[STATUS_BUFFER_SIZE];
while (!mStopReadStatusThread) {
+ byte[] buffer = new byte[STATUS_BUFFER_SIZE];
long endTime = MonotonicClock.millis() + 500;
int readBytesCount = mConnection.bulkTransfer(mInterruptEndpoint, buffer, STATUS_BUFFER_SIZE, 500);
- if(readBytesCount == -1)
- testConnection(MonotonicClock.millis() < endTime);
+ if(readBytesCount == -1 && MonotonicClock.millis() < endTime)
+ testConnection();
if (readBytesCount > 0) {
if (readBytesCount != STATUS_BUFFER_SIZE) {
throw new IOException("Invalid status notification, expected " + STATUS_BUFFER_SIZE + " bytes, got " + readBytesCount);
@@ -217,9 +218,8 @@ public class ProlificSerialDriver implements UsbSerialDriver {
}
}
}
- } catch (Exception e) {
- if (isOpen())
- mReadStatusException = e;
+ } catch (IOException e) {
+ mReadStatusException = e;
}
//Log.d(TAG, "end control line status thread " + mStopReadStatusThread + " " + (mReadStatusException == null ? "-" : mReadStatusException.getMessage()));
}
@@ -250,8 +250,8 @@ public class ProlificSerialDriver implements UsbSerialDriver {
}
}
- /* throw and clear an exception which occurred in the status read thread */
- Exception readStatusException = mReadStatusException;
+ /* throw and clear an exception which occured in the status read thread */
+ IOException readStatusException = mReadStatusException;
if (mReadStatusException != null) {
mReadStatusException = null;
throw new IOException(readStatusException);
@@ -265,10 +265,10 @@ public class ProlificSerialDriver implements UsbSerialDriver {
}
@Override
- public void openInt() throws IOException {
+ public void openInt(UsbDeviceConnection connection) throws IOException {
UsbInterface usbInterface = mDevice.getInterface(0);
- if (!mConnection.claimInterface(usbInterface, true)) {
+ if (!connection.claimInterface(usbInterface, true)) {
throw new IOException("Error claiming Prolific interface 0");
}
@@ -290,7 +290,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
}
}
- byte[] rawDescriptors = mConnection.getRawDescriptors();
+ byte[] rawDescriptors = connection.getRawDescriptors();
if(rawDescriptors == null || rawDescriptors.length < 14) {
throw new IOException("Could not get device descriptors");
}
@@ -299,19 +299,15 @@ public class ProlificSerialDriver implements UsbSerialDriver {
byte maxPacketSize0 = rawDescriptors[7];
if (mDevice.getDeviceClass() == 0x02 || maxPacketSize0 != 64) {
mDeviceType = DeviceType.DEVICE_TYPE_01;
- } else if(usbVersion == 0x200) {
- if(deviceVersion == 0x300 && testHxStatus()) {
- mDeviceType = DeviceType.DEVICE_TYPE_T; // TA
- } else if(deviceVersion == 0x500 && testHxStatus()) {
- mDeviceType = DeviceType.DEVICE_TYPE_T; // TB
- } else {
- mDeviceType = DeviceType.DEVICE_TYPE_HXN;
- }
+ } else if(deviceVersion == 0x300 && usbVersion == 0x200) {
+ mDeviceType = DeviceType.DEVICE_TYPE_T; // TA
+ } else if(deviceVersion == 0x500) {
+ mDeviceType = DeviceType.DEVICE_TYPE_T; // TB
+ } else if(usbVersion == 0x200 && !testHxStatus()) {
+ mDeviceType = DeviceType.DEVICE_TYPE_HXN;
} else {
mDeviceType = DeviceType.DEVICE_TYPE_HX;
}
- Log.d(TAG, String.format("usbVersion=%x, deviceVersion=%x, deviceClass=%d, packetSize=%d => deviceType=%s",
- usbVersion, deviceVersion, mDevice.getDeviceClass(), maxPacketSize0, mDeviceType.name()));
resetDevice();
doBlackMagic();
setControlLines(mControlLinesValue);
@@ -567,7 +563,6 @@ public class ProlificSerialDriver implements UsbSerialDriver {
}
}
- @SuppressWarnings({"unused"})
public static Map getSupportedDevices() {
final Map supportedDevices = new LinkedHashMap<>();
supportedDevices.put(UsbId.VENDOR_PROLIFIC,
@@ -576,6 +571,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
UsbId.PROLIFIC_PL2303GC,
UsbId.PROLIFIC_PL2303GB,
UsbId.PROLIFIC_PL2303GT,
+ UsbId.PROLIFIC_PL2303GT3,
UsbId.PROLIFIC_PL2303GL,
UsbId.PROLIFIC_PL2303GE,
UsbId.PROLIFIC_PL2303GS,
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/SerialTimeoutException.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/SerialTimeoutException.java
index 41bae99..c45ebac 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/SerialTimeoutException.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/SerialTimeoutException.java
@@ -9,8 +9,7 @@ import java.io.InterruptedIOException;
* {@see InterruptedIOException#bytesTransferred} may contain bytes transferred
*/
public class SerialTimeoutException extends InterruptedIOException {
- public SerialTimeoutException(String s, int bytesTransferred) {
+ public SerialTimeoutException(String s) {
super(s);
- this.bytesTransferred = bytesTransferred;
}
}
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbId.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbId.java
index 755f008..b94206f 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbId.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbId.java
@@ -23,6 +23,27 @@ public final class UsbId {
public static final int FTDI_FT232H = 0x6014;
public static final int FTDI_FT231X = 0x6015; // same ID for FT230X, FT231X, FT234XD
+ public static final int VENDOR_ATMEL = 0x03EB;
+ public static final int ATMEL_LUFA_CDC_DEMO_APP = 0x2044;
+
+ public static final int VENDOR_ARDUINO = 0x2341;
+ public static final int ARDUINO_UNO = 0x0001;
+ public static final int ARDUINO_MEGA_2560 = 0x0010;
+ public static final int ARDUINO_SERIAL_ADAPTER = 0x003b;
+ public static final int ARDUINO_MEGA_ADK = 0x003f;
+ public static final int ARDUINO_MEGA_2560_R3 = 0x0042;
+ public static final int ARDUINO_UNO_R3 = 0x0043;
+ public static final int ARDUINO_MEGA_ADK_R3 = 0x0044;
+ public static final int ARDUINO_SERIAL_ADAPTER_R3 = 0x0044;
+ public static final int ARDUINO_LEONARDO = 0x8036;
+ public static final int ARDUINO_MICRO = 0x8037;
+
+ public static final int VENDOR_VAN_OOIJEN_TECH = 0x16c0;
+ public static final int VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL = 0x0483;
+
+ public static final int VENDOR_LEAFLABS = 0x1eaf;
+ public static final int LEAFLABS_MAPLE = 0x0004;
+
public static final int VENDOR_SILABS = 0x10c4;
public static final int SILABS_CP2102 = 0xea60; // same ID for CP2101, CP2103, CP2104, CP2109
public static final int SILABS_CP2105 = 0xea70;
@@ -32,22 +53,22 @@ public final class UsbId {
public static final int PROLIFIC_PL2303 = 0x2303; // device type 01, T, HX
public static final int PROLIFIC_PL2303GC = 0x23a3; // device type HXN
public static final int PROLIFIC_PL2303GB = 0x23b3; // "
- public static final int PROLIFIC_PL2303GT = 0x23c3; // "
- public static final int PROLIFIC_PL2303GL = 0x23d3; // "
+ public static final int PROLIFIC_PL2303GT = 0x23cd; // "
+ public static final int PROLIFIC_PL2303GT3 = 0x23c3; // "
+ public static final int PROLIFIC_PL2303GL = 0x23e3; // "
public static final int PROLIFIC_PL2303GE = 0x23e3; // "
public static final int PROLIFIC_PL2303GS = 0x23f3; // "
- public static final int VENDOR_GOOGLE = 0x18d1;
- public static final int GOOGLE_CR50 = 0x5014;
-
public static final int VENDOR_QINHENG = 0x1a86;
public static final int QINHENG_CH340 = 0x7523;
public static final int QINHENG_CH341A = 0x5523;
- public static final int VENDOR_UNISOC = 0x1782;
- public static final int FIBOCOM_L610 = 0x4D10;
- public static final int FIBOCOM_L612 = 0x4D12;
+ // at www.linux-usb.org/usb.ids listed for NXP/LPC1768, but all processors supported by ARM mbed DAPLink firmware report these ids
+ public static final int VENDOR_ARM = 0x0d28;
+ public static final int ARM_MBED = 0x0204;
+ public static final int VENDOR_ST = 0x0483;
+ public static final int ST_CDC = 0x5740;
private UsbId() {
throw new IllegalAccessError("Non-instantiable class");
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialDriver.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialDriver.java
index df8912f..bbc761a 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialDriver.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialDriver.java
@@ -10,17 +10,12 @@ import android.hardware.usb.UsbDevice;
import java.util.List;
+/**
+ *
+ * @author mike wakerly (opensource@hoho.com)
+ */
public interface UsbSerialDriver {
- /*
- * Additional interface properties. Invoked thru reflection.
- *
- UsbSerialDriver(UsbDevice device); // constructor with device
- static Map getSupportedDevices();
- static boolean probe(UsbDevice device); // optional
- */
-
-
/**
* Returns the raw {@link UsbDevice} backing this port.
*
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialPort.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialPort.java
index c162ac8..03f1e6b 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialPort.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialPort.java
@@ -58,7 +58,7 @@ public interface UsbSerialPort extends Closeable {
int STOPBITS_2 = 2;
/** Values for get[Supported]ControlLines() */
- enum ControlLine { RTS, CTS, DTR, DSR, CD, RI }
+ enum ControlLine { RTS, CTS, DTR, DSR, CD, RI }
/**
* Returns the driver used by this port.
@@ -122,17 +122,6 @@ public interface UsbSerialPort extends Closeable {
*/
int read(final byte[] dest, final int timeout) throws IOException;
- /**
- * Reads bytes with specified length into the destination buffer.
- *
- * @param dest the destination byte buffer
- * @param length the maximum length of the data to read
- * @param timeout the timeout for reading in milliseconds, 0 is infinite
- * @return the actual number of bytes read
- * @throws IOException if an error occurred during reading
- */
- int read(final byte[] dest, int length, final int timeout) throws IOException;
-
/**
* Writes as many bytes as possible from the source buffer.
*
@@ -144,18 +133,6 @@ public interface UsbSerialPort extends Closeable {
*/
void write(final byte[] src, final int timeout) throws IOException;
- /**
- * Writes bytes with specified length from the source buffer.
- *
- * @param src the source byte buffer
- * @param length the length of the data to write
- * @param timeout the timeout for writing in milliseconds, 0 is infinite
- * @throws SerialTimeoutException if timeout reached before sending all data.
- * ex.bytesTransferred may contain bytes transferred
- * @throws IOException if an error occurred during writing
- */
- void write(final byte[] src, int length, final int timeout) throws IOException;
-
/**
* Sets various serial port parameters.
*
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialProber.java b/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialProber.java
index 13c8f4b..6755bb0 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialProber.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/driver/UsbSerialProber.java
@@ -37,8 +37,6 @@ public class UsbSerialProber {
probeTable.addDriver(FtdiSerialDriver.class);
probeTable.addDriver(ProlificSerialDriver.class);
probeTable.addDriver(Ch34xSerialDriver.class);
- probeTable.addDriver(GsmModemSerialDriver.class);
- probeTable.addDriver(ChromeCcdSerialDriver.class);
return probeTable;
}
@@ -71,7 +69,11 @@ public class UsbSerialProber {
* {@code null} if none available.
*/
public UsbSerialDriver probeDevice(final UsbDevice usbDevice) {
- final Class extends UsbSerialDriver> driverClass = mProbeTable.findDriver(usbDevice);
+ final int vendorId = usbDevice.getVendorId();
+ final int productId = usbDevice.getProductId();
+
+ final Class extends UsbSerialDriver> driverClass =
+ mProbeTable.findDriver(vendorId, productId);
if (driverClass != null) {
final UsbSerialDriver driver;
try {
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/util/HexDump.java b/app/src/main/java/org/emulator/calculator/usbserial/util/HexDump.java
deleted file mode 100644
index 42a1eeb..0000000
--- a/app/src/main/java/org/emulator/calculator/usbserial/util/HexDump.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- */
-
-package org.emulator.calculator.usbserial.util;
-
-import java.security.InvalidParameterException;
-
-/**
- * Clone of Android's /core/java/com/android/internal/util/HexDump class, for use in debugging.
- * Changes: space separated hex strings
- */
-public class HexDump {
- private final static char[] HEX_DIGITS = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
- };
-
- private HexDump() {
- }
-
- public static String dumpHexString(byte[] array) {
- return dumpHexString(array, 0, array.length);
- }
-
- public static String dumpHexString(byte[] array, int offset, int length) {
- StringBuilder result = new StringBuilder();
-
- byte[] line = new byte[8];
- int lineIndex = 0;
-
- for (int i = offset; i < offset + length; i++) {
- if (lineIndex == line.length) {
- for (int j = 0; j < line.length; j++) {
- if (line[j] > ' ' && line[j] < '~') {
- result.append(new String(line, j, 1));
- } else {
- result.append(".");
- }
- }
-
- result.append("\n");
- lineIndex = 0;
- }
-
- byte b = array[i];
- result.append(HEX_DIGITS[(b >>> 4) & 0x0F]);
- result.append(HEX_DIGITS[b & 0x0F]);
- result.append(" ");
-
- line[lineIndex++] = b;
- }
-
- for (int i = 0; i < (line.length - lineIndex); i++) {
- result.append(" ");
- }
- for (int i = 0; i < lineIndex; i++) {
- if (line[i] > ' ' && line[i] < '~') {
- result.append(new String(line, i, 1));
- } else {
- result.append(".");
- }
- }
-
- return result.toString();
- }
-
- public static String toHexString(byte b) {
- return toHexString(toByteArray(b));
- }
-
- public static String toHexString(byte[] array) {
- return toHexString(array, 0, array.length);
- }
-
- public static String toHexString(byte[] array, int offset, int length) {
- char[] buf = new char[length > 0 ? length * 3 - 1 : 0];
-
- int bufIndex = 0;
- for (int i = offset; i < offset + length; i++) {
- if (i > offset)
- buf[bufIndex++] = ' ';
- byte b = array[i];
- buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
- buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
- }
-
- return new String(buf);
- }
-
- public static String toHexString(int i) {
- return toHexString(toByteArray(i));
- }
-
- public static String toHexString(short i) {
- return toHexString(toByteArray(i));
- }
-
- public static byte[] toByteArray(byte b) {
- byte[] array = new byte[1];
- array[0] = b;
- return array;
- }
-
- public static byte[] toByteArray(int i) {
- byte[] array = new byte[4];
-
- array[3] = (byte) (i & 0xFF);
- array[2] = (byte) ((i >> 8) & 0xFF);
- array[1] = (byte) ((i >> 16) & 0xFF);
- array[0] = (byte) ((i >> 24) & 0xFF);
-
- return array;
- }
-
- public static byte[] toByteArray(short i) {
- byte[] array = new byte[2];
-
- array[1] = (byte) (i & 0xFF);
- array[0] = (byte) ((i >> 8) & 0xFF);
-
- return array;
- }
-
- private static int toByte(char c) {
- if (c >= '0' && c <= '9')
- return (c - '0');
- if (c >= 'A' && c <= 'F')
- return (c - 'A' + 10);
- if (c >= 'a' && c <= 'f')
- return (c - 'a' + 10);
-
- throw new InvalidParameterException("Invalid hex char '" + c + "'");
- }
-
- /** accepts any separator, e.g. space or newline */
- public static byte[] hexStringToByteArray(String hexString) {
- int length = hexString.length();
- byte[] buffer = new byte[(length + 1) / 3];
-
- for (int i = 0; i < length; i += 3) {
- buffer[i / 3] = (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1)));
- }
-
- return buffer;
- }
-}
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/util/SerialInputOutputManager.java b/app/src/main/java/org/emulator/calculator/usbserial/util/SerialInputOutputManager.java
index f37dfbe..1bb9cf3 100644
--- a/app/src/main/java/org/emulator/calculator/usbserial/util/SerialInputOutputManager.java
+++ b/app/src/main/java/org/emulator/calculator/usbserial/util/SerialInputOutputManager.java
@@ -9,7 +9,6 @@ package org.emulator.calculator.usbserial.util;
import android.os.Process;
import android.util.Log;
-import org.emulator.calculator.usbserial.driver.SerialTimeoutException;
import org.emulator.calculator.usbserial.driver.UsbSerialPort;
import java.io.IOException;
@@ -22,15 +21,8 @@ import java.nio.ByteBuffer;
*/
public class SerialInputOutputManager implements Runnable {
- public enum State {
- STOPPED,
- RUNNING,
- STOPPING
- }
-
- public static boolean DEBUG = false;
-
private static final String TAG = SerialInputOutputManager.class.getSimpleName();
+ public static boolean DEBUG = false;
private static final int BUFSIZ = 4096;
/**
@@ -45,6 +37,12 @@ public class SerialInputOutputManager implements Runnable {
private ByteBuffer mReadBuffer; // default size = getReadEndpoint().getMaxPacketSize()
private ByteBuffer mWriteBuffer = ByteBuffer.allocate(BUFSIZ);
+ public enum State {
+ STOPPED,
+ RUNNING,
+ STOPPING
+ }
+
private int mThreadPriority = Process.THREAD_PRIORITY_URGENT_AUDIO;
private State mState = State.STOPPED; // Synchronized by 'this'
private Listener mListener; // Synchronized by 'this'
@@ -204,11 +202,7 @@ public class SerialInputOutputManager implements Runnable {
step();
}
} catch (Exception e) {
- if(mSerialPort.isOpen()) {
- Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e);
- } else {
- Log.i(TAG, "Socket closed");
- }
+ Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e);
final Listener listener = getListener();
if (listener != null) {
listener.onRunError(e);
@@ -229,9 +223,7 @@ public class SerialInputOutputManager implements Runnable {
}
int len = mSerialPort.read(buffer, mReadTimeout);
if (len > 0) {
- if (DEBUG) {
- Log.d(TAG, "Read data len=" + len);
- }
+ if (DEBUG) Log.d(TAG, "Read data len=" + len);
final Listener listener = getListener();
if (listener != null) {
final byte[] data = new byte[len];
@@ -255,23 +247,7 @@ public class SerialInputOutputManager implements Runnable {
if (DEBUG) {
Log.d(TAG, "Writing data len=" + len);
}
- try {
- mSerialPort.write(buffer, mWriteTimeout);
- } catch (SerialTimeoutException ex) {
- synchronized (mWriteBufferLock) {
- byte[] buffer2 = null;
- int len2 = mWriteBuffer.position();
- if (len2 > 0) {
- buffer2 = new byte[len2];
- mWriteBuffer.rewind();
- mWriteBuffer.get(buffer2, 0, len2);
- mWriteBuffer.clear();
- }
- mWriteBuffer.put(buffer, ex.bytesTransferred, buffer.length - ex.bytesTransferred);
- if (buffer2 != null)
- mWriteBuffer.put(buffer2);
- }
- }
+ mSerialPort.write(buffer, mWriteTimeout);
}
}
diff --git a/app/src/main/java/org/emulator/calculator/usbserial/util/UsbUtils.java b/app/src/main/java/org/emulator/calculator/usbserial/util/UsbUtils.java
deleted file mode 100644
index 69aae75..0000000
--- a/app/src/main/java/org/emulator/calculator/usbserial/util/UsbUtils.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.emulator.calculator.usbserial.util;
-
-import android.hardware.usb.UsbDeviceConnection;
-
-import java.util.ArrayList;
-
-public class UsbUtils {
-
- private UsbUtils() {
- }
-
- public static ArrayList getDescriptors(UsbDeviceConnection connection) {
- ArrayList descriptors = new ArrayList<>();
- byte[] rawDescriptors = connection.getRawDescriptors();
- if (rawDescriptors != null) {
- int pos = 0;
- while (pos < rawDescriptors.length) {
- int len = rawDescriptors[pos] & 0xFF;
- if (len == 0)
- break;
- if (pos + len > rawDescriptors.length)
- len = rawDescriptors.length - pos;
- byte[] descriptor = new byte[len];
- System.arraycopy(rawDescriptors, pos, descriptor, 0, len);
- descriptors.add(descriptor);
- pos += len;
- }
- }
- return descriptors;
- }
-
-
-}
diff --git a/app/src/main/java/org/emulator/forty/eight/MainActivity.java b/app/src/main/java/org/emulator/forty/eight/MainActivity.java
index f72b2d5..d190de5 100644
--- a/app/src/main/java/org/emulator/forty/eight/MainActivity.java
+++ b/app/src/main/java/org/emulator/forty/eight/MainActivity.java
@@ -140,13 +140,13 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
// Most Recently Used state files
private final int MRU_ID_START = 10000;
private final int MAX_MRU = 5;
- private LinkedHashMap mruLinkedHashMap = new LinkedHashMap(5, 1.0f, true) {
+ private final LinkedHashMap mruLinkedHashMap = new LinkedHashMap(5, 1.0f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_MRU;
}
};
- private HashMap mruByMenuId = new HashMap<>();
+ private final HashMap mruByMenuId = new HashMap<>();
private final PrinterSimulator printerSimulator = new PrinterSimulator();
private final PrinterSimulatorFragment fragmentPrinterSimulator = new PrinterSimulatorFragment();
@@ -246,7 +246,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
}
- if(documentToOpenUrl != null && documentToOpenUrl.length() > 0)
+ if(documentToOpenUrl != null && !documentToOpenUrl.isEmpty())
try {
// FileOpen auto-open.
onFileOpen(documentToOpenUrl, intent, null);
@@ -276,7 +276,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
for (int i = mrus.length - 1; i >= 0; i--) {
String mostRecentlyUsedFile = mrus[i];
String displayName = getFilenameFromURL(mostRecentlyUsedFile);
- if(displayName == null || displayName.equals("") || displayName.equals(mostRecentlyUsedFile)) {
+ if(displayName == null || displayName.isEmpty() || displayName.equals(mostRecentlyUsedFile)) {
// We should remove this file because it seems impossible to get the display name of this Most Recently Used state file.
// It might be deleted or the permissions does not allow to reach it anymore.
mruLinkedHashMap.remove(mostRecentlyUsedFile);
@@ -301,7 +301,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
if (NativeLib.isDocumentAvailable() && settings.getBoolean("settings_autosave", true)) {
String currentFilename = NativeLib.getCurrentFilename();
- if (currentFilename != null && currentFilename.length() > 0)
+ if (currentFilename != null && !currentFilename.isEmpty())
onFileSave();
}
@@ -1140,7 +1140,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
saveWhenLaunchingActivity = false;
startActivityForResult(intent, INTENT_LOAD_FLASH_ROM);
};
- if(currentFlashPort2Url != null && currentFlashPort2Url.length() > 0)
+ if(currentFlashPort2Url != null && !currentFlashPort2Url.isEmpty())
new AlertDialog.Builder(this)
.setTitle(getString(R.string.alert_losing_flash_rom_title))
.setMessage(getString(R.string.alert_losing_flash_rom_message))
@@ -1165,8 +1165,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
// Reset to default Flash ROM from the KML file
settings.putString("settings_flash_port2", null);
String kmlFilename = NativeLib.getCurrentKml();
- if(kmlFilename.length() > 0) {
- String kmlFolder = kmlFolderURL == null || kmlFolderURL.length() == 0 ? null : kmlFolderURL;
+ if(!kmlFilename.isEmpty()) {
+ String kmlFolder = kmlFolderURL == null || kmlFolderURL.isEmpty() ? null : kmlFolderURL;
// Reset the flashROM
NativeLib.onLoadFlashROM("");
// Load the KML file again. TODO If it goes wrong, we are lost.
@@ -1237,7 +1237,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
updateFromPreferences("settings_flash_port2", true);
displayFilename(url);
String settingsFlashPort2Url = settings.getString("settings_flash_port2", null);
- if(settingsFlashPort2Url != null && settingsFlashPort2Url.length() > 0)
+ if(settingsFlashPort2Url != null && !settingsFlashPort2Url.isEmpty())
showAlert(String.format(Locale.US, getString(R.string.message_state_and_flash_saved), getFilenameFromURL(url), getFilenameFromURL(settingsFlashPort2Url)));
else
showAlert(String.format(Locale.US, getString(R.string.message_state_saved), getFilenameFromURL(url)));
@@ -1344,8 +1344,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
// Not possible to save the current FlashROM :-( [NativeLib.onSaveFlashROM(url);]
// So, we are going to create a new one from the ROM loaded by the current KML script!
String kmlFilename = NativeLib.getCurrentKml();
- if(kmlFilename != null && kmlFilename.length() > 0) {
- if(kmlFolderURL != null && kmlFolderURL.length() > 0)
+ if(kmlFilename != null && !kmlFilename.isEmpty()) {
+ if(kmlFolderURL != null && !kmlFolderURL.isEmpty())
copyROMFromFolder(kmlFilename, uri);
else
copyROMFromAsset(kmlFilename, uri);
@@ -1453,7 +1453,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
}
}
- if(romFilename != null && romFilename.length() > 0) {
+ if(romFilename != null && !romFilename.isEmpty()) {
ParcelFileDescriptor pfdROM = openFileInFolderFromContentResolverPFD(romFilename, kmlFolderURL, GENERIC_READ);
if(pfdROM != null) {
try {
@@ -1479,7 +1479,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
try {
kmlInputStream = assetManager.open("calculators/" + kmlFilename);
String romFilename = extractROMFilename(kmlInputStream);
- if(romFilename != null && romFilename.length() > 0) {
+ if(romFilename != null && !romFilename.isEmpty()) {
InputStream romInputStream = assetManager.open("calculators/" + romFilename);
copyROMtoFlashROM(romInputStream, uri);
}
@@ -1583,7 +1583,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
if(getPackageName().contains("org.emulator.forty.eight") && settings.getBoolean("settings_port2en", false)) {
// Check if the access to the port2 shared file is still possible.
String port2Url = settings.getString("settings_port2load", "");
- if(port2Url != null && port2Url.length() > 0) {
+ if(port2Url != null && !port2Url.isEmpty()) {
Uri port2Uri = Uri.parse(port2Url);
DocumentFile port2DocumentFile = DocumentFile.fromSingleUri(this, port2Uri);
if (port2DocumentFile == null || !port2DocumentFile.exists()) {
@@ -1706,7 +1706,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
updateFromPreferences("settings_flash_port2", true);
String settingsFlashPort2Url = settings.getString("settings_flash_port2", null);
- if(settingsFlashPort2Url != null && settingsFlashPort2Url.length() > 0)
+ if(settingsFlashPort2Url != null && !settingsFlashPort2Url.isEmpty())
showAlert(String.format(Locale.US, getString(R.string.message_state_and_flash_saved), getFilenameFromURL(currentFilenameUrl), getFilenameFromURL(settingsFlashPort2Url)));
else
showAlert(String.format(Locale.US, getString(R.string.message_state_saved), getFilenameFromURL(currentFilenameUrl)));
@@ -1716,7 +1716,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void displayFilename(String stateFileURL) {
String displayName = getFilenameFromURL(stateFileURL == null ? "" : stateFileURL);
String port2FileURL = settings.getString("settings_flash_port2", null);
- if(port2FileURL != null && port2FileURL.length() > 0)
+ if(port2FileURL != null && !port2FileURL.isEmpty())
displayName += " " + getFilenameFromURL(port2FileURL);
View headerView = displayKMLTitle();
if(headerView != null) {
@@ -2082,14 +2082,14 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
private int serialIndex = 1;
- private HashMap serialsById = new HashMap<>();
+ private final HashMap serialsById = new HashMap<>();
@SuppressWarnings("UnusedDeclaration")
int openSerialPort(String serialPort) {
// Search if this same serial port is not already opened
- Integer serialPortId = serialIndex;
+ int serialPortId = serialIndex;
Serial serial = new Serial(this, serialPortId);
if(serial.connect(serialPort)) {
serialsById.put(serialPortId, serial);
@@ -2104,10 +2104,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
String connectionStatus = serial.getConnectionStatus();
try {
int resId = Utils.resId(MainActivity.this, "string", connectionStatus);
- Toast.makeText(MainActivity.this, resId, Toast.LENGTH_LONG).show();
+ Toast.makeText(MainActivity.this, resId, Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
- Log.e(TAG, ex.getMessage());
- Toast.makeText(MainActivity.this, "Unknown error, connectionStatus: " + connectionStatus, Toast.LENGTH_LONG).show();
+ Log.e(TAG, "Unknown error, connectionStatus: " + connectionStatus + ", " + ex.getMessage());
+ Toast.makeText(MainActivity.this, "Unknown error, connectionStatus: " + connectionStatus, Toast.LENGTH_SHORT).show();
}
});
return 0;
@@ -2200,7 +2200,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
}
private void setPort1Settings(boolean port1Plugged, boolean port1Writable) {
- if(this.getClass().getPackage().getName().equals("org.emulator.forty.eight")) {
+ Package pack = this.getClass().getPackage();
+ if(pack != null && pack.getName().equals("org.emulator.forty.eight")) {
settings.putBoolean("settings_port1en", port1Plugged);
settings.putBoolean("settings_port1wr", port1Writable);
updateFromPreferences("settings_port1", true);
@@ -2224,7 +2225,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
switch (key) {
case "settings_realspeed":
case "settings_grayscale":
- NativeLib.setConfiguration(key, isDynamicValue, settings.getBoolean(key, false) ? 1 : 0, 0, null);
+ case "settings_serial_slowdown":
+ NativeLib.setConfiguration(key, isDynamicValue, settings.getBoolean(key, false) ? 1 : 0, 0, null);
break;
case "settings_rotation":
@@ -2347,9 +2349,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
NativeLib.setConfiguration("settings_serial_ports_ir", isDynamicValue, 0, 0,
DevicesFragment.SerialConnectParameters.fromSettingsString(settings.getString("settings_serial_ports_ir", "")).toWin32String());
break;
- case "settings_serial_slowdown":
- NativeLib.setConfiguration(key, isDynamicValue, settings.getBoolean(key, false) ? 1 : 0, 0, null);
- break;
}
}
}
diff --git a/build.gradle b/build.gradle
index bf9b331..cbacbf7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.4.2'
+ classpath 'com.android.tools.build:gradle:8.6.1'
// NOTE: Do not place your application dependencies here; they belong
diff --git a/gradle.properties b/gradle.properties
index 70517d2..0471563 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,7 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-android.defaults.buildfeatures.buildconfig=true
+#android.defaults.buildfeatures.buildconfig=true
android.enableJetifier=true
android.nonFinalResIds=true
android.nonTransitiveRClass=true
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 3f37000..534e239 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Sat Jan 28 21:16:38 CET 2023
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME