Annotation of /trunk/plymouth/patches/plymouth-fix-frozen-input.patch
Parent Directory | Revision Log
Revision 1347 -
(hide 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 | niro | 1347 | 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 |