@@ -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 ;
@@ -38,6 +40,7 @@ typedef struct {
38
40
uint16_t cmap [3 ][256 ];
39
41
uint8_t * fb_base ;
40
42
size_t fb_len ;
43
+
41
44
} twin_fbdev_t ;
42
45
43
46
/* color conversion */
@@ -86,22 +89,6 @@ static void twin_fbdev_get_screen_size(twin_fbdev_t *tx,
86
89
* height = info .yres ;
87
90
}
88
91
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
92
static inline bool twin_fbdev_is_rgb565 (twin_fbdev_t * tx )
106
93
{
107
94
return tx -> fb_var .red .offset == 11 && tx -> fb_var .red .length == 5 &&
@@ -192,6 +179,50 @@ static bool twin_fbdev_apply_config(twin_fbdev_t *tx)
192
179
return true;
193
180
}
194
181
182
+ static void twin_fbdev_damage (twin_fbdev_t * tx )
183
+ {
184
+ int width , height ;
185
+ twin_fbdev_get_screen_size (tx , & width , & height );
186
+ twin_screen_damage (tx -> screen , 0 , 0 , width , height );
187
+ }
188
+
189
+ static bool twin_fbdev_damaged (void * closure )
190
+ {
191
+ twin_fbdev_t * tx = PRIV (closure );
192
+ twin_screen_t * screen = SCREEN (closure );
193
+
194
+ if (!tx -> vt_active && twin_screen_damaged (screen ))
195
+ twin_screen_update (screen );
196
+
197
+ return true;
198
+ }
199
+
200
+ static bool twin_fbdev_work (void * closure )
201
+ {
202
+ twin_fbdev_t * tx = PRIV (closure );
203
+ twin_screen_t * screen = SCREEN (closure );
204
+
205
+ if (tx -> vt_active && (tx -> fb_base != MAP_FAILED )) {
206
+ /* Unmap the fbdev */
207
+ munmap (tx -> fb_base , tx -> fb_len );
208
+ tx -> fb_base = MAP_FAILED ;
209
+ }
210
+
211
+ if (!tx -> vt_active && (tx -> fb_base == MAP_FAILED )) {
212
+ /* Restore the fbdev settings */
213
+ if (!twin_fbdev_apply_config (tx ))
214
+ log_error ("Failed to apply configurations to the fbdev" );
215
+
216
+ /* Mark entire screen for refresh */
217
+ twin_screen_damage (screen , 0 , 0 , screen -> width , screen -> height );
218
+ }
219
+
220
+ if (!tx -> vt_active && twin_screen_damaged (screen ))
221
+ twin_screen_update (screen );
222
+
223
+ return true;
224
+ }
225
+
195
226
twin_context_t * twin_fbdev_init (int width , int height )
196
227
{
197
228
char * fbdev_path = getenv (FBDEV_NAME );
@@ -204,6 +235,7 @@ twin_context_t *twin_fbdev_init(int width, int height)
204
235
twin_context_t * ctx = calloc (1 , sizeof (twin_context_t ));
205
236
if (!ctx )
206
237
return NULL ;
238
+
207
239
ctx -> priv = calloc (1 , sizeof (twin_fbdev_t ));
208
240
if (!ctx -> priv )
209
241
return NULL ;
@@ -218,10 +250,13 @@ twin_context_t *twin_fbdev_init(int width, int height)
218
250
}
219
251
220
252
/* Set up virtual terminal environment */
221
- if (!twin_vt_setup (& tx -> vt_fd )) {
253
+ if (!twin_vt_setup (& tx -> vt_fd , & tx -> old_vtm , & tx -> vt_active )) {
222
254
goto bail_fb_fd ;
223
255
}
224
256
257
+ /* Set up signal handlers for switching TTYs */
258
+ twin_vt_setup_signal_handler ();
259
+
225
260
/* Apply configurations to the framebuffer device */
226
261
if (!twin_fbdev_apply_config (tx )) {
227
262
log_error ("Failed to apply configurations to the framebuffer device" );
@@ -254,6 +289,9 @@ twin_context_t *twin_fbdev_init(int width, int height)
254
289
/* Setup file handler and work functions */
255
290
twin_set_work (twin_fbdev_work , TWIN_WORK_REDISPLAY , ctx );
256
291
292
+ /* Register a callback function to handle damaged rendering */
293
+ twin_screen_register_damaged (ctx -> screen , twin_fbdev_damaged , ctx );
294
+
257
295
return ctx ;
258
296
259
297
bail_screen :
@@ -292,7 +330,6 @@ static void twin_fbdev_exit(twin_context_t *ctx)
292
330
}
293
331
294
332
/* Register the Linux framebuffer backend */
295
-
296
333
const twin_backend_t g_twin_backend = {
297
334
.init = twin_fbdev_init ,
298
335
.configure = twin_fbdev_configure ,
0 commit comments