mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-08 16:36:14 +00:00
lib: add helper to set VT graphics mode
Signed-off-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
d2f7a66fee
commit
cf26435be8
199
lib/drmtest.c
199
lib/drmtest.c
@ -38,6 +38,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <linux/kd.h>
|
||||||
|
|
||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "i915_drm.h"
|
#include "i915_drm.h"
|
||||||
@ -1013,3 +1014,201 @@ int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id)
|
|||||||
return pfci.pipe;
|
return pfci.pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_SIGNALS 32
|
||||||
|
#define MAX_EXIT_HANDLERS 5
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
sighandler_t handler;
|
||||||
|
bool installed;
|
||||||
|
} orig_sig[MAX_SIGNALS];
|
||||||
|
|
||||||
|
typedef void (*drmtest_exit_handler_t)(int sig);
|
||||||
|
static drmtest_exit_handler_t exit_handler_fn[MAX_EXIT_HANDLERS];
|
||||||
|
static int exit_handler_count;
|
||||||
|
static bool exit_handler_disabled;
|
||||||
|
static sigset_t saved_sig_mask;
|
||||||
|
static const int handled_signals[] =
|
||||||
|
{ SIGINT, SIGHUP, SIGTERM, SIGQUIT, SIGPIPE, SIGABRT };
|
||||||
|
|
||||||
|
static int install_sig_handler(int sig_num, sighandler_t handler)
|
||||||
|
{
|
||||||
|
orig_sig[sig_num].handler = signal(sig_num, handler);
|
||||||
|
|
||||||
|
if (orig_sig[sig_num].handler == SIG_ERR)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
orig_sig[sig_num].installed = true;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void restore_sig_handler(int sig_num)
|
||||||
|
{
|
||||||
|
if (orig_sig[sig_num].installed)
|
||||||
|
signal(sig_num, orig_sig[sig_num].handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void restore_all_sig_handler(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(orig_sig); i++)
|
||||||
|
restore_sig_handler(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void call_exit_handlers(int sig)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!exit_handler_count) {
|
||||||
|
fprintf(stderr, "no exit handlers?\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < exit_handler_count; i++)
|
||||||
|
exit_handler_fn[i](sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drmtest_atexit_handler(void)
|
||||||
|
{
|
||||||
|
restore_all_sig_handler();
|
||||||
|
|
||||||
|
if (!exit_handler_disabled)
|
||||||
|
call_exit_handlers(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drmtest_sig_handler(int sig)
|
||||||
|
{
|
||||||
|
restore_all_sig_handler();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* exit_handler_disabled is always false here, since when we set it
|
||||||
|
* we also block signals.
|
||||||
|
*/
|
||||||
|
call_exit_handlers(sig);
|
||||||
|
|
||||||
|
raise(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set a handler that will be called either when the process calls exit() or
|
||||||
|
* returns from the main function, or one of the signals in 'handled_signals'
|
||||||
|
* is raised. MAX_EXIT_HANDLERS handlers can be installed, each of which will
|
||||||
|
* be called only once, even if a subsequent signal is raised. If the exit
|
||||||
|
* handlers are called due to a signal, the signal will be re-raised with the
|
||||||
|
* original signal disposition after all handlers returned.
|
||||||
|
*
|
||||||
|
* The handler will be passed the signal number if called due to a signal, or
|
||||||
|
* 0 otherwise.
|
||||||
|
*/
|
||||||
|
static int drmtest_install_exit_handler(drmtest_exit_handler_t fn)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (exit_handler_count == MAX_EXIT_HANDLERS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
exit_handler_fn[exit_handler_count] = fn;
|
||||||
|
exit_handler_count++;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(handled_signals); i++) {
|
||||||
|
if (install_sig_handler(handled_signals[i],
|
||||||
|
drmtest_sig_handler))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atexit(drmtest_atexit_handler))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
restore_all_sig_handler();
|
||||||
|
exit_handler_count--;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drmtest_disable_exit_handler(void)
|
||||||
|
{
|
||||||
|
sigset_t set;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (exit_handler_disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sigemptyset(&set);
|
||||||
|
for (i = 0; i < ARRAY_SIZE(handled_signals); i++)
|
||||||
|
sigaddset(&set, handled_signals[i]);
|
||||||
|
|
||||||
|
if (sigprocmask(SIG_BLOCK, &set, &saved_sig_mask)) {
|
||||||
|
perror("sigprocmask");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_handler_disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drmtest_enable_exit_handler(void)
|
||||||
|
{
|
||||||
|
if (!exit_handler_disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sigprocmask(SIG_SETMASK, &saved_sig_mask, NULL)) {
|
||||||
|
perror("sigprocmask");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_handler_disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static signed long set_vt_mode(unsigned long mode)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
unsigned long prev_mode;
|
||||||
|
|
||||||
|
fd = open("/dev/tty0", O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
prev_mode = 0;
|
||||||
|
if (drmIoctl(fd, KDGETMODE, &prev_mode))
|
||||||
|
goto err;
|
||||||
|
if (drmIoctl(fd, KDSETMODE, (void *)mode))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return prev_mode;
|
||||||
|
err:
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long orig_vt_mode = -1UL;
|
||||||
|
|
||||||
|
static void restore_vt_mode_at_exit(int sig)
|
||||||
|
{
|
||||||
|
if (orig_vt_mode != -1UL)
|
||||||
|
set_vt_mode(orig_vt_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the VT to graphics mode and install an exit handler to restore the
|
||||||
|
* original mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int drmtest_set_vt_graphics_mode(void)
|
||||||
|
{
|
||||||
|
if (drmtest_install_exit_handler(restore_vt_mode_at_exit))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
drmtest_disable_exit_handler();
|
||||||
|
orig_vt_mode = set_vt_mode(KD_GRAPHICS);
|
||||||
|
if (orig_vt_mode < 0)
|
||||||
|
orig_vt_mode = -1UL;
|
||||||
|
drmtest_enable_exit_handler();
|
||||||
|
|
||||||
|
return orig_vt_mode < 0 ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -131,3 +131,5 @@ inline static void _do_or_die(const char *function, int line, int ret)
|
|||||||
}
|
}
|
||||||
#define do_or_die(x) _do_or_die(__FUNCTION__, __LINE__, x)
|
#define do_or_die(x) _do_or_die(__FUNCTION__, __LINE__, x)
|
||||||
#define do_ioctl(fd, ptr, sz) do_or_die(drmIoctl((fd), (ptr), (sz)))
|
#define do_ioctl(fd, ptr, sz) do_or_die(drmIoctl((fd), (ptr), (sz)))
|
||||||
|
|
||||||
|
int drmtest_set_vt_graphics_mode(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user