diff options
-rw-r--r-- | drivers/video/console/fbcon.c | 48 | ||||
-rw-r--r-- | drivers/video/fbmem.c | 6 | ||||
-rw-r--r-- | include/linux/fb.h | 3 |
3 files changed, 55 insertions, 2 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 35c88bd7ba5..751890a5f5f 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2593,6 +2593,51 @@ static void fbcon_modechanged(struct fb_info *info) } } +static void fbcon_set_all_vcs(struct fb_info *info) +{ + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data *vc; + struct display *p; + int i, rows, cols; + + if (!ops || ops->currcon < 0) + return; + + for (i = 0; i < MAX_NR_CONSOLES; i++) { + vc = vc_cons[i].d; + if (!vc || vc->vc_mode != KD_TEXT || + registered_fb[con2fb_map[i]] != info) + continue; + + p = &fb_display[vc->vc_num]; + + info->var.xoffset = info->var.yoffset = p->yscroll = 0; + var_to_display(p, &info->var, info); + cols = info->var.xres / vc->vc_font.width; + rows = info->var.yres / vc->vc_font.height; + vc_resize(vc, cols, rows); + + if (CON_IS_VISIBLE(vc)) { + updatescrollmode(p, info, vc); + scrollback_max = 0; + scrollback_current = 0; + update_var(vc->vc_num, info); + fbcon_set_palette(vc, color_table); + update_screen(vc); + if (softback_buf) { + int l = fbcon_softback_size / vc->vc_size_row; + if (l > 5) + softback_end = softback_buf + l * vc->vc_size_row; + else { + /* Smaller scrollback makes no sense, and 0 + would screw the operation totally */ + softback_top = 0; + } + } + } + } +} + static int fbcon_mode_deleted(struct fb_info *info, struct fb_videomode *mode) { @@ -2708,6 +2753,9 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_MODE_CHANGE: fbcon_modechanged(info); break; + case FB_EVENT_MODE_CHANGE_ALL: + fbcon_set_all_vcs(info); + break; case FB_EVENT_MODE_DELETE: mode = event->data; ret = fbcon_mode_deleted(info, mode); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 4ff853fbe0b..a8eee79e117 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -684,11 +684,13 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) if (!err && (flags & FBINFO_MISC_USEREVENT)) { struct fb_event event; + int evnt = (var->activate & FB_ACTIVATE_ALL) ? + FB_EVENT_MODE_CHANGE_ALL : + FB_EVENT_MODE_CHANGE; info->flags &= ~FBINFO_MISC_USEREVENT; event.info = info; - notifier_call_chain(&fb_notifier_list, - FB_EVENT_MODE_CHANGE, + notifier_call_chain(&fb_notifier_list, evnt, &event); } } diff --git a/include/linux/fb.h b/include/linux/fb.h index bc24beeed97..70da819df0f 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -495,6 +495,9 @@ struct fb_cursor_user { #define FB_EVENT_BLANK 0x08 /* Private modelist is to be replaced */ #define FB_EVENT_NEW_MODELIST 0x09 +/* The resolution of the passed in fb_info about to change and + all vc's should be changed */ +#define FB_EVENT_MODE_CHANGE_ALL 0x0A struct fb_event { struct fb_info *info; |