diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt index ecdf208ebf..7de20e579d 100644 --- a/Applications/CMakeLists.txt +++ b/Applications/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(Help) add_subdirectory(HexEditor) add_subdirectory(IRCClient) add_subdirectory(KeyboardMapper) +add_subdirectory(KeyboardSettings) add_subdirectory(Piano) add_subdirectory(PixelPaint) add_subdirectory(QuickShow) diff --git a/Applications/KeyboardSettings/CMakeLists.txt b/Applications/KeyboardSettings/CMakeLists.txt new file mode 100644 index 0000000000..54f5ea70aa --- /dev/null +++ b/Applications/KeyboardSettings/CMakeLists.txt @@ -0,0 +1,6 @@ +set(SOURCES + main.cpp +) + +serenity_bin(KeyboardSettings) +target_link_libraries(KeyboardSettings LibGUI LibKeyboard) diff --git a/Applications/KeyboardSettings/CharacterMapFileListModel.h b/Applications/KeyboardSettings/CharacterMapFileListModel.h new file mode 100644 index 0000000000..29d79e06d0 --- /dev/null +++ b/Applications/KeyboardSettings/CharacterMapFileListModel.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020, Hüseyin Aslıtürk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include + +class CharacterMapFileListModel final : public GUI::Model { +public: + static NonnullRefPtr create(Vector& file_names) + { + return adopt(*new CharacterMapFileListModel(file_names)); + } + + virtual ~CharacterMapFileListModel() override {} + + virtual int row_count(const GUI::ModelIndex&) const override + { + return m_file_names.size(); + } + + virtual int column_count(const GUI::ModelIndex&) const override + { + return 1; + } + + virtual GUI::Variant data(const GUI::ModelIndex& index, Role role = Role::Display) const override + { + ASSERT(index.is_valid()); + ASSERT(index.column() == 0); + + if (role == Role::Display) + return m_file_names.at(index.row()); + + return {}; + } + + virtual void update() override + { + did_update(); + } + +private: + explicit CharacterMapFileListModel(Vector& file_names) + : m_file_names(file_names) + { + } + + Vector& m_file_names; +}; diff --git a/Applications/KeyboardSettings/main.cpp b/Applications/KeyboardSettings/main.cpp new file mode 100644 index 0000000000..6a70c1beb9 --- /dev/null +++ b/Applications/KeyboardSettings/main.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2020, Hüseyin Aslıtürk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "CharacterMapFileListModel.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + const char* path = nullptr; + Core::ArgsParser args_parser; + args_parser.add_positional_argument(path, "The mapping file to be used", "file", Core::ArgsParser::Required::No); + args_parser.parse(argc, argv); + + if (path != nullptr) { + Keyboard::CharacterMap character_map(path); + int rc = character_map.set_system_map(); + + if (rc != 0) { + fprintf(stderr, "%s\n", strerror(-rc)); + } + + return rc; + } + + // If there is no command line parameter go for GUI. + GUI::Application app(argc, argv); + auto app_icon = GUI::Icon::default_icon("app-keyboard-settings"); + + Vector character_map_files; + Core::DirIterator iterator("/res/keymaps/", Core::DirIterator::Flags::SkipDots); + if (iterator.has_error()) { + GUI::MessageBox::show(String::format("Error on reading mapping file list: %d", iterator.error_string()), "Keyboard settings", GUI::MessageBox::Type::Error, GUI::MessageBox::InputType::OK); + return -1; + } + + while (iterator.has_next()) { + auto name = iterator.next_path(); + name.replace(".json", ""); + character_map_files.append(name); + } + quick_sort(character_map_files); + + auto window = GUI::Window::construct(); + window->set_title("Keyboard settings"); + window->set_rect(200, 200, 300, 70); + window->set_icon(app_icon.bitmap_for_size(16)); + + auto& root_widget = window->set_main_widget(); + root_widget.set_layout(); + root_widget.set_fill_with_background_color(true); + root_widget.layout()->set_spacing(0); + root_widget.layout()->set_margins({ 4, 4, 4, 4 }); + + auto& character_map_file_selection_container = root_widget.add(); + character_map_file_selection_container.set_layout(); + character_map_file_selection_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed); + character_map_file_selection_container.set_preferred_size(0, 22); + + auto& character_map_file_label = character_map_file_selection_container.add(); + character_map_file_label.set_text_alignment(Gfx::TextAlignment::CenterLeft); + character_map_file_label.set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fill); + character_map_file_label.set_preferred_size({ 130, 0 }); + character_map_file_label.set_text("Character Mapping File:"); + + auto& character_map_file_combo = character_map_file_selection_container.add(); + character_map_file_combo.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed); + character_map_file_combo.set_preferred_size(0, 22); + character_map_file_combo.set_only_allow_values_from_model(true); + character_map_file_combo.set_model(*CharacterMapFileListModel::create(character_map_files)); + + root_widget.layout()->add_spacer(); + + auto apply_settings = [&](bool quit) { + String character_map_file = character_map_file_combo.text(); + if (character_map_file.is_empty()) { + GUI::MessageBox::show("Please select character mapping file.", "Keyboard settings", GUI::MessageBox::Type::Error, GUI::MessageBox::InputType::OK, window); + return; + } + + Keyboard::CharacterMap character_map(character_map_file); + int rc = character_map.set_system_map(); + if (rc != 0) { + GUI::MessageBox::show(strerror(-rc), "Keyboard settings", GUI::MessageBox::Type::Error, GUI::MessageBox::InputType::OK, window); + return; + } + + if (quit) + app.quit(); + }; + + auto& bottom_widget = root_widget.add(); + bottom_widget.set_layout(); + bottom_widget.layout()->add_spacer(); + bottom_widget.set_size_policy(Orientation::Vertical, GUI::SizePolicy::Fixed); + bottom_widget.set_preferred_size(1, 22); + + auto& apply_button = bottom_widget.add(); + apply_button.set_text("Apply"); + apply_button.set_size_policy(Orientation::Horizontal, GUI::SizePolicy::Fixed); + apply_button.set_preferred_size(60, 22); + apply_button.on_click = [&](auto) { + apply_settings(false); + }; + + auto& ok_button = bottom_widget.add(); + ok_button.set_text("OK"); + ok_button.set_size_policy(Orientation::Horizontal, GUI::SizePolicy::Fixed); + ok_button.set_preferred_size(60, 22); + ok_button.on_click = [&](auto) { + apply_settings(true); + }; + + auto& cancel_button = bottom_widget.add(); + cancel_button.set_text("Cancel"); + cancel_button.set_size_policy(Orientation::Horizontal, GUI::SizePolicy::Fixed); + cancel_button.set_preferred_size(60, 22); + cancel_button.on_click = [&](auto) { + app.quit(); + }; + + auto quit_action = GUI::CommonActions::make_quit_action( + [&](auto&) { + app.quit(); + }); + + auto about_action = GUI::Action::create("About", + [&](auto&) { + GUI::AboutDialog::show("Keyboard settings", app_icon.bitmap_for_size(32), window); + }); + + auto menubar = GUI::MenuBar::construct(); + + auto& app_menu = menubar->add_menu("Keyboard settings"); + app_menu.add_action(quit_action); + + auto& help_menu = menubar->add_menu("Help"); + help_menu.add_action(about_action); + + app.set_menubar(move(menubar)); + + window->show(); + + return app.exec(); +} diff --git a/Base/res/apps/Keyboard.af b/Base/res/apps/Keyboard.af new file mode 100644 index 0000000000..ad0aced0ee --- /dev/null +++ b/Base/res/apps/Keyboard.af @@ -0,0 +1,8 @@ +[App] +Name=Keyboard settings +Executable=/bin/KeyboardSettings +Category=Settings + +[Icons] +16x16=/res/icons/16x16/app-keyboard-settings.png +32x32=/res/icons/32x32/app-keyboard-settings.png diff --git a/Meta/build-root-filesystem.sh b/Meta/build-root-filesystem.sh index 97adba4df4..949e166d61 100755 --- a/Meta/build-root-filesystem.sh +++ b/Meta/build-root-filesystem.sh @@ -37,6 +37,7 @@ chown $window_uid:$window_gid mnt/etc/WindowServer/WindowServer.ini echo "/bin/sh" > mnt/etc/shells chown 0:$wheel_gid mnt/bin/su +chown 0:$wheel_gid mnt/bin/KeyboardSettings chown 0:$phys_gid mnt/bin/shutdown chown 0:$phys_gid mnt/bin/reboot chown 0:0 mnt/boot/Kernel @@ -47,6 +48,7 @@ chmod 4750 mnt/bin/su chmod 4755 mnt/bin/ping chmod 4750 mnt/bin/reboot chmod 4750 mnt/bin/shutdown +chmod 4750 mnt/bin/KeyboardSettings echo "done" @@ -158,6 +160,7 @@ ln -s Debugger mnt/bin/sdb ln -s SystemMonitor mnt/bin/sm ln -s ProfileViewer mnt/bin/pv ln -s WebServer mnt/bin/ws +ln -s KeyboardSettings mnt/bin/keymap ln -s Solitaire mnt/bin/sl echo "done"