Commit 81d5fd84 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fbdev: video mode change notify (fbset)

From: "Antonino A. Daplas" <adaplas@hotpop.com>

This patch allows fbset to change the video mode and the console window
size via the notifier call chain.  It will only notify fbcon of mode
changes from user space.  Changes coming from upstream will be ignored.

The code will only update the current console.
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0a88d609
...@@ -2358,6 +2358,56 @@ static void fbcon_resumed(struct fb_info *info) ...@@ -2358,6 +2358,56 @@ static void fbcon_resumed(struct fb_info *info)
update_screen(vc->vc_num); update_screen(vc->vc_num);
} }
static void fbcon_modechanged(struct fb_info *info)
{
struct vc_data *vc = vc_cons[info->currcon].d;
struct display *p;
int rows, cols;
if (info->currcon < 0 || vt_cons[info->currcon]->vc_mode !=
KD_TEXT)
return;
p = &fb_display[vc->vc_num];
info->var.xoffset = info->var.yoffset = p->yscroll = 0;
vc->vc_can_do_color = info->var.bits_per_pixel != 1;
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
if (CON_IS_VISIBLE(vc)) {
cols = info->var.xres / vc->vc_font.width;
rows = info->var.yres / vc->vc_font.height;
vc_resize(vc->vc_num, cols, rows);
switch (p->scrollmode) {
case SCROLL_WRAP:
scrollback_phys_max = p->vrows - vc->vc_rows;
break;
case SCROLL_PAN:
scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
if (scrollback_phys_max < 0)
scrollback_phys_max = 0;
break;
default:
scrollback_phys_max = 0;
break;
}
scrollback_max = 0;
scrollback_current = 0;
update_var(vc->vc_num, info);
fbcon_set_palette(vc, color_table);
update_screen(vc->vc_num);
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_event_notify(struct notifier_block *self, static int fbcon_event_notify(struct notifier_block *self,
unsigned long action, void *data) unsigned long action, void *data)
{ {
...@@ -2370,6 +2420,9 @@ static int fbcon_event_notify(struct notifier_block *self, ...@@ -2370,6 +2420,9 @@ static int fbcon_event_notify(struct notifier_block *self,
case FB_EVENT_RESUME: case FB_EVENT_RESUME:
fbcon_resumed(info); fbcon_resumed(info);
break; break;
case FB_EVENT_MODE_CHANGE:
fbcon_modechanged(info);
break;
} }
return 0; return 0;
......
...@@ -1005,7 +1005,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) ...@@ -1005,7 +1005,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
fb_set_cmap(&info->cmap, 1, info); fb_set_cmap(&info->cmap, 1, info);
notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_CHANGE, info); if (info->flags & FBINFO_MISC_MODECHANGEUSER) {
notifier_call_chain(&fb_notifier_list,
FB_EVENT_MODE_CHANGE, info);
info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
}
} }
} }
return 0; return 0;
...@@ -1056,7 +1060,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -1056,7 +1060,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (copy_from_user(&var, (void *) arg, sizeof(var))) if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT; return -EFAULT;
acquire_console_sem(); acquire_console_sem();
info->flags |= FBINFO_MISC_MODECHANGEUSER;
i = fb_set_var(info, &var); i = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
release_console_sem(); release_console_sem();
if (i) return i; if (i) return i;
if (copy_to_user((void *) arg, &var, sizeof(var))) if (copy_to_user((void *) arg, &var, sizeof(var)))
......
...@@ -530,6 +530,8 @@ struct fb_ops { ...@@ -530,6 +530,8 @@ struct fb_ops {
#define FBINFO_HWACCEL_YPAN 0x2000 /* optional */ #define FBINFO_HWACCEL_YPAN 0x2000 /* optional */
#define FBINFO_HWACCEL_YWRAP 0x4000 /* optional */ #define FBINFO_HWACCEL_YWRAP 0x4000 /* optional */
#define FBINFO_MISC_MODECHANGEUSER 0x10000 /* mode change request
from userspace */
struct fb_info { struct fb_info {
int node; int node;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment