[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-fbdev-devel
Subject: [Linux-fbdev-devel] [PATCH 4/9] fbcon/fbdev: Add blanking notification
From: "Antonino A. Daplas" <adaplas () hotpop ! com>
Date: 2004-12-21 21:35:13
Message-ID: 20041221213648.89B701A0278 () smtp-1 ! hotpop ! com
[Download RAW message or body]
Add blanking event to the notifier call chain. This can be used by fbcon
to blank/unblank the console, and theoretically, by backlight drivers.
Signed-off-by: Antonino Daplas <adaplas@pol.net>
---
drivers/video/console/fbcon.c | 91 ++++++++++++++++++++++--------------------
drivers/video/console/fbcon.h | 1
drivers/video/fbmem.c | 26 ++++++++----
include/linux/fb.h | 5 +-
4 files changed, 70 insertions(+), 53 deletions(-)
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- a/drivers/video/console/fbcon.c 2004-11-17 18:15:17 +08:00
+++ b/drivers/video/console/fbcon.c 2004-12-21 05:55:41 +08:00
@@ -2000,44 +2000,20 @@
int blank)
{
if (blank) {
- if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
- info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
- struct fb_cmap cmap;
- u16 *black;
-
- black = kmalloc(sizeof(u16) * info->cmap.len,
- GFP_KERNEL);
- if (black) {
- memset(black, 0, info->cmap.len * sizeof(u16));
- cmap.red = cmap.green = cmap.blue = black;
- cmap.transp = info->cmap.transp ? black : NULL;
- cmap.start = info->cmap.start;
- cmap.len = info->cmap.len;
- fb_set_cmap(&cmap, info);
- }
-
- kfree(black);
- } else {
- unsigned short charmask = vc->vc_hi_font_mask ?
- 0x1ff : 0xff;
- unsigned short oldc;
-
- oldc = vc->vc_video_erase_char;
- vc->vc_video_erase_char &= charmask;
- fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
- vc->vc_video_erase_char = oldc;
- }
- } else {
- if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
- info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
- fb_set_cmap(&info->cmap, info);
+ unsigned short charmask = vc->vc_hi_font_mask ?
+ 0x1ff : 0xff;
+ unsigned short oldc;
+
+ oldc = vc->vc_video_erase_char;
+ vc->vc_video_erase_char &= charmask;
+ fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
+ vc->vc_video_erase_char = oldc;
}
}
static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
- struct fbcon_ops *ops = info->fbcon_par;
int active = !fbcon_is_inactive(vc, info);
if (mode_switch) {
@@ -2061,19 +2037,21 @@
}
if (active) {
- int ret = -1;
+ struct fbcon_ops *ops = info->fbcon_par;
fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
ops->cursor_flash = (!blank);
- if (info->fbops->fb_blank)
- ret = info->fbops->fb_blank(blank, info);
-
- if (ret)
- fbcon_generic_blank(vc, info, blank);
+ if (ops->blank_state != blank) {
+ if (info->fbops->fb_blank &&
+ info->fbops->fb_blank(blank, info))
+ fbcon_generic_blank(vc, info, blank);
+
+ ops->blank_state = blank;
+ }
if (!blank)
- update_screen(vc->vc_num);
+ update_screen(vc->vc_num);
}
return 0;
@@ -2580,14 +2558,12 @@
struct display *p;
int rows, cols;
- if (!ops)
+ if (!ops || ops->currcon < 0 || vt_cons[ops->currcon]->vc_mode !=
+ KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info)
return;
vc = vc_cons[ops->currcon].d;
- if (ops->currcon < 0 || vt_cons[ops->currcon]->vc_mode !=
- KD_TEXT)
- return;
p = &fb_display[vc->vc_num];
info->var.xoffset = info->var.yoffset = p->yscroll = 0;
@@ -2665,6 +2641,32 @@
return ret;
}
+static void fbcon_fb_blanked(struct fb_info *info, int blank)
+{
+ struct fbcon_ops *ops = info->fbcon_par;
+ int valid = 1;
+
+ if (!ops || ops->currcon < 0 ||
+ vt_cons[ops->currcon]->vc_mode != KD_TEXT ||
+ registered_fb[con2fb_map[ops->currcon]] != info)
+ valid = 0;
+
+ if (valid) {
+ struct vc_data *vc;
+
+ vc = vc_cons[ops->currcon].d;
+
+ if (CON_IS_VISIBLE(vc)) {
+ ops->blank_state = blank;
+
+ if (blank)
+ do_blank_screen(0);
+ else
+ do_unblank_screen(0);
+ }
+ }
+}
+
static int fbcon_event_notify(struct notifier_block *self,
unsigned long action, void *data)
{
@@ -2699,6 +2701,9 @@
case FB_EVENT_GET_CONSOLE_MAP:
con2fb = event->data;
con2fb->framebuffer = con2fb_map[con2fb->console - 1];
+ break;
+ case FB_EVENT_BLANK:
+ fbcon_fb_blanked(info, *(int *)event->data);
break;
}
diff -Nru a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
--- a/drivers/video/console/fbcon.h 2004-11-17 18:15:17 +08:00
+++ b/drivers/video/console/fbcon.h 2004-11-29 05:42:49 +08:00
@@ -66,6 +66,7 @@
int currcon; /* Current VC. */
int cursor_flash;
int cursor_reset;
+ int blank_state;
char *cursor_data;
};
/*
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c 2004-12-21 05:44:01 +08:00
+++ b/drivers/video/fbmem.c 2004-12-21 22:44:55 +08:00
@@ -730,10 +730,10 @@
!list_empty(&info->modelist))
fb_add_videomode(&mode, &info->modelist);
- if (info->flags & FBINFO_MISC_MODECHANGEUSER) {
+ if (info->flags & FBINFO_MISC_USEREVENT) {
struct fb_event event;
- info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
+ info->flags &= ~FBINFO_MISC_USEREVENT;
event.info = info;
notifier_call_chain(&fb_notifier_list,
FB_EVENT_MODE_CHANGE, &event);
@@ -746,15 +746,23 @@
int
fb_blank(struct fb_info *info, int blank)
{
- int err = -EINVAL;
-
+ int ret = -EINVAL;
+
if (blank > FB_BLANK_POWERDOWN)
blank = FB_BLANK_POWERDOWN;
if (info->fbops->fb_blank)
- err = info->fbops->fb_blank(blank, info);
+ ret = info->fbops->fb_blank(blank, info);
+
+ if (!ret) {
+ struct fb_event event;
+
+ event.info = info;
+ event.data = ␣
+ notifier_call_chain(&fb_notifier_list, FB_EVENT_BLANK, &event);
+ }
- return err;
+ return ret;
}
static int
@@ -782,9 +790,9 @@
if (copy_from_user(&var, argp, sizeof(var)))
return -EFAULT;
acquire_console_sem();
- info->flags |= FBINFO_MISC_MODECHANGEUSER;
+ info->flags |= FBINFO_MISC_USEREVENT;
i = fb_set_var(info, &var);
- info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
+ info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
if (i) return i;
if (copy_to_user(argp, &var, sizeof(var)))
@@ -846,7 +854,9 @@
&event);
case FBIOBLANK:
acquire_console_sem();
+ info->flags |= FBINFO_MISC_USEREVENT;
i = fb_blank(info, arg);
+ info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
return i;
default:
diff -Nru a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h 2004-11-10 06:15:14 +08:00
+++ b/include/linux/fb.h 2004-12-21 05:51:16 +08:00
@@ -488,7 +488,8 @@
#define FB_EVENT_GET_CONSOLE_MAP 0x06
/* set console to framebuffer mapping */
#define FB_EVENT_SET_CONSOLE_MAP 0x07
-
+/* A display blank is requested */
+#define FB_EVENT_BLANK 0x08
struct fb_event {
struct fb_info *info;
@@ -690,7 +691,7 @@
#define FBINFO_HWACCEL_YPAN 0x2000 /* optional */
#define FBINFO_HWACCEL_YWRAP 0x4000 /* optional */
-#define FBINFO_MISC_MODECHANGEUSER 0x10000 /* mode change request
+#define FBINFO_MISC_USEREVENT 0x10000 /* event request
from userspace */
#define FBINFO_MISC_MODESWITCH 0x20000 /* mode switch */
#define FBINFO_MISC_MODESWITCHLATE 0x40000 /* init hardware later */
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
Linux-fbdev-devel mailing list
Linux-fbdev-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic