output: save and restore crtc upon (de)activation
The crtc is saved from kmscon_output_activate, and restored from kmscon_output_deactivate. This means that when the program exits, the screen is back to what it was - we don't need to switch back VTs if we started the program from an fbcon, etc. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
25b85f5f26
commit
aacb342092
34
src/output.c
34
src/output.c
@ -72,6 +72,8 @@ struct kmscon_output {
|
|||||||
unsigned int cur_rb;
|
unsigned int cur_rb;
|
||||||
struct render_buffer rb[2];
|
struct render_buffer rb[2];
|
||||||
GLuint fb;
|
GLuint fb;
|
||||||
|
|
||||||
|
drmModeCrtcPtr saved_crtc;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum compositor_state {
|
enum compositor_state {
|
||||||
@ -561,6 +563,8 @@ static void destroy_rb(struct render_buffer *rb,
|
|||||||
* This activates the output in the given mode. This returns -EALREADY if the
|
* This activates the output in the given mode. This returns -EALREADY if the
|
||||||
* output is already activated. To switch modes, deactivate and then reactivate
|
* output is already activated. To switch modes, deactivate and then reactivate
|
||||||
* the output.
|
* the output.
|
||||||
|
* When the output is activated, its previous screen contents and mode are
|
||||||
|
* saved, to be restored when the output is deactivated.
|
||||||
* Returns 0 on success.
|
* Returns 0 on success.
|
||||||
* This does not work if the compositor is asleep.
|
* This does not work if the compositor is asleep.
|
||||||
*/
|
*/
|
||||||
@ -583,15 +587,16 @@ int kmscon_output_activate(struct kmscon_output *output,
|
|||||||
mode = output->modes;
|
mode = output->modes;
|
||||||
|
|
||||||
comp = output->comp;
|
comp = output->comp;
|
||||||
|
output->saved_crtc = drmModeGetCrtc(comp->drm_fd, output->crtc_id);
|
||||||
|
|
||||||
ret = init_rb(&output->rb[0], comp, &mode->info);
|
ret = init_rb(&output->rb[0], comp, &mode->info);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto err_saved;
|
||||||
|
|
||||||
ret = init_rb(&output->rb[1], comp, &mode->info);
|
ret = init_rb(&output->rb[1], comp, &mode->info);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
destroy_rb(&output->rb[0], comp);
|
destroy_rb(&output->rb[0], comp);
|
||||||
return ret;
|
goto err_saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->current = mode;
|
output->current = mode;
|
||||||
@ -625,23 +630,38 @@ err_fb:
|
|||||||
destroy_rb(&output->rb[1], output->comp);
|
destroy_rb(&output->rb[1], output->comp);
|
||||||
output->active = 0;
|
output->active = 0;
|
||||||
output->current = NULL;
|
output->current = NULL;
|
||||||
|
err_saved:
|
||||||
|
if (output->saved_crtc) {
|
||||||
|
drmModeFreeCrtc(output->saved_crtc);
|
||||||
|
output->saved_crtc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deactivate the output. This does not disconnect the output so you can
|
* Deactivate the output. This does not disconnect the output so you can
|
||||||
* reactivate this output again.
|
* reactivate this output again.
|
||||||
|
* When the output is deactivated, the screen contents and mode it had before
|
||||||
|
* it was activated are restored.
|
||||||
*/
|
*/
|
||||||
void kmscon_output_deactivate(struct kmscon_output *output)
|
void kmscon_output_deactivate(struct kmscon_output *output)
|
||||||
{
|
{
|
||||||
if (!output || !output->active)
|
if (!output || !output->active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
if (output->saved_crtc) {
|
||||||
* TODO: Do we need to reset the CRTC/connector here? We delete an
|
drmModeSetCrtc(output->comp->drm_fd,
|
||||||
* active framebuffer here so the crtc will become blank, but instead
|
output->saved_crtc->crtc_id,
|
||||||
* the previous framebuffer should be restored.
|
output->saved_crtc->buffer_id,
|
||||||
*/
|
output->saved_crtc->x,
|
||||||
|
output->saved_crtc->y,
|
||||||
|
&output->conn_id,
|
||||||
|
1,
|
||||||
|
&output->saved_crtc->mode);
|
||||||
|
drmModeFreeCrtc(output->saved_crtc);
|
||||||
|
output->saved_crtc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
glDeleteFramebuffers(1, &output->fb);
|
glDeleteFramebuffers(1, &output->fb);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user