All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2] allow multiple concurrent visible displays
@ 2011-09-03  1:29 ` Florian Tobias Schandinat
  0 siblings, 0 replies; 10+ messages in thread
From: Florian Tobias Schandinat @ 2011-09-03  1:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fbdev, Greg Kroah-Hartman, Dave Airlie, Arnd Bergmann,
	Bernie Thompson, Martin Decky, Florian Tobias Schandinat

Hi all,

this is the second version of my multi-display support.

Compared to the first version:
The bug reported in the first patch that prevented booting when 
"fbcon=cmap:01" was given is fixed (annoying NULL pointer in vc)
and a dummy vc_display_fg management was added to prevent 
modifying vc structures we do not "own".
The second patch is new and a hack that allows graphic and console 
applications to work concurrently.

Background:
At the moment only one display (in multi-display setups) will be 
updated when
(1) multiple console applications run on different displays
(2) a graphic application runs in the active vt on one display and a 
    console application on another display
(3) multiple graphic (framebuffer) applications run on different
    displays (usually)

The first patch fixes (1) and I'm pretty happy with it. Works well 
for me except rarely cursor visibility glitches but that might be a 
bug somewhere else.

(2) requires some sort of policy change. At the moment we forbid 
any console from working just because on one vt a graphic 
application started. Obviously that's not what I want and also not 
what most applications require. Therefore changing it to only allow 
the application to use the graphic resource associated with the vt 
it switches to KD_GRAPHIC seems reasonable to me. If there are 
concerns about compatiblity we could make this change an option or 
introduce a new KD_PGRAPHICS which behaves as I want (though the 
last one would be ugly and require changing all userspace to work).
My second patch gives this functionality but I do not expect it to 
be acceptable as is. At first I wanted to revert f700d6e5 but for 
some reason the result did not even boot so I hacked my way around 
it. Basically my question here aside the policy change is why do we 
blank when entering graphics mode and why do we not allow updates 
to other consoles when one is blanked?

(3) is a completly different beast which will probably require 
changes in userspace applications. Most framebuffer applications at 
the moment just access the framebuffer if they are in the current 
vt and stop on vt change. To make this working concurrently the 
applications would need a way to get a notification when its 
visibility changes. As this one requires much more work and thought 
than the (1) and (2) I'll at first concentrate on solving those.
But if anyone has any suggestions on this one I'd be verry happy.


Best regards,

Florian Tobias Schandinat


Florian Tobias Schandinat (2):
  fbdev: allow multiple concurrent visible consoles
  vt: dirty hack

 drivers/tty/vt/vt.c           |    4 +---
 drivers/video/console/fbcon.c |   34 ++++++++++++++++++++++++++++++----
 drivers/video/console/fbcon.h |    1 +
 3 files changed, 32 insertions(+), 7 deletions(-)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [RFC v2] allow multiple concurrent visible displays
@ 2011-09-03  1:29 ` Florian Tobias Schandinat
  0 siblings, 0 replies; 10+ messages in thread
From: Florian Tobias Schandinat @ 2011-09-03  1:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fbdev, Greg Kroah-Hartman, Dave Airlie, Arnd Bergmann,
	Bernie Thompson, Martin Decky, Florian Tobias Schandinat

Hi all,

this is the second version of my multi-display support.

Compared to the first version:
The bug reported in the first patch that prevented booting when 
"fbcon=cmap:01" was given is fixed (annoying NULL pointer in vc)
and a dummy vc_display_fg management was added to prevent 
modifying vc structures we do not "own".
The second patch is new and a hack that allows graphic and console 
applications to work concurrently.

Background:
At the moment only one display (in multi-display setups) will be 
updated when
(1) multiple console applications run on different displays
(2) a graphic application runs in the active vt on one display and a 
    console application on another display
(3) multiple graphic (framebuffer) applications run on different
    displays (usually)

The first patch fixes (1) and I'm pretty happy with it. Works well 
for me except rarely cursor visibility glitches but that might be a 
bug somewhere else.

(2) requires some sort of policy change. At the moment we forbid 
any console from working just because on one vt a graphic 
application started. Obviously that's not what I want and also not 
what most applications require. Therefore changing it to only allow 
the application to use the graphic resource associated with the vt 
it switches to KD_GRAPHIC seems reasonable to me. If there are 
concerns about compatiblity we could make this change an option or 
introduce a new KD_PGRAPHICS which behaves as I want (though the 
last one would be ugly and require changing all userspace to work).
My second patch gives this functionality but I do not expect it to 
be acceptable as is. At first I wanted to revert f700d6e5 but for 
some reason the result did not even boot so I hacked my way around 
it. Basically my question here aside the policy change is why do we 
blank when entering graphics mode and why do we not allow updates 
to other consoles when one is blanked?

(3) is a completly different beast which will probably require 
changes in userspace applications. Most framebuffer applications at 
the moment just access the framebuffer if they are in the current 
vt and stop on vt change. To make this working concurrently the 
applications would need a way to get a notification when its 
visibility changes. As this one requires much more work and thought 
than the (1) and (2) I'll at first concentrate on solving those.
But if anyone has any suggestions on this one I'd be verry happy.


Best regards,

Florian Tobias Schandinat


Florian Tobias Schandinat (2):
  fbdev: allow multiple concurrent visible consoles
  vt: dirty hack

 drivers/tty/vt/vt.c           |    4 +---
 drivers/video/console/fbcon.c |   34 ++++++++++++++++++++++++++++++----
 drivers/video/console/fbcon.h |    1 +
 3 files changed, 32 insertions(+), 7 deletions(-)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/2] fbdev: allow multiple concurrent visible consoles
  2011-09-03  1:29 ` Florian Tobias Schandinat
@ 2011-09-03  1:29   ` Florian Tobias Schandinat
  -1 siblings, 0 replies; 10+ messages in thread
From: Florian Tobias Schandinat @ 2011-09-03  1:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fbdev, Greg Kroah-Hartman, Dave Airlie, Arnd Bergmann,
	Bernie Thompson, Martin Decky, Florian Tobias Schandinat

This patch allows having multiple visible consoles that receive
display updates. For example one can have running "top" to monitor
the system on fb0 and at the same time work on a shell on fb1.
At the moment that works only with consoles, not with console and
graphical application nor with two graphical applications.

Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
---
 drivers/video/console/fbcon.c |   34 ++++++++++++++++++++++++++++++----
 drivers/video/console/fbcon.h |    1 +
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 8745637..ce9a686 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -94,6 +94,7 @@ enum {
 };
 
 static struct display fb_display[MAX_NR_CONSOLES];
+static struct vc_data *dummy_fg;
 
 static signed char con2fb_map[MAX_NR_CONSOLES];
 static signed char con2fb_map_boot[MAX_NR_CONSOLES];
@@ -816,7 +817,8 @@ static int set_con2fb_map(int unit, int newidx, int user)
 	int oldidx = con2fb_map[unit];
 	struct fb_info *info = registered_fb[newidx];
 	struct fb_info *oldinfo = NULL;
- 	int found, err = 0;
+	struct fbcon_ops *ops;
+	int found, err = 0, visible = vc && CON_IS_VISIBLE(vc);
 
 	if (oldidx == newidx)
 		return 0;
@@ -839,6 +841,15 @@ static int set_con2fb_map(int unit, int newidx, int user)
 	if (!err && !found)
  		err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
 
+	if (!err && vc && oldinfo && oldinfo->fbcon_par) {
+		ops = oldinfo->fbcon_par;
+		if (vc->vc_display_fg == &ops->vc_fg) {
+			if (CON_IS_VISIBLE(vc))
+				ops->vc_fg = NULL;
+
+			vc->vc_display_fg = &dummy_fg;
+		}
+	}
 
 	/*
 	 * If old fb is not mapped to any of the consoles,
@@ -852,6 +863,13 @@ static int set_con2fb_map(int unit, int newidx, int user)
  		int show_logo = (fg_console == 0 && !user &&
  				 logo_shown != FBCON_LOGO_DONTSHOW);
 
+		ops = info->fbcon_par;
+		if (!ops->vc_fg || visible)
+			ops->vc_fg = vc;
+
+		if (vc && vc->vc_display_fg == &dummy_fg)
+			vc->vc_display_fg = &ops->vc_fg;
+
  		if (!found)
  			fbcon_add_cursor_timer(info);
  		con2fb_map_boot[unit] = newidx;
@@ -1023,8 +1041,10 @@ static void fbcon_init(struct vc_data *vc, int init)
 	int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;
 	int cap, ret;
 
-	if (info_idx == -1 || info == NULL)
-	    return;
+	if (info_idx == -1 || info == NULL) {
+		vc->vc_display_fg = &dummy_fg;
+		return;
+	}
 
 	cap = info->flags;
 
@@ -1089,6 +1109,10 @@ static void fbcon_init(struct vc_data *vc, int init)
 		con_copy_unimap(vc, svc);
 
 	ops = info->fbcon_par;
+	if (!ops->vc_fg)
+		ops->vc_fg = vc;
+
+	vc->vc_display_fg = &ops->vc_fg;
 	p->con_rotate = initial_rotation;
 	set_blitting_type(vc, info);
 
@@ -1184,8 +1208,10 @@ static void fbcon_deinit(struct vc_data *vc)
 	if (!ops)
 		goto finished;
 
-	if (CON_IS_VISIBLE(vc))
+	if (CON_IS_VISIBLE(vc)) {
 		fbcon_del_cursor_timer(info);
+		ops->vc_fg = NULL;
+	}
 
 	ops->flags &= ~FBCON_FLAGS_INIT;
 finished:
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 6bd2e0c..adc7316 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -69,6 +69,7 @@ struct fbcon_ops {
 	struct timer_list cursor_timer; /* Cursor timer */
 	struct fb_cursor cursor_state;
 	struct display *p;
+	struct vc_data *vc_fg;
         int    currcon;	                /* Current VC. */
 	int    cursor_flash;
 	int    cursor_reset;
-- 
1.6.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 1/2] fbdev: allow multiple concurrent visible consoles
@ 2011-09-03  1:29   ` Florian Tobias Schandinat
  0 siblings, 0 replies; 10+ messages in thread
From: Florian Tobias Schandinat @ 2011-09-03  1:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fbdev, Greg Kroah-Hartman, Dave Airlie, Arnd Bergmann,
	Bernie Thompson, Martin Decky, Florian Tobias Schandinat

This patch allows having multiple visible consoles that receive
display updates. For example one can have running "top" to monitor
the system on fb0 and at the same time work on a shell on fb1.
At the moment that works only with consoles, not with console and
graphical application nor with two graphical applications.

Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
---
 drivers/video/console/fbcon.c |   34 ++++++++++++++++++++++++++++++----
 drivers/video/console/fbcon.h |    1 +
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 8745637..ce9a686 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -94,6 +94,7 @@ enum {
 };
 
 static struct display fb_display[MAX_NR_CONSOLES];
+static struct vc_data *dummy_fg;
 
 static signed char con2fb_map[MAX_NR_CONSOLES];
 static signed char con2fb_map_boot[MAX_NR_CONSOLES];
@@ -816,7 +817,8 @@ static int set_con2fb_map(int unit, int newidx, int user)
 	int oldidx = con2fb_map[unit];
 	struct fb_info *info = registered_fb[newidx];
 	struct fb_info *oldinfo = NULL;
- 	int found, err = 0;
+	struct fbcon_ops *ops;
+	int found, err = 0, visible = vc && CON_IS_VISIBLE(vc);
 
 	if (oldidx = newidx)
 		return 0;
@@ -839,6 +841,15 @@ static int set_con2fb_map(int unit, int newidx, int user)
 	if (!err && !found)
  		err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
 
+	if (!err && vc && oldinfo && oldinfo->fbcon_par) {
+		ops = oldinfo->fbcon_par;
+		if (vc->vc_display_fg = &ops->vc_fg) {
+			if (CON_IS_VISIBLE(vc))
+				ops->vc_fg = NULL;
+
+			vc->vc_display_fg = &dummy_fg;
+		}
+	}
 
 	/*
 	 * If old fb is not mapped to any of the consoles,
@@ -852,6 +863,13 @@ static int set_con2fb_map(int unit, int newidx, int user)
  		int show_logo = (fg_console = 0 && !user &&
  				 logo_shown != FBCON_LOGO_DONTSHOW);
 
+		ops = info->fbcon_par;
+		if (!ops->vc_fg || visible)
+			ops->vc_fg = vc;
+
+		if (vc && vc->vc_display_fg = &dummy_fg)
+			vc->vc_display_fg = &ops->vc_fg;
+
  		if (!found)
  			fbcon_add_cursor_timer(info);
  		con2fb_map_boot[unit] = newidx;
@@ -1023,8 +1041,10 @@ static void fbcon_init(struct vc_data *vc, int init)
 	int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;
 	int cap, ret;
 
-	if (info_idx = -1 || info = NULL)
-	    return;
+	if (info_idx = -1 || info = NULL) {
+		vc->vc_display_fg = &dummy_fg;
+		return;
+	}
 
 	cap = info->flags;
 
@@ -1089,6 +1109,10 @@ static void fbcon_init(struct vc_data *vc, int init)
 		con_copy_unimap(vc, svc);
 
 	ops = info->fbcon_par;
+	if (!ops->vc_fg)
+		ops->vc_fg = vc;
+
+	vc->vc_display_fg = &ops->vc_fg;
 	p->con_rotate = initial_rotation;
 	set_blitting_type(vc, info);
 
@@ -1184,8 +1208,10 @@ static void fbcon_deinit(struct vc_data *vc)
 	if (!ops)
 		goto finished;
 
-	if (CON_IS_VISIBLE(vc))
+	if (CON_IS_VISIBLE(vc)) {
 		fbcon_del_cursor_timer(info);
+		ops->vc_fg = NULL;
+	}
 
 	ops->flags &= ~FBCON_FLAGS_INIT;
 finished:
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 6bd2e0c..adc7316 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -69,6 +69,7 @@ struct fbcon_ops {
 	struct timer_list cursor_timer; /* Cursor timer */
 	struct fb_cursor cursor_state;
 	struct display *p;
+	struct vc_data *vc_fg;
         int    currcon;	                /* Current VC. */
 	int    cursor_flash;
 	int    cursor_reset;
-- 
1.6.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/2] vt: dirty hack
  2011-09-03  1:29 ` Florian Tobias Schandinat
@ 2011-09-03  1:29   ` Florian Tobias Schandinat
  -1 siblings, 0 replies; 10+ messages in thread
From: Florian Tobias Schandinat @ 2011-09-03  1:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fbdev, Greg Kroah-Hartman, Dave Airlie, Arnd Bergmann,
	Bernie Thompson, Martin Decky, Florian Tobias Schandinat

---
 drivers/tty/vt/vt.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b3915b7..8332004 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3740,7 +3740,6 @@ void do_blank_screen(int entering_gfx)
 		hide_cursor(vc);
 		save_screen(vc);
 		vc->vc_sw->con_blank(vc, -1, 1);
-		console_blanked = fg_console + 1;
 		blank_state = blank_off;
 		set_origin(vc);
 		return;
@@ -3752,7 +3751,6 @@ void do_blank_screen(int entering_gfx)
 
 	/* don't blank graphics */
 	if (vc->vc_mode != KD_TEXT) {
-		console_blanked = fg_console + 1;
 		return;
 	}
 
@@ -3795,7 +3793,7 @@ void do_unblank_screen(int leaving_gfx)
 	WARN_CONSOLE_UNLOCKED();
 
 	ignore_poke = 0;
-	if (!console_blanked)
+	if (!console_blanked && !leaving_gfx)
 		return;
 	if (!vc_cons_allocated(fg_console)) {
 		/* impossible */
-- 
1.6.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/2] vt: dirty hack
@ 2011-09-03  1:29   ` Florian Tobias Schandinat
  0 siblings, 0 replies; 10+ messages in thread
From: Florian Tobias Schandinat @ 2011-09-03  1:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fbdev, Greg Kroah-Hartman, Dave Airlie, Arnd Bergmann,
	Bernie Thompson, Martin Decky, Florian Tobias Schandinat

---
 drivers/tty/vt/vt.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b3915b7..8332004 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3740,7 +3740,6 @@ void do_blank_screen(int entering_gfx)
 		hide_cursor(vc);
 		save_screen(vc);
 		vc->vc_sw->con_blank(vc, -1, 1);
-		console_blanked = fg_console + 1;
 		blank_state = blank_off;
 		set_origin(vc);
 		return;
@@ -3752,7 +3751,6 @@ void do_blank_screen(int entering_gfx)
 
 	/* don't blank graphics */
 	if (vc->vc_mode != KD_TEXT) {
-		console_blanked = fg_console + 1;
 		return;
 	}
 
@@ -3795,7 +3793,7 @@ void do_unblank_screen(int leaving_gfx)
 	WARN_CONSOLE_UNLOCKED();
 
 	ignore_poke = 0;
-	if (!console_blanked)
+	if (!console_blanked && !leaving_gfx)
 		return;
 	if (!vc_cons_allocated(fg_console)) {
 		/* impossible */
-- 
1.6.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] vt: dirty hack
  2011-09-03  1:29   ` Florian Tobias Schandinat
@ 2011-09-03 10:25     ` Alan Cox
  -1 siblings, 0 replies; 10+ messages in thread
From: Alan Cox @ 2011-09-03 10:25 UTC (permalink / raw)
  To: Florian Tobias Schandinat
  Cc: linux-kernel, linux-fbdev, Greg Kroah-Hartman, Dave Airlie,
	Arnd Bergmann, Bernie Thompson, Martin Decky

On Sat,  3 Sep 2011 01:29:21 +0000
Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:

All of the vt stuff wants doing properly not as hacks.

I think the fundamental change you need is to instroduce some sort of
vc->group pointer and vc group object that holds all the globals in the
vt layer for each group (ie move fg_console, console_blanked etc).

That can be done in steps, and once done you can then start to use
vc->group-> within the fbcon driver and possibly also have a per fb
group data attached to vc->group->fb or similar.

Hacks are fine for early prototyping but doing it right means thinking
about the data structures you ultimately need so that existing systems
work, multi-monitor continues to work and you can do proper multi-console
stuff.

I'm all for it happening done right, and some things like being able to
attach an fb console to arbitary GEM objects would allow very nice
integration of the console into things like Wayland.

Alan

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] vt: dirty hack
@ 2011-09-03 10:25     ` Alan Cox
  0 siblings, 0 replies; 10+ messages in thread
From: Alan Cox @ 2011-09-03 10:25 UTC (permalink / raw)
  To: Florian Tobias Schandinat
  Cc: linux-kernel, linux-fbdev, Greg Kroah-Hartman, Dave Airlie,
	Arnd Bergmann, Bernie Thompson, Martin Decky

On Sat,  3 Sep 2011 01:29:21 +0000
Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:

All of the vt stuff wants doing properly not as hacks.

I think the fundamental change you need is to instroduce some sort of
vc->group pointer and vc group object that holds all the globals in the
vt layer for each group (ie move fg_console, console_blanked etc).

That can be done in steps, and once done you can then start to use
vc->group-> within the fbcon driver and possibly also have a per fb
group data attached to vc->group->fb or similar.

Hacks are fine for early prototyping but doing it right means thinking
about the data structures you ultimately need so that existing systems
work, multi-monitor continues to work and you can do proper multi-console
stuff.

I'm all for it happening done right, and some things like being able to
attach an fb console to arbitary GEM objects would allow very nice
integration of the console into things like Wayland.

Alan

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] vt: dirty hack
  2011-09-03 10:25     ` Alan Cox
@ 2011-09-03 16:36       ` Florian Tobias Schandinat
  -1 siblings, 0 replies; 10+ messages in thread
From: Florian Tobias Schandinat @ 2011-09-03 16:36 UTC (permalink / raw)
  To: Alan Cox
  Cc: Florian Tobias Schandinat, linux-kernel, linux-fbdev,
	Greg Kroah-Hartman, Dave Airlie, Arnd Bergmann, Bernie Thompson,
	Martin Decky

Hi Alan,

On 09/03/2011 10:25 AM, Alan Cox wrote:
> On Sat,  3 Sep 2011 01:29:21 +0000
> Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
> 
> All of the vt stuff wants doing properly not as hacks.
> 
> I think the fundamental change you need is to instroduce some sort of
> vc->group pointer and vc group object that holds all the globals in the
> vt layer for each group (ie move fg_console, console_blanked etc).

It sounds like a good idea. But I doubt that I need all of them for what
I want to achieve. For example, I think fg_console should be a console 
that gets keyboard data, but in my setup I have only one keyboard so that 
would not be needed. Note that the concept of visibility is already 
available for drivers via vc_display_fg which is used by CON_IS_VISIBLE()
my problem is just that it does not help if no updates are performed 
because everything is blanked (due to the lack of per display blanking).
Still your suggestion would be interesting to pursue later on to build 
multiple terminals, I guess Bernie would like that.

> That can be done in steps, and once done you can then start to use
> vc->group-> within the fbcon driver and possibly also have a per fb
> group data attached to vc->group->fb or similar.

Okay, I tried to implement this for blanking as it was already done for 
vc_display_fg, see the patch below. Does it look better?

> Hacks are fine for early prototyping but doing it right means thinking
> about the data structures you ultimately need so that existing systems
> work, multi-monitor continues to work and you can do proper multi-console
> stuff.
>
> I'm all for it happening done right, and some things like being able to
> attach an fb console to arbitary GEM objects would allow very nice
> integration of the console into things like Wayland.
> 
> Alan


Thanks,

Florian Tobias Schandinat


vt: allow per display blanking

At the moment blanking always affects all displays as it is done in
a global variable. This patch allows display driver to override it
and have their private blanking. The design is pretty much the same
as for vc_display_fg which is used for implementing per
driver/display visibility.
---
 drivers/tty/vt/vt.c            |   32 ++++++++++++++++----------------
 drivers/video/console/fbcon.c  |    9 ++++++---
 drivers/video/console/fbcon.h  |    1 +
 include/linux/console_struct.h |    1 +
 4 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b3915b7..bc42f8e 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -277,7 +277,7 @@ static void notify_update(struct vc_data *vc)
 #ifdef VT_BUF_VRAM_ONLY
 #define DO_UPDATE(vc)	0
 #else
-#define DO_UPDATE(vc)	(CON_IS_VISIBLE(vc) && !console_blanked)
+#define DO_UPDATE(vc)	(CON_IS_VISIBLE(vc) && !*vc->vc_display_blanked)
 #endif
 
 static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
@@ -619,7 +619,7 @@ static void hide_cursor(struct vc_data *vc)
 
 static void set_cursor(struct vc_data *vc)
 {
-	if (!IS_FG(vc) || console_blanked ||
+	if (!IS_FG(vc) || *vc->vc_display_blanked ||
 	    vc->vc_mode == KD_GRAPHICS)
 		return;
 	if (vc->vc_deccm) {
@@ -753,6 +753,7 @@ static void visual_init(struct vc_data *vc, int num, int init)
 	__module_get(vc->vc_sw->owner);
 	vc->vc_num = num;
 	vc->vc_display_fg = &master_display_fg;
+	vc->vc_display_blanked = &console_blanked;
 	vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
 	vc->vc_uni_pagedir = 0;
 	vc->vc_hi_font_mask = 0;
@@ -2684,7 +2685,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
 			console_unlock();
 			break;
 		case TIOCL_BLANKEDSCREEN:
-			ret = console_blanked;
+			ret = *vc_cons[fg_console].d->vc_display_blanked;
 			break;
 		default:
 			ret = -EINVAL;
@@ -3454,9 +3455,9 @@ int con_debug_enter(struct vc_data *vc)
 	saved_last_console = last_console;
 	saved_want_console = want_console;
 	saved_vc_mode = vc->vc_mode;
-	saved_console_blanked = console_blanked;
+	saved_console_blanked = *vc->vc_display_blanked;
 	vc->vc_mode = KD_TEXT;
-	console_blanked = 0;
+	*vc->vc_display_blanked = 0;
 	if (vc->vc_sw->con_debug_enter)
 		ret = vc->vc_sw->con_debug_enter(vc);
 #ifdef CONFIG_KGDB_KDB
@@ -3498,10 +3499,9 @@ int con_debug_leave(void)
 	fg_console = saved_fg_console;
 	last_console = saved_last_console;
 	want_console = saved_want_console;
-	console_blanked = saved_console_blanked;
-	vc_cons[fg_console].d->vc_mode = saved_vc_mode;
-
 	vc = vc_cons[fg_console].d;
+	*vc->vc_display_blanked = saved_console_blanked;
+	vc->vc_mode = saved_vc_mode;
 	if (vc->vc_sw->con_debug_leave)
 		ret = vc->vc_sw->con_debug_leave(vc);
 	return ret;
@@ -3727,7 +3727,7 @@ void do_blank_screen(int entering_gfx)
 
 	WARN_CONSOLE_UNLOCKED();
 
-	if (console_blanked) {
+	if (*vc->vc_display_blanked) {
 		if (blank_state == blank_vesa_wait) {
 			blank_state = blank_off;
 			vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
@@ -3740,7 +3740,7 @@ void do_blank_screen(int entering_gfx)
 		hide_cursor(vc);
 		save_screen(vc);
 		vc->vc_sw->con_blank(vc, -1, 1);
-		console_blanked = fg_console + 1;
+		*vc->vc_display_blanked = fg_console + 1;
 		blank_state = blank_off;
 		set_origin(vc);
 		return;
@@ -3752,7 +3752,7 @@ void do_blank_screen(int entering_gfx)
 
 	/* don't blank graphics */
 	if (vc->vc_mode != KD_TEXT) {
-		console_blanked = fg_console + 1;
+		*vc->vc_display_blanked = fg_console + 1;
 		return;
 	}
 
@@ -3763,7 +3763,7 @@ void do_blank_screen(int entering_gfx)
 	save_screen(vc);
 	/* In case we need to reset origin, blanking hook returns 1 */
 	i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
-	console_blanked = fg_console + 1;
+	*vc->vc_display_blanked = fg_console + 1;
 	if (i)
 		set_origin(vc);
 
@@ -3795,8 +3795,6 @@ void do_unblank_screen(int leaving_gfx)
 	WARN_CONSOLE_UNLOCKED();
 
 	ignore_poke = 0;
-	if (!console_blanked)
-		return;
 	if (!vc_cons_allocated(fg_console)) {
 		/* impossible */
 		pr_warning("unblank_screen: tty %d not allocated ??\n",
@@ -3804,6 +3802,8 @@ void do_unblank_screen(int leaving_gfx)
 		return;
 	}
 	vc = vc_cons[fg_console].d;
+	if (!*vc->vc_display_blanked)
+		return;
 	/* Try to unblank in oops case too */
 	if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
 		return; /* but leave console_blanked != 0 */
@@ -3813,7 +3813,7 @@ void do_unblank_screen(int leaving_gfx)
 		blank_state = blank_normal_wait;
 	}
 
-	console_blanked = 0;
+	*vc->vc_display_blanked = 0;
 	if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
 		/* Low-level driver cannot restore -> do it ourselves */
 		update_screen(vc);
@@ -3871,7 +3871,7 @@ void poke_blanked_console(void)
 
 	if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS)
 		return;
-	if (console_blanked)
+	if (*vc_cons[fg_console].d->vc_display_blanked)
 		unblank_screen();
 	else if (blankinterval) {
 		mod_timer(&console_timer, jiffies + (blankinterval * HZ));
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index ce9a686..bb2bc13 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -294,7 +294,7 @@ static int get_color(struct vc_data *vc, struct fb_info *info,
 	int depth = fb_get_color_depth(&info->var, &info->fix);
 	int color = 0;
 
-	if (console_blanked) {
+	if (*vc->vc_display_blanked) {
 		unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 
 		c = vc->vc_video_erase_char & charmask;
@@ -312,7 +312,7 @@ static int get_color(struct vc_data *vc, struct fb_info *info,
 		int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
 		int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
 
-		if (console_blanked)
+		if (*vc->vc_display_blanked)
 			fg = bg;
 
 		color = (is_fg) ? fg : bg;
@@ -867,8 +867,10 @@ static int set_con2fb_map(int unit, int newidx, int user)
 		if (!ops->vc_fg || visible)
 			ops->vc_fg = vc;
 
-		if (vc && vc->vc_display_fg == &dummy_fg)
+		if (vc && vc->vc_display_fg == &dummy_fg) {
 			vc->vc_display_fg = &ops->vc_fg;
+			vc->vc_display_blanked = &ops->vc_blanked;
+		}
 
  		if (!found)
  			fbcon_add_cursor_timer(info);
@@ -1113,6 +1115,7 @@ static void fbcon_init(struct vc_data *vc, int init)
 		ops->vc_fg = vc;
 
 	vc->vc_display_fg = &ops->vc_fg;
+	vc->vc_display_blanked = &ops->vc_blanked;
 	p->con_rotate = initial_rotation;
 	set_blitting_type(vc, info);
 
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index adc7316..8d5f173 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -70,6 +70,7 @@ struct fbcon_ops {
 	struct fb_cursor cursor_state;
 	struct display *p;
 	struct vc_data *vc_fg;
+	int    vc_blanked;
         int    currcon;	                /* Current VC. */
 	int    cursor_flash;
 	int    cursor_reset;
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 7f0c329..086e623 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -104,6 +104,7 @@ struct vc_data {
 	unsigned int	vc_bell_pitch;		/* Console bell pitch */
 	unsigned int	vc_bell_duration;	/* Console bell duration */
 	struct vc_data **vc_display_fg;		/* [!] Ptr to var holding fg console for this display */
+		 int	*vc_display_blanked;
 	unsigned long	vc_uni_pagedir;
 	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
 	bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
-- 
1.6.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/2] vt: dirty hack
@ 2011-09-03 16:36       ` Florian Tobias Schandinat
  0 siblings, 0 replies; 10+ messages in thread
From: Florian Tobias Schandinat @ 2011-09-03 16:36 UTC (permalink / raw)
  To: Alan Cox
  Cc: Florian Tobias Schandinat, linux-kernel, linux-fbdev,
	Greg Kroah-Hartman, Dave Airlie, Arnd Bergmann, Bernie Thompson,
	Martin Decky

Hi Alan,

On 09/03/2011 10:25 AM, Alan Cox wrote:
> On Sat,  3 Sep 2011 01:29:21 +0000
> Florian Tobias Schandinat <FlorianSchandinat@gmx.de> wrote:
> 
> All of the vt stuff wants doing properly not as hacks.
> 
> I think the fundamental change you need is to instroduce some sort of
> vc->group pointer and vc group object that holds all the globals in the
> vt layer for each group (ie move fg_console, console_blanked etc).

It sounds like a good idea. But I doubt that I need all of them for what
I want to achieve. For example, I think fg_console should be a console 
that gets keyboard data, but in my setup I have only one keyboard so that 
would not be needed. Note that the concept of visibility is already 
available for drivers via vc_display_fg which is used by CON_IS_VISIBLE()
my problem is just that it does not help if no updates are performed 
because everything is blanked (due to the lack of per display blanking).
Still your suggestion would be interesting to pursue later on to build 
multiple terminals, I guess Bernie would like that.

> That can be done in steps, and once done you can then start to use
> vc->group-> within the fbcon driver and possibly also have a per fb
> group data attached to vc->group->fb or similar.

Okay, I tried to implement this for blanking as it was already done for 
vc_display_fg, see the patch below. Does it look better?

> Hacks are fine for early prototyping but doing it right means thinking
> about the data structures you ultimately need so that existing systems
> work, multi-monitor continues to work and you can do proper multi-console
> stuff.
>
> I'm all for it happening done right, and some things like being able to
> attach an fb console to arbitary GEM objects would allow very nice
> integration of the console into things like Wayland.
> 
> Alan


Thanks,

Florian Tobias Schandinat


vt: allow per display blanking

At the moment blanking always affects all displays as it is done in
a global variable. This patch allows display driver to override it
and have their private blanking. The design is pretty much the same
as for vc_display_fg which is used for implementing per
driver/display visibility.
---
 drivers/tty/vt/vt.c            |   32 ++++++++++++++++----------------
 drivers/video/console/fbcon.c  |    9 ++++++---
 drivers/video/console/fbcon.h  |    1 +
 include/linux/console_struct.h |    1 +
 4 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b3915b7..bc42f8e 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -277,7 +277,7 @@ static void notify_update(struct vc_data *vc)
 #ifdef VT_BUF_VRAM_ONLY
 #define DO_UPDATE(vc)	0
 #else
-#define DO_UPDATE(vc)	(CON_IS_VISIBLE(vc) && !console_blanked)
+#define DO_UPDATE(vc)	(CON_IS_VISIBLE(vc) && !*vc->vc_display_blanked)
 #endif
 
 static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
@@ -619,7 +619,7 @@ static void hide_cursor(struct vc_data *vc)
 
 static void set_cursor(struct vc_data *vc)
 {
-	if (!IS_FG(vc) || console_blanked ||
+	if (!IS_FG(vc) || *vc->vc_display_blanked ||
 	    vc->vc_mode = KD_GRAPHICS)
 		return;
 	if (vc->vc_deccm) {
@@ -753,6 +753,7 @@ static void visual_init(struct vc_data *vc, int num, int init)
 	__module_get(vc->vc_sw->owner);
 	vc->vc_num = num;
 	vc->vc_display_fg = &master_display_fg;
+	vc->vc_display_blanked = &console_blanked;
 	vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
 	vc->vc_uni_pagedir = 0;
 	vc->vc_hi_font_mask = 0;
@@ -2684,7 +2685,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
 			console_unlock();
 			break;
 		case TIOCL_BLANKEDSCREEN:
-			ret = console_blanked;
+			ret = *vc_cons[fg_console].d->vc_display_blanked;
 			break;
 		default:
 			ret = -EINVAL;
@@ -3454,9 +3455,9 @@ int con_debug_enter(struct vc_data *vc)
 	saved_last_console = last_console;
 	saved_want_console = want_console;
 	saved_vc_mode = vc->vc_mode;
-	saved_console_blanked = console_blanked;
+	saved_console_blanked = *vc->vc_display_blanked;
 	vc->vc_mode = KD_TEXT;
-	console_blanked = 0;
+	*vc->vc_display_blanked = 0;
 	if (vc->vc_sw->con_debug_enter)
 		ret = vc->vc_sw->con_debug_enter(vc);
 #ifdef CONFIG_KGDB_KDB
@@ -3498,10 +3499,9 @@ int con_debug_leave(void)
 	fg_console = saved_fg_console;
 	last_console = saved_last_console;
 	want_console = saved_want_console;
-	console_blanked = saved_console_blanked;
-	vc_cons[fg_console].d->vc_mode = saved_vc_mode;
-
 	vc = vc_cons[fg_console].d;
+	*vc->vc_display_blanked = saved_console_blanked;
+	vc->vc_mode = saved_vc_mode;
 	if (vc->vc_sw->con_debug_leave)
 		ret = vc->vc_sw->con_debug_leave(vc);
 	return ret;
@@ -3727,7 +3727,7 @@ void do_blank_screen(int entering_gfx)
 
 	WARN_CONSOLE_UNLOCKED();
 
-	if (console_blanked) {
+	if (*vc->vc_display_blanked) {
 		if (blank_state = blank_vesa_wait) {
 			blank_state = blank_off;
 			vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
@@ -3740,7 +3740,7 @@ void do_blank_screen(int entering_gfx)
 		hide_cursor(vc);
 		save_screen(vc);
 		vc->vc_sw->con_blank(vc, -1, 1);
-		console_blanked = fg_console + 1;
+		*vc->vc_display_blanked = fg_console + 1;
 		blank_state = blank_off;
 		set_origin(vc);
 		return;
@@ -3752,7 +3752,7 @@ void do_blank_screen(int entering_gfx)
 
 	/* don't blank graphics */
 	if (vc->vc_mode != KD_TEXT) {
-		console_blanked = fg_console + 1;
+		*vc->vc_display_blanked = fg_console + 1;
 		return;
 	}
 
@@ -3763,7 +3763,7 @@ void do_blank_screen(int entering_gfx)
 	save_screen(vc);
 	/* In case we need to reset origin, blanking hook returns 1 */
 	i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
-	console_blanked = fg_console + 1;
+	*vc->vc_display_blanked = fg_console + 1;
 	if (i)
 		set_origin(vc);
 
@@ -3795,8 +3795,6 @@ void do_unblank_screen(int leaving_gfx)
 	WARN_CONSOLE_UNLOCKED();
 
 	ignore_poke = 0;
-	if (!console_blanked)
-		return;
 	if (!vc_cons_allocated(fg_console)) {
 		/* impossible */
 		pr_warning("unblank_screen: tty %d not allocated ??\n",
@@ -3804,6 +3802,8 @@ void do_unblank_screen(int leaving_gfx)
 		return;
 	}
 	vc = vc_cons[fg_console].d;
+	if (!*vc->vc_display_blanked)
+		return;
 	/* Try to unblank in oops case too */
 	if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
 		return; /* but leave console_blanked != 0 */
@@ -3813,7 +3813,7 @@ void do_unblank_screen(int leaving_gfx)
 		blank_state = blank_normal_wait;
 	}
 
-	console_blanked = 0;
+	*vc->vc_display_blanked = 0;
 	if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
 		/* Low-level driver cannot restore -> do it ourselves */
 		update_screen(vc);
@@ -3871,7 +3871,7 @@ void poke_blanked_console(void)
 
 	if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode = KD_GRAPHICS)
 		return;
-	if (console_blanked)
+	if (*vc_cons[fg_console].d->vc_display_blanked)
 		unblank_screen();
 	else if (blankinterval) {
 		mod_timer(&console_timer, jiffies + (blankinterval * HZ));
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index ce9a686..bb2bc13 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -294,7 +294,7 @@ static int get_color(struct vc_data *vc, struct fb_info *info,
 	int depth = fb_get_color_depth(&info->var, &info->fix);
 	int color = 0;
 
-	if (console_blanked) {
+	if (*vc->vc_display_blanked) {
 		unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 
 		c = vc->vc_video_erase_char & charmask;
@@ -312,7 +312,7 @@ static int get_color(struct vc_data *vc, struct fb_info *info,
 		int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
 		int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
 
-		if (console_blanked)
+		if (*vc->vc_display_blanked)
 			fg = bg;
 
 		color = (is_fg) ? fg : bg;
@@ -867,8 +867,10 @@ static int set_con2fb_map(int unit, int newidx, int user)
 		if (!ops->vc_fg || visible)
 			ops->vc_fg = vc;
 
-		if (vc && vc->vc_display_fg = &dummy_fg)
+		if (vc && vc->vc_display_fg = &dummy_fg) {
 			vc->vc_display_fg = &ops->vc_fg;
+			vc->vc_display_blanked = &ops->vc_blanked;
+		}
 
  		if (!found)
  			fbcon_add_cursor_timer(info);
@@ -1113,6 +1115,7 @@ static void fbcon_init(struct vc_data *vc, int init)
 		ops->vc_fg = vc;
 
 	vc->vc_display_fg = &ops->vc_fg;
+	vc->vc_display_blanked = &ops->vc_blanked;
 	p->con_rotate = initial_rotation;
 	set_blitting_type(vc, info);
 
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index adc7316..8d5f173 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -70,6 +70,7 @@ struct fbcon_ops {
 	struct fb_cursor cursor_state;
 	struct display *p;
 	struct vc_data *vc_fg;
+	int    vc_blanked;
         int    currcon;	                /* Current VC. */
 	int    cursor_flash;
 	int    cursor_reset;
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 7f0c329..086e623 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -104,6 +104,7 @@ struct vc_data {
 	unsigned int	vc_bell_pitch;		/* Console bell pitch */
 	unsigned int	vc_bell_duration;	/* Console bell duration */
 	struct vc_data **vc_display_fg;		/* [!] Ptr to var holding fg console for this display */
+		 int	*vc_display_blanked;
 	unsigned long	vc_uni_pagedir;
 	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
 	bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
-- 
1.6.3.2


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-09-03 16:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-03  1:29 [RFC v2] allow multiple concurrent visible displays Florian Tobias Schandinat
2011-09-03  1:29 ` Florian Tobias Schandinat
2011-09-03  1:29 ` [PATCH 1/2] fbdev: allow multiple concurrent visible consoles Florian Tobias Schandinat
2011-09-03  1:29   ` Florian Tobias Schandinat
2011-09-03  1:29 ` [PATCH 2/2] vt: dirty hack Florian Tobias Schandinat
2011-09-03  1:29   ` Florian Tobias Schandinat
2011-09-03 10:25   ` Alan Cox
2011-09-03 10:25     ` Alan Cox
2011-09-03 16:36     ` Florian Tobias Schandinat
2011-09-03 16:36       ` Florian Tobias Schandinat

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.