1 #include "core/calc.h"
2 #include "core/config.h"
3 #include "core/encoding.h"
4 #include "core/string.h"
5 #include "game/system.h"
6 #include "graphics/screen.h"
7 #include "input/keyboard.h"
8 #include "input/mouse.h"
9 #include "input/touch.h"
10 #include "platform/switch/switch.h"
11 
12 #include <switch.h>
13 
14 #define MAX_VKBD_TEXT_SIZE 600
15 
16 static AppletOperationMode display_mode = -1;
17 
18 #define HANDHELD_SCREEN_SCALE 200
19 #define DOCKED_SCREEN_SCALE 150
20 #define CURSOR_SCALE 200
21 
22 static struct {
23     uint8_t text[MAX_VKBD_TEXT_SIZE];
24     char utf8_text[MAX_VKBD_TEXT_SIZE];
25     int requested;
26 } vkbd;
27 
center_mouse_cursor(void)28 static void center_mouse_cursor(void)
29 {
30     int x = screen_width() / 2;
31     int y = screen_height() / 2;
32     system_set_mouse_position(&x, &y);
33     mouse_set_position(x, y);
34 }
35 
change_display_size(void)36 static void change_display_size(void)
37 {
38     AppletOperationMode mode = appletGetOperationMode();
39     if (mode != display_mode) {
40         SDL_Log("Changing display mode to %s", mode == AppletOperationMode_Handheld ? "handheld" : "docked");
41         display_mode = mode;
42         if (display_mode == AppletOperationMode_Handheld) {
43             system_scale_display(HANDHELD_SCREEN_SCALE);
44         } else {
45             system_scale_display(DOCKED_SCREEN_SCALE);
46         }
47         center_mouse_cursor();
48     }
49 }
50 
switch_keyboard_get(const uint8_t * text,int max_length)51 static const uint8_t *switch_keyboard_get(const uint8_t *text, int max_length)
52 {
53     max_length = calc_bound(max_length, 0, MAX_VKBD_TEXT_SIZE);
54     string_copy(text, vkbd.text, max_length);
55     encoding_to_utf8(text, vkbd.utf8_text, max_length, 0);
56     Result rc = 0;
57 
58     SwkbdConfig kbd;
59 
60     rc = swkbdCreate(&kbd, 0);
61 
62     if (R_SUCCEEDED(rc)) {
63         swkbdConfigMakePresetDefault(&kbd);
64         swkbdConfigSetInitialText(&kbd, vkbd.utf8_text);
65         rc = swkbdShow(&kbd, vkbd.utf8_text, max_length);
66         swkbdClose(&kbd);
67         if (R_SUCCEEDED(rc)) {
68             encoding_from_utf8(vkbd.utf8_text, vkbd.text, max_length);
69         }
70     }
71 
72     return vkbd.text;
73 }
74 
switch_start_text_input(void)75 static void switch_start_text_input(void)
76 {
77     if (!keyboard_is_capturing()) {
78         return;
79     }
80     const uint8_t *text = switch_keyboard_get(keyboard_get_text(), keyboard_get_max_text_length());
81     keyboard_set_text(text);
82 }
83 
platform_init_callback(void)84 void platform_init_callback(void)
85 {
86     romfsInit();
87     config_set(CONFIG_SCREEN_CURSOR_SCALE, CURSOR_SCALE);
88     touch_set_mode(TOUCH_MODE_TOUCHPAD);
89 }
90 
platform_per_frame_callback(void)91 void platform_per_frame_callback(void)
92 {
93     change_display_size();
94     if (vkbd.requested) {
95         switch_start_text_input();
96         vkbd.requested = 0;
97     }
98 }
99 
platform_show_virtual_keyboard(void)100 void platform_show_virtual_keyboard(void)
101 {
102     vkbd.requested = 1;
103 }
104 
platform_hide_virtual_keyboard(void)105 void platform_hide_virtual_keyboard(void)
106 {}
107