diff options
Diffstat (limited to 'src/display.c')
-rw-r--r-- | src/display.c | 501 |
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; } + + + + |