aboutsummaryrefslogtreecommitdiff
path: root/src/display.c
diff options
context:
space:
mode:
authorpk33 <pk33@pk33.space>2024-11-03 01:39:28 +0100
committerpk33 <pk33@pk33.space>2024-11-03 01:39:28 +0100
commitee7cd3e6b622a8c40236ac26270e369bc28af007 (patch)
treed5473064793f559d6677de193b4c827cf6623d2e /src/display.c
parentdd5240ff7a87e85bca15b294236220ac0576055f (diff)
downloadengine33-ee7cd3e6b622a8c40236ac26270e369bc28af007.tar.gz
modesetting tweaks
Diffstat (limited to 'src/display.c')
-rw-r--r--src/display.c501
1 files changed, 245 insertions, 256 deletions
diff --git a/src/display.c b/src/display.c
index 901a570..1e68f89 100644
--- a/src/display.c
+++ b/src/display.c
@@ -20,6 +20,7 @@
#include "display.h"
#include "system.h"
#include "logger.h"
+#include "options.h"
#define REL_SIGNAL SIGUSR1
@@ -38,12 +39,11 @@ typedef struct {
__u64 *drmRes_encs;
__u64 *drmRes_crtcs;
- struct drm_mode_get_connector connector;
__u64 connProps[ 16 ];
__u64 connPropVals[ 16 ];
__u64 connEncs[ 16 ];
struct drm_mode_modeinfo connModes[ 32 ];
- struct drm_mode_modeinfo *mode;
+ struct drm_mode_get_encoder *encoder;
struct drm_mode_create_dumb drmCreateDumb[2];
struct drm_mode_map_dumb drmMapDumb[2];
@@ -56,14 +56,11 @@ static Size vtPipe[2] = { -1, -1 };
static struct termios termOldConfig;
-
-static Size _get_drm_resources( Size fd );
-static Size _get_drm_connector( Size fd );
-static Size _get_drm_crtc( Size fd );
-static Size _get_drm_framebuffer( Size fd );
-
-static int _is_card( const struct dirent *f );
-static Size _open_graphics_device( Size *fd );
+static err _open_graphics_device( void );
+static err _get_drm_resources( void );
+static err _get_drm_connector( void );
+static err _get_drm_crtc( void );
+static err _get_drm_framebuffer(void );
static Size _init_vt_switch( void );
static void _vt_release( void );
@@ -73,10 +70,8 @@ static Size _has_signal(Size signo);
static Size _set_signal(Size signo, void(*sig_handler)(int));
-Size display_init( void )
+err display_init( void )
{
- Size i, fd;
-
struct termios termConfig;
@@ -89,20 +84,19 @@ Size display_init( void )
logf( "Could not get terminal attributes" );
return E33_EXIT_FAILURE;
}
- else {
- termConfig = termOldConfig;
- termConfig.c_iflag &= ~(IGNBRK | BRKINT | PARMRK);
- termConfig.c_lflag &= ~(ICANON | ECHO | IEXTEN | TOSTOP);
- termConfig.c_lflag |= ISIG;
- termConfig.c_cc[VTIME] = 0;
- termConfig.c_cc[VMIN] = 0;
- termConfig.c_cc[VSTART] = 0;
- termConfig.c_cc[VSTOP] = 0;
-
- if( tcsetattr(STDIN_FILENO, TCSANOW, &termConfig) == -1 ) {
- logf( "Could not set terminal attributes" );
- return E33_EXIT_FAILURE;
- }
+
+ termConfig = termOldConfig;
+ termConfig.c_iflag &= ~(IGNBRK | BRKINT | PARMRK);
+ termConfig.c_lflag &= ~(ICANON | ECHO | IEXTEN | TOSTOP);
+ termConfig.c_lflag |= ISIG;
+ termConfig.c_cc[VTIME] = 0;
+ termConfig.c_cc[VMIN] = 0;
+ termConfig.c_cc[VSTART] = 0;
+ termConfig.c_cc[VSTOP] = 0;
+
+ if( tcsetattr(STDIN_FILENO, TCSANOW, &termConfig) == -1 ) {
+ logf( "Could not set terminal attributes" );
+ return E33_EXIT_FAILURE;
}
if( _init_vt_switch() ) {
@@ -110,40 +104,37 @@ Size display_init( void )
}
- if( _open_graphics_device( &fd ) ) {
+ if( _open_graphics_device() ) {
logf( "Failed to find a suitable graphics device" );
return E33_EXIT_FAILURE;
}
-
- if( e33_ioctl( fd, DRM_IOCTL_SET_MASTER, 0 ) == -1 )
+ if( e33_ioctl( __display.devfd, DRM_IOCTL_SET_MASTER, 0 ) == -1 )
{
logf( "Failed to set DRM master" );
return E33_EXIT_FAILURE;
}
-
- if( _get_drm_resources( fd ) ) {
+ if( _get_drm_resources() ) {
logf( "Failed to get resources" );
return E33_EXIT_FAILURE;
}
- if( _get_drm_connector( fd ) ) {
+ if( _get_drm_connector() ) {
logf( "Failed to set connector" );
return E33_EXIT_FAILURE;
}
- if( _get_drm_framebuffer( fd ) ) {
+ if( _get_drm_framebuffer() ) {
logf( "Failed to set framebuffer" );
return E33_EXIT_FAILURE;
}
- if( _get_drm_crtc( fd ) ) {
+ if( _get_drm_crtc() ) {
logf( "Failed to set crtc" );
return E33_EXIT_FAILURE;
}
- __display.devFd = fd;
- __display.surface.w = drmData.mode->hdisplay;
- __display.surface.h = drmData.mode->vdisplay;
+ __display.surface.w = __display.mode.hdisplay;
+ __display.surface.h = __display.mode.vdisplay;
__display.fb.size = (Size)drmData.drmCreateDumb[0].size;
__display.surface.data = __display.fb.map[0];
__display.active = 1;
@@ -162,7 +153,7 @@ void display_flip( void )
i ^= 1;
__display.crtc.fb_id = __display.fb.id[i];
- if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_SETCRTC, &__display.crtc ) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_SETCRTC, &__display.crtc ) == -1 ) {
return;
}
@@ -171,7 +162,7 @@ void display_flip( void )
flip.user_data = ((__u64)(&__display.crtc.crtc_id));
flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
- if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_PAGE_FLIP, &flip ) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_PAGE_FLIP, &flip ) == -1 ) {
return;
}
@@ -181,11 +172,11 @@ void display_flip( void )
void display_term( void )
{
- if( e33_ioctl( __display.devFd, DRM_IOCTL_DROP_MASTER, 0 ) == -1 ) {
+ if( e33_ioctl( __display.devfd, DRM_IOCTL_DROP_MASTER, 0 ) == -1 ) {
logw( "Failed to drop drm master. Oh well." );
}
- if( ioctl(__display.ttyFd, VT_RELDISP, 1) == -1 ) {
+ if( ioctl(__display.ttyfd, VT_RELDISP, 1) == -1 ) {
logw( "Failed to drop release vt. Oh well." );
}
@@ -201,10 +192,10 @@ void display_term( void )
free( drmData.drmRes_encs );
free( drmData.drmRes_conns );
- if( close( __display.ttyFd ) == -1 ) {
+ if( close( __display.ttyfd ) == -1 ) {
logw( "Failed to close TTY. Oh well." );
}
- if( close( __display.devFd ) ) {
+ if( close( __display.devfd ) ) {
logw( "Failed to close graphics device. Oh well." );
}
@@ -227,7 +218,7 @@ void display_vtswitcher_poll( int timeout )
if( !fds[0].revents ) {
return;
}
-
+
if( read(fds[0].fd, &event, sizeof(event)) != sizeof(event) ) {
logw( "Invalid VT switch events read");
return;
@@ -241,164 +232,37 @@ void display_vtswitcher_poll( int timeout )
}
}
-static void _vt_release( void )
-{
- logi( "VT release signal");
- if( ioctl( __display.devFd, DRM_IOCTL_DROP_MASTER, 0 ) ) {
- loge( "Could not drop DRM master" );
- }
- if( ioctl(__display.ttyFd, VT_RELDISP, 1) < 0 ) {
- loge( "Failed to release VT");
- }
- __display.active = 0;
-}
-static void _vt_acquire( void )
+static err _open_graphics_device( void )
{
- logi( "VT acquire signal");
-
- if( ioctl( __display.devFd, DRM_IOCTL_SET_MASTER, 0 ) == -1 ) {
- logw( "Could not become DRM master." );
- }
+ struct drm_get_cap cap = {0,};
- if( ioctl(__display.ttyFd, VT_RELDISP, VT_ACKACQ) < 0 ) {
- loge( "(vt_acquire) Failed to acquire VT.");
- }
- if( ioctl( __display.devFd, (int)DRM_IOCTL_MODE_SETCRTC, &__display.crtc ) == -1 ) {
- loge( "Failed to set crtc on VT switch." );
- }
-
- __display.active = 1;
-}
-
-
-static int _set_pipe(int fd)
-{
- if (fd >= 0)
- {
- int flags = fcntl(fd, F_GETFD);
-
- if (flags == -1) {
- logw( "Could not get flags for VT switcher pipe");
- return E33_EXIT_FAILURE;
- }
-
- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
- logw( "Could not set flags for VT switcher pipe");
- return E33_EXIT_FAILURE;
- }
- }
-
- return E33_EXIT_SUCCESS;
-}
-
-static Size _has_signal(Size signo)
-{
- struct sigaction sact = {0};
- sigaction(signo, 0, &sact);
- return sact.sa_handler != 0;
-}
-
-static Size _set_signal(Size signo, void(*sig_handler)(int))
-{
- struct sigaction sact = {0};
- sact.sa_handler = sig_handler;
- sigemptyset(&sact.sa_mask);
- sact.sa_flags = SA_RESTART;
- return sigaction(signo, &sact, NULL);
-}
-
-static void _vt_switch_sighandler(int sig)
-{
- unsigned char event = REL_EVENT;
-
- if( sig == ACQ_SIGNAL ) {
- event = ACQ_EVENT;
- }
-
- (void)write( vtPipe[1], &event, sizeof(event) );
-}
-
-static Size _init_vt_switch( void )
-{
- struct vt_mode vt_mode = {0,};
- sigset_t set;
-
- __display.ttyFd = -1;
-
-
- /* Init VT pipes */
- if (pipe(vtPipe) != 0) {
- vtPipe[0] = vtPipe[1] = -1;
- loge( "Could not set VT pipes");
- return E33_EXIT_FAILURE;
- }
-
- if( _set_pipe(vtPipe[0]) ) {
- loge( "Could not set VT read pipe" );
- return E33_EXIT_FAILURE;
- }
- if( _set_pipe(vtPipe[1]) ) {
- loge( "Could not set VT write pipe" );
- return E33_EXIT_FAILURE;
- }
- /**/
-
-
- if( __display.ttyFd = open("/dev/tty", O_RDWR | O_CLOEXEC ) < 0 ) {
- loge( "Could not open TTY for VT control" );
- return E33_EXIT_FAILURE;
- }
-
-
- /* Setup signals */
- if( _has_signal(REL_SIGNAL) ) {
- loge( "VT release signal is already in use");
- return E33_EXIT_FAILURE;
- }
- if( _has_signal(ACQ_SIGNAL) ) {
- loge( "VT acquire signal is already in use");
+ if( (__display.devfd = open(DRM_DEVICE, O_RDWR )) == -1 ) {
+ logw( "Failed to open DRM device" );
return E33_EXIT_FAILURE;
}
- if( _set_signal( REL_SIGNAL, _vt_switch_sighandler ) ) {
- loge( "Could not set relese signal handler");
- return E33_EXIT_FAILURE;
- }
- if( _set_signal( ACQ_SIGNAL, _vt_switch_sighandler ) ) {
- loge( "Could not set acquire signal handler");
- return E33_EXIT_FAILURE;
- }
- /**/
-
-
+ cap.capability = DRM_CAP_DUMB_BUFFER;
- if( ioctl(__display.ttyFd, VT_GETMODE, &vt_mode) < 0 ) {
- logw( "Could not get VT mode" );
+ if( e33_ioctl( __display.devfd, DRM_IOCTL_GET_CAP, &cap ) == -1 ) {
+ logw( "Failed to get DRM device capabilities" );
return E33_EXIT_FAILURE;
}
- vt_mode.mode = VT_PROCESS;
- vt_mode.relsig = REL_SIGNAL;
- vt_mode.acqsig = ACQ_SIGNAL;
- vt_mode.frsig = SIGIO;
-
- if( ioctl(__display.ttyFd, VT_SETMODE, &vt_mode) < 0 ) {
- logw( "Could not set VT mode" );
- return E33_EXIT_FAILURE;
+ if( cap.value ) {
+ return E33_EXIT_SUCCESS;
}
- return E33_EXIT_SUCCESS;
+ return E33_EXIT_FAILURE;
}
-
-static Size _get_drm_resources( Size fd )
+static Size _get_drm_resources( void )
{
- if( e33_ioctl(fd, (int)DRM_IOCTL_MODE_GETRESOURCES, &drmData.drmRes) == -1 ) {
+ if( e33_ioctl(__display.devfd, (int)DRM_IOCTL_MODE_GETRESOURCES, &drmData.drmRes) == -1 ) {
logw( "Failed to init drm resources" );
return E33_EXIT_FAILURE;
}
@@ -406,13 +270,13 @@ static Size _get_drm_resources( Size fd )
drmData.drmRes_fbs = malloc( sizeof(__u64) * drmData.drmRes.count_fbs );
drmData.drmRes_crtcs = malloc( sizeof(__u64) * drmData.drmRes.count_crtcs );
drmData.drmRes_encs = malloc( sizeof(__u64) * drmData.drmRes.count_encoders );
- drmData.drmRes_conns = malloc( sizeof(__u64) * drmData.drmRes.count_connectors );
+ drmData.drmRes_conns = malloc( sizeof(__u32) * drmData.drmRes.count_connectors );
/* DRM resource objects must also be zero'd before second call */
memset( drmData.drmRes_fbs, 0, sizeof(__u64) * drmData.drmRes.count_fbs );
memset( drmData.drmRes_crtcs, 0, sizeof(__u64) * drmData.drmRes.count_crtcs );
memset( drmData.drmRes_encs, 0, sizeof(__u64) * drmData.drmRes.count_encoders );
- memset( drmData.drmRes_conns, 0, sizeof(__u64) * drmData.drmRes.count_connectors );
+ memset( drmData.drmRes_conns, 0, sizeof(__u32) * drmData.drmRes.count_connectors );
drmData.drmRes.fb_id_ptr = (__u64)drmData.drmRes_fbs;
drmData.drmRes.crtc_id_ptr = (__u64)drmData.drmRes_crtcs;
@@ -420,7 +284,7 @@ static Size _get_drm_resources( Size fd )
drmData.drmRes.encoder_id_ptr = (__u64)drmData.drmRes_encs;
/* Second call writes drm resource data using the given pointers */
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_GETRESOURCES, &drmData.drmRes ) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_GETRESOURCES, &drmData.drmRes ) == -1 ) {
logw( "Failed to get drm resources" );
return E33_EXIT_FAILURE;
}
@@ -429,69 +293,75 @@ static Size _get_drm_resources( Size fd )
}
-static Size _get_drm_connector( Size fd )
+static Size _get_drm_connector( void )
{
- struct drm_mode_get_connector *connector = &__display.connector;
u16 i, j;
for( i = 0; i < drmData.drmRes.count_connectors; ++i )
{
+ struct drm_mode_get_connector *connector = &__display.connector;
+
+
connector->connector_id = drmData.drmRes_conns[i];
if( connector->connector_id <= 0 ) {
continue;
}
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_GETCONNECTOR, connector ) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_GETCONNECTOR, connector ) == -1 ) {
continue;
}
- if( connector->connection && connector->count_modes > 0 &&
- connector->encoder_id && connector->count_encoders > 0 )
- {
+ if( connector->connection == 1 &&
+ connector->count_modes > 0 &&
+ connector->count_encoders > 0
+ ) {
connector->modes_ptr = (__u64)drmData.connModes;
connector->props_ptr = (__u64)drmData.connProps;
connector->prop_values_ptr = (__u64)drmData.connPropVals;
connector->encoders_ptr = (__u64)drmData.connEncs;
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_GETCONNECTOR, connector) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_GETCONNECTOR, connector) == -1 ) {
continue;
}
-
- goto success;
+
+ for( j = 0; j < connector->count_modes; ++j )
+ {
+ struct drm_mode_modeinfo *mode = &drmData.connModes[j];
+
+ if( strcomp( mode->name, DRM_MODE ) && (mode->vrefresh == DRM_RATE) )
+ {
+ /* TODO there has to be a better way */
+ if( mode->hdisplay % 8 ) {
+ mode->hdisplay += (mode->hdisplay % 8);
+ }
+
+ __display.mode = *mode;
+ return E33_EXIT_SUCCESS;
+ }
+ }
}
}
- loge( "Failed to find suitable connector");
+ logw( "Failed to find a valid connector" );
return E33_EXIT_FAILURE;
-
-success:
- drmData.mode = &drmData.connModes[0];
-
- logi( "Using mode '%s'", drmData.mode->name );
-
- /* TODO there has to be a better way */
- if( _strcomp( drmData.mode->name, "1366x768" ) ) {
- drmData.mode->hdisplay += 10;
- }
- return E33_EXIT_SUCCESS;
}
-static Size _get_drm_crtc( Size fd )
+static Size _get_drm_crtc( void )
{
- struct drm_mode_get_encoder *encoder = &__display.encoder;
+ struct drm_mode_get_encoder encoder = {0,};
struct drm_mode_crtc *crtc = &__display.crtc;
- encoder->encoder_id = __display.connector.encoder_id;
+ encoder.encoder_id = __display.connector.encoder_id;
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_GETENCODER, encoder ) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_GETENCODER, &encoder ) == -1 ) {
loge( "Failed to get encoder" );
return E33_EXIT_FAILURE;
}
- crtc->crtc_id = encoder->crtc_id;
+ crtc->crtc_id = encoder.crtc_id;
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_GETCRTC, crtc ) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_GETCRTC, crtc ) == -1 ) {
loge( "Failed to get CRTC" );
return E33_EXIT_FAILURE;
}
@@ -499,10 +369,10 @@ static Size _get_drm_crtc( Size fd )
crtc->fb_id = drmData.drmFBCmd[0].fb_id;
crtc->set_connectors_ptr = (__u64)drmData.drmRes_conns;
crtc->count_connectors = 1;
- crtc->mode = *drmData.mode;
+ crtc->mode = __display.mode;
crtc->mode_valid = 1;
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_SETCRTC, crtc ) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_SETCRTC, crtc ) == -1 ) {
loge( "Could not set CRTC" );
return E33_EXIT_FAILURE;
}
@@ -510,12 +380,12 @@ static Size _get_drm_crtc( Size fd )
return E33_EXIT_SUCCESS;
}
-static Size _get_drm_framebuffer( Size fd )
+static Size _get_drm_framebuffer( void )
{
struct drm_mode_create_dumb *drmCreateDumb = drmData.drmCreateDumb;
struct drm_mode_map_dumb *drmMapDumb = drmData.drmMapDumb;
struct drm_mode_fb_cmd *drmFBCmd = drmData.drmFBCmd;
- struct drm_mode_modeinfo *mode = drmData.mode;
+ struct drm_mode_modeinfo *mode = &__display.mode;
u8 i;
for( i = 0; i < 2; ++i )
@@ -524,7 +394,7 @@ static Size _get_drm_framebuffer( Size fd )
drmCreateDumb[i].height = mode->vdisplay;
drmCreateDumb[i].bpp = 32;
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_CREATE_DUMB,
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_CREATE_DUMB,
drmCreateDumb + i ) == -1 )
{
loge( "Failed to create dumb buffer #%d", i );
@@ -538,7 +408,7 @@ static Size _get_drm_framebuffer( Size fd )
drmFBCmd[i].depth = 24;
drmFBCmd[i].handle = drmCreateDumb[i].handle;
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_ADDFB, drmFBCmd + i ) == -1 ) {
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_ADDFB, drmFBCmd + i ) == -1 ) {
loge( "Failed to add framebuffer #%d", i );
return E33_EXIT_FAILURE;
}
@@ -547,7 +417,7 @@ static Size _get_drm_framebuffer( Size fd )
drmMapDumb[i].handle = drmCreateDumb[i].handle;
- if( e33_ioctl( fd, (int)DRM_IOCTL_MODE_MAP_DUMB, drmMapDumb + i ) == -1 )
+ if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_MAP_DUMB, drmMapDumb + i ) == -1 )
{
loge( "Failed to map dumb buffer #%d", i );
return E33_EXIT_FAILURE;
@@ -555,7 +425,7 @@ static Size _get_drm_framebuffer( Size fd )
__display.fb.map[i] =
mmap( 0, drmCreateDumb[i].size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, drmMapDumb[i].offset );
+ MAP_SHARED, __display.devfd, drmMapDumb[i].offset );
if( __display.fb.map[i] == MAP_FAILED ) {
loge( "Failed to map framebuffer #%d", i );
@@ -567,57 +437,176 @@ static Size _get_drm_framebuffer( Size fd )
}
-static int _is_card( const struct dirent *f )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static void _vt_release( void )
+{
+ logi( "VT release signal");
+
+ if( ioctl( __display.devfd, DRM_IOCTL_DROP_MASTER, 0 ) ) {
+ loge( "Could not drop DRM master" );
+ }
+
+ if( ioctl(__display.ttyfd, VT_RELDISP, 1) < 0 ) {
+ loge( "Failed to release VT");
+ }
+
+ __display.active = 0;
+}
+
+static void _vt_acquire( void )
+{
+ logi( "VT acquire signal");
+
+ if( ioctl( __display.devfd, DRM_IOCTL_SET_MASTER, 0 ) == -1 ) {
+ logw( "Could not become DRM master." );
+ }
+
+ if( ioctl(__display.ttyfd, VT_RELDISP, VT_ACKACQ) < 0 ) {
+ loge( "(vt_acquire) Failed to acquire VT.");
+ }
+
+ if( ioctl( __display.devfd, (int)DRM_IOCTL_MODE_SETCRTC, &__display.crtc ) == -1 ) {
+ loge( "Failed to set crtc on VT switch." );
+ }
+
+ __display.active = 1;
+}
+
+
+static int _set_pipe(int fd)
{
- return _strcomp(f->d_name, "card");
+ if (fd >= 0)
+ {
+ int flags = fcntl(fd, F_GETFD);
+
+ if (flags == -1) {
+ logw( "Could not get flags for VT switcher pipe");
+ return E33_EXIT_FAILURE;
+ }
+
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
+ logw( "Could not set flags for VT switcher pipe");
+ return E33_EXIT_FAILURE;
+ }
+ }
+
+ return E33_EXIT_SUCCESS;
}
+static Size _has_signal(Size signo)
+{
+ struct sigaction sact = {0};
+ sigaction(signo, 0, &sact);
+ return sact.sa_handler != 0;
+}
-static Size _open_graphics_device( Size *fd )
+static Size _set_signal(Size signo, void(*sig_handler)(int))
{
- Size i, num, _fd;
- struct dirent **evfs;
- char path[512];
+ struct sigaction sact = {0};
+ sact.sa_handler = sig_handler;
+ sigemptyset(&sact.sa_mask);
+ sact.sa_flags = SA_RESTART;
+ return sigaction(signo, &sact, NULL);
+}
- num = scandir( "/dev/dri", &evfs, _is_card, 0 );
+static void _vt_switch_sighandler(int sig)
+{
+ unsigned char event = REL_EVENT;
- if( num <= 0 ) {
- loge( "No graphics devices found" );
- goto failure;
+ if( sig == ACQ_SIGNAL ) {
+ event = ACQ_EVENT;
}
- for( i = 0; i < num; ++i )
+ (void)write( vtPipe[1], &event, sizeof(event) );
+}
+
+static Size _init_vt_switch( void )
+{
+ struct vt_mode vt_mode = {0,};
+ sigset_t set;
+
+ __display.ttyfd = -1;
+
+
+ /* Init VT pipes */
+ if (pipe(vtPipe) != 0)
{
- struct drm_get_cap cap = {0,};
+ vtPipe[0] = vtPipe[1] = -1;
+ loge( "Could not set VT pipes");
+ return E33_EXIT_FAILURE;
+ }
- snprintf( path, 512, "%s%s", "/dev/dri/", evfs[i]->d_name );
+ if( _set_pipe(vtPipe[0]) ) {
+ loge( "Could not set VT read pipe" );
+ return E33_EXIT_FAILURE;
+ }
+ if( _set_pipe(vtPipe[1]) ) {
+ loge( "Could not set VT write pipe" );
+ return E33_EXIT_FAILURE;
+ }
+ /**/
- logi( "Trying '%s'", path );
- if( (_fd = open(path, O_RDWR )) == -1 ) {
- logw( "Failed to open graphics device '%s'", path );
- continue;
- }
+ if( __display.ttyfd = open("/dev/tty", O_RDWR ) < 0 ) {
+ loge( "Could not open TTY for VT control" );
+ return E33_EXIT_FAILURE;
+ }
- cap.capability = DRM_CAP_DUMB_BUFFER;
- if( e33_ioctl( _fd, DRM_IOCTL_GET_CAP, &cap ) == -1 ) {
- logw( "Failed to get device capabilities for '%s'", path );
- continue;
- }
- if( cap.value )
- {
- logi("Using device: %s", path);
- *fd = _fd;
- free( evfs );
- return E33_EXIT_SUCCESS;
- }
+ /* Setup signals */
+ if( _has_signal(REL_SIGNAL) ) {
+ loge( "VT release signal is already in use");
+ return E33_EXIT_FAILURE;
+ }
+ if( _has_signal(ACQ_SIGNAL) ) {
+ loge( "VT acquire signal is already in use");
+ return E33_EXIT_FAILURE;
+ }
- close( _fd );
+ if( _set_signal( REL_SIGNAL, _vt_switch_sighandler ) ) {
+ loge( "Could not set relese signal handler");
+ return E33_EXIT_FAILURE;
+ }
+ if( _set_signal( ACQ_SIGNAL, _vt_switch_sighandler ) ) {
+ loge( "Could not set acquire signal handler");
+ return E33_EXIT_FAILURE;
}
+ /**/
-failure:
- free( evfs );
- return E33_EXIT_FAILURE;
+
+
+ if( ioctl(__display.ttyfd, VT_GETMODE, &vt_mode) < 0 ) {
+ logw( "Could not get VT mode" );
+ return E33_EXIT_FAILURE;
+ }
+
+ vt_mode.mode = VT_PROCESS;
+ vt_mode.relsig = REL_SIGNAL;
+ vt_mode.acqsig = ACQ_SIGNAL;
+ vt_mode.frsig = SIGIO;
+
+ if( ioctl(__display.ttyfd, VT_SETMODE, &vt_mode) < 0 ) {
+ logw( "Could not set VT mode" );
+ return E33_EXIT_FAILURE;
+ }
+
+ return E33_EXIT_SUCCESS;
}
+
+
+
+