| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  | /*
 | 
					
						
							|  |  |  |  |  * Copyright (c) 2020, Hüseyin Aslıtürk <asliturk@hotmail.com> | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |  */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #include "CharacterMapFile.h"
 | 
					
						
							| 
									
										
										
										
											2020-11-15 13:11:21 +01:00
										 |  |  |  | #include <AK/ByteBuffer.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:51:20 +03:00
										 |  |  |  | #include <AK/Utf8View.h>
 | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  | #include <LibCore/File.h>
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | namespace Keyboard { | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-29 21:46:15 +02:00
										 |  |  |  | Optional<CharacterMapData> CharacterMapFile::load_from_file(const String& filename) | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-29 21:46:15 +02:00
										 |  |  |  |     auto path = filename; | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |     if (!path.ends_with(".json")) { | 
					
						
							|  |  |  |  |         StringBuilder full_path; | 
					
						
							|  |  |  |  |         full_path.append("/res/keymaps/"); | 
					
						
							| 
									
										
										
										
											2021-04-29 21:46:15 +02:00
										 |  |  |  |         full_path.append(filename); | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |         full_path.append(".json"); | 
					
						
							|  |  |  |  |         path = full_path.to_string(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto file = Core::File::construct(path); | 
					
						
							| 
									
										
										
										
											2021-05-12 13:56:43 +04:30
										 |  |  |  |     file->open(Core::OpenMode::ReadOnly); | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |     if (!file->is_open()) { | 
					
						
							| 
									
										
										
										
											2021-06-04 20:26:39 +02:00
										 |  |  |  |         dbgln("Failed to open {}: {}", path, file->error_string()); | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |         return {}; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto file_contents = file->read_all(); | 
					
						
							| 
									
										
										
										
											2020-06-10 21:40:27 -07:00
										 |  |  |  |     auto json_result = JsonValue::from_string(file_contents); | 
					
						
							| 
									
										
										
										
											2021-11-15 01:46:51 +01:00
										 |  |  |  |     if (json_result.is_error()) { | 
					
						
							| 
									
										
										
										
											2021-06-04 20:26:39 +02:00
										 |  |  |  |         dbgln("Failed to load character map from file {}", path); | 
					
						
							| 
									
										
										
										
											2020-06-29 12:51:07 +02:00
										 |  |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2021-06-04 20:26:39 +02:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-06-10 21:40:27 -07:00
										 |  |  |  |     auto json = json_result.value().as_object(); | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:51:20 +03:00
										 |  |  |  |     Vector<u32> map = read_map(json, "map"); | 
					
						
							|  |  |  |  |     Vector<u32> shift_map = read_map(json, "shift_map"); | 
					
						
							|  |  |  |  |     Vector<u32> alt_map = read_map(json, "alt_map"); | 
					
						
							|  |  |  |  |     Vector<u32> altgr_map = read_map(json, "altgr_map"); | 
					
						
							| 
									
										
										
										
											2021-01-05 09:45:17 +01:00
										 |  |  |  |     Vector<u32> shift_altgr_map = read_map(json, "shift_altgr_map"); | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     CharacterMapData character_map; | 
					
						
							|  |  |  |  |     for (int i = 0; i < CHAR_MAP_SIZE; i++) { | 
					
						
							| 
									
										
										
										
											2020-06-13 13:51:20 +03:00
										 |  |  |  |         character_map.map[i] = map.at(i); | 
					
						
							|  |  |  |  |         character_map.shift_map[i] = shift_map.at(i); | 
					
						
							|  |  |  |  |         character_map.alt_map[i] = alt_map.at(i); | 
					
						
							|  |  |  |  |         if (altgr_map.is_empty()) { | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |             // AltGr map was not found, using Alt map as fallback.
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:51:20 +03:00
										 |  |  |  |             character_map.altgr_map[i] = alt_map.at(i); | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             character_map.altgr_map[i] = altgr_map.at(i); | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-01-05 09:45:17 +01:00
										 |  |  |  |         if (shift_altgr_map.is_empty()) { | 
					
						
							|  |  |  |  |             // Shift+AltGr map was not found, using Alt map as fallback.
 | 
					
						
							|  |  |  |  |             character_map.shift_altgr_map[i] = alt_map.at(i); | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             character_map.shift_altgr_map[i] = shift_altgr_map.at(i); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return character_map; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:51:20 +03:00
										 |  |  |  | Vector<u32> CharacterMapFile::read_map(const JsonObject& json, const String& name) | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |     if (!json.has(name)) | 
					
						
							| 
									
										
										
										
											2020-06-13 13:51:20 +03:00
										 |  |  |  |         return {}; | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:51:20 +03:00
										 |  |  |  |     Vector<u32> buffer; | 
					
						
							|  |  |  |  |     buffer.resize(CHAR_MAP_SIZE); | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     auto map_arr = json.get(name).as_array(); | 
					
						
							| 
									
										
										
										
											2021-06-28 11:57:37 +02:00
										 |  |  |  |     for (size_t i = 0; i < map_arr.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |         auto key_value = map_arr.at(i).as_string(); | 
					
						
							|  |  |  |  |         if (key_value.length() == 0) { | 
					
						
							|  |  |  |  |             buffer[i] = 0; | 
					
						
							|  |  |  |  |         } else if (key_value.length() == 1) { | 
					
						
							|  |  |  |  |             buffer[i] = key_value.characters()[0]; | 
					
						
							|  |  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2021-09-18 18:02:41 +02:00
										 |  |  |  |             Utf8View m_utf8_view(key_value); | 
					
						
							| 
									
										
										
										
											2020-06-13 13:51:20 +03:00
										 |  |  |  |             buffer[i] = *m_utf8_view.begin(); | 
					
						
							| 
									
										
										
										
											2020-05-31 16:23:55 +03:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return buffer; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | } |