@@ -30,6 +30,8 @@ typedef struct {
30
30
31
31
/* Linux virtual terminal (VT) */
32
32
int vt_fd ;
33
+ bool vt_active ;
34
+ struct vt_mode old_vtm ;
33
35
34
36
/* Linux framebuffer */
35
37
int fb_fd ;
@@ -86,22 +88,6 @@ static void twin_fbdev_get_screen_size(twin_fbdev_t *tx,
86
88
* height = info .yres ;
87
89
}
88
90
89
- static void twin_fbdev_damage (twin_screen_t * screen , twin_fbdev_t * tx )
90
- {
91
- int width , height ;
92
- twin_fbdev_get_screen_size (tx , & width , & height );
93
- twin_screen_damage (tx -> screen , 0 , 0 , width , height );
94
- }
95
-
96
- static bool twin_fbdev_work (void * closure )
97
- {
98
- twin_screen_t * screen = SCREEN (closure );
99
-
100
- if (twin_screen_damaged (screen ))
101
- twin_screen_update (screen );
102
- return true;
103
- }
104
-
105
91
static inline bool twin_fbdev_is_rgb565 (twin_fbdev_t * tx )
106
92
{
107
93
return tx -> fb_var .red .offset == 11 && tx -> fb_var .red .length == 5 &&
@@ -192,6 +178,50 @@ static bool twin_fbdev_apply_config(twin_fbdev_t *tx)
192
178
return true;
193
179
}
194
180
181
+ static void twin_fbdev_damage (twin_fbdev_t * tx )
182
+ {
183
+ int width , height ;
184
+ twin_fbdev_get_screen_size (tx , & width , & height );
185
+ twin_screen_damage (tx -> screen , 0 , 0 , width , height );
186
+ }
187
+
188
+ static bool twin_fbdev_update_damage (void * closure )
189
+ {
190
+ twin_fbdev_t * tx = PRIV (closure );
191
+ twin_screen_t * screen = SCREEN (closure );
192
+
193
+ if (!tx -> vt_active && twin_screen_damaged (screen ))
194
+ twin_screen_update (screen );
195
+
196
+ return true;
197
+ }
198
+
199
+ static bool twin_fbdev_work (void * closure )
200
+ {
201
+ twin_fbdev_t * tx = PRIV (closure );
202
+ twin_screen_t * screen = SCREEN (closure );
203
+
204
+ if (tx -> vt_active && (tx -> fb_base != MAP_FAILED )) {
205
+ /* Unmap the fbdev */
206
+ munmap (tx -> fb_base , tx -> fb_len );
207
+ tx -> fb_base = MAP_FAILED ;
208
+ }
209
+
210
+ if (!tx -> vt_active && (tx -> fb_base == MAP_FAILED )) {
211
+ /* Restore the fbdev settings */
212
+ if (!twin_fbdev_apply_config (tx ))
213
+ log_error ("Failed to apply configurations to the fbdev" );
214
+
215
+ /* Mark entire screen for refresh */
216
+ twin_screen_damage (screen , 0 , 0 , screen -> width , screen -> height );
217
+ }
218
+
219
+ if (!tx -> vt_active && twin_screen_damaged (screen ))
220
+ twin_screen_update (screen );
221
+
222
+ return true;
223
+ }
224
+
195
225
twin_context_t * twin_fbdev_init (int width , int height )
196
226
{
197
227
char * fbdev_path = getenv (FBDEV_NAME );
@@ -218,10 +248,13 @@ twin_context_t *twin_fbdev_init(int width, int height)
218
248
}
219
249
220
250
/* Set up virtual terminal environment */
221
- if (!twin_vt_setup (& tx -> vt_fd )) {
251
+ if (!twin_vt_setup (& tx -> vt_fd , & tx -> old_vtm , & tx -> vt_active )) {
222
252
goto bail_fb_fd ;
223
253
}
224
254
255
+ /* Set up signal handlers for switching TTYs */
256
+ twin_vt_setup_signal_handler ();
257
+
225
258
/* Apply configurations to the framebuffer device */
226
259
if (!twin_fbdev_apply_config (tx )) {
227
260
log_error ("Failed to apply configurations to the framebuffer device" );
@@ -254,6 +287,9 @@ twin_context_t *twin_fbdev_init(int width, int height)
254
287
/* Setup file handler and work functions */
255
288
twin_set_work (twin_fbdev_work , TWIN_WORK_REDISPLAY , ctx );
256
289
290
+ /* Register a callback function to handle damaged rendering */
291
+ twin_screen_register_damaged (ctx -> screen , twin_fbdev_update_damage , ctx );
292
+
257
293
return ctx ;
258
294
259
295
bail_screen :
@@ -292,7 +328,6 @@ static void twin_fbdev_exit(twin_context_t *ctx)
292
328
}
293
329
294
330
/* Register the Linux framebuffer backend */
295
-
296
331
const twin_backend_t g_twin_backend = {
297
332
.init = twin_fbdev_init ,
298
333
.configure = twin_fbdev_configure ,
0 commit comments