2020-12-05 13:08:24 +01:00
# include "stdafx.h"
2017-05-15 13:58:32 +02:00
# include "Emu/System.h"
2020-03-14 22:03:56 +01:00
# include "Emu/system_config.h"
2018-12-30 02:34:15 +01:00
# include "Emu/Cell/PPUModule.h"
2020-10-04 22:46:28 +02:00
# include "Emu/Io/interception.h"
2022-04-19 23:36:18 +02:00
# include "Emu/Io/Keyboard.h"
2020-02-24 20:09:46 +01:00
# include "Emu/RSX/Overlays/overlay_osk.h"
2020-11-06 18:45:06 +01:00
# include "Emu/IdManager.h"
2017-05-15 13:58:32 +02:00
2017-01-18 23:01:25 +01:00
# include "cellSysutil.h"
# include "cellOskDialog.h"
2017-01-23 18:14:12 +01:00
# include "cellMsgDialog.h"
2023-01-18 21:39:13 +01:00
# include "cellImeJp.h"
2015-07-30 03:43:03 +02:00
2020-11-06 18:45:06 +01:00
# include <thread>
2018-08-25 14:39:00 +02:00
LOG_CHANNEL ( cellOskDialog ) ;
2015-07-30 03:43:03 +02:00
2019-01-04 14:45:32 +01:00
template < >
void fmt_class_string < CellOskDialogError > : : format ( std : : string & out , u64 arg )
{
format_enum ( out , arg , [ ] ( auto error )
{
switch ( error )
{
STR_CASE ( CELL_OSKDIALOG_ERROR_IME_ALREADY_IN_USE ) ;
STR_CASE ( CELL_OSKDIALOG_ERROR_GET_SIZE_ERROR ) ;
STR_CASE ( CELL_OSKDIALOG_ERROR_UNKNOWN ) ;
STR_CASE ( CELL_OSKDIALOG_ERROR_PARAM ) ;
}
return unknown ;
} ) ;
}
2021-09-21 00:59:11 +02:00
template < >
void fmt_class_string < CellOskDialogContinuousMode > : : format ( std : : string & out , u64 arg )
{
format_enum ( out , arg , [ ] ( auto mode )
{
switch ( mode )
{
STR_CASE ( CELL_OSKDIALOG_CONTINUOUS_MODE_NONE ) ;
STR_CASE ( CELL_OSKDIALOG_CONTINUOUS_MODE_REMAIN_OPEN ) ;
STR_CASE ( CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE ) ;
STR_CASE ( CELL_OSKDIALOG_CONTINUOUS_MODE_SHOW ) ;
}
return unknown ;
} ) ;
}
2023-01-20 22:43:24 +01:00
void osk_info : : reset ( )
2019-01-04 22:28:52 +01:00
{
2023-01-20 22:43:24 +01:00
std : : lock_guard lock ( text_mtx ) ;
dlg . reset ( ) ;
valid_text = { } ;
use_separate_windows = false ;
2023-01-22 17:01:33 +01:00
lock_ext_input_device = false ;
2023-01-20 22:43:24 +01:00
device_mask = 0 ;
input_field_window_width = 0 ;
2023-01-21 11:57:10 +01:00
input_field_background_transparency = 1.0f ;
2023-01-20 22:43:24 +01:00
input_field_layout_info = { } ;
input_panel_layout_info = { } ;
key_layout_options = CELL_OSKDIALOG_10KEY_PANEL ;
initial_key_layout = CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_SYSTEM ;
initial_input_device = CELL_OSKDIALOG_INPUT_DEVICE_PAD ;
clipboard_enabled = false ;
half_byte_kana_enabled = false ;
supported_languages = 0 ;
dimmer_enabled = true ;
base_color = OskDialogBase : : color { 0.2f , 0.2f , 0.2f , 1.0f } ;
pointer_enabled = false ;
pointer_x = 0.0f ;
pointer_y = 0.0f ;
initial_scale = 1.0f ;
layout = { } ;
osk_continuous_mode = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE ;
last_dialog_state = CELL_SYSUTIL_OSKDIALOG_UNLOADED ;
osk_confirm_callback . store ( { } ) ;
osk_force_finish_callback . store ( { } ) ;
osk_hardware_keyboard_event_hook_callback . store ( { } ) ;
hook_event_mode . store ( 0 ) ;
2019-01-04 22:28:52 +01:00
}
2017-01-23 18:14:12 +01:00
2023-01-20 22:43:24 +01:00
// Align horizontally
u32 osk_info : : get_aligned_x ( u32 layout_mode )
2023-01-20 00:24:27 +01:00
{
2023-01-20 22:43:24 +01:00
// Let's prefer a centered alignment.
if ( layout_mode & CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_CENTER )
2023-01-20 00:24:27 +01:00
{
2023-01-20 22:43:24 +01:00
return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_CENTER ;
2023-01-20 00:24:27 +01:00
}
2021-09-19 21:21:56 +02:00
2023-01-20 22:43:24 +01:00
if ( layout_mode & CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT )
2021-09-19 21:51:45 +02:00
{
2023-01-20 22:43:24 +01:00
return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_LEFT ;
2021-09-19 21:51:45 +02:00
}
2023-01-19 23:33:52 +01:00
2023-01-20 22:43:24 +01:00
return CELL_OSKDIALOG_LAYOUTMODE_X_ALIGN_RIGHT ;
}
2023-01-19 23:33:52 +01:00
2023-01-20 22:43:24 +01:00
// Align vertically
u32 osk_info : : get_aligned_y ( u32 layout_mode )
{
// Let's prefer a centered alignment.
if ( layout_mode & CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_CENTER )
{
return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_CENTER ;
2023-01-19 23:33:52 +01:00
}
2023-01-20 22:43:24 +01:00
if ( layout_mode & CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP )
2023-01-19 23:33:52 +01:00
{
2023-01-20 22:43:24 +01:00
return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_TOP ;
2023-01-19 23:33:52 +01:00
}
2023-01-20 22:43:24 +01:00
return CELL_OSKDIALOG_LAYOUTMODE_Y_ALIGN_BOTTOM ;
}
2019-09-26 20:35:27 +02:00
// TODO: don't use this function
2022-04-19 19:15:12 +02:00
std : : shared_ptr < OskDialogBase > _get_osk_dialog ( bool create )
2019-09-26 20:35:27 +02:00
{
2021-03-02 12:59:19 +01:00
auto & osk = g_fxo - > get < osk_info > ( ) ;
2019-09-26 20:35:27 +02:00
if ( create )
2019-01-29 17:29:55 +01:00
{
2021-03-02 12:59:19 +01:00
const auto init = osk . init . init ( ) ;
2019-09-26 20:35:27 +02:00
if ( ! init )
2019-01-29 17:29:55 +01:00
{
2019-09-26 20:35:27 +02:00
return nullptr ;
}
2021-02-03 19:14:31 +01:00
if ( auto manager = g_fxo - > try_get < rsx : : overlays : : display_manager > ( ) )
2019-09-26 20:35:27 +02:00
{
2020-03-14 22:03:56 +01:00
std : : shared_ptr < rsx : : overlays : : osk_dialog > dlg = std : : make_shared < rsx : : overlays : : osk_dialog > ( ) ;
2021-03-02 12:59:19 +01:00
osk . dlg = manager - > add ( dlg ) ;
2019-09-26 20:35:27 +02:00
}
else
{
2021-03-02 12:59:19 +01:00
osk . dlg = Emu . GetCallbacks ( ) . get_osk_dialog ( ) ;
2019-01-29 17:29:55 +01:00
}
2021-03-02 12:59:19 +01:00
return osk . dlg ;
2019-01-29 17:29:55 +01:00
}
2019-09-26 20:35:27 +02:00
2021-09-20 20:39:37 +02:00
const auto init = osk . init . access ( ) ;
2019-01-29 17:29:55 +01:00
2021-09-20 20:39:37 +02:00
if ( ! init )
{
return nullptr ;
2019-01-29 17:29:55 +01:00
}
2021-09-20 20:39:37 +02:00
return osk . dlg ;
2019-01-29 17:29:55 +01:00
}
2023-01-21 19:01:20 +01:00
extern bool close_osk_from_ps_button ( )
{
const auto osk = _get_osk_dialog ( false ) ;
if ( ! osk )
{
// The OSK is not open
return true ;
}
osk_info & info = g_fxo - > get < osk_info > ( ) ;
// We can only close the osk in separate window mode when it is hidden (continuous_mode is set to CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
if ( ! info . use_separate_windows | | osk - > continuous_mode ! = CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE )
{
cellOskDialog . warning ( " close_osk_from_ps_button: can't close OSK (use_separate_windows=%d, continuous_mode=%s) " , info . use_separate_windows . load ( ) , osk - > continuous_mode . load ( ) ) ;
return false ;
}
std : : lock_guard lock ( info . text_mtx ) ;
if ( auto cb = info . osk_force_finish_callback . load ( ) )
{
bool done = false ;
bool close_osk = false ;
sysutil_register_cb ( [ & ] ( ppu_thread & cb_ppu ) - > s32
{
cellOskDialog . notice ( " osk_force_finish_callback() " ) ;
close_osk = cb ( cb_ppu ) ;
cellOskDialog . notice ( " osk_force_finish_callback returned %d " , close_osk ) ;
done = true ;
return 0 ;
} ) ;
// wait for check callback
while ( ! done & & ! Emu . IsStopped ( ) )
{
std : : this_thread : : yield ( ) ;
}
if ( ! close_osk )
{
// We are not allowed to close the OSK
cellOskDialog . warning ( " close_osk_from_ps_button: can't close OSK (osk_force_finish_callback returned false) " ) ;
return false ;
}
}
// Forcefully terminate the OSK
cellOskDialog . warning ( " close_osk_from_ps_button: Terminating the OSK ... " ) ;
osk - > Close ( FAKE_CELL_OSKDIALOG_CLOSE_TERMINATE ) ;
osk - > state = OskDialogState : : Closed ;
cellOskDialog . notice ( " close_osk_from_ps_button: sending CELL_SYSUTIL_OSKDIALOG_FINISHED " ) ;
sysutil_send_system_cmd ( CELL_SYSUTIL_OSKDIALOG_FINISHED , 0 ) ;
return true ;
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogLoadAsync ( u32 container , vm : : ptr < CellOskDialogParam > dialogParam , vm : : ptr < CellOskDialogInputFieldInfo > inputFieldInfo )
2015-07-30 03:43:03 +02:00
{
2017-01-18 23:01:25 +01:00
cellOskDialog . warning ( " cellOskDialogLoadAsync(container=0x%x, dialogParam=*0x%x, inputFieldInfo=*0x%x) " , container , dialogParam , inputFieldInfo ) ;
2017-01-23 18:14:12 +01:00
2019-01-05 18:11:43 +01:00
if ( ! dialogParam | | ! inputFieldInfo | | ! inputFieldInfo - > message | | ! inputFieldInfo - > init_text | | inputFieldInfo - > limit_length > CELL_OSKDIALOG_STRING_SIZE )
2018-12-30 22:27:37 +01:00
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2023-01-20 00:24:27 +01:00
cellOskDialog . notice ( " cellOskDialogLoadAsync: dialogParam={ allowOskPanelFlg=0x%x, prohibitFlgs=0x%x, firstViewPanel=%d, controlPoint=(%.2f,%.2f) } " ,
dialogParam - > allowOskPanelFlg , dialogParam - > prohibitFlgs , dialogParam - > firstViewPanel , dialogParam - > controlPoint . x , dialogParam - > controlPoint . y ) ;
2019-01-29 17:29:55 +01:00
auto osk = _get_osk_dialog ( true ) ;
2018-12-30 22:27:37 +01:00
2019-01-04 02:02:26 +01:00
// Can't open another dialog if this one is already open.
2021-09-21 00:59:11 +02:00
if ( ! osk | | osk - > state . load ( ) ! = OskDialogState : : Unloaded )
2018-12-30 22:27:37 +01:00
{
return CELL_SYSUTIL_ERROR_BUSY ;
}
2019-01-05 18:11:43 +01:00
// Get the OSK options
2022-04-19 20:27:32 +02:00
auto & info = g_fxo - > get < osk_info > ( ) ;
2019-12-02 22:31:34 +01:00
u32 maxLength = ( inputFieldInfo - > limit_length > = CELL_OSKDIALOG_STRING_SIZE ) ? 511 : u32 { inputFieldInfo - > limit_length } ;
2020-03-14 22:03:56 +01:00
const u32 prohibitFlgs = dialogParam - > prohibitFlgs ;
const u32 allowOskPanelFlg = dialogParam - > allowOskPanelFlg ;
const u32 firstViewPanel = dialogParam - > firstViewPanel ;
2023-01-20 00:24:27 +01:00
info . layout . x_offset = dialogParam - > controlPoint . x ;
info . layout . y_offset = dialogParam - > controlPoint . y ;
2017-08-21 01:10:28 +02:00
2019-01-04 14:05:37 +01:00
// Get init text and prepare return value
2019-01-04 22:28:52 +01:00
osk - > osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK ;
std : : memset ( osk - > osk_text , 0 , sizeof ( osk - > osk_text ) ) ;
2021-09-20 21:19:34 +02:00
// Also clear the info text just to be sure (it should be zeroed at this point anyway)
{
std : : lock_guard lock ( info . text_mtx ) ;
info . valid_text = { } ;
}
2017-01-23 18:14:12 +01:00
2019-12-20 04:51:16 +01:00
if ( inputFieldInfo - > init_text )
2018-12-30 20:58:56 +01:00
{
2017-08-21 01:10:28 +02:00
for ( u32 i = 0 ; ( i < maxLength ) & & ( inputFieldInfo - > init_text [ i ] ! = 0 ) ; i + + )
2018-12-30 20:58:56 +01:00
{
2019-01-04 22:28:52 +01:00
osk - > osk_text [ i ] = inputFieldInfo - > init_text [ i ] ;
2018-12-30 20:58:56 +01:00
}
}
2017-08-21 01:10:28 +02:00
2019-01-04 14:05:37 +01:00
// Get message to display above the input field
// Guarantees 0 terminated (+1). In praxis only 128 but for now lets display all of it
2019-12-20 04:51:16 +01:00
char16_t message [ CELL_OSKDIALOG_STRING_SIZE + 1 ] { } ;
2019-01-04 14:05:37 +01:00
2019-12-20 04:51:16 +01:00
if ( inputFieldInfo - > message )
2019-01-04 14:05:37 +01:00
{
for ( u32 i = 0 ; ( i < CELL_OSKDIALOG_STRING_SIZE ) & & ( inputFieldInfo - > message [ i ] ! = 0 ) ; i + + )
{
message [ i ] = inputFieldInfo - > message [ i ] ;
}
}
2023-01-23 19:08:01 +01:00
osk - > on_osk_close = [ ] ( s32 status )
2017-01-23 18:14:12 +01:00
{
2022-04-09 23:41:33 +02:00
cellOskDialog . notice ( " on_osk_close(status=%d) " , status ) ;
2019-01-12 11:30:33 +01:00
2023-01-23 19:08:01 +01:00
const auto osk = _get_osk_dialog ( false ) ;
if ( ! osk )
{
return ;
}
2021-09-21 00:59:11 +02:00
osk - > state = OskDialogState : : Closed ;
2019-01-12 11:30:33 +01:00
2021-09-20 21:19:34 +02:00
auto & info = g_fxo - > get < osk_info > ( ) ;
const bool keep_seperate_window_open = info . use_separate_windows . load ( ) & & ( info . osk_continuous_mode . load ( ) ! = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE ) ;
2019-01-04 04:33:05 +01:00
2021-09-19 21:12:42 +02:00
switch ( status )
{
case CELL_OSKDIALOG_CLOSE_CONFIRM :
2019-01-04 04:33:05 +01:00
{
2023-01-21 19:01:20 +01:00
if ( auto ccb = info . osk_confirm_callback . load ( ) )
2019-01-05 01:32:45 +01:00
{
2021-09-21 10:29:32 +02:00
std : : vector < u16 > string_to_send ( CELL_OSKDIALOG_STRING_SIZE ) ;
2019-01-05 01:32:45 +01:00
atomic_t < bool > done = false ;
2019-06-07 06:27:49 +02:00
u32 i ;
2019-01-05 01:32:45 +01:00
2019-06-07 06:27:49 +02:00
for ( i = 0 ; i < CELL_OSKDIALOG_STRING_SIZE - 1 ; i + + )
2019-01-05 01:32:45 +01:00
{
string_to_send [ i ] = osk - > osk_text [ i ] ;
if ( osk - > osk_text [ i ] = = 0 ) break ;
}
2021-09-21 10:29:32 +02:00
sysutil_register_cb ( [ & , length = i , string_to_send = std : : move ( string_to_send ) ] ( ppu_thread & cb_ppu ) - > s32
2019-01-05 01:32:45 +01:00
{
2021-09-21 10:29:32 +02:00
vm : : var < u16 [ ] , vm : : page_allocator < > > string_var ( CELL_OSKDIALOG_STRING_SIZE , string_to_send . data ( ) ) ;
const u32 return_value = ccb ( cb_ppu , string_var . begin ( ) , static_cast < s32 > ( length ) ) ;
2019-01-05 01:32:45 +01:00
cellOskDialog . warning ( " osk_confirm_callback return_value=%d " , return_value ) ;
for ( u32 i = 0 ; i < CELL_OSKDIALOG_STRING_SIZE - 1 ; i + + )
{
2021-09-21 10:29:32 +02:00
osk - > osk_text [ i ] = string_var . begin ( ) [ i ] ;
2019-01-05 01:32:45 +01:00
}
done = true ;
return 0 ;
} ) ;
2019-01-05 18:11:43 +01:00
// wait for check callback
2021-02-13 17:05:31 +01:00
while ( ! done & & ! Emu . IsStopped ( ) )
2019-01-05 01:32:45 +01:00
{
2019-01-05 18:11:43 +01:00
std : : this_thread : : yield ( ) ;
2019-01-05 01:32:45 +01:00
}
}
2019-01-05 18:11:43 +01:00
2021-09-20 21:19:34 +02:00
if ( info . use_separate_windows . load ( ) & & osk - > osk_text [ 0 ] = = 0 )
2019-01-05 18:11:43 +01:00
{
2023-01-21 19:01:20 +01:00
cellOskDialog . warning ( " on_osk_close: input result is CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT " ) ;
2019-01-06 13:40:03 +01:00
osk - > osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT ;
2019-01-05 18:11:43 +01:00
}
else
{
osk - > osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK ;
}
2021-09-19 21:12:42 +02:00
break ;
2019-01-05 18:11:43 +01:00
}
2021-09-19 21:12:42 +02:00
case CELL_OSKDIALOG_CLOSE_CANCEL :
2019-01-05 18:11:43 +01:00
{
osk - > osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_CANCELED ;
2021-09-19 21:12:42 +02:00
break ;
}
2021-09-21 00:59:11 +02:00
case FAKE_CELL_OSKDIALOG_CLOSE_ABORT :
2021-09-19 21:12:42 +02:00
{
osk - > osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_ABORT ;
break ;
}
2021-09-21 00:59:11 +02:00
default :
{
cellOskDialog . fatal ( " on_osk_close: Unknown status (%d) " , status ) ;
break ;
}
2019-01-04 04:33:05 +01:00
}
2019-01-05 18:11:43 +01:00
// Send OSK status
2021-09-20 21:19:34 +02:00
if ( keep_seperate_window_open )
2019-01-05 18:11:43 +01:00
{
2021-09-19 21:12:42 +02:00
switch ( status )
{
case CELL_OSKDIALOG_CLOSE_CONFIRM :
2019-01-05 18:11:43 +01:00
{
2021-09-20 21:19:34 +02:00
info . last_dialog_state = CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED ;
2023-01-21 19:01:20 +01:00
cellOskDialog . notice ( " on_osk_close: sending CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED " ) ;
2019-01-06 13:40:03 +01:00
sysutil_send_system_cmd ( CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED , 0 ) ;
2021-09-19 21:12:42 +02:00
break ;
2019-01-05 18:11:43 +01:00
}
2021-09-19 21:12:42 +02:00
case CELL_OSKDIALOG_CLOSE_CANCEL :
2019-01-05 18:11:43 +01:00
{
2021-09-20 21:19:34 +02:00
info . last_dialog_state = CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED ;
2023-01-21 19:01:20 +01:00
cellOskDialog . notice ( " on_osk_close: sending CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED " ) ;
2019-01-05 18:11:43 +01:00
sysutil_send_system_cmd ( CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED , 0 ) ;
2021-09-19 21:12:42 +02:00
break ;
}
2021-09-21 00:59:11 +02:00
case FAKE_CELL_OSKDIALOG_CLOSE_ABORT :
{
// Handled in cellOskDialogAbort
break ;
}
2021-09-19 21:12:42 +02:00
default :
{
2021-09-21 00:59:11 +02:00
cellOskDialog . fatal ( " on_osk_close: Unknown status (%d) " , status ) ;
2021-09-19 21:12:42 +02:00
break ;
}
2019-01-05 18:11:43 +01:00
}
}
2021-09-21 00:59:11 +02:00
else if ( status ! = FAKE_CELL_OSKDIALOG_CLOSE_ABORT ) // Handled in cellOskDialogAbort
2019-01-05 18:11:43 +01:00
{
2021-09-20 21:19:34 +02:00
info . last_dialog_state = CELL_SYSUTIL_OSKDIALOG_FINISHED ;
2023-01-21 19:01:20 +01:00
cellOskDialog . notice ( " on_osk_close: sending CELL_SYSUTIL_OSKDIALOG_FINISHED " ) ;
2019-01-05 18:11:43 +01:00
sysutil_send_system_cmd ( CELL_SYSUTIL_OSKDIALOG_FINISHED , 0 ) ;
}
2018-12-30 02:34:15 +01:00
2023-01-21 19:01:20 +01:00
// The interception status of the continuous separate window is handled differently
if ( ! keep_seperate_window_open )
{
input : : SetIntercepted ( false ) ;
}
2017-01-23 18:14:12 +01:00
} ;
2022-04-19 23:36:18 +02:00
// Set key callback
2023-01-23 19:08:01 +01:00
osk - > on_osk_key_input_entered = [ ] ( CellOskDialogKeyMessage key_message )
2021-09-21 00:59:11 +02:00
{
2022-04-19 23:36:18 +02:00
auto & info = g_fxo - > get < osk_info > ( ) ;
2022-04-20 22:44:57 +02:00
std : : lock_guard lock ( info . text_mtx ) ;
auto event_hook_callback = info . osk_hardware_keyboard_event_hook_callback . load ( ) ;
cellOskDialog . notice ( " on_osk_key_input_entered: led=%d, mkey=%d, keycode=%d, hook_event_mode=%d, event_hook_callback=*0x%x " , key_message . led , key_message . mkey , key_message . keycode , info . hook_event_mode . load ( ) , event_hook_callback ) ;
2023-01-23 19:08:01 +01:00
const auto osk = _get_osk_dialog ( false ) ;
if ( ! osk | | ! event_hook_callback )
2022-04-20 22:44:57 +02:00
{
// Nothing to do here
return ;
}
2022-04-19 23:36:18 +02:00
bool is_kook_key = false ;
switch ( key_message . keycode )
{
case CELL_KEYC_NO_EVENT :
{
// Any shift/alt/ctrl key
is_kook_key = key_message . mkey > 0 & & ( info . hook_event_mode & CELL_OSKDIALOG_EVENT_HOOK_TYPE_ONLY_MODIFIER ) ;
break ;
}
case CELL_KEYC_E_ROLLOVER :
case CELL_KEYC_E_POSTFAIL :
case CELL_KEYC_E_UNDEF :
case CELL_KEYC_ESCAPE :
case CELL_KEYC_106_KANJI :
case CELL_KEYC_CAPS_LOCK :
case CELL_KEYC_F1 :
case CELL_KEYC_F2 :
case CELL_KEYC_F3 :
case CELL_KEYC_F4 :
case CELL_KEYC_F5 :
case CELL_KEYC_F6 :
case CELL_KEYC_F7 :
case CELL_KEYC_F8 :
case CELL_KEYC_F9 :
case CELL_KEYC_F10 :
case CELL_KEYC_F11 :
case CELL_KEYC_F12 :
case CELL_KEYC_PRINTSCREEN :
case CELL_KEYC_SCROLL_LOCK :
case CELL_KEYC_PAUSE :
case CELL_KEYC_INSERT :
case CELL_KEYC_HOME :
case CELL_KEYC_PAGE_UP :
case CELL_KEYC_DELETE :
case CELL_KEYC_END :
case CELL_KEYC_PAGE_DOWN :
case CELL_KEYC_RIGHT_ARROW :
case CELL_KEYC_LEFT_ARROW :
case CELL_KEYC_DOWN_ARROW :
case CELL_KEYC_UP_ARROW :
case CELL_KEYC_NUM_LOCK :
case CELL_KEYC_APPLICATION :
case CELL_KEYC_KANA :
case CELL_KEYC_HENKAN :
case CELL_KEYC_MUHENKAN :
{
// Any function key or other special key like Delete
is_kook_key = ( info . hook_event_mode & CELL_OSKDIALOG_EVENT_HOOK_TYPE_FUNCTION_KEY ) ;
break ;
}
default :
{
// Any regular ascii key
is_kook_key = ( info . hook_event_mode & CELL_OSKDIALOG_EVENT_HOOK_TYPE_ASCII_KEY ) ;
break ;
}
}
if ( ! is_kook_key )
2022-04-20 22:44:57 +02:00
{
cellOskDialog . notice ( " on_osk_key_input_entered: not a hook key: led=%d, mkey=%d, keycode=%d, hook_event_mode=%d " , key_message . led , key_message . mkey , key_message . keycode , info . hook_event_mode . load ( ) ) ;
2022-04-19 23:36:18 +02:00
return ;
2022-04-20 22:44:57 +02:00
}
constexpr u32 max_size = 101 ;
std : : vector < u16 > string_to_send ( max_size , 0 ) ;
atomic_t < bool > done = false ;
2022-04-19 23:36:18 +02:00
2022-04-20 22:44:57 +02:00
for ( u32 i = 0 ; i < max_size - 1 ; i + + )
2022-04-19 23:36:18 +02:00
{
2022-04-20 22:44:57 +02:00
string_to_send [ i ] = osk - > osk_text [ i ] ;
if ( osk - > osk_text [ i ] = = 0 ) break ;
}
2022-04-19 23:36:18 +02:00
2022-04-20 22:44:57 +02:00
sysutil_register_cb ( [ & ] ( ppu_thread & cb_ppu ) - > s32
{
vm : : var < CellOskDialogKeyMessage > keyMessage ( key_message ) ;
vm : : var < u32 > action ( CELL_OSKDIALOG_CHANGE_NO_EVENT ) ;
vm : : var < u16 [ ] , vm : : page_allocator < > > pActionInfo ( max_size , string_to_send . data ( ) ) ;
std : : u16string utf16_string ;
utf16_string . insert ( 0 , reinterpret_cast < char16_t * > ( string_to_send . data ( ) ) , string_to_send . size ( ) ) ;
std : : string action_info = utf16_to_ascii8 ( utf16_string ) ;
2022-04-19 23:36:18 +02:00
2022-04-20 22:44:57 +02:00
cellOskDialog . notice ( " osk_hardware_keyboard_event_hook_callback(led=%d, mkey=%d, keycode=%d, action=%d, pActionInfo='%s') " , keyMessage - > led , keyMessage - > mkey , keyMessage - > keycode , * action , action_info ) ;
const bool return_value = event_hook_callback ( cb_ppu , keyMessage , action , pActionInfo . begin ( ) ) ;
ensure ( action ) ;
ensure ( pActionInfo ) ;
utf16_string . clear ( ) ;
for ( u32 i = 0 ; i < max_size ; i + + )
2022-04-19 23:36:18 +02:00
{
2022-04-20 22:44:57 +02:00
const u16 code = pActionInfo [ i ] ;
if ( ! code ) break ;
utf16_string . push_back ( code ) ;
}
action_info = utf16_to_ascii8 ( utf16_string ) ;
2022-04-19 23:36:18 +02:00
2022-04-20 22:44:57 +02:00
cellOskDialog . notice ( " osk_hardware_keyboard_event_hook_callback: return_value=%d, action=%d, pActionInfo='%s' " , return_value , * action , action_info ) ;
2022-04-19 23:36:18 +02:00
2022-04-20 22:44:57 +02:00
if ( return_value )
{
switch ( * action )
2022-04-19 23:36:18 +02:00
{
2022-04-20 22:44:57 +02:00
case CELL_OSKDIALOG_CHANGE_NO_EVENT :
case CELL_OSKDIALOG_CHANGE_EVENT_CANCEL :
{
// Do nothing
break ;
}
case CELL_OSKDIALOG_CHANGE_WORDS_INPUT :
{
// Set unconfirmed string and reset unconfirmed string
for ( u32 i = 0 ; i < max_size ; i + + )
2022-04-19 23:36:18 +02:00
{
2022-04-20 22:44:57 +02:00
osk - > osk_text [ i ] = pActionInfo . begin ( ) [ i ] ;
2022-04-19 23:36:18 +02:00
}
2022-04-20 22:44:57 +02:00
break ;
}
case CELL_OSKDIALOG_CHANGE_WORDS_INSERT :
{
// Set confirmed string and reset unconfirmed string
for ( u32 i = 0 ; i < max_size ; i + + )
2022-04-19 23:36:18 +02:00
{
2022-04-20 22:44:57 +02:00
info . valid_text [ i ] = pActionInfo . begin ( ) [ i ] ;
osk - > osk_text [ i ] = 0 ;
2022-04-19 23:36:18 +02:00
}
2022-04-20 22:44:57 +02:00
break ;
}
case CELL_OSKDIALOG_CHANGE_WORDS_REPLACE_ALL :
{
// Set confirmed string and reset all strings
for ( u32 i = 0 ; i < max_size ; i + + )
2022-04-19 23:36:18 +02:00
{
2022-04-20 22:44:57 +02:00
info . valid_text [ i ] = pActionInfo . begin ( ) [ i ] ;
osk - > osk_text [ i ] = 0 ;
2022-04-19 23:36:18 +02:00
}
2022-04-20 22:44:57 +02:00
break ;
}
default :
{
cellOskDialog . error ( " osk_hardware_keyboard_event_hook_callback returned invalid action (%d) " , * action ) ;
break ;
2022-04-19 23:36:18 +02:00
}
2022-04-20 22:44:57 +02:00
}
}
2022-04-19 23:36:18 +02:00
2022-04-20 22:44:57 +02:00
done = true ;
return 0 ;
} ) ;
2022-04-19 23:36:18 +02:00
2022-04-20 22:44:57 +02:00
// wait for callback
while ( ! done & & ! Emu . IsStopped ( ) )
{
std : : this_thread : : yield ( ) ;
2022-04-19 23:36:18 +02:00
}
} ;
2021-09-21 00:59:11 +02:00
2022-04-19 20:27:32 +02:00
// Set device mask and event lock
2023-01-22 17:01:33 +01:00
osk - > ignore_device_events = info . lock_ext_input_device . load ( ) ;
2023-01-21 15:42:10 +01:00
osk - > input_device = info . initial_input_device . load ( ) ;
2023-01-21 19:01:20 +01:00
osk - > continuous_mode = info . osk_continuous_mode . load ( ) ;
2022-04-19 20:27:32 +02:00
if ( info . use_separate_windows )
{
osk - > pad_input_enabled = ( info . device_mask ! = CELL_OSKDIALOG_DEVICE_MASK_PAD ) ;
osk - > mouse_input_enabled = ( info . device_mask ! = CELL_OSKDIALOG_DEVICE_MASK_PAD ) ;
}
2022-04-26 00:20:57 +02:00
input : : SetIntercepted ( osk - > pad_input_enabled , osk - > keyboard_input_enabled , osk - > mouse_input_enabled ) ;
2023-01-21 19:01:20 +01:00
cellOskDialog . notice ( " cellOskDialogLoadAsync: creating OSK dialog ... " ) ;
2022-06-24 19:58:26 +02:00
Emu . BlockingCallFromMainThread ( [ = , & info ] ( )
2017-01-23 18:14:12 +01:00
{
2023-01-18 20:14:42 +01:00
osk - > Create ( {
. title = get_localized_string ( localized_string_id : : CELL_OSK_DIALOG_TITLE ) ,
. message = message ,
. init_text = osk - > osk_text ,
. charlimit = maxLength ,
. prohibit_flags = prohibitFlgs ,
. panel_flag = allowOskPanelFlg ,
. support_language = info . supported_languages ,
. first_view_panel = firstViewPanel ,
2023-01-21 11:57:10 +01:00
. layout = info . layout ,
. input_layout = info . input_field_layout_info ,
. panel_layout = info . input_panel_layout_info ,
. input_field_window_width = info . input_field_window_width ,
. input_field_background_transparency = info . input_field_background_transparency ,
2023-01-18 23:17:00 +01:00
. initial_scale = info . initial_scale ,
2023-01-21 11:57:10 +01:00
. base_color = info . base_color ,
. dimmer_enabled = info . dimmer_enabled ,
. use_separate_windows = info . use_separate_windows ,
. intercept_input = false // We handle the interception manually based on the device mask
2023-01-18 20:14:42 +01:00
} ) ;
2017-01-23 18:14:12 +01:00
} ) ;
2023-01-21 19:01:20 +01:00
g_fxo - > get < osk_info > ( ) . last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED ;
if ( info . use_separate_windows )
2017-01-23 18:14:12 +01:00
{
2023-01-21 19:01:20 +01:00
const bool visible = osk - > continuous_mode ! = CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE ;
cellOskDialog . notice ( " cellOskDialogLoadAsync: sending CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED with %s " , visible ? " CELL_OSKDIALOG_DISPLAY_STATUS_SHOW " : " CELL_OSKDIALOG_DISPLAY_STATUS_HIDE " ) ;
sysutil_send_system_cmd ( CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED , visible ? CELL_OSKDIALOG_DISPLAY_STATUS_SHOW : CELL_OSKDIALOG_DISPLAY_STATUS_HIDE ) ;
2017-01-23 18:14:12 +01:00
}
2023-01-21 19:01:20 +01:00
cellOskDialog . notice ( " cellOskDialogLoadAsync: sending CELL_SYSUTIL_OSKDIALOG_LOADED " ) ;
2022-06-24 19:58:26 +02:00
sysutil_send_system_cmd ( CELL_SYSUTIL_OSKDIALOG_LOADED , 0 ) ;
2023-01-21 19:01:20 +01:00
cellOskDialog . notice ( " cellOskDialogLoadAsync: created OSK dialog " ) ;
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-04-05 20:14:01 +02:00
error_code cellOskDialogLoadAsyncExt ( )
{
2021-09-20 20:39:37 +02:00
cellOskDialog . todo ( " cellOskDialogLoadAsyncExt() " ) ;
2019-04-05 20:14:01 +02:00
return CELL_OK ;
}
2019-01-04 14:45:32 +01:00
error_code getText ( vm : : ptr < CellOskDialogCallbackReturnParam > OutputInfo , bool is_unload )
2015-07-30 03:43:03 +02:00
{
2018-12-30 20:58:56 +01:00
if ( ! OutputInfo | | OutputInfo - > numCharsResultString < 0 )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2022-04-19 19:15:12 +02:00
const auto osk = _get_osk_dialog ( false ) ;
2019-01-04 22:28:52 +01:00
if ( ! osk )
{
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED ;
}
2021-09-20 21:19:34 +02:00
auto & info = g_fxo - > get < osk_info > ( ) ;
const bool keep_seperate_window_open = info . use_separate_windows . load ( ) & & ( info . osk_continuous_mode . load ( ) ! = CELL_OSKDIALOG_CONTINUOUS_MODE_NONE ) ;
info . text_mtx . lock ( ) ;
// Update text buffer if called from cellOskDialogUnloadAsync or if the user accepted the dialog during continuous seperate window mode.
if ( is_unload | | ( keep_seperate_window_open & & info . last_dialog_state = = CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED ) )
{
for ( s32 i = 0 ; i < CELL_OSKDIALOG_STRING_SIZE - 1 ; i + + )
{
info . valid_text [ i ] = osk - > osk_text [ i ] ;
}
}
2018-12-30 20:58:56 +01:00
if ( is_unload )
{
2019-01-06 13:40:03 +01:00
OutputInfo - > result = osk - > osk_input_result . load ( ) ;
2018-12-30 20:58:56 +01:00
}
else
{
2021-09-20 21:19:34 +02:00
if ( info . valid_text [ 0 ] = = 0 )
2018-12-30 20:58:56 +01:00
{
OutputInfo - > result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT ;
}
else
{
OutputInfo - > result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK ;
}
}
2017-01-18 23:01:25 +01:00
2021-09-20 21:19:34 +02:00
const bool do_copy = OutputInfo - > pResultString & & ( OutputInfo - > result = = CELL_OSKDIALOG_INPUT_FIELD_RESULT_OK | | ( is_unload & & OutputInfo - > result = = CELL_OSKDIALOG_INPUT_FIELD_RESULT_NO_INPUT_TEXT ) ) ;
2019-01-04 02:02:26 +01:00
2021-09-20 21:19:34 +02:00
for ( s32 i = 0 ; do_copy & & i < CELL_OSKDIALOG_STRING_SIZE - 1 ; i + + )
2017-05-15 13:58:32 +02:00
{
2021-09-20 21:19:34 +02:00
if ( i < OutputInfo - > numCharsResultString )
2018-12-30 20:58:56 +01:00
{
2021-09-20 21:19:34 +02:00
OutputInfo - > pResultString [ i ] = info . valid_text [ i ] ;
if ( info . valid_text [ i ] = = 0 )
2019-01-12 12:00:50 +01:00
{
2021-09-20 21:19:34 +02:00
break ;
2019-01-12 09:23:43 +01:00
}
2018-12-30 20:58:56 +01:00
}
2021-09-20 21:19:34 +02:00
else
{
OutputInfo - > pResultString [ i ] = 0 ;
break ;
}
2017-01-23 18:14:12 +01:00
}
2017-01-18 23:01:25 +01:00
2021-09-20 21:19:34 +02:00
info . text_mtx . unlock ( ) ;
2019-01-04 22:28:52 +01:00
if ( is_unload )
{
// Unload should be called last, so remove the dialog here
2021-09-20 21:19:34 +02:00
if ( const auto reset_lock = info . init . reset ( ) )
2019-09-26 20:35:27 +02:00
{
2021-09-20 21:19:34 +02:00
info . reset ( ) ;
2019-09-26 20:35:27 +02:00
}
2023-01-21 19:01:20 +01:00
if ( keep_seperate_window_open )
{
cellOskDialog . notice ( " cellOskDialogUnloadAsync: terminating continuous overlay " ) ;
osk - > Close ( FAKE_CELL_OSKDIALOG_CLOSE_TERMINATE ) ;
}
2021-09-21 00:59:11 +02:00
osk - > state = OskDialogState : : Unloaded ;
2023-01-21 19:01:20 +01:00
cellOskDialog . notice ( " cellOskDialogUnloadAsync: sending CELL_SYSUTIL_OSKDIALOG_UNLOADED " ) ;
2019-01-04 22:28:52 +01:00
sysutil_send_system_cmd ( CELL_SYSUTIL_OSKDIALOG_UNLOADED , 0 ) ;
}
2021-09-20 21:19:34 +02:00
else if ( keep_seperate_window_open )
{
// Clear text buffer unless the dialog is still open during continuous seperate window mode.
switch ( info . last_dialog_state )
{
case CELL_SYSUTIL_OSKDIALOG_FINISHED :
case CELL_SYSUTIL_OSKDIALOG_UNLOADED :
case CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED :
case CELL_SYSUTIL_OSKDIALOG_INPUT_ENTERED :
info . valid_text = { } ;
break ;
default :
break ;
}
}
2017-03-16 10:34:47 +01:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogUnloadAsync ( vm : : ptr < CellOskDialogCallbackReturnParam > OutputInfo )
2018-12-30 20:58:56 +01:00
{
cellOskDialog . warning ( " cellOskDialogUnloadAsync(OutputInfo=*0x%x) " , OutputInfo ) ;
return getText ( OutputInfo , true ) ;
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogGetSize ( vm : : ptr < u16 > width , vm : : ptr < u16 > height , u32 /*CellOskDialogType*/ dialogType )
2015-07-30 03:43:03 +02:00
{
2019-01-04 22:28:52 +01:00
cellOskDialog . warning ( " cellOskDialogGetSize(width=*0x%x, height=*0x%x, dialogType=%d) " , width , height , dialogType ) ;
2018-12-30 22:27:37 +01:00
if ( ! width | | ! height )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
if ( dialogType > = CELL_OSKDIALOG_TYPE_SEPARATE_SINGLELINE_TEXT_WINDOW )
{
* width = 0 ;
}
else
{
* width = 1 ;
}
2017-01-18 23:01:25 +01:00
* height = 1 ;
2018-12-30 22:27:37 +01:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogAbort ( )
2015-07-30 03:43:03 +02:00
{
2017-01-23 18:14:12 +01:00
cellOskDialog . warning ( " cellOskDialogAbort() " ) ;
2018-12-30 02:34:15 +01:00
2022-04-19 19:15:12 +02:00
const auto osk = _get_osk_dialog ( false ) ;
2018-12-30 02:34:15 +01:00
2019-01-12 12:53:18 +01:00
if ( ! osk )
2018-12-30 02:34:15 +01:00
{
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED ;
}
2022-04-09 23:41:33 +02:00
const error_code result = osk - > state . atomic_op ( [ ] ( OskDialogState & state ) - > error_code
2018-12-30 02:34:15 +01:00
{
2021-09-21 00:59:11 +02:00
// Check for open dialog. In this case the dialog is "Open" if it was not unloaded before.
if ( state = = OskDialogState : : Unloaded )
2019-01-12 12:53:18 +01:00
{
2022-04-09 23:41:33 +02:00
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED ;
2019-01-12 12:53:18 +01:00
}
state = OskDialogState : : Abort ;
2022-04-09 23:41:33 +02:00
return CELL_OK ;
2019-01-12 12:53:18 +01:00
} ) ;
2022-04-09 23:44:13 +02:00
if ( result = = CELL_OK )
2019-01-12 12:53:18 +01:00
{
2022-04-09 23:44:13 +02:00
osk - > osk_input_result = CELL_OSKDIALOG_INPUT_FIELD_RESULT_ABORT ;
osk - > Close ( FAKE_CELL_OSKDIALOG_CLOSE_ABORT ) ;
2018-12-30 02:34:15 +01:00
}
2021-09-21 00:59:11 +02:00
g_fxo - > get < osk_info > ( ) . last_dialog_state = CELL_SYSUTIL_OSKDIALOG_FINISHED ;
2023-01-21 19:01:20 +01:00
cellOskDialog . notice ( " cellOskDialogAbort: sending CELL_SYSUTIL_OSKDIALOG_FINISHED " ) ;
2021-09-21 00:59:11 +02:00
sysutil_send_system_cmd ( CELL_SYSUTIL_OSKDIALOG_FINISHED , 0 ) ;
2019-01-05 18:11:43 +01:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogSetDeviceMask ( u32 deviceMask )
2015-07-30 03:43:03 +02:00
{
2022-04-20 18:42:32 +02:00
cellOskDialog . warning ( " cellOskDialogSetDeviceMask(deviceMask=0x%x) " , deviceMask ) ;
2021-09-19 21:21:56 +02:00
2022-04-19 19:15:12 +02:00
// TODO: It might also return an error if use_separate_windows is not enabled
if ( deviceMask > CELL_OSKDIALOG_DEVICE_MASK_PAD )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2021-09-19 21:21:56 +02:00
2022-04-19 20:27:32 +02:00
auto & info = g_fxo - > get < osk_info > ( ) ;
info . device_mask = deviceMask ;
if ( info . use_separate_windows )
{
if ( const auto osk = _get_osk_dialog ( false ) )
{
osk - > pad_input_enabled = ( deviceMask ! = CELL_OSKDIALOG_DEVICE_MASK_PAD ) ;
osk - > mouse_input_enabled = ( deviceMask ! = CELL_OSKDIALOG_DEVICE_MASK_PAD ) ;
2021-09-19 21:21:56 +02:00
2022-04-19 20:27:32 +02:00
input : : SetIntercepted ( osk - > pad_input_enabled , osk - > keyboard_input_enabled , osk - > mouse_input_enabled ) ;
}
}
2021-09-19 21:21:56 +02:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogSetSeparateWindowOption ( vm : : ptr < CellOskDialogSeparateWindowOption > windowOption )
2015-07-30 03:43:03 +02:00
{
2023-01-21 19:01:20 +01:00
cellOskDialog . warning ( " cellOskDialogSetSeparateWindowOption(windowOption=*0x%x) " , windowOption ) ;
2019-01-04 04:33:05 +01:00
2023-01-19 23:33:52 +01:00
if ( ! windowOption | |
! windowOption - > inputFieldLayoutInfo | |
! ! windowOption - > reserved | |
windowOption - > continuousMode > CELL_OSKDIALOG_CONTINUOUS_MODE_SHOW | |
windowOption - > deviceMask > CELL_OSKDIALOG_DEVICE_MASK_PAD )
2019-01-06 13:40:03 +01:00
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2021-09-19 21:21:56 +02:00
auto & osk = g_fxo - > get < osk_info > ( ) ;
osk . use_separate_windows = true ;
osk . osk_continuous_mode = static_cast < CellOskDialogContinuousMode > ( + windowOption - > continuousMode ) ;
2022-04-19 20:27:32 +02:00
osk . device_mask = windowOption - > deviceMask ;
2023-01-19 23:33:52 +01:00
osk . input_field_window_width = windowOption - > inputFieldWindowWidth ;
osk . input_field_background_transparency = std : : clamp < f32 > ( windowOption - > inputFieldBackgroundTrans , 0.0f , 1.0f ) ;
// Choose proper alignments, since the devs didn't make them exclusive for some reason.
2023-01-20 00:24:27 +01:00
const auto aligned_layout = [ ] ( const CellOskDialogLayoutInfo & info ) - > osk_window_layout
{
osk_window_layout res { } ;
res . layout_mode = info . layoutMode ;
res . x_align = osk_info : : get_aligned_x ( res . layout_mode ) ;
res . y_align = osk_info : : get_aligned_y ( res . layout_mode ) ;
res . x_offset = info . position . x ;
res . y_offset = info . position . y ;
2023-01-19 23:33:52 +01:00
return res ;
} ;
osk . input_field_layout_info = aligned_layout ( * windowOption - > inputFieldLayoutInfo ) ;
// Panel layout is optional
if ( windowOption - > inputPanelLayoutInfo )
{
osk . input_panel_layout_info = aligned_layout ( * windowOption - > inputPanelLayoutInfo ) ;
}
else
{
// Align to input field
osk . input_panel_layout_info = osk . input_field_layout_info ;
}
2021-09-21 00:59:11 +02:00
2023-01-22 17:01:33 +01:00
cellOskDialog . warning ( " cellOskDialogSetSeparateWindowOption: use_separate_windows=true, continuous_mode=%s, device_mask=0x%x, input_field_window_width=%d, input_field_background_transparency=%.2f, input_field_layout_info=%s, input_panel_layout_info=%s) " ,
2023-01-20 00:24:27 +01:00
osk . osk_continuous_mode . load ( ) , osk . device_mask . load ( ) , osk . input_field_window_width . load ( ) , osk . input_field_background_transparency . load ( ) , osk . input_field_layout_info , osk . input_panel_layout_info ) ;
2019-01-04 04:33:05 +01:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2021-09-19 21:21:56 +02:00
error_code cellOskDialogSetInitialInputDevice ( u32 inputDevice )
2015-07-30 03:43:03 +02:00
{
2023-01-21 15:42:10 +01:00
cellOskDialog . warning ( " cellOskDialogSetInitialInputDevice(inputDevice=%d) " , inputDevice ) ;
2021-09-19 21:21:56 +02:00
2022-04-19 19:15:12 +02:00
if ( inputDevice > CELL_OSKDIALOG_INPUT_DEVICE_KEYBOARD )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2021-09-19 21:21:56 +02:00
g_fxo - > get < osk_info > ( ) . initial_input_device = static_cast < CellOskDialogInputDevice > ( inputDevice ) ;
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2021-09-19 21:21:56 +02:00
error_code cellOskDialogSetInitialKeyLayout ( u32 initialKeyLayout )
2015-07-30 03:43:03 +02:00
{
2023-01-19 00:39:43 +01:00
cellOskDialog . warning ( " cellOskDialogSetInitialKeyLayout(initialKeyLayout=%d) " , initialKeyLayout ) ;
2021-09-19 21:21:56 +02:00
2023-01-18 20:27:44 +01:00
if ( initialKeyLayout > CELL_OSKDIALOG_INITIAL_PANEL_LAYOUT_FULLKEY )
2022-04-19 19:15:12 +02:00
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2021-09-19 21:21:56 +02:00
2023-01-18 20:27:44 +01:00
auto & osk = g_fxo - > get < osk_info > ( ) ;
2021-09-19 21:21:56 +02:00
2023-01-18 20:27:44 +01:00
if ( osk . key_layout_options & initialKeyLayout )
{
osk . initial_key_layout = static_cast < CellOskDialogInitialKeyLayout > ( initialKeyLayout ) ;
}
2021-09-19 21:21:56 +02:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogDisableDimmer ( )
2015-07-30 03:43:03 +02:00
{
2022-04-20 18:42:32 +02:00
cellOskDialog . warning ( " cellOskDialogDisableDimmer() " ) ;
2021-09-19 21:21:56 +02:00
g_fxo - > get < osk_info > ( ) . dimmer_enabled = false ;
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogSetKeyLayoutOption ( u32 option )
2015-07-30 03:43:03 +02:00
{
2023-01-19 00:39:43 +01:00
cellOskDialog . warning ( " cellOskDialogSetKeyLayoutOption(option=0x%x) " , option ) ;
2019-10-06 11:32:54 +02:00
if ( option = = 0 | | option > 3 ) // CELL_OSKDIALOG_10KEY_PANEL OR CELL_OSKDIALOG_FULLKEY_PANEL
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2023-01-18 20:27:44 +01:00
g_fxo - > get < osk_info > ( ) . key_layout_options = option ;
2021-09-19 21:21:56 +02:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogAddSupportLanguage ( u32 supportLanguage )
2015-07-30 03:43:03 +02:00
{
2023-01-19 00:39:43 +01:00
cellOskDialog . warning ( " cellOskDialogAddSupportLanguage(supportLanguage=0x%x) " , supportLanguage ) ;
2021-09-19 21:21:56 +02:00
g_fxo - > get < osk_info > ( ) . supported_languages = supportLanguage ;
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogSetLayoutMode ( s32 layoutMode )
2015-07-30 03:43:03 +02:00
{
2023-01-19 00:39:43 +01:00
cellOskDialog . warning ( " cellOskDialogSetLayoutMode(layoutMode=0x%x) " , layoutMode ) ;
2021-09-19 21:21:56 +02:00
2023-01-18 22:30:00 +01:00
auto & osk = g_fxo - > get < osk_info > ( ) ;
2023-01-20 00:24:27 +01:00
osk . layout . layout_mode = layoutMode ;
2023-01-18 22:30:00 +01:00
2023-01-19 23:33:52 +01:00
// Choose proper alignments, since the devs didn't make them exclusive for some reason.
2023-01-20 00:24:27 +01:00
osk . layout . x_align = osk_info : : get_aligned_x ( layoutMode ) ;
osk . layout . y_align = osk_info : : get_aligned_y ( layoutMode ) ;
2021-09-19 21:21:56 +02:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogGetInputText ( vm : : ptr < CellOskDialogCallbackReturnParam > OutputInfo )
2015-07-30 03:43:03 +02:00
{
2017-01-18 23:01:25 +01:00
cellOskDialog . warning ( " cellOskDialogGetInputText(OutputInfo=*0x%x) " , OutputInfo ) ;
2018-12-30 20:58:56 +01:00
return getText ( OutputInfo , false ) ;
2015-07-30 03:43:03 +02:00
}
2019-10-06 11:32:54 +02:00
error_code register_keyboard_event_hook_callback ( u16 hookEventMode , vm : : ptr < cellOskDialogHardwareKeyboardEventHookCallback > pCallback )
{
2022-04-20 18:42:32 +02:00
cellOskDialog . warning ( " register_keyboard_event_hook_callback(hookEventMode=%u, pCallback=*0x%x) " , hookEventMode , pCallback ) ;
2019-10-06 11:32:54 +02:00
if ( ! pCallback )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2022-04-19 19:15:12 +02:00
g_fxo - > get < osk_info > ( ) . osk_hardware_keyboard_event_hook_callback = pCallback ;
2022-04-19 23:36:18 +02:00
g_fxo - > get < osk_info > ( ) . hook_event_mode = hookEventMode ;
2021-09-19 21:21:56 +02:00
2019-10-06 11:32:54 +02:00
return CELL_OK ;
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtRegisterKeyboardEventHookCallback ( u16 hookEventMode , vm : : ptr < cellOskDialogHardwareKeyboardEventHookCallback > pCallback )
2015-07-30 03:43:03 +02:00
{
2022-04-20 18:42:32 +02:00
cellOskDialog . warning ( " cellOskDialogExtRegisterKeyboardEventHookCallback(hookEventMode=%u, pCallback=*0x%x) " , hookEventMode , pCallback ) ;
2019-10-06 11:32:54 +02:00
2022-04-19 19:15:12 +02:00
if ( hookEventMode = = 0 | | hookEventMode > ( CELL_OSKDIALOG_EVENT_HOOK_TYPE_FUNCTION_KEY | CELL_OSKDIALOG_EVENT_HOOK_TYPE_ASCII_KEY ) )
2019-10-06 11:32:54 +02:00
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
return register_keyboard_event_hook_callback ( hookEventMode , pCallback ) ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtRegisterKeyboardEventHookCallbackEx ( u16 hookEventMode , vm : : ptr < cellOskDialogHardwareKeyboardEventHookCallback > pCallback )
2017-07-21 17:41:11 +02:00
{
2022-04-20 18:42:32 +02:00
cellOskDialog . warning ( " cellOskDialogExtRegisterKeyboardEventHookCallbackEx(hookEventMode=%u, pCallback=*0x%x) " , hookEventMode , pCallback ) ;
2019-10-06 11:32:54 +02:00
2022-04-19 19:15:12 +02:00
if ( hookEventMode = = 0 | | hookEventMode > ( CELL_OSKDIALOG_EVENT_HOOK_TYPE_FUNCTION_KEY | CELL_OSKDIALOG_EVENT_HOOK_TYPE_ASCII_KEY | CELL_OSKDIALOG_EVENT_HOOK_TYPE_ONLY_MODIFIER ) )
2019-10-06 11:32:54 +02:00
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
return register_keyboard_event_hook_callback ( hookEventMode , pCallback ) ;
2017-07-21 17:41:11 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtAddJapaneseOptionDictionary ( vm : : cpptr < char > filePath )
2015-07-30 03:43:03 +02:00
{
2017-01-26 15:53:07 +01:00
cellOskDialog . todo ( " cellOskDialogExtAddJapaneseOptionDictionary(filePath=**0x%0x) " , filePath ) ;
2023-01-18 21:39:13 +01:00
std : : vector < std : : string > paths ;
if ( filePath )
{
for ( u32 i = 0 ; i < 4 ; i + + )
{
if ( ! filePath [ i ] )
{
break ;
}
std : : array < char , CELL_IMEJP_DIC_PATH_MAXLENGTH + 1 > path { } ;
std : : memcpy ( path . data ( ) , filePath [ i ] . get_ptr ( ) , CELL_IMEJP_DIC_PATH_MAXLENGTH ) ;
paths . push_back ( path . data ( ) ) ;
}
}
cellOskDialog . todo ( " cellOskDialogExtAddJapaneseOptionDictionary: got %d dictionaries: \n %s " , paths . size ( ) , fmt : : merge ( paths , " \n " ) ) ;
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtEnableClipboard ( )
2015-07-30 03:43:03 +02:00
{
2017-01-18 23:01:25 +01:00
cellOskDialog . todo ( " cellOskDialogExtEnableClipboard() " ) ;
2021-09-19 21:21:56 +02:00
g_fxo - > get < osk_info > ( ) . clipboard_enabled = true ;
// TODO: implement copy paste
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-05 18:11:43 +01:00
error_code cellOskDialogExtSendFinishMessage ( u32 /*CellOskDialogFinishReason*/ finishReason )
2015-07-30 03:43:03 +02:00
{
2019-01-05 18:11:43 +01:00
cellOskDialog . warning ( " cellOskDialogExtSendFinishMessage(finishReason=%d) " , finishReason ) ;
2022-04-19 19:15:12 +02:00
const auto osk = _get_osk_dialog ( false ) ;
2019-01-05 18:11:43 +01:00
2021-09-21 00:59:11 +02:00
// Check for "Open" dialog.
if ( ! osk | | osk - > state . load ( ) = = OskDialogState : : Unloaded )
2019-01-05 18:11:43 +01:00
{
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED ;
}
2021-09-19 21:12:42 +02:00
osk - > Close ( finishReason ) ;
2019-01-05 18:11:43 +01:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2023-01-18 21:39:13 +01:00
error_code cellOskDialogExtAddOptionDictionary ( vm : : cpptr < CellOskDialogImeDictionaryInfo > dictionaryInfo )
2015-07-30 03:43:03 +02:00
{
2017-01-18 23:01:25 +01:00
cellOskDialog . todo ( " cellOskDialogExtAddOptionDictionary(dictionaryInfo=*0x%x) " , dictionaryInfo ) ;
2023-01-18 21:39:13 +01:00
if ( ! dictionaryInfo )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
std : : vector < std : : pair < u32 , std : : string > > paths ; // language and path
for ( u32 i = 0 ; i < 10 ; i + + )
{
if ( ! dictionaryInfo [ i ] | | ! dictionaryInfo [ i ] - > dictionaryPath )
{
break ;
}
std : : array < char , CELL_IMEJP_DIC_PATH_MAXLENGTH + 1 > path { } ;
std : : memcpy ( path . data ( ) , dictionaryInfo [ i ] - > dictionaryPath . get_ptr ( ) , CELL_IMEJP_DIC_PATH_MAXLENGTH ) ;
paths . push_back ( { dictionaryInfo [ i ] - > targetLanguage , path . data ( ) } ) ;
}
std : : vector < std : : string > msgs ;
for ( const auto & entry : paths )
{
msgs . push_back ( fmt : : format ( " languages=0x%x, path='%s' " , entry . first , entry . second ) ) ;
}
cellOskDialog . todo ( " cellOskDialogExtAddOptionDictionary: got %d dictionaries: \n %s " , msgs . size ( ) , fmt : : merge ( msgs , " \n " ) ) ;
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtSetInitialScale ( f32 initialScale )
2015-07-30 03:43:03 +02:00
{
2023-01-19 00:39:43 +01:00
cellOskDialog . warning ( " cellOskDialogExtSetInitialScale(initialScale=%f) " , initialScale ) ;
2021-09-19 21:21:56 +02:00
2022-04-19 19:15:12 +02:00
if ( initialScale < CELL_OSKDIALOG_SCALE_MIN | | initialScale > CELL_OSKDIALOG_SCALE_MAX )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2021-09-19 21:21:56 +02:00
g_fxo - > get < osk_info > ( ) . initial_scale = initialScale ;
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtInputDeviceLock ( )
2015-07-30 03:43:03 +02:00
{
2022-04-20 18:42:32 +02:00
cellOskDialog . warning ( " cellOskDialogExtInputDeviceLock() " ) ;
2021-09-19 21:21:56 +02:00
2023-01-22 17:01:33 +01:00
g_fxo - > get < osk_info > ( ) . lock_ext_input_device = true ;
2021-09-19 21:21:56 +02:00
2022-04-19 20:27:32 +02:00
if ( const auto osk = _get_osk_dialog ( false ) )
{
2023-01-22 17:01:33 +01:00
osk - > ignore_device_events = true ;
2022-04-19 20:27:32 +02:00
}
2021-09-19 21:21:56 +02:00
return CELL_OK ;
}
error_code cellOskDialogExtInputDeviceUnlock ( )
{
2022-04-20 18:42:32 +02:00
cellOskDialog . warning ( " cellOskDialogExtInputDeviceUnlock() " ) ;
2021-09-19 21:21:56 +02:00
2023-01-22 17:01:33 +01:00
g_fxo - > get < osk_info > ( ) . lock_ext_input_device = false ;
2021-09-19 21:21:56 +02:00
2022-04-19 20:27:32 +02:00
if ( const auto osk = _get_osk_dialog ( false ) )
{
2023-01-22 17:01:33 +01:00
osk - > ignore_device_events = false ;
2022-04-19 20:27:32 +02:00
}
2021-09-19 21:21:56 +02:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2022-04-19 19:15:12 +02:00
error_code cellOskDialogExtSetBaseColor ( f32 red , f32 green , f32 blue , f32 alpha )
2015-07-30 03:43:03 +02:00
{
2022-04-20 18:42:32 +02:00
cellOskDialog . warning ( " cellOskDialogExtSetBaseColor(red=%f, blue=%f, green=%f, alpha=%f) " , red , blue , green , alpha ) ;
2021-09-19 21:21:56 +02:00
2022-04-19 19:15:12 +02:00
if ( red < 0.0f | | red > 1.0f | | green < 0.0f | | green > 1.0f | | blue < 0.0f | | blue > 1.0f | | alpha < 0.0f | | alpha > 1.0f )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2021-09-19 21:21:56 +02:00
auto & osk = g_fxo - > get < osk_info > ( ) ;
2022-04-20 18:16:27 +02:00
osk . base_color = OskDialogBase : : color { red , green , blue , alpha } ;
2021-09-19 21:21:56 +02:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtRegisterConfirmWordFilterCallback ( vm : : ptr < cellOskDialogConfirmWordFilterCallback > pCallback )
2015-07-30 03:43:03 +02:00
{
2019-01-04 22:28:52 +01:00
cellOskDialog . warning ( " cellOskDialogExtRegisterConfirmWordFilterCallback(pCallback=*0x%x) " , pCallback ) ;
2019-01-05 01:32:45 +01:00
2019-01-12 09:23:43 +01:00
if ( ! pCallback )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2021-09-19 21:21:56 +02:00
g_fxo - > get < osk_info > ( ) . osk_confirm_callback = pCallback ;
2019-01-05 01:32:45 +01:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtUpdateInputText ( )
2015-07-30 03:43:03 +02:00
{
2017-01-26 15:53:07 +01:00
cellOskDialog . todo ( " cellOskDialogExtUpdateInputText() " ) ;
2021-09-20 21:19:34 +02:00
// Usually, user input is only available when the dialog was accepted.
// This function seems to be called in order to copy the current text to an internal buffer.
// Afterwards, cellOskDialogGetInputText can be called to fetch the current text regardless of
// user confirmation, even if the dialog is still in use.
// TODO: error checks
2022-04-19 19:15:12 +02:00
const auto osk = _get_osk_dialog ( false ) ;
2021-09-20 21:19:34 +02:00
if ( osk )
{
auto & info = g_fxo - > get < osk_info > ( ) ;
std : : lock_guard lock ( info . text_mtx ) ;
for ( s32 i = 0 ; i < CELL_OSKDIALOG_STRING_SIZE - 1 ; i + + )
{
info . valid_text [ i ] = osk - > osk_text [ i ] ;
}
}
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtSetPointerEnable ( b8 enable )
2015-07-30 03:43:03 +02:00
{
2023-01-19 00:39:43 +01:00
cellOskDialog . warning ( " cellOskDialogExtSetPointerEnable(enable=%d) " , enable ) ;
2021-09-19 21:21:56 +02:00
2023-01-21 11:57:10 +01:00
// TODO: While the pointer is already displayed in the osk overlay, it is not really useful right now.
// On real hardware, this may be used for actual PS Move or mouse input.
2021-09-19 21:21:56 +02:00
g_fxo - > get < osk_info > ( ) . pointer_enabled = enable ;
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2021-09-19 21:21:56 +02:00
error_code cellOskDialogExtUpdatePointerDisplayPos ( vm : : cptr < CellOskDialogPoint > pos )
2015-07-30 03:43:03 +02:00
{
2023-01-20 22:43:24 +01:00
cellOskDialog . warning ( " cellOskDialogExtUpdatePointerDisplayPos(pos=0x%x, posX=%f, posY=%f) " , pos , pos - > x , pos - > y ) ;
2021-09-19 21:21:56 +02:00
if ( pos )
{
2023-01-20 22:43:24 +01:00
osk_info & osk = g_fxo - > get < osk_info > ( ) ;
osk . pointer_x = pos - > x ;
osk . pointer_y = pos - > y ;
2021-09-19 21:21:56 +02:00
}
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtEnableHalfByteKana ( )
2015-07-30 03:43:03 +02:00
{
2017-01-18 23:01:25 +01:00
cellOskDialog . todo ( " cellOskDialogExtEnableHalfByteKana() " ) ;
2021-09-19 21:21:56 +02:00
g_fxo - > get < osk_info > ( ) . half_byte_kana_enabled = true ;
// TODO: use new value in osk
return CELL_OK ;
}
error_code cellOskDialogExtDisableHalfByteKana ( )
{
cellOskDialog . todo ( " cellOskDialogExtDisableHalfByteKana() " ) ;
g_fxo - > get < osk_info > ( ) . half_byte_kana_enabled = false ;
// TODO: use new value in osk
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
2019-01-04 14:45:32 +01:00
error_code cellOskDialogExtRegisterForceFinishCallback ( vm : : ptr < cellOskDialogForceFinishCallback > pCallback )
2015-07-30 03:43:03 +02:00
{
2023-01-21 19:01:20 +01:00
cellOskDialog . warning ( " cellOskDialogExtRegisterForceFinishCallback(pCallback=*0x%x) " , pCallback ) ;
2019-10-06 11:32:54 +02:00
if ( ! pCallback )
{
return CELL_OSKDIALOG_ERROR_PARAM ;
}
2023-01-21 19:01:20 +01:00
osk_info & info = g_fxo - > get < osk_info > ( ) ;
std : : lock_guard lock ( info . text_mtx ) ;
info . osk_force_finish_callback = pCallback ;
2022-04-19 19:15:12 +02:00
2023-01-21 19:01:20 +01:00
// We use the force finish callback when the PS-Button is pressed and a System dialog shall be spawned while the OSK is loaded
// 1. Check if we are in any continuous mode and the dialog is hidden
// 2. If the above is true, call osk_force_finish_callback, deny the PS-Button press otherwise
// 3. Check the return value of osk_force_finish_callback.
// if false, ignore the PS-Button press,
// else close the dialog etc., send CELL_SYSUTIL_OSKDIALOG_FINISHED
2021-09-19 21:21:56 +02:00
2017-05-15 13:58:32 +02:00
return CELL_OK ;
2015-07-30 03:43:03 +02:00
}
void cellSysutil_OskDialog_init ( )
{
REG_FUNC ( cellSysutil , cellOskDialogLoadAsync ) ;
2019-04-05 20:14:01 +02:00
REG_FUNC ( cellSysutil , cellOskDialogLoadAsyncExt ) ;
2015-07-30 03:43:03 +02:00
REG_FUNC ( cellSysutil , cellOskDialogUnloadAsync ) ;
REG_FUNC ( cellSysutil , cellOskDialogGetSize ) ;
REG_FUNC ( cellSysutil , cellOskDialogAbort ) ;
REG_FUNC ( cellSysutil , cellOskDialogSetDeviceMask ) ;
REG_FUNC ( cellSysutil , cellOskDialogSetSeparateWindowOption ) ;
REG_FUNC ( cellSysutil , cellOskDialogSetInitialInputDevice ) ;
REG_FUNC ( cellSysutil , cellOskDialogSetInitialKeyLayout ) ;
REG_FUNC ( cellSysutil , cellOskDialogDisableDimmer ) ;
REG_FUNC ( cellSysutil , cellOskDialogSetKeyLayoutOption ) ;
REG_FUNC ( cellSysutil , cellOskDialogAddSupportLanguage ) ;
REG_FUNC ( cellSysutil , cellOskDialogSetLayoutMode ) ;
REG_FUNC ( cellSysutil , cellOskDialogGetInputText ) ;
}
2016-03-21 20:43:03 +01:00
DECLARE ( ppu_module_manager : : cellOskDialog ) ( " cellOskExtUtility " , [ ] ( )
{
REG_FUNC ( cellOskExtUtility , cellOskDialogExtInputDeviceUnlock ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtRegisterKeyboardEventHookCallback ) ;
2017-07-21 17:41:11 +02:00
REG_FUNC ( cellOskExtUtility , cellOskDialogExtRegisterKeyboardEventHookCallbackEx ) ;
2016-03-21 20:43:03 +01:00
REG_FUNC ( cellOskExtUtility , cellOskDialogExtAddJapaneseOptionDictionary ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtEnableClipboard ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtSendFinishMessage ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtAddOptionDictionary ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtSetInitialScale ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtInputDeviceLock ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtSetBaseColor ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtRegisterConfirmWordFilterCallback ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtUpdateInputText ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtDisableHalfByteKana ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtSetPointerEnable ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtUpdatePointerDisplayPos ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtEnableHalfByteKana ) ;
REG_FUNC ( cellOskExtUtility , cellOskDialogExtRegisterForceFinishCallback ) ;
2015-07-30 03:43:03 +02:00
} ) ;