diff options
author | Antonino A. Daplas <adaplas@gmail.com> | 2007-05-08 09:39:37 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 20:15:32 +0200 |
commit | 38a3dc51852d8350b156ea909c5aa8767d71b005 (patch) | |
tree | 933e9a4b7b0a0d871aaccd7d44e9224ea6c4a0b5 /drivers/video/console | |
parent | nvidiafb: prevent triggering of softlockup (diff) | |
download | linux-38a3dc51852d8350b156ea909c5aa8767d71b005.tar.xz linux-38a3dc51852d8350b156ea909c5aa8767d71b005.zip |
fbdev: fbcon: check if mode can handle new screen
Check if the mode can properly display the screen. This will be needed by
drivers where the capability is not constant with each mode. The function
fb_set_var() will query fbcon the requirement, then it will query the driver
(via a new hook fb_get_caps()) its capability. If the driver's capability
cannot handle fbcon's requirement, then fb_set_var() will fail.
For example, if a particular driver supports 2 modes where:
mode1 = can only display 8x16 bitmaps
mode2 = can display any bitmap
then if current mode = mode2 and current font = 12x22
fbset <mode1> /* mode1 cannot handle 12x22 */
fbset will fail
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/console')
-rw-r--r-- | drivers/video/console/fbcon.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 6fc3501581d6..34899bd7c9f3 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -3043,6 +3043,43 @@ static void fbcon_new_modelist(struct fb_info *info) } } +static void fbcon_get_requirement(struct fb_info *info, + struct fb_blit_caps *caps) +{ + struct vc_data *vc; + struct display *p; + int charcnt; + + if (caps->flags) { + int i; + + for (i = first_fb_vc; i <= last_fb_vc; i++) { + vc = vc_cons[i].d; + if (vc && vc->vc_mode == KD_TEXT) { + p = &fb_display[i]; + caps->x |= 1 << (vc->vc_font.width - 1); + caps->y |= 1 << (vc->vc_font.height - 1); + charcnt = (p->userfont) ? + FNTCHARCNT(p->fontdata) : 256; + if (caps->len < charcnt) + caps->len = charcnt; + } + } + } else { + vc = vc_cons[fg_console].d; + + if (vc && vc->vc_mode == KD_TEXT) { + p = &fb_display[fg_console]; + caps->x |= 1 << (vc->vc_font.width - 1); + caps->y |= 1 << (vc->vc_font.height - 1); + charcnt = (p->userfont) ? + FNTCHARCNT(p->fontdata) : 256; + if (caps->len < charcnt) + caps->len = charcnt; + } + } +} + static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { @@ -3050,6 +3087,7 @@ static int fbcon_event_notify(struct notifier_block *self, struct fb_info *info = event->info; struct fb_videomode *mode; struct fb_con2fbmap *con2fb; + struct fb_blit_caps *caps; int ret = 0; /* @@ -3098,6 +3136,10 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_NEW_MODELIST: fbcon_new_modelist(info); break; + case FB_EVENT_GET_REQ: + caps = event->data; + fbcon_get_requirement(info, caps); + break; } done: |