Mir

Merge lp:~robertcarr/mir/disable-sequences-and-add-terminate-handler into lp:~mir-team/mir/trunk

Proposed by Robert Carr
Status: Rejected
Rejected by: Robert Carr
Proposed branch: lp:~robertcarr/mir/disable-sequences-and-add-terminate-handler
Merge into: lp:~mir-team/mir/trunk
Diff against target: 278 lines (+118/-3)
9 files modified
examples/demo-shell/demo_shell.cpp (+33/-2)
include/test/mir_test_doubles/null_virtual_terminal.h (+1/-0)
src/server/graphics/gbm/gbm_display.cpp (+1/-0)
src/server/graphics/gbm/gbm_platform.cpp (+14/-0)
src/server/graphics/gbm/linux_virtual_terminal.cpp (+11/-0)
src/server/graphics/gbm/linux_virtual_terminal.h (+2/-0)
src/server/graphics/gbm/virtual_terminal.h (+1/-0)
tests/unit-tests/graphics/gbm/test_gbm_display.cpp (+4/-1)
tests/unit-tests/graphics/gbm/test_linux_virtual_terminal.cpp (+51/-0)
To merge this branch: bzr merge lp:~robertcarr/mir/disable-sequences-and-add-terminate-handler
Reviewer Review Type Date Requested Status
Alan Griffiths Needs Fixing
Alexandros Frantzis (community) Needs Fixing
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+164014@code.launchpad.net

Commit message

Disable control sequences (ctrl+c, etc...) and add a way to kill mir (demo shell) in lieu of this.

Description of the change

Disable control sequences (ctrl+c, etc...) and add a way to kill mir (demo shell) in lieu of this.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Robert Ancell (robert-ancell) wrote :

The name disable_control_sequences() seems confusing - this is just setting the console into raw mode right? Shouldn't it be called set_raw_mode() or similar?

Is there an easy way for the demo shell to note that it can only be quit using alt+ctrl+backspace? This is likely to confuse people using this.

This change is going to affect all shells, not just the demo shell. It might be worth putting alt+ctrl+backspace into libmirserver by default (at least for now) so other shells also are quittable if we disable input.

Finally, check with Alexandros but I think there was some issues that meant he hadn't enabled raw input yet.

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> This change is going to affect all shells, not just the demo shell.
> It might be worth putting alt+ctrl+backspace into libmirserver by default
> (at least for now) so other shells also are quittable if we disable input.

+1, we can put it in run_mir.cpp

> Finally, check with Alexandros but I think there was some issues that meant
> he hadn't enabled raw input yet.

My only concern is that we would disable VT switching key sequences, while we didn't yet have another way to handle them. It seems that the current raw mode options don't affect this, so no problem there.

Plus, I think that the input stack has matured enough to support this (i.e. catching ctrl-alt-f1 and initiating a VT switch), and when we get this we can completely disable VT input (something like ioctl(fd, KDSKBMODE, K_OFF), but I need to experiment), which means that we won't need FOPS::make_raw()/VT::disable_control_sequences() any more, we will just need VT::disable_input().

137 +void mgg::LinuxVirtualTerminal::disable_control_sequences()

We also need to restore the VT input handling state in the LinuxVirtualTerminal destructor, to get back to a sane console after shutdown.

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

In addition to Alexandros's comments around VT switching there should be some *documentation* to alert users that:

1. Ctrl-C doesn't kill mir_demo_shell
2. How to kill it

review: Needs Fixing

Unmerged revisions

692. By Robert Carr

Correct terminate handler

691. By Robert Carr

Make test pass

690. By Robert Carr

Failing test for disabling control sequences

689. By Robert Carr

Add a disable control sequences interface to VT

688. By Robert Carr

Add a make_raw method to VTFileOperations which disables control sequences

687. By Robert Carr

Allow access to the internal egl native display without usage of a surface.

Approved by PS Jenkins bot, Kevin DuBois.

686. By Robert Ancell

Release version 0.0.3

685. By Alexandros Frantzis

shell: Close all open sessions when destroying the SessionManager

We need to do this manually to break the cyclic dependency between msh::Session
and msh::InputTargetListener, since our implementations of these interfaces
keep strong references to each other. This change fixes LP:#1170643. Fixes: https://bugs.launchpad.net/bugs/1170643.

Approved by Robert Carr, Alan Griffiths, PS Jenkins bot.

684. By Alan Griffiths

Remove MIR_GCC_VERSION variable.

This was useful when the Android SDK wasn't up to date. We're now building
on a full Raring/Saucy image, so we don't want to use a non-default compiler.

Approved by Kevin DuBois, Alexandros Frantzis, PS Jenkins bot.

683. By Chris Halse Rogers

Fix build with g++ 4.8.

Approved by PS Jenkins bot, Robert Carr.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/demo-shell/demo_shell.cpp'
2--- examples/demo-shell/demo_shell.cpp 2013-04-29 17:39:12 +0000
3+++ examples/demo-shell/demo_shell.cpp 2013-05-15 18:11:27 +0000
4@@ -22,6 +22,7 @@
5 #include "fullscreen_placement_strategy.h"
6
7 #include "mir/run_mir.h"
8+#include "mir/display_server.h"
9 #include "mir/report_exception.h"
10 #include "mir/default_server_configuration.h"
11 #include "mir/shell/session_manager.h"
12@@ -33,6 +34,8 @@
13
14 #include <iostream>
15
16+#include <linux/input.h>
17+
18 namespace me = mir::examples;
19 namespace msh = mir::shell;
20 namespace mg = mir::graphics;
21@@ -44,6 +47,31 @@
22 namespace examples
23 {
24
25+struct TerminateHandler : mi::EventFilter
26+{
27+ TerminateHandler() : server(0) {}
28+ void set_server(DisplayServer* ds)
29+ {
30+ server = ds;
31+ }
32+
33+ bool handles(MirEvent const& ev)
34+ {
35+ if (ev.type != mir_event_type_key)
36+ return false;
37+ if (!(ev.key.modifiers & mir_key_modifier_ctrl))
38+ return false;
39+ if (!(ev.key.modifiers & mir_key_modifier_alt))
40+ return false;
41+ if (ev.key.scan_code != KEY_BACKSPACE)
42+ return false;
43+ server->stop();
44+ return true;
45+ }
46+
47+ DisplayServer* server;
48+};
49+
50 struct DemoServerConfiguration : mir::DefaultServerConfiguration
51 {
52 DemoServerConfiguration(int argc, char const* argv[],
53@@ -76,14 +104,17 @@
54 int main(int argc, char const* argv[])
55 try
56 {
57+ auto terminate_handler = std::make_shared<me::TerminateHandler>();
58 auto app_switcher = std::make_shared<me::ApplicationSwitcher>();
59- me::DemoServerConfiguration config(argc, argv, {app_switcher});
60+ auto event_filters = std::initializer_list<std::shared_ptr<mi::EventFilter> const>{terminate_handler, app_switcher};
61+ me::DemoServerConfiguration config(argc, argv, event_filters);
62
63- mir::run_mir(config, [&config, &app_switcher](mir::DisplayServer&)
64+ mir::run_mir(config, [&](mir::DisplayServer& server)
65 {
66 // We use this strange two stage initialization to avoid a circular dependency between the EventFilters
67 // and the SessionStore
68 app_switcher->set_focus_controller(config.the_focus_controller());
69+ terminate_handler->set_server(&server);
70 });
71 return 0;
72 }
73
74=== modified file 'include/test/mir_test_doubles/null_virtual_terminal.h'
75--- include/test/mir_test_doubles/null_virtual_terminal.h 2013-04-25 09:48:54 +0000
76+++ include/test/mir_test_doubles/null_virtual_terminal.h 2013-05-15 18:11:27 +0000
77@@ -32,6 +32,7 @@
78 {
79 public:
80 void set_graphics_mode() {}
81+ void disable_control_sequences() {}
82
83 void register_switch_handlers(MainLoop&,
84 std::function<bool()> const&,
85
86=== modified file 'src/server/graphics/gbm/gbm_display.cpp'
87--- src/server/graphics/gbm/gbm_display.cpp 2013-05-13 09:23:04 +0000
88+++ src/server/graphics/gbm/gbm_display.cpp 2013-05-15 18:11:27 +0000
89@@ -56,6 +56,7 @@
90 std::make_shared<KMSPageFlipper>(platform->drm.fd)}
91 {
92 platform->vt->set_graphics_mode();
93+ platform->vt->disable_control_sequences();
94
95 shared_egl.setup(platform->gbm);
96
97
98=== modified file 'src/server/graphics/gbm/gbm_platform.cpp'
99--- src/server/graphics/gbm/gbm_platform.cpp 2013-05-14 16:45:25 +0000
100+++ src/server/graphics/gbm/gbm_platform.cpp 2013-05-15 18:11:27 +0000
101@@ -29,6 +29,7 @@
102
103 #include <fcntl.h>
104 #include <sys/ioctl.h>
105+#include <termios.h>
106
107 namespace mg = mir::graphics;
108 namespace mgg = mg::gbm;
109@@ -71,6 +72,19 @@
110 {
111 return ::ioctl(d, request, p_val);
112 }
113+
114+ int make_raw(int vt_fd)
115+ {
116+ struct termios terminal_attributes;
117+ auto status = tcgetattr(vt_fd, &terminal_attributes);
118+ if (status)
119+ return status;
120+
121+ cfmakeraw(&terminal_attributes);
122+ terminal_attributes.c_oflag |= OPOST | OCRNL;
123+
124+ return tcsetattr(vt_fd, TCSANOW, &terminal_attributes);
125+ }
126 };
127
128 }
129
130=== modified file 'src/server/graphics/gbm/linux_virtual_terminal.cpp'
131--- src/server/graphics/gbm/linux_virtual_terminal.cpp 2013-04-25 09:48:54 +0000
132+++ src/server/graphics/gbm/linux_virtual_terminal.cpp 2013-05-15 18:11:27 +0000
133@@ -82,6 +82,17 @@
134 }
135 }
136
137+void mgg::LinuxVirtualTerminal::disable_control_sequences()
138+{
139+ if (fops->make_raw(vt_fd.fd()))
140+ {
141+ BOOST_THROW_EXCEPTION(
142+ boost::enable_error_info(
143+ std::runtime_error("Failed to disable control sequences on VT"))
144+ << boost::errinfo_errno(errno));
145+ }
146+}
147+
148 void mgg::LinuxVirtualTerminal::register_switch_handlers(
149 MainLoop& main_loop,
150 std::function<bool()> const& switch_away,
151
152=== modified file 'src/server/graphics/gbm/linux_virtual_terminal.h'
153--- src/server/graphics/gbm/linux_virtual_terminal.h 2013-04-25 09:48:54 +0000
154+++ src/server/graphics/gbm/linux_virtual_terminal.h 2013-05-15 18:11:27 +0000
155@@ -45,6 +45,7 @@
156 virtual int close(int fd) = 0;
157 virtual int ioctl(int d, int request, int val) = 0;
158 virtual int ioctl(int d, int request, void* p_val) = 0;
159+ virtual int make_raw(int vt_fd) = 0;
160
161 protected:
162 VTFileOperations() = default;
163@@ -60,6 +61,7 @@
164 ~LinuxVirtualTerminal() noexcept(true);
165
166 void set_graphics_mode();
167+ void disable_control_sequences();
168 void register_switch_handlers(
169 MainLoop& main_loop,
170 std::function<bool()> const& switch_away,
171
172=== modified file 'src/server/graphics/gbm/virtual_terminal.h'
173--- src/server/graphics/gbm/virtual_terminal.h 2013-04-25 09:48:54 +0000
174+++ src/server/graphics/gbm/virtual_terminal.h 2013-05-15 18:11:27 +0000
175@@ -37,6 +37,7 @@
176 virtual ~VirtualTerminal() = default;
177
178 virtual void set_graphics_mode() = 0;
179+ virtual void disable_control_sequences() = 0;
180 virtual void register_switch_handlers(
181 MainLoop& main_loop,
182 std::function<bool()> const& switch_away,
183
184=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display.cpp'
185--- tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-05-10 18:32:25 +0000
186+++ tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-05-15 18:11:27 +0000
187@@ -58,6 +58,7 @@
188 ~MockVirtualTerminal() noexcept(true) {}
189
190 MOCK_METHOD0(set_graphics_mode, void());
191+ MOCK_METHOD0(disable_control_sequences, void());
192 MOCK_METHOD3(register_switch_handlers,
193 void(mir::MainLoop&,
194 std::function<bool()> const&,
195@@ -627,7 +628,7 @@
196 EXPECT_NE(0, callback_count);
197 }
198
199-TEST_F(GBMDisplayTest, constructor_sets_vt_graphics_mode)
200+TEST_F(GBMDisplayTest, constructor_sets_vt_graphics_and_input_mode)
201 {
202 using namespace testing;
203
204@@ -635,6 +636,8 @@
205
206 EXPECT_CALL(*mock_vt, set_graphics_mode())
207 .Times(1);
208+ EXPECT_CALL(*mock_vt, disable_control_sequences())
209+ .Times(1);
210
211 auto platform = std::make_shared<mgg::GBMPlatform>(null_report, mock_vt);
212
213
214=== modified file 'tests/unit-tests/graphics/gbm/test_linux_virtual_terminal.cpp'
215--- tests/unit-tests/graphics/gbm/test_linux_virtual_terminal.cpp 2013-04-18 12:56:58 +0000
216+++ tests/unit-tests/graphics/gbm/test_linux_virtual_terminal.cpp 2013-05-15 18:11:27 +0000
217@@ -47,6 +47,7 @@
218 MOCK_METHOD1(close, int(int));
219 MOCK_METHOD3(ioctl, int(int, int, int));
220 MOCK_METHOD3(ioctl, int(int, int, void*));
221+ MOCK_METHOD1(make_raw, int(int));
222 };
223
224 class MockMainLoop : public mir::MainLoop
225@@ -382,3 +383,53 @@
226 /* Fake a VT switch back request */
227 sig_handler(SIGUSR1);
228 }
229+
230+TEST_F(LinuxVirtualTerminalTest, disables_control_sequences)
231+{
232+ using namespace testing;
233+
234+ int const vt_num{7};
235+ int const success = 0;
236+
237+ InSequence s;
238+
239+ set_up_expectations_for_current_vt_search(vt_num);
240+ set_up_expectations_for_vt_setup(vt_num);
241+
242+ EXPECT_CALL(mock_fops, make_raw(fake_vt_fd))
243+ .WillOnce(Return(success));
244+
245+ set_up_expectations_for_vt_teardown();
246+
247+ auto fops = mt::fake_shared<mgg::VTFileOperations>(mock_fops);
248+ auto null_report = std::make_shared<mg::NullDisplayReport>();
249+
250+ mgg::LinuxVirtualTerminal vt(fops, null_report);
251+ vt.disable_control_sequences();
252+}
253+
254+TEST_F(LinuxVirtualTerminalTest, failure_to_disable_control_sequences_throws)
255+{
256+ using namespace testing;
257+
258+ int const vt_num{7};
259+ int const failure = -1;
260+
261+ InSequence s;
262+
263+ set_up_expectations_for_current_vt_search(vt_num);
264+ set_up_expectations_for_vt_setup(vt_num);
265+
266+ EXPECT_CALL(mock_fops, make_raw(fake_vt_fd))
267+ .WillOnce(Return(failure));
268+
269+ set_up_expectations_for_vt_teardown();
270+
271+ auto fops = mt::fake_shared<mgg::VTFileOperations>(mock_fops);
272+ auto null_report = std::make_shared<mg::NullDisplayReport>();
273+
274+ mgg::LinuxVirtualTerminal vt(fops, null_report);
275+ EXPECT_THROW({
276+ vt.disable_control_sequences();
277+ }, std::runtime_error);
278+}

Subscribers

People subscribed via source and target branches