diff --git a/ohos-project/entry/oh-package-lock.json5 b/ohos-project/entry/oh-package-lock.json5 index 8d56dfdc2f..2967845e7e 100644 --- a/ohos-project/entry/oh-package-lock.json5 +++ b/ohos-project/entry/oh-package-lock.json5 @@ -1,19 +1,19 @@ -{ - "meta": { - "stableOrder": true, - "enableUnifiedLockfile": false - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "libSDL3.so@src/main/cpp/sdl": "libSDL3.so@src/main/cpp/sdl" - }, - "packages": { - "libSDL3.so@src/main/cpp/sdl": { - "name": "libSDL3.so", - "version": "1.0.0", - "resolved": "", - "registryType": "local" - } - } +{ + "meta": { + "stableOrder": true, + "enableUnifiedLockfile": false + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "libSDL3.so@src/main/cpp/sdl": "libSDL3.so@src/main/cpp/sdl" + }, + "packages": { + "libSDL3.so@src/main/cpp/sdl": { + "name": "libSDL3.so", + "version": "1.0.0", + "resolved": "", + "registryType": "local" + } + } } \ No newline at end of file diff --git a/ohos-project/entry/src/main/ets/pages/Index.ets b/ohos-project/entry/src/main/ets/pages/Index.ets index 72da526504..5b94ed296a 100644 --- a/ohos-project/entry/src/main/ets/pages/Index.ets +++ b/ohos-project/entry/src/main/ets/pages/Index.ets @@ -1,208 +1,212 @@ -import { hilog } from '@kit.PerformanceAnalysisKit'; -import sdl from 'libSDL3.so'; -import { intl } from '@kit.LocalizationKit'; -import { promptAction, ShowDialogSuccessResponse } from '@kit.ArkUI'; -import { inputMethod } from '@kit.IMEKit' -import { pasteboard } from '@kit.BasicServicesKit'; -import { common, ConfigurationConstant } from '@kit.AbilityKit'; -import { batteryInfo } from '@kit.BasicServicesKit'; - -import { picker } from '@kit.CoreFileKit'; -import { BusinessError } from '@kit.BasicServicesKit'; - -const DOMAIN = 0x0000; - -let controller = inputMethod.getController() -let input = false -let targetText = "" -let context: UIContext - -export class ArkNapiCallback { - onMainLaunch() { - sdl.sdlLaunchMain("libentry.so", "main") - } - - showDialog(title: string, message: string, indexMapping: number[], names: string[]) { - let target: promptAction.Button[] = [] - for (let i = 0; i < names.length; i++) - { - target.push({ text: names[i], color: '#999999' }) - } - promptAction.showDialog({ title: title, message: message, buttons: target }).then((a) => { - sdl.sdlSendDialogStatus(indexMapping[a.index]) - }) - } - fetchLocale(): string { - let locale = new intl.Locale() - return locale.language + "_" + locale.region - } - firstCall() { - hilog.info(DOMAIN, 'surfaceLayer', 'Native binding finished.') - sdl.sdlOnConfigUpdate(); - } - - openLink(url: string) { - let con = context.getHostContext() as common.UIAbilityContext - con.openLink(url) - } - - hasBattery(): number { - return batteryInfo.isBatteryPresent ? 1 : 0 - } - batteryCharging(): number { - return batteryInfo.chargingStatus == batteryInfo.BatteryChargeState.ENABLE ? 1 : 0 - } - batteryCharged(): number { - return batteryInfo.chargingStatus == batteryInfo.BatteryChargeState.FULL ? 1 : 0 - } - batteryPercent(): number { - return batteryInfo.batterySOC - } - - setPasteboardString(text: string) { - let pasteData: pasteboard.PasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); - let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); - systemPasteboard.setData(pasteData, (err, data) => { - if (err) { - hilog.error(DOMAIN, 'surfaceLayer', 'Failed to set PasteData. Cause: ' + err.message); - return; - } - - hilog.info(DOMAIN, 'surfaceLayer', 'Succeed in setting PasteData.'); - }); - } - - textEditing(): number { - return input ? 1 : 0; - } - - startTextInput() { - input = true - controller.showTextInput() - hilog.info(DOMAIN, 'surfaceLayer', 'text input start') - } - stopTextInput() { - input = false - controller.hideTextInput() - hilog.info(DOMAIN, 'surfaceLayer', 'text input stop') - targetText = "" - } - - openFileDialog(id: number, defpath: string, itemcount: number, filter: string) { - const documentSelectOptions = new picker.DocumentSelectOptions(); - documentSelectOptions.maxSelectNumber = itemcount; - documentSelectOptions.defaultFilePathUri = defpath; - - if (id == 0 || id == 1) - { - documentSelectOptions.selectMode = picker.DocumentSelectMode.FILE; - } - if (id == 2) - { - documentSelectOptions.selectMode = picker.DocumentSelectMode.FOLDER; - } - - let targetfilter: string[] = [] - let temp = filter.split('\u0002') - for (let index = 0; index < temp.length; index++) { - const element = temp[index]; - - let temp2 = element.split("|") - - // broken filter! - if (temp2.length == 1) - { - targetfilter.push(element + "|.*") - } - else - { - let targettemp = temp2[0] + "|"; - - let temp3 = temp2[1].split(";") - for (let index1 = 0; index1 < temp3.length; index1++) { - targettemp += "." + temp3[index1] + ","; - } - targetfilter.push(targettemp) - } - } - - documentSelectOptions.fileSuffixFilters = targetfilter; - documentSelectOptions.authMode = false; - documentSelectOptions.mergeMode = picker.MergeTypeMode.DEFAULT; - documentSelectOptions.isEncryptionSupported = false; - - let uris: string[] = []; - let contextt = context.getHostContext() as common.UIAbilityContext; - const documentViewPicker = new picker.DocumentViewPicker(contextt); - documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array) => { - uris = documentSelectResult; - sdl.sdlDialogClearSelection() - for (let idx = 0; idx < uris.length; idx++) - { - let target = uris[idx].replace("file://docs", "") - sdl.sdlDialogFileSelected(target) - console.info('documentViewPicker.select to file succeed and uris are: ' + target); - } - sdl.sdlDialogExecCallback() - }).catch((err: BusinessError) => { - console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`); - }) - } - - getInternalPath(): string { - let contextt = context.getHostContext() as common.UIAbilityContext - return contextt.filesDir - } - - themeIsDark(): number { - let contextt = context.getHostContext() as common.UIAbilityContext - return (contextt.config.colorMode == ConfigurationConstant.ColorMode.COLOR_MODE_DARK) ? 1 : 0; - } -} - -let callbackRef: ArkNapiCallback = new ArkNapiCallback() - -@Entry -@Component -struct Index { - async aboutToAppear(): Promise { - context = this.getUIContext() - - sdl.sdlCallbackInit(callbackRef) - focusControl.requestFocus('mainView') - await controller.attach(true, { - inputAttribute: { - textInputType: inputMethod.TextInputType.TEXT, - enterKeyType: inputMethod.EnterKeyType.DONE - } - }); - controller.on('insertText', (text) => { - targetText += text; - sdl.sdlTextAppend(text) - }) - controller.on('deleteLeft', (i) => { - sdl.sdlTextEditing(targetText, targetText.length - 1 - i, i); - - if (targetText.length > 0) { - targetText = targetText.substring(0, targetText.length - i) - } - }) - controller.on('deleteRight', (i) => { - sdl.sdlTextEditing(targetText, 0, i); - - if (targetText.length > 0) { - targetText = targetText.substring(i, targetText.length) - } - }) - } - - build() { - Column() { - XComponent({ id: 'mainView', type: 'surface', libraryname: 'SDL3' }) - .id('mainView') - } - .onKeyEvent((keyevent) => { - sdl.sdlKeyEvent(keyevent.keyCode, keyevent.type); - }) - } -} +import { hilog } from '@kit.PerformanceAnalysisKit'; +import sdl from 'libSDL3.so'; +import { intl } from '@kit.LocalizationKit'; +import { promptAction, ShowDialogSuccessResponse } from '@kit.ArkUI'; +import { inputMethod } from '@kit.IMEKit' +import { deviceInfo, pasteboard } from '@kit.BasicServicesKit'; +import { common, ConfigurationConstant } from '@kit.AbilityKit'; +import { batteryInfo } from '@kit.BasicServicesKit'; + +import { picker } from '@kit.CoreFileKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +const DOMAIN = 0x0000; + +let controller = inputMethod.getController() +let input = false +let targetText = "" +let context: UIContext + +export class ArkNapiCallback { + onMainLaunch() { + sdl.sdlLaunchMain("libentry.so", "main") + } + + showDialog(title: string, message: string, indexMapping: number[], names: string[]) { + let target: promptAction.Button[] = [] + for (let i = 0; i < names.length; i++) + { + target.push({ text: names[i], color: '#999999' }) + } + promptAction.showDialog({ title: title, message: message, buttons: target }).then((a) => { + sdl.sdlSendDialogStatus(indexMapping[a.index]) + }) + } + fetchLocale(): string { + let locale = new intl.Locale() + return locale.language + "_" + locale.region + } + firstCall() { + hilog.info(DOMAIN, 'surfaceLayer', 'Native binding finished.') + sdl.sdlOnConfigUpdate(); + } + + openLink(url: string) { + let con = context.getHostContext() as common.UIAbilityContext + con.openLink(url) + } + + hasBattery(): number { + return batteryInfo.isBatteryPresent ? 1 : 0 + } + batteryCharging(): number { + return batteryInfo.chargingStatus == batteryInfo.BatteryChargeState.ENABLE ? 1 : 0 + } + batteryCharged(): number { + return batteryInfo.chargingStatus == batteryInfo.BatteryChargeState.FULL ? 1 : 0 + } + batteryPercent(): number { + return batteryInfo.batterySOC + } + + setPasteboardString(text: string) { + let pasteData: pasteboard.PasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); + let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); + systemPasteboard.setData(pasteData, (err, data) => { + if (err) { + hilog.error(DOMAIN, 'surfaceLayer', 'Failed to set PasteData. Cause: ' + err.message); + return; + } + + hilog.info(DOMAIN, 'surfaceLayer', 'Succeed in setting PasteData.'); + }); + } + + textEditing(): number { + return input ? 1 : 0; + } + + startTextInput() { + input = true + controller.showTextInput() + hilog.info(DOMAIN, 'surfaceLayer', 'text input start') + } + stopTextInput() { + input = false + controller.hideTextInput() + hilog.info(DOMAIN, 'surfaceLayer', 'text input stop') + targetText = "" + } + + openFileDialog(id: number, defpath: string, itemcount: number, filter: string) { + const documentSelectOptions = new picker.DocumentSelectOptions(); + documentSelectOptions.maxSelectNumber = itemcount; + documentSelectOptions.defaultFilePathUri = defpath; + + if (id == 0 || id == 1) + { + documentSelectOptions.selectMode = picker.DocumentSelectMode.FILE; + } + if (id == 2) + { + documentSelectOptions.selectMode = picker.DocumentSelectMode.FOLDER; + } + + let targetfilter: string[] = [] + let temp = filter.split('\u0002') + for (let index = 0; index < temp.length; index++) { + const element = temp[index]; + + let temp2 = element.split("|") + + // broken filter! + if (temp2.length == 1) + { + targetfilter.push(element + "|.*") + } + else + { + let targettemp = temp2[0] + "|"; + + let temp3 = temp2[1].split(";") + for (let index1 = 0; index1 < temp3.length; index1++) { + targettemp += "." + temp3[index1] + ","; + } + targetfilter.push(targettemp) + } + } + + documentSelectOptions.fileSuffixFilters = targetfilter; + documentSelectOptions.authMode = false; + documentSelectOptions.mergeMode = picker.MergeTypeMode.DEFAULT; + documentSelectOptions.isEncryptionSupported = false; + + let uris: string[] = []; + let contextt = context.getHostContext() as common.UIAbilityContext; + const documentViewPicker = new picker.DocumentViewPicker(contextt); + documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array) => { + uris = documentSelectResult; + sdl.sdlDialogClearSelection() + for (let idx = 0; idx < uris.length; idx++) + { + let target = uris[idx].replace("file://docs", "") + sdl.sdlDialogFileSelected(target) + console.info('documentViewPicker.select to file succeed and uris are: ' + target); + } + sdl.sdlDialogExecCallback() + }).catch((err: BusinessError) => { + console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`); + }) + } + + getInternalPath(): string { + let contextt = context.getHostContext() as common.UIAbilityContext + return contextt.filesDir + } + + themeIsDark(): number { + let contextt = context.getHostContext() as common.UIAbilityContext + return (contextt.config.colorMode == ConfigurationConstant.ColorMode.COLOR_MODE_DARK) ? 1 : 0; + } + + isPhone(): number { + return deviceInfo.deviceType == "phone" ? 1 : 0; + } +} + +let callbackRef: ArkNapiCallback = new ArkNapiCallback() + +@Entry +@Component +struct Index { + async aboutToAppear(): Promise { + context = this.getUIContext() + + sdl.sdlCallbackInit(callbackRef) + focusControl.requestFocus('mainView') + await controller.attach(true, { + inputAttribute: { + textInputType: inputMethod.TextInputType.TEXT, + enterKeyType: inputMethod.EnterKeyType.DONE + } + }); + controller.on('insertText', (text) => { + targetText += text; + sdl.sdlTextAppend(text) + }) + controller.on('deleteLeft', (i) => { + sdl.sdlTextEditing(targetText, targetText.length - 1 - i, i); + + if (targetText.length > 0) { + targetText = targetText.substring(0, targetText.length - i) + } + }) + controller.on('deleteRight', (i) => { + sdl.sdlTextEditing(targetText, 0, i); + + if (targetText.length > 0) { + targetText = targetText.substring(i, targetText.length) + } + }) + } + + build() { + Column() { + XComponent({ id: 'mainView', type: 'surface', libraryname: 'SDL3' }) + .id('mainView') + } + .onKeyEvent((keyevent) => { + sdl.sdlKeyEvent(keyevent.keyCode, keyevent.type); + }) + } +} diff --git a/ohos-project/oh-package-lock.json5 b/ohos-project/oh-package-lock.json5 index 6b264af261..35c2f794fa 100644 --- a/ohos-project/oh-package-lock.json5 +++ b/ohos-project/oh-package-lock.json5 @@ -1,28 +1,28 @@ -{ - "meta": { - "stableOrder": true, - "enableUnifiedLockfile": false - }, - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": { - "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", - "@ohos/hypium@1.0.24": "@ohos/hypium@1.0.24" - }, - "packages": { - "@ohos/hamock@1.0.0": { - "name": "", - "version": "1.0.0", - "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", - "registryType": "ohpm" - }, - "@ohos/hypium@1.0.24": { - "name": "", - "version": "1.0.24", - "integrity": "sha512-3dCqc+BAR5LqEGG2Vtzi8O3r7ci/3fYU+FWjwvUobbfko7DUnXGOccaror0yYuUhJfXzFK0aZNMGSnXaTwEnbw==", - "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.24.har", - "registryType": "ohpm" - } - } +{ + "meta": { + "stableOrder": true, + "enableUnifiedLockfile": false + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.24": "@ohos/hypium@1.0.24" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.24": { + "name": "", + "version": "1.0.24", + "integrity": "sha512-3dCqc+BAR5LqEGG2Vtzi8O3r7ci/3fYU+FWjwvUobbfko7DUnXGOccaror0yYuUhJfXzFK0aZNMGSnXaTwEnbw==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.24.har", + "registryType": "ohpm" + } + } } \ No newline at end of file diff --git a/src/SDL.c b/src/SDL.c index ed27b2e64b..b6408818e6 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -61,6 +61,10 @@ #include "core/android/SDL_android.h" #endif +#ifdef SDL_PLATFORM_OHOS +#include "core/ohos/SDL_ohos.h" +#endif + #define SDL_ALL_SUBSYSTEM_FLAGS ~0U // Initialization/Cleanup routines @@ -820,7 +824,7 @@ const char *SDL_GetPlatform(void) #elif defined(__managarm__) return "Managarm"; #elif defined(SDL_PLATFORM_OHOS) - return "OpenHarmony/HarmonyOS" + return "OpenHarmony/HarmonyOS"; #else return "Unknown (see SDL_platform.h)"; #endif @@ -833,6 +837,8 @@ bool SDL_IsPhone(void) if (!SDL_IsTablet() && !SDL_IsTV()) { return true; } +#elif defined(SDL_PLATFORM_OHOS) + return OHOS_IsPhone(); #endif return false; } diff --git a/src/core/ohos/SDL_ohos.c b/src/core/ohos/SDL_ohos.c index eb140504b9..c2082467a0 100644 --- a/src/core/ohos/SDL_ohos.c +++ b/src/core/ohos/SDL_ohos.c @@ -468,6 +468,24 @@ bool OHOS_ThemeDark() return data->ret.data.i; } +bool OHOS_IsPhone() +{ + napiCallbackData *data = SDL_malloc(sizeof(napiCallbackData)); + SDL_memset(data, 0, sizeof(napiCallbackData)); + data->func = "isPhone"; + data->argCount = 0; + data->type = Int; + data->returned = false; + + napi_call_threadsafe_function(napiEnv.func, data, napi_tsfn_nonblocking); + + while (!data->returned) {} + + int d = data->ret.data.i; + SDL_free(data); + return d; +} + const char* OHOS_Locale() { napiCallbackData *data = SDL_malloc(sizeof(napiCallbackData)); diff --git a/src/core/ohos/SDL_ohos.h b/src/core/ohos/SDL_ohos.h index e82b8ff376..fa2788af8b 100644 --- a/src/core/ohos/SDL_ohos.h +++ b/src/core/ohos/SDL_ohos.h @@ -1,38 +1,40 @@ -#ifndef SDL_OHOS_H -#define SDL_OHOS_H - -#include "SDL3/SDL_video.h" -#include "video/SDL_sysvideo.h" -#include - -void OHOS_windowDataFill(SDL_Window* w); -void OHOS_removeWindow(SDL_Window* w); -void OHOS_LockPage(); -void OHOS_UnlockPage(); -int OHOS_FetchWidth(); -int OHOS_FetchHeight(); - -int OHOS_MessageBox(const char* title, const char* message, int ml, int* mapping, int bl, const char * const *buttons); -const char* OHOS_Locale(); -void OHOS_OpenLink(const char* url); -bool OHOS_IsBatteryPresent(); -bool OHOS_IsBatteryCharging(); -bool OHOS_IsBatteryCharged(); -int OHOS_GetBatteryPercent(); -void OHOS_SetClipboardText(const char* data); -char* OHOS_GetStoragePath(); -bool OHOS_ThemeDark(); - -void OHOS_FileDialog(int id, const char* defpath, int allowmany, const char* filter); - -bool OHOS_IsScreenKeyboardShown(); -void OHOS_StartTextInput(); -void OHOS_StopTextInput(); - -typedef struct SDL_VideoData { - SDL_Rect textRect; - int isPaused; - int isPausing; -} SDL_VideoData; - -#endif +#ifndef SDL_OHOS_H +#define SDL_OHOS_H + +#include "SDL3/SDL_video.h" +#include "video/SDL_sysvideo.h" +#include + +void OHOS_windowDataFill(SDL_Window* w); +void OHOS_removeWindow(SDL_Window* w); +void OHOS_LockPage(); +void OHOS_UnlockPage(); +int OHOS_FetchWidth(); +int OHOS_FetchHeight(); + +int OHOS_MessageBox(const char* title, const char* message, int ml, int* mapping, int bl, const char * const *buttons); +const char* OHOS_Locale(); +void OHOS_OpenLink(const char* url); +bool OHOS_IsBatteryPresent(); +bool OHOS_IsBatteryCharging(); +bool OHOS_IsBatteryCharged(); +int OHOS_GetBatteryPercent(); +void OHOS_SetClipboardText(const char* data); +char* OHOS_GetStoragePath(); +bool OHOS_ThemeDark(); + +bool OHOS_IsPhone(); + +void OHOS_FileDialog(int id, const char* defpath, int allowmany, const char* filter); + +bool OHOS_IsScreenKeyboardShown(); +void OHOS_StartTextInput(); +void OHOS_StopTextInput(); + +typedef struct SDL_VideoData { + SDL_Rect textRect; + int isPaused; + int isPausing; +} SDL_VideoData; + +#endif