Contents of /trunk/plymouth/patches/plymouth-fix-frozen-input.patch
Parent Directory | Revision Log
Revision 1347 -
(show annotations)
(download)
Fri Jun 3 13:34:41 2011 UTC (13 years, 3 months ago) by niro
File size: 9870 byte(s)
Fri Jun 3 13:34:41 2011 UTC (13 years, 3 months ago) by niro
File size: 9870 byte(s)
added keyboard fix
1 | From 113b2e27726c5d95c31034dc5e9db1e8b985c963 Mon Sep 17 00:00:00 2001 |
2 | From: Ray Strode <rstrode@redhat.com> |
3 | Date: Wed, 11 May 2011 10:28:47 -0400 |
4 | Subject: [PATCH] keyboard: handle kernel terminal EIO better |
5 | |
6 | In commit 89096d735f78fab300248962030d6554f9894011 we added |
7 | reopen retries when the kernel returns EIO to ply-terminal.c. |
8 | |
9 | This is because when the kernel is closing a tty down, that |
10 | tty is unavailable to userspace to reopen. |
11 | |
12 | Unfortunately, that commit neglected to inform the ply-keyboard |
13 | part of the code when the terminal retry was successful. The |
14 | upshot of this, is that if plymouthd needs to retry opening the |
15 | tty, then the splash screens lose control over the keyboard. |
16 | |
17 | This commit changes how input notification is sent to the keyboard |
18 | handling code, so the tty disconnects are transparent. |
19 | --- |
20 | src/libply-splash-core/ply-keyboard.c | 27 ++------- |
21 | src/libply-splash-core/ply-terminal.c | 100 +++++++++++++++++++++++++++++++- |
22 | src/libply-splash-core/ply-terminal.h | 10 +++- |
23 | 3 files changed, 112 insertions(+), 25 deletions(-) |
24 | |
25 | diff --git a/src/libply-splash-core/ply-keyboard.c b/src/libply-splash-core/ply-keyboard.c |
26 | index b5b4c39..624f906 100644 |
27 | --- a/src/libply-splash-core/ply-keyboard.c |
28 | +++ b/src/libply-splash-core/ply-keyboard.c |
29 | @@ -65,7 +65,6 @@ typedef enum |
30 | typedef struct |
31 | { |
32 | ply_terminal_t *terminal; |
33 | - ply_fd_watch_t *input_watch; |
34 | ply_buffer_t *key_buffer; |
35 | } ply_keyboard_terminal_provider_t; |
36 | |
37 | @@ -342,15 +341,6 @@ on_terminal_data (ply_keyboard_t *keyboard) |
38 | on_key_event (keyboard, keyboard->provider.if_terminal->key_buffer); |
39 | } |
40 | |
41 | -static void |
42 | -on_terminal_disconnected (ply_keyboard_t *keyboard) |
43 | -{ |
44 | - ply_trace ("keyboard input terminal watch invalidated, rewatching"); |
45 | - keyboard->provider.if_terminal->input_watch = NULL; |
46 | - |
47 | - ply_keyboard_watch_for_terminal_input (keyboard); |
48 | -} |
49 | - |
50 | static bool |
51 | ply_keyboard_watch_for_terminal_input (ply_keyboard_t *keyboard) |
52 | { |
53 | @@ -366,10 +356,9 @@ ply_keyboard_watch_for_terminal_input (ply_keyboard_t *keyboard) |
54 | return false; |
55 | } |
56 | |
57 | - keyboard->provider.if_terminal->input_watch = ply_event_loop_watch_fd (keyboard->loop, terminal_fd, PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, |
58 | - (ply_event_handler_t) on_terminal_data, |
59 | - (ply_event_handler_t) on_terminal_disconnected, |
60 | - keyboard); |
61 | + ply_terminal_watch_for_input (keyboard->provider.if_terminal->terminal, |
62 | + (ply_terminal_input_handler_t) on_terminal_data, |
63 | + keyboard); |
64 | |
65 | return true; |
66 | } |
67 | @@ -377,12 +366,10 @@ ply_keyboard_watch_for_terminal_input (ply_keyboard_t *keyboard) |
68 | static void |
69 | ply_keyboard_stop_watching_for_terminal_input (ply_keyboard_t *keyboard) |
70 | { |
71 | - if (keyboard->provider.if_terminal->input_watch == NULL) |
72 | - return; |
73 | - |
74 | - ply_event_loop_stop_watching_fd (keyboard->loop, |
75 | - keyboard->provider.if_terminal->input_watch); |
76 | - keyboard->provider.if_terminal->input_watch = NULL; |
77 | + ply_terminal_stop_watching_for_input (keyboard->provider.if_terminal->terminal, |
78 | + (ply_terminal_input_handler_t) |
79 | + on_terminal_data, |
80 | + keyboard); |
81 | } |
82 | |
83 | bool |
84 | diff --git a/src/libply-splash-core/ply-terminal.c b/src/libply-splash-core/ply-terminal.c |
85 | index c11a6dd..8876aa0 100644 |
86 | --- a/src/libply-splash-core/ply-terminal.c |
87 | +++ b/src/libply-splash-core/ply-terminal.c |
88 | @@ -60,6 +60,12 @@ |
89 | |
90 | typedef struct |
91 | { |
92 | + ply_terminal_input_handler_t handler; |
93 | + void *user_data; |
94 | +} ply_terminal_input_closure_t; |
95 | + |
96 | +typedef struct |
97 | +{ |
98 | ply_terminal_active_vt_changed_handler_t handler; |
99 | void *user_data; |
100 | } ply_terminal_active_vt_changed_closure_t; |
101 | @@ -78,6 +84,7 @@ struct _ply_terminal |
102 | int number_of_reopen_tries; |
103 | |
104 | ply_list_t *vt_change_closures; |
105 | + ply_list_t *input_closures; |
106 | ply_fd_watch_t *fd_watch; |
107 | ply_terminal_color_t foreground_color; |
108 | ply_terminal_color_t background_color; |
109 | @@ -118,6 +125,7 @@ ply_terminal_new (const char *device_name) |
110 | |
111 | terminal->loop = ply_event_loop_get_default (); |
112 | terminal->vt_change_closures = ply_list_new (); |
113 | + terminal->input_closures = ply_list_new (); |
114 | |
115 | if (strncmp (device_name, "/dev/", strlen ("/dev/")) == 0) |
116 | terminal->name = strdup (device_name); |
117 | @@ -361,6 +369,28 @@ ply_terminal_reopen_device (ply_terminal_t *terminal) |
118 | } |
119 | |
120 | static void |
121 | +on_tty_input (ply_terminal_t *terminal) |
122 | +{ |
123 | + |
124 | + ply_list_node_t *node; |
125 | + |
126 | + node = ply_list_get_first_node (terminal->input_closures); |
127 | + while (node != NULL) |
128 | + { |
129 | + ply_terminal_input_closure_t *closure; |
130 | + ply_list_node_t *next_node; |
131 | + |
132 | + closure = ply_list_node_get_data (node); |
133 | + next_node = ply_list_get_next_node (terminal->input_closures, node); |
134 | + |
135 | + if (closure->handler != NULL) |
136 | + closure->handler (closure->user_data, terminal); |
137 | + |
138 | + node = next_node; |
139 | + } |
140 | +} |
141 | + |
142 | +static void |
143 | on_tty_disconnected (ply_terminal_t *terminal) |
144 | { |
145 | ply_trace ("tty disconnected (fd %d)", terminal->fd); |
146 | @@ -559,10 +589,10 @@ ply_terminal_open_device (ply_terminal_t *terminal) |
147 | } |
148 | |
149 | terminal->fd_watch = ply_event_loop_watch_fd (terminal->loop, terminal->fd, |
150 | - PLY_EVENT_LOOP_FD_STATUS_NONE, |
151 | - (ply_event_handler_t) NULL, |
152 | - (ply_event_handler_t) on_tty_disconnected, |
153 | - terminal); |
154 | + PLY_EVENT_LOOP_FD_STATUS_HAS_DATA, |
155 | + (ply_event_handler_t) on_tty_input, |
156 | + (ply_event_handler_t) on_tty_disconnected, |
157 | + terminal); |
158 | |
159 | ply_terminal_check_for_vt (terminal); |
160 | |
161 | @@ -805,6 +835,26 @@ free_vt_change_closures (ply_terminal_t *terminal) |
162 | ply_list_free (terminal->vt_change_closures); |
163 | } |
164 | |
165 | +static void |
166 | +free_input_closures (ply_terminal_t *terminal) |
167 | +{ |
168 | + ply_list_node_t *node; |
169 | + |
170 | + node = ply_list_get_first_node (terminal->input_closures); |
171 | + while (node != NULL) |
172 | + { |
173 | + ply_terminal_input_closure_t *closure; |
174 | + ply_list_node_t *next_node; |
175 | + |
176 | + closure = ply_list_node_get_data (node); |
177 | + next_node = ply_list_get_next_node (terminal->input_closures, node); |
178 | + |
179 | + free (closure); |
180 | + node = next_node; |
181 | + } |
182 | + ply_list_free (terminal->input_closures); |
183 | +} |
184 | + |
185 | void |
186 | ply_terminal_free (ply_terminal_t *terminal) |
187 | { |
188 | @@ -830,6 +880,7 @@ ply_terminal_free (ply_terminal_t *terminal) |
189 | ply_terminal_close (terminal); |
190 | |
191 | free_vt_change_closures (terminal); |
192 | + free_input_closures (terminal); |
193 | free (terminal->name); |
194 | free (terminal); |
195 | } |
196 | @@ -1001,4 +1052,45 @@ ply_terminal_stop_watching_for_active_vt_change (ply_terminal_t *terminal, |
197 | } |
198 | } |
199 | |
200 | +void |
201 | +ply_terminal_watch_for_input (ply_terminal_t *terminal, |
202 | + ply_terminal_input_handler_t input_handler, |
203 | + void *user_data) |
204 | +{ |
205 | + ply_terminal_input_closure_t *closure; |
206 | + |
207 | + closure = calloc (1, sizeof (*closure)); |
208 | + closure->handler = input_handler; |
209 | + closure->user_data = user_data; |
210 | + |
211 | + ply_list_append_data (terminal->input_closures, closure); |
212 | +} |
213 | + |
214 | +void |
215 | +ply_terminal_stop_watching_for_input (ply_terminal_t *terminal, |
216 | + ply_terminal_input_handler_t input_handler, |
217 | + void *user_data) |
218 | +{ |
219 | + ply_list_node_t *node; |
220 | + |
221 | + node = ply_list_get_first_node (terminal->input_closures); |
222 | + while (node != NULL) |
223 | + { |
224 | + ply_terminal_input_closure_t *closure; |
225 | + ply_list_node_t *next_node; |
226 | + |
227 | + closure = ply_list_node_get_data (node); |
228 | + next_node = ply_list_get_next_node (terminal->input_closures, node); |
229 | + |
230 | + if (closure->handler == input_handler && |
231 | + closure->user_data == user_data) |
232 | + { |
233 | + free (closure); |
234 | + ply_list_remove_node (terminal->input_closures, node); |
235 | + } |
236 | + |
237 | + node = next_node; |
238 | + } |
239 | +} |
240 | + |
241 | /* vim: set ts=4 sw=4 et ai ci cino={.5s,^-2,+.5s,t0,g0,e-2,n-2,p2s,(0,=.5s,:.5s */ |
242 | diff --git a/src/libply-splash-core/ply-terminal.h b/src/libply-splash-core/ply-terminal.h |
243 | index 2eb9950..8b4b017 100644 |
244 | --- a/src/libply-splash-core/ply-terminal.h |
245 | +++ b/src/libply-splash-core/ply-terminal.h |
246 | @@ -33,7 +33,8 @@ |
247 | typedef struct _ply_terminal ply_terminal_t; |
248 | typedef void (* ply_terminal_active_vt_changed_handler_t) (void *user_data, |
249 | ply_terminal_t *terminal); |
250 | - |
251 | +typedef void (* ply_terminal_input_handler_t) (void *user_data, |
252 | + ply_terminal_t *terminal); |
253 | typedef enum |
254 | { |
255 | PLY_TERMINAL_COLOR_BLACK = 0, |
256 | @@ -104,6 +105,13 @@ void ply_terminal_stop_watching_for_active_vt_change (ply_terminal_t *terminal, |
257 | ply_terminal_active_vt_changed_handler_t active_vt_changed_handler, |
258 | void *user_data); |
259 | |
260 | +void ply_terminal_watch_for_input (ply_terminal_t *terminal, |
261 | + ply_terminal_input_handler_t input_handler, |
262 | + void *user_data); |
263 | +void ply_terminal_stop_watching_for_input (ply_terminal_t *terminal, |
264 | + ply_terminal_input_handler_t input_handler, |
265 | + void *user_data); |
266 | + |
267 | #endif |
268 | |
269 | #endif /* PLY_TERMINAL_H */ |
270 | -- |
271 | 1.7.5 |
272 |