From 5a54774474f43ae29716751d6415563a59b92c7d Mon Sep 17 00:00:00 2001 From: pk33 Date: Mon, 11 Nov 2024 18:06:18 +0100 Subject: tidying up and basic input --- README.html | 7 +- include/clock.h | 12 -- include/clock33.h | 12 ++ include/display.h | 48 ----- include/display33.h | 51 +++++ include/input33.h | 63 ++++++ include/logger.h | 35 ---- include/logger33.h | 26 +++ include/options.h | 12 -- include/options33.h | 12 ++ include/strings33.h | 57 ++--- include/system.h | 26 --- include/system33.h | 28 +++ include/types.h | 46 ---- include/types33.h | 47 +++++ include/ui33.h | 30 ++- makefile | 6 +- src/clock.c | 19 -- src/clock33.c | 19 ++ src/display.c | 592 ---------------------------------------------------- src/display33.c | 575 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/input33.c | 232 ++++++++++++++++++++ src/logger.c | 103 --------- src/logger33.c | 111 ++++++++++ src/main.c | 63 ++++-- src/strings33.c | 51 ++--- src/system.c | 50 ----- src/system33.c | 50 +++++ src/ui33.c | 54 +++-- 29 files changed, 1392 insertions(+), 1045 deletions(-) delete mode 100644 include/clock.h create mode 100644 include/clock33.h delete mode 100644 include/display.h create mode 100644 include/display33.h create mode 100644 include/input33.h delete mode 100644 include/logger.h create mode 100644 include/logger33.h delete mode 100644 include/options.h create mode 100644 include/options33.h delete mode 100644 include/system.h create mode 100644 include/system33.h delete mode 100644 include/types.h create mode 100644 include/types33.h delete mode 100644 src/clock.c create mode 100644 src/clock33.c delete mode 100644 src/display.c create mode 100644 src/display33.c create mode 100644 src/input33.c delete mode 100644 src/logger.c create mode 100644 src/logger33.c delete mode 100644 src/system.c create mode 100644 src/system33.c diff --git a/README.html b/README.html index d5f93c6..293830b 100644 --- a/README.html +++ b/README.html @@ -6,21 +6,20 @@

COMPILING


-

Set CC in the makefile then run bmake.

+

run bmake.



USAGE


You need a monitor connected to an on-board connector.
-Edit options.h.
+Edit options33.h.
Run ./bin/engine33 on a TTY.


TODO


    -
  1. tidying up and abiding by naming conventions
  2. -
  3. *Input
  4. +
  5. *Draw some primitive graphics


diff --git a/include/clock.h b/include/clock.h deleted file mode 100644 index 589fd61..0000000 --- a/include/clock.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __TIME_H__ -#define __TIME_H__ - - -#include "types.h" - - -Size clock_get_us( void ); -f64 clock_get_s_hires( void ); - - -#endif /* __TIME_H__ */ diff --git a/include/clock33.h b/include/clock33.h new file mode 100644 index 0000000..3b0c405 --- /dev/null +++ b/include/clock33.h @@ -0,0 +1,12 @@ +#ifndef __TIME33_H__ +#define __TIME33_H__ + + +#include "types33.h" + + +Size clock33_get_us( void ); +f64 clock33_get_s_hires( void ); + + +#endif /* __TIME33_H__ */ diff --git a/include/display.h b/include/display.h deleted file mode 100644 index 63fc7b2..0000000 --- a/include/display.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __DISPLAY_H__ -#define __DISPLAY_H__ - -#include "libdrm/drm_mode.h" - -#include "types.h" -/* TEMP */ -typedef struct { - u32 *data; - Size w, h; -} Surface; -/**/ - - -typedef struct { - Size id[2]; - u32 *map[2]; - Size stride; - Size size; -} Framebuffer; - - -typedef struct { - Framebuffer fb; - Surface surface; - - struct drm_mode_crtc crtc; - struct drm_mode_modeinfo mode; - struct drm_mode_get_connector connector; - - Size devfd, ttyfd; - - Size active; -} Display; - - -extern Display __display; - - -Size display_init( void ); - -void display_flip( void ); -void display_vtswitcher_poll( int timeout ); - -void display_term( void ); - - -#endif /* __DISPLAY_H__ */ diff --git a/include/display33.h b/include/display33.h new file mode 100644 index 0000000..85e0172 --- /dev/null +++ b/include/display33.h @@ -0,0 +1,51 @@ +#ifndef __DISPLAY33_H__ +#define __DISPLAY33_H__ + + +#include "libdrm/drm_mode.h" + +#include "types33.h" + + +/* TEMP XXX */ +typedef struct { + u32 *data; + Size w, h; +} Surface33; +/**/ + + +typedef struct { + Size id[2]; + u8 *map[2]; + Size stride; + Size size; +} Framebuffer33; + + +typedef struct { + Framebuffer33 fb; + Surface33 surface; + + struct drm_mode_crtc crtc; + struct drm_mode_modeinfo mode; + struct drm_mode_get_connector connector; + + Size devFd, ttyFd; + + Boolean active; +} Display33; + + +extern Display33 __display; + + +Error display33_init( void ); + +void display33_flip( void ); +void display33_vtswitcher_poll( int timeout ); + +void display33_term( void ); + + +#endif /* __DISPLAY33_H__ */ diff --git a/include/input33.h b/include/input33.h new file mode 100644 index 0000000..e0d7df0 --- /dev/null +++ b/include/input33.h @@ -0,0 +1,63 @@ +#ifndef __INPUT_H__ +#define __INPUT_H__ + + +#include "linux/input.h" + +#include "types33.h" + + +//#define MAX_INPUT_EVENTS 32 +//#define INPUT_BUFFLEN 32 + +#define _KBBUFF_LEN 32 /* must be ^2 */ +#define _MAX_DEVS 8 + +//#define KEYBOARD 0x01 +//#define MOUSE 0x02 + +#define _RELEASE 0x00 +#define _PRESS 0x01 +#define _REPEAT 0x02 + +#define _SCROLLL 0x01 +#define _NUML 0x02 +#define _CAPSL 0x04 +/* TODO move these */ +#define _CAN_CAPSL 0x0B + + +#define KEYDOWN(K) (__input.keyStates[K] >= _PRESS) +#define KEYUP(K) (__input.keyStates[K] == _RELEASE) +#define KEYREP(K) (__input.keyStates[K] == _REPEAT) +#define MOUSE1 (__input.keyStates[BTN_LEFT] == 1) +#define MOUSE2 (__input.keyStates[BTN_RIGHT] == 1) +#define MOUSE3 (__input.keyStates[BTN_MIDDLE] == 1) +#define MOUSEX (__input.relStates[REL_X]) +#define MOUSEY (__input.relStates[REL_Y]) +#define SCROLLW (__input.relStates[REL_WHEEL]) + + +typedef struct { + int devices[ _MAX_DEVS ]; + Size deviceCount; + + Bitfield cnsFlags; /* [0x7] :: Caps Num Scrl */ + Bitfield modFlags; /* [0x1FF] :: CS AR AL SR SL A C AGr S */ + + int keyStates[ KEY_MAX ]; + int relStates[ REL_MAX ]; + + __u16 buffer[ _KBBUFF_LEN ]; + Size head, tail; +} Input33; + +extern Input33 __input; + + +Error input33_init( void ); +void input33_poll( void ); +void input33_term( void ); + + +#endif /** __INPUT_H__ **/ diff --git a/include/logger.h b/include/logger.h deleted file mode 100644 index f582100..0000000 --- a/include/logger.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __LOGGER_H__ -#define __LOGGER_H__ - -#include "types.h" - - -#define LOG_DEBUG 0 -#define LOG_INFO 1 -#define LOG_WARN 2 -#define LOG_ERROR 3 /* will be fatal */ -#define LOG_FATAL 4 /* followed directly by maybe cleanup and exit */ - -#define __LOGFUNC__ __logger.func = __func__ - -#define logd( s, ... ) __LOGFUNC__; logger( LOG_DEBUG, s, ##__VA_ARGS__ ); -#define logi( s, ... ) __LOGFUNC__; logger( LOG_INFO, s, ##__VA_ARGS__ ); -#define logw( s, ... ) __LOGFUNC__; logger( LOG_WARN, s, ##__VA_ARGS__ ); -#define loge( s, ... ) __LOGFUNC__; logger( LOG_ERROR, s, ##__VA_ARGS__ ); -#define logf( s, ... ) __LOGFUNC__; logger( LOG_FATAL, s, ##__VA_ARGS__ ); - - -typedef struct { - Size fd; - String func; -} Logger; - -extern Logger __logger; - - -Size logger_init( void ); -void logger( Size level, String fmt, ... ); -void logger_term( void ); - - -#endif /* __DISPLAY_H__ */ diff --git a/include/logger33.h b/include/logger33.h new file mode 100644 index 0000000..a489f67 --- /dev/null +++ b/include/logger33.h @@ -0,0 +1,26 @@ +#ifndef __LOGGER33_H__ +#define __LOGGER33_H__ + + +#include "types33.h" + + +#define _DEBUG 0 +#define _INFO 1 +#define _WARN 2 +#define _ERROR 3 /* will be fatal */ +#define _FATAL 4 + +#define LOGD( STR, ... ) _logger( _DEBUG, __FILE__, __LINE__, __FUNCTION__, STR, ##__VA_ARGS__ ); +#define LOGI( STR, ... ) _logger( _INFO, __FILE__, __LINE__, __FUNCTION__, STR, ##__VA_ARGS__ ); +#define LOGW( STR, ... ) _logger( _WARN, __FILE__, __LINE__, __FUNCTION__, STR, ##__VA_ARGS__ ); +#define LOGE( STR, ... ) _logger( _ERROR, __FILE__, __LINE__, __FUNCTION__, STR, ##__VA_ARGS__ ); +#define LOGF( STR, ... ) _logger( _FATAL, __FILE__, __LINE__, __FUNCTION__, STR, ##__VA_ARGS__ ); + + +Size logger33_init( void ); +void _logger( Size level, String file, int line, String function, const char *fmt, ... ); +void logger33_term( void ); + + +#endif /* __DISPLAY33_H__ */ diff --git a/include/options.h b/include/options.h deleted file mode 100644 index 418a296..0000000 --- a/include/options.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __OPTIONS_H__ -#define __OPTIONS_H__ - - -#define LOG_PATH "/dev/tty3" - -#define DRM_DEVICE "/dev/dri/card0" -#define DRM_MODE "1024x768" -#define DRM_RATE 75 - - -#endif /* __OPTIONS_H */ diff --git a/include/options33.h b/include/options33.h new file mode 100644 index 0000000..4d3c4a3 --- /dev/null +++ b/include/options33.h @@ -0,0 +1,12 @@ +#ifndef __OPTIONS33_H__ +#define __OPTIONS33_H__ + + +#define E33_LOG_FILE "/dev/tty3" + +#define E33_DRM_DEVICE "/dev/dri/card0" +#define E33_DRM_MODE "1024x768" +#define E33_DRM_RATE 75 + + +#endif /* __OPTIONS33_H */ diff --git a/include/strings33.h b/include/strings33.h index c987690..5591913 100644 --- a/include/strings33.h +++ b/include/strings33.h @@ -1,42 +1,49 @@ -#ifndef __STRINGS_H__ -#define __STRINGS_H__ +#ifndef __STRINGS33_H__ +#define __STRINGS33_H__ -#include "types.h" -#include "display.h" -#include "system.h" +#include "system33.h" +#include "display33.h" -#define E33_MAX_GLYPH_PLOTS 256 -#define E33_MAX_FONT_GLYPHS 256 -#define E33_FONT_DEFAULT 0 -#define E33_FONT_BIG 1 +#define _MAX_GLYPH_PLOTS 256 +#define _MAX_FONT_GLYPHS 256 -#define quprint( s, x, y, str ) e33_uprint( s, E33_FONT_DEFAULT, WHITE, x, y, str ); -#define quprintf( s, x, y, frm, ... ) e33_uprintf( s, E33_FONT_DEFAULT, WHITE, x, y, frm, ##__VA_ARGS__ ); -#define suprint( f, c, x, y, str ) e33_uprint( &__display.surface, f, c, x, y, str ); -#define suprintf( f, c, x, y, frm, ... ) e33_uprintf( &__display.surface, f, c, x, y, frm, ##__VA_ARGS__ ); -#define qsuprint( str, x, y ) e33_uprint( &__display.surface, E33_FONT_DEFAULT, WHITE, x, y, str ); -#define qsuprintf( x, y, frm, ... ) e33_uprintf( &__display.surface, E33_FONT_DEFAULT, WHITE, x, y, frm, ##__VA_ARGS__ ) +#define STRINGS33_FONT_DEFAULT 0 +#define STRINGS33_FONT_BIG 1 + + +#define SPRINT( s, x, y, str ) e33_uprint( s, STRINGS33_FONT_DEFAULT, WHITE, x, y, str ); +#define SPRINTF( s, x, y, frm, ... ) e33_uprintf( s, STRINGS33_FONT_DEFAULT, WHITE, x, y, frm, ##__VA_ARGS__ ); + +#define PRINT( f, c, x, y, str ) e33_uprint( &__display.surface, f, c, x, y, str ); +#define PRINTF( f, c, x, y, frm, ... ) e33_uprintf( &__display.surface, f, c, x, y, frm, ##__VA_ARGS__ ); + +#define QPRINT( str, x, y ) e33_uprint( &__display.surface, STRINGS33_FONT_DEFAULT, WHITE, x, y, str ); +#define QPRINTF( x, y, frm, ... ) e33_uprintf( &__display.surface, STRINGS33_FONT_DEFAULT, WHITE, x, y, frm, ##__VA_ARGS__ ) typedef struct { - Size num_plots; - Size width; - u16 plots[ E33_MAX_GLYPH_PLOTS ]; + Size plotCount; + Size w; + u16 plots[ _MAX_GLYPH_PLOTS ]; } FontGlyph33; typedef struct { Size xShift, yAnd; - Size height; - Size num_glyphs; - Size maxGlyphWidth; - FontGlyph33 glyphs[ E33_MAX_FONT_GLYPHS ]; + Size h; + Size glyphCount; + Size glyphWidthMax; + FontGlyph33 glyphs[ _MAX_FONT_GLYPHS ]; } Font33; -void e33_uprint( Surface *surf, Size font, u32 col, Size x, Size y, String str ); -void e33_uprintf( Surface *surf, Size font, u32 col, Size x, Size y, String fmt, ... ); +extern Font33 defFont; +extern Font33 bigFont; + + +void strings33_uprint( Surface33 *surf, Size font, u32 col, Size x, Size y, String str ); +void strings33_uprintf( Surface33 *surf, Size font, u32 col, Size x, Size y, String fmt, ... ); -#endif /* __STRING_H__ */ +#endif /* __STRINGS33_H__ */ diff --git a/include/system.h b/include/system.h deleted file mode 100644 index 68cbac9..0000000 --- a/include/system.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __SYSTEM_H__ -#define __SYSTEM_H__ - -#include "types.h" - -#define NEAR 1.0 -#define FAR 24.0 - -#define TRANSPARENT 0x0 -#define BLACK 0xff000000 -#define WHITE 0xffffffff -#define RED 0xffff0000 -#define GREEN 0xff00ff00 -#define BLUE 0xff0000ff -#define YELLOW 0xffffff00 -#define MAGENTA 0xffff00ff -#define CYAN 0xff00ffff - - -err e33_ioctl( Size fd, unsigned long req, void *arg ); -boolean e33_strcmp( String s1, String s2 ); -err e33_has_signal(Size signo); -err e33_set_signal(Size signo, void(*sig_handler)(int)); - - -#endif /** __SYSTEM_H__ **/ diff --git a/include/system33.h b/include/system33.h new file mode 100644 index 0000000..b61eddd --- /dev/null +++ b/include/system33.h @@ -0,0 +1,28 @@ +#ifndef __SYSTEM33_H__ +#define __SYSTEM33_H__ + + +#include "types33.h" + + +#define _STRING_MAX 256 + + +#define BLACK 0xff000000 +#define RED 0xffff0000 +#define GREEN 0xff00ff00 +#define BLUE 0xff0000ff +#define YELLOW 0xffffff00 +#define ORANGE 0xffffaa00 +#define MAGENTA 0xffff00ff +#define CYAN 0xff00ffff +#define WHITE 0xffffffff + + +Error e33_ioctl( Size fd, unsigned long req, void *arg ); +Boolean e33_strcmp( String s1, String s2 ); +Error e33_has_signal(Size signo); +Error e33_set_signal(Size signo, void(*sig_handler)(int)); + + +#endif /** __SYSTEM33_H__ **/ diff --git a/include/types.h b/include/types.h deleted file mode 100644 index bd52ac4..0000000 --- a/include/types.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __TYPES_H__ -#define __TYPES_H__ - -#include "stdlib.h" -#include "stdint.h" -#include "sys/types.h" - - -#define E33_EXIT_SUCCESS 0 -#define E33_EXIT_FAILURE 1 -#define E33_TRUE 1 -#define E33_FALSE 0 - -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; - -typedef float f32; -typedef double f64; - -typedef uintptr_t uPtr; -typedef ssize_t Size; -typedef size_t uSize; - -typedef const char * String; - -typedef Size err; -typedef Size boolean; - -#define sizeof(x) (Size)sizeof(x) -#define alignof(x) (Size)_Alignof(x) -#define countof(a) (sizeof(a) / sizeof(*(a))) -#define lengthof(s) (countof(s) - 1) - -#define assert(c) while( !(c) ){ __builtin_unreachable(); } - -#define bp(V) logd( "BREAKPOINT :: %d", V ); - - -#endif /* __TYPES_H__ */ diff --git a/include/types33.h b/include/types33.h new file mode 100644 index 0000000..a72414e --- /dev/null +++ b/include/types33.h @@ -0,0 +1,47 @@ +#ifndef __TYPES33_H__ +#define __TYPES33_H__ + + +#include "stdlib.h" +#include "stdint.h" + +#include "sys/types.h" + + +#define E33_EXIT_SUCCESS 0 +#define E33_EXIT_FAILURE 1 +#define E33_TRUE 1 +#define E33_FALSE 0 + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef float f32; +typedef double f64; + +typedef uintptr_t uPtr; +typedef ssize_t Size; +typedef size_t uSize; + +typedef const char * String; + +typedef Size Error; +typedef Size Boolean; +typedef Size Bitfield; + +//#define sizeof(x) (Size)sizeof(x) +//#define alignof(x) (Size)_Alignof(x) +//#define countof(a) (sizeof(a) / sizeof(*(a))) +//#define lengthof(s) (countof(s) - 1) + +//#define assert(c) while( !(c) ){ __builtin_unreachable(); } + + +#endif /* __TYPES33_H__ */ diff --git a/include/ui33.h b/include/ui33.h index 7aa489c..22208fe 100644 --- a/include/ui33.h +++ b/include/ui33.h @@ -1,9 +1,29 @@ -#ifndef __UI_H__ -#define __UI_H__ +#ifndef __UI33_H__ +#define __UI33_H__ -void ui_add_message( String fmt, ... ); -void ui_draw_messages( void ); +#define UI33_BLACK 0 +#define UI33_RED 1 +#define UI33_GREEN 2 +#define UI33_BLUE 3 +#define UI33_YELLOW 4 +#define UI33_ORANGE 5 +#define UI33_MAGENTA 6 +#define UI33_CYAN 7 +#define UI33_WHITE 8 -#endif /** UI **/ + +typedef struct { + Size x, y; +} Mouse33; + +extern Mouse33 __mouse; + + +void ui33_add_message( String fmt, ... ); +void ui33_draw_messages( void ); +void ui33_draw_mouse( void ); + + +#endif /** UI33_H **/ diff --git a/makefile b/makefile index 36d7c36..b36fe8b 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,7 @@ -CC = clang +CC = gcc PROJECT = engine33 -OBJS = main.o system.o logger.o font33.o strings33.o ui33.o clock.o display.o +OBJS = main.o system33.o input33.o logger33.o font33.o strings33.o ui33.o clock33.o display33.o PDIR = ./bin .PATH: ./src @@ -10,7 +10,7 @@ INCS = -I./include -I./include/musl -I./include/libdrm LIBS = -L./lib/musl -L./lib/libdrm -CFLAGS = -march=native -mtune=native -std=c99 -static -w -Wall -Werror -Wextra -Wshadow -Wpedantic -D_XOPEN_SOURCE=700 +CFLAGS = -march=native -mtune=native -static -w -Wall -Werror -Wextra -Wshadow -Wpedantic -D_XOPEN_SOURCE=700 .MAKE.JOBS = 1C diff --git a/src/clock.c b/src/clock.c deleted file mode 100644 index 7cb5ec3..0000000 --- a/src/clock.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "sys/time.h" - -#include "clock.h" - - -Size clock_get_us( void ) -{ - static struct timeval tv; - gettimeofday( &tv, 0 ); - return (tv.tv_sec * 1000000) + tv.tv_usec; -} - -f64 clock_get_s_hires( void ) -{ - static struct timeval tv; - gettimeofday( &tv, 0 ); - return (f64)((f64)tv.tv_sec + ((f64)tv.tv_usec / 1000000)); -} - diff --git a/src/clock33.c b/src/clock33.c new file mode 100644 index 0000000..2fe0d3c --- /dev/null +++ b/src/clock33.c @@ -0,0 +1,19 @@ +#include "sys/time.h" + +#include "clock33.h" + + +Size clock_get_us( void ) +{ + static struct timeval tv; + gettimeofday( &tv, 0 ); + return (tv.tv_sec * 1000000) + tv.tv_usec; +} + +f64 clock_get_s_hires( void ) +{ + static struct timeval tv; + gettimeofday( &tv, 0 ); + return (f64)((f64)tv.tv_sec + ((f64)tv.tv_usec / 1000000)); +} + diff --git a/src/display.c b/src/display.c deleted file mode 100644 index bad4d69..0000000 --- a/src/display.c +++ /dev/null @@ -1,592 +0,0 @@ -#include "string.h" -#include "stdlib.h" -#include "signal.h" -#include "fcntl.h" -#include "errno.h" -#include "termios.h" -#include "unistd.h" -#include "poll.h" -#include "dirent.h" -#include "termio.h" -#include "stdio.h" - -#include "libdrm/drm_mode.h" -#include "sys/vt.h" -#include "sys/kd.h" - -#include "sys/ioctl.h" -#include "sys/mman.h" - -#include "display.h" -#include "system.h" -#include "logger.h" -#include "options.h" - - -#define REL_SIGNAL SIGUSR1 -#define ACQ_SIGNAL SIGUSR2 -#define REL_EVENT 1 -#define ACQ_EVENT 2 - - -Display __display = {0}; - - -typedef struct { - struct drm_mode_card_res drmRes; - __u64 *drmRes_fbs; - __u32 *drmRes_conns; - __u64 *drmRes_encs; - __u64 *drmRes_crtcs; - - __u64 connProps[ 16 ]; - __u64 connPropVals[ 16 ]; - __u64 connEncs[ 16 ]; - struct drm_mode_modeinfo connModes[ 32 ]; - struct drm_mode_get_encoder *encoder; - - struct drm_mode_create_dumb drmCreateDumb[2]; - struct drm_mode_map_dumb drmMapDumb[2]; - struct drm_mode_fb_cmd drmFBCmd[2]; -} DRMData_d; - -static DRMData_d drmData = {0,}; - -static int vtPipe[2] = { -1, -1 }; - -static struct termios termOldConfig; -static struct vt_mode vtModeOld = {0,}; - -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 ); -static void _vt_acquire( void ); -static void _vt_switch_sighandler(int sig); - - -err display_init( void ) -{ - struct termios termConfig; - - - if(!isatty(STDIN_FILENO)) { - logf( "stdin is not a terminal" ); - return E33_EXIT_FAILURE; - } - - if( tcgetattr(STDIN_FILENO, &termOldConfig) == -1 ) { - logf( "Could not get 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() ) { - logw( "Failed to initialize VT switcher. VT switching will not be available" ); - } - - - if( _open_graphics_device() ) { - logf( "Failed to find a suitable graphics device" ); - return E33_EXIT_FAILURE; - } - - 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() ) { - logf( "Failed to get resources" ); - return E33_EXIT_FAILURE; - } - if( _get_drm_connector() ) { - logf( "Failed to set connector" ); - return E33_EXIT_FAILURE; - } - if( _get_drm_framebuffer() ) { - logf( "Failed to set framebuffer" ); - return E33_EXIT_FAILURE; - } - if( _get_drm_crtc() ) { - logf( "Failed to set crtc" ); - return E33_EXIT_FAILURE; - } - - - __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; - - free( drmData.drmRes_fbs ); - free( drmData.drmRes_encs ); - free( drmData.drmRes_conns ); - - return E33_EXIT_SUCCESS; -} - -void display_flip( void ) -{ - static u8 i = 1; - - struct drm_mode_crtc_page_flip flip = { 0, }; - - __display.surface.data = __display.fb.map[i]; - i ^= 1; - __display.crtc.fb_id = __display.fb.id[i]; - - if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_SETCRTC, &__display.crtc ) == -1 ) { - logw( "Failed to set CRTC for page flip prep. Skipping" ); - return; - } - - flip.fb_id = __display.fb.id[i]; - flip.crtc_id = __display.crtc.crtc_id; - flip.user_data = ((__u64)(&__display.crtc.crtc_id)); - flip.flags = DRM_MODE_PAGE_FLIP_EVENT; - - e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_PAGE_FLIP, &flip ); - - /* TODO remove later */ - memset( __display.surface.data, 0, (uSize)__display.fb.size ); -} - -void display_term( void ) -{ - if( e33_ioctl( __display.devfd, DRM_IOCTL_DROP_MASTER, 0 ) == -1 ) { - logw( "Failed to drop drm master. Oh well" ); - } - - if( munmap( __display.fb.map[0], (uSize)__display.fb.size ) == -1 ) { - logw( "Failed to unmap framebuffer[0]. Oh well" ); - } - if( munmap( __display.fb.map[1], (uSize)__display.fb.size ) == -1 ) { - logw( "Failed to unmap framebuffer[1]. Oh well" ); - } - - if( close( __display.devfd ) ) { - logw( "Failed to close graphics device. Oh well" ); - } - - free( drmData.drmRes_crtcs ); - - if( ioctl(__display.ttyfd, VT_SETMODE, &vtModeOld) < 0 ) { - logw( "Could not reset VT mode. Oh well" ); - } - - if( tcsetattr(STDIN_FILENO, TCSAFLUSH, &termOldConfig) == -1 ) { - logw( "Failed to set stdin attributes. Oh well" ); - } - - if( close( __display.ttyfd ) == -1 ) { - logw( "Failed to close TTY. Oh well" ); - } -} - - -void display_vtswitcher_poll( int timeout ) -{ - struct pollfd fds[1]; - unsigned char event; - - fds[0].fd = vtPipe[0]; - fds[0].events = POLLIN; - fds[0].revents = 0; - - poll( fds, 1, timeout ); - if( !fds[0].revents ) { - return; - } - - if( read(fds[0].fd, &event, sizeof(event)) != sizeof(event) ) { - logw( "Invalid VT switch events read"); - return; - } - - switch(event) { - case REL_EVENT: _vt_release(); - break; - case ACQ_EVENT: _vt_acquire(); - break; - } -} - - - - - -static err _open_graphics_device( void ) -{ - struct drm_get_cap cap = {0,}; - - - if( (__display.devfd = open(DRM_DEVICE, O_RDWR )) == -1 ) { - logw( "Failed to open DRM device" ); - return E33_EXIT_FAILURE; - } - - cap.capability = DRM_CAP_DUMB_BUFFER; - - if( e33_ioctl( __display.devfd, DRM_IOCTL_GET_CAP, &cap ) == -1 ) { - logw( "Failed to get DRM device capabilities" ); - return E33_EXIT_FAILURE; - } - - if( cap.value ) { - return E33_EXIT_SUCCESS; - } - - return E33_EXIT_FAILURE; -} - -static Size _get_drm_resources( void ) -{ - if( e33_ioctl(__display.devfd, (int)DRM_IOCTL_MODE_GETRESOURCES, &drmData.drmRes) == -1 ) { - logw( "Failed to init drm resources" ); - return E33_EXIT_FAILURE; - } - - 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(__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(__u32) * drmData.drmRes.count_connectors ); - - drmData.drmRes.fb_id_ptr = (__u64)drmData.drmRes_fbs; - drmData.drmRes.crtc_id_ptr = (__u64)drmData.drmRes_crtcs; - drmData.drmRes.connector_id_ptr = (__u64)drmData.drmRes_conns; - drmData.drmRes.encoder_id_ptr = (__u64)drmData.drmRes_encs; - - /* Second call writes drm resource data using the given pointers */ - if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_GETRESOURCES, &drmData.drmRes ) == -1 ) { - logw( "Failed to get drm resources" ); - return E33_EXIT_FAILURE; - } - - return E33_EXIT_SUCCESS; -} - - -static Size _get_drm_connector( void ) -{ - 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( __display.devfd, (int)DRM_IOCTL_MODE_GETCONNECTOR, connector ) == -1 ) { - continue; - } - - 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( __display.devfd, (int)DRM_IOCTL_MODE_GETCONNECTOR, connector) == -1 ) { - continue; - } - - for( j = 0; j < connector->count_modes; ++j ) - { - struct drm_mode_modeinfo *mode = &drmData.connModes[j]; - - if( e33_strcmp( 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; - } - } - } - } - - logw( "Failed to find a valid connector" ); - return E33_EXIT_FAILURE; -} - -static Size _get_drm_crtc( void ) -{ - struct drm_mode_get_encoder encoder = {0,}; - struct drm_mode_crtc *crtc = &__display.crtc; - - encoder.encoder_id = __display.connector.encoder_id; - - 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; - - if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_GETCRTC, crtc ) == -1 ) { - loge( "Failed to get CRTC" ); - return E33_EXIT_FAILURE; - } - - crtc->fb_id = drmData.drmFBCmd[0].fb_id; - crtc->set_connectors_ptr = (__u64)drmData.drmRes_conns; - crtc->count_connectors = 1; - crtc->mode = __display.mode; - crtc->mode_valid = 1; - - if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_SETCRTC, crtc ) == -1 ) { - loge( "Could not set CRTC" ); - return E33_EXIT_FAILURE; - } - - return E33_EXIT_SUCCESS; -} - -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 = &__display.mode; - u8 i; - - for( i = 0; i < 2; ++i ) - { - drmCreateDumb[i].width = mode->hdisplay; - drmCreateDumb[i].height = mode->vdisplay; - drmCreateDumb[i].bpp = 32; - - if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_CREATE_DUMB, - drmCreateDumb + i ) == -1 ) - { - loge( "Failed to create dumb buffer #%d", i ); - return E33_EXIT_FAILURE; - } - - drmFBCmd[i].width = drmCreateDumb[i].width; - drmFBCmd[i].height = drmCreateDumb[i].height; - drmFBCmd[i].bpp = drmCreateDumb[i].bpp; - drmFBCmd[i].pitch = drmCreateDumb[i].pitch; - drmFBCmd[i].depth = 24; - drmFBCmd[i].handle = drmCreateDumb[i].handle; - - if( e33_ioctl( __display.devfd, (int)DRM_IOCTL_MODE_ADDFB, drmFBCmd + i ) == -1 ) { - loge( "Failed to add framebuffer #%d", i ); - return E33_EXIT_FAILURE; - } - - __display.fb.id[i] = drmFBCmd[i].fb_id; - - drmMapDumb[i].handle = drmCreateDumb[i].handle; - - 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; - } - - __display.fb.map[i] = - mmap( 0, drmCreateDumb[i].size, PROT_READ | PROT_WRITE, - MAP_SHARED, __display.devfd, drmMapDumb[i].offset ); - - if( __display.fb.map[i] == MAP_FAILED ) { - loge( "Failed to map framebuffer #%d", i ); - return E33_EXIT_FAILURE; - } - } - - return E33_EXIT_SUCCESS; -} - - - - - - - - - - - - - - - - -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) -{ - 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 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 vtMode = {0,}; - sigset_t set; - - - __display.ttyfd = -1; - - if( pipe2(vtPipe, 0) == -1 ) - { - 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 ) < 0 ) { - loge( "Could not open TTY for VT control" ); - return E33_EXIT_FAILURE; - } - - - if( e33_has_signal(REL_SIGNAL) ) { - loge( "VT release signal is already in use"); - return E33_EXIT_FAILURE; - } - if( e33_has_signal(ACQ_SIGNAL) ) { - loge( "VT acquire signal is already in use"); - return E33_EXIT_FAILURE; - } - - if( e33_set_signal( REL_SIGNAL, _vt_switch_sighandler ) ) { - loge( "Could not set relese signal handler"); - return E33_EXIT_FAILURE; - } - if( e33_set_signal( ACQ_SIGNAL, _vt_switch_sighandler ) ) { - loge( "Could not set acquire signal handler"); - return E33_EXIT_FAILURE; - } - - - if( ioctl(__display.ttyfd, VT_GETMODE, &vtModeOld) < 0 ) { - logw( "Could not get VT mode" ); - return E33_EXIT_FAILURE; - } - - vtMode = vtModeOld; - vtMode.mode = VT_PROCESS; - vtMode.relsig = REL_SIGNAL; - vtMode.acqsig = ACQ_SIGNAL; - vtMode.frsig = SIGIO; - - if( ioctl(__display.ttyfd, VT_SETMODE, &vtMode) < 0 ) { - logw( "Could not set VT mode" ); - return E33_EXIT_FAILURE; - } - - return E33_EXIT_SUCCESS; -} - - - - - diff --git a/src/display33.c b/src/display33.c new file mode 100644 index 0000000..928d4e0 --- /dev/null +++ b/src/display33.c @@ -0,0 +1,575 @@ +#include "string.h" +#include "stdlib.h" +#include "signal.h" +#include "fcntl.h" +#include "errno.h" +#include "termios.h" +#include "unistd.h" +#include "poll.h" +#include "dirent.h" +#include "termio.h" +#include "stdio.h" +#include "libdrm/drm_mode.h" +#include "sys/vt.h" +#include "sys/kd.h" +#include "sys/ioctl.h" +#include "sys/mman.h" + +#include "display33.h" +#include "system33.h" +#include "logger33.h" +#include "options33.h" + + +#define REL_SIGNAL SIGUSR1 +#define ACQ_SIGNAL SIGUSR2 +#define REL_EVENT 1 +#define ACQ_EVENT 2 + + +Display33 __display = {0,}; + + +typedef struct { + struct drm_mode_card_res drmRes; + __u64 *drmRes_fbs; + __u32 *drmRes_conns; + __u64 *drmRes_encs; + __u64 *drmRes_crtcs; + + __u64 connProps[ 16 ]; + __u64 connPropVals[ 16 ]; + __u64 connEncs[ 16 ]; + struct drm_mode_modeinfo connModes[ 32 ]; + struct drm_mode_get_encoder *encoder; + + struct drm_mode_create_dumb drmCreateDumb[2]; + struct drm_mode_map_dumb drmMapDumb[2]; + struct drm_mode_fb_cmd drmFBCmd[2]; +} DRMData_t; + +static DRMData_t drmData = {0,}; + +static int vtPipe[2] = { -1, -1 }; + +static struct termios termOldConfig; +static struct vt_mode vtModeOld = {0,}; + +static Error _open_graphics_device( void ); +static Error _get_drm_resources( void ); +static Error _get_drm_connector( void ); +static Error _get_drm_crtc( void ); +static Error _get_drm_framebuffer(void ); + +static Size _init_vt_switch( void ); +static void _vt_release( void ); +static void _vt_acquire( void ); +static void _vt_switch_sighandler(int sig); + + +Error display33_init( void ) +{ + struct termios termConfig; + + + if(!isatty(STDIN_FILENO)) { + LOGF( "stdin is not a terminal." ); + return E33_EXIT_FAILURE; + } + + if( tcgetattr(STDIN_FILENO, &termOldConfig) == -1 ) { + LOGF( "Could not get 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() ) { + LOGW( "Failed to initialize VT switcher. VT switching will not be available." ); + } + + + if( _open_graphics_device() ) { + LOGF( "Failed to find a suitable graphics device." ); + return E33_EXIT_FAILURE; + } + + 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() ) { + LOGF( "Failed to get resources." ); + return E33_EXIT_FAILURE; + } + if( _get_drm_connector() ) { + LOGF( "Failed to set connector." ); + return E33_EXIT_FAILURE; + } + if( _get_drm_framebuffer() ) { + LOGF( "Failed to set framebuffer." ); + return E33_EXIT_FAILURE; + } + if( _get_drm_crtc() ) { + LOGF( "Failed to set crtc." ); + return E33_EXIT_FAILURE; + } + + + __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 = E33_TRUE; + + free( drmData.drmRes_fbs ); + free( drmData.drmRes_encs ); + free( drmData.drmRes_conns ); + + return E33_EXIT_SUCCESS; +} + +void display33_flip( void ) +{ + static u8 i_s = 1; + + struct drm_mode_crtc_page_flip flip = { 0, }; + + __display.surface.data = __display.fb.map[i_s]; + i_s ^= 1; + __display.crtc.fb_id = __display.fb.id[i_s]; + + if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_SETCRTC, &__display.crtc ) == -1 ) { + LOGW( "Failed to set CRTC for page flip prep. Skipping." ); + return; + } + + flip.fb_id = __display.fb.id[i_s]; + flip.crtc_id = __display.crtc.crtc_id; + flip.user_data = ((__u64)(&__display.crtc.crtc_id)); + flip.flags = DRM_MODE_PAGE_FLIP_EVENT; + + e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_PAGE_FLIP, &flip ); + + /* TODO remove later */ + memset( __display.surface.data, 0, (uSize)__display.fb.size ); +} + +void display33_term( void ) +{ + if( e33_ioctl( __display.devFd, DRM_IOCTL_DROP_MASTER, 0 ) == -1 ) { + LOGW( "Failed to drop drm master." ); + } + + if( munmap( __display.fb.map[0], (uSize)__display.fb.size ) == -1 ) { + LOGW( "Failed to unmap framebuffer[0]." ); + } + if( munmap( __display.fb.map[1], (uSize)__display.fb.size ) == -1 ) { + LOGW( "Failed to unmap framebuffer[1]." ); + } + + if( close( __display.devFd ) ) { + LOGW( "Failed to close graphics device." ); + } + + free( drmData.drmRes_crtcs ); + + if( ioctl(__display.ttyFd, VT_SETMODE, &vtModeOld) < 0 ) { + LOGW( "Could not reset VT mode." ); + } + + if( tcsetattr(STDIN_FILENO, TCSAFLUSH, &termOldConfig) == -1 ) { + LOGW( "Failed to set stdin attributes." ); + } + + if( close( __display.ttyFd ) == -1 ) { + LOGW( "Failed to close TTY." ); + } +} + + +void display33_vtswitcher_poll( int timeout ) +{ + struct pollfd fds[1]; + unsigned char event; + + fds[0].fd = vtPipe[0]; + fds[0].events = POLLIN; + fds[0].revents = 0; + + poll( fds, 1, timeout ); + if( !fds[0].revents ) { + return; + } + + if( read(fds[0].fd, &event, sizeof(event)) != sizeof(event) ) { + LOGW( "Invalid VT switch events read."); + return; + } + + switch(event) { + case REL_EVENT: _vt_release(); + break; + case ACQ_EVENT: _vt_acquire(); + break; + } +} + + + + + +static Error _open_graphics_device( void ) +{ + struct drm_get_cap cap = {0,}; + + + if( (__display.devFd = open( E33_DRM_DEVICE, O_RDWR )) == -1 ) { + LOGE( "Failed to open DRM device '%s'.", E33_DRM_DEVICE ); + return E33_EXIT_FAILURE; + } + + cap.capability = DRM_CAP_DUMB_BUFFER; + + if( e33_ioctl( __display.devFd, DRM_IOCTL_GET_CAP, &cap ) == -1 ) { + LOGW( "Failed to get DRM device capabilities." ); + return E33_EXIT_FAILURE; + } + + if( cap.value ) { + return E33_EXIT_SUCCESS; + } + + return E33_EXIT_FAILURE; +} + +static Size _get_drm_resources( void ) +{ + if( e33_ioctl(__display.devFd, (int)DRM_IOCTL_MODE_GETRESOURCES, &drmData.drmRes) == -1 ) { + LOGE( "Failed to init drm resources." ); + return E33_EXIT_FAILURE; + } + + 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(__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(__u32) * drmData.drmRes.count_connectors ); + + drmData.drmRes.fb_id_ptr = (__u64)drmData.drmRes_fbs; + drmData.drmRes.crtc_id_ptr = (__u64)drmData.drmRes_crtcs; + drmData.drmRes.connector_id_ptr = (__u64)drmData.drmRes_conns; + drmData.drmRes.encoder_id_ptr = (__u64)drmData.drmRes_encs; + + /* Second call writes drm resource data using the given pointers */ + if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_GETRESOURCES, &drmData.drmRes ) == -1 ) { + LOGE( "Failed to get drm resources." ); + return E33_EXIT_FAILURE; + } + + return E33_EXIT_SUCCESS; +} + + +static Size _get_drm_connector( void ) +{ + 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( __display.devFd, (int)DRM_IOCTL_MODE_GETCONNECTOR, connector ) == -1 ) { + continue; + } + + 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( __display.devFd, (int)DRM_IOCTL_MODE_GETCONNECTOR, connector) == -1 ) { + continue; + } + + for( j = 0; j < connector->count_modes; ++j ) + { + struct drm_mode_modeinfo *mode = &drmData.connModes[j]; + + if( e33_strcmp( mode->name, E33_DRM_MODE ) && (mode->vrefresh == E33_DRM_RATE) ) + { + /* TODO there has to be a better way */ + if( mode->hdisplay == 1366 ) { + mode->hdisplay += 10; + } + + __display.mode = *mode; + return E33_EXIT_SUCCESS; + } + } + } + } + + LOGE( "Failed to find a valid connector." ); + return E33_EXIT_FAILURE; +} + +static Size _get_drm_crtc( void ) +{ + struct drm_mode_get_encoder encoder = {0,}; + struct drm_mode_crtc *crtc = &__display.crtc; + + encoder.encoder_id = __display.connector.encoder_id; + + 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; + + if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_GETCRTC, crtc ) == -1 ) { + LOGE( "Failed to get CRTC." ); + return E33_EXIT_FAILURE; + } + + crtc->fb_id = drmData.drmFBCmd[0].fb_id; + crtc->set_connectors_ptr = (__u64)drmData.drmRes_conns; + crtc->count_connectors = 1; + crtc->mode = __display.mode; + crtc->mode_valid = 1; + + if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_SETCRTC, crtc ) == -1 ) { + LOGE( "Could not set CRTC." ); + return E33_EXIT_FAILURE; + } + + return E33_EXIT_SUCCESS; +} + +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 = &__display.mode; + u8 i; + + for( i = 0; i < 2; ++i ) + { + drmCreateDumb[i].width = mode->hdisplay; + drmCreateDumb[i].height = mode->vdisplay; + drmCreateDumb[i].bpp = 32; + + if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_CREATE_DUMB, + drmCreateDumb + i ) == -1 ) + { + LOGE( "Failed to create dumb buffer." ); + return E33_EXIT_FAILURE; + } + + drmFBCmd[i].width = drmCreateDumb[i].width; + drmFBCmd[i].height = drmCreateDumb[i].height; + drmFBCmd[i].bpp = drmCreateDumb[i].bpp; + drmFBCmd[i].pitch = drmCreateDumb[i].pitch; + drmFBCmd[i].depth = 24; + drmFBCmd[i].handle = drmCreateDumb[i].handle; + + if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_ADDFB, drmFBCmd + i ) == -1 ) { + LOGE( "Failed to add framebuffer." ); + return E33_EXIT_FAILURE; + } + + __display.fb.id[i] = drmFBCmd[i].fb_id; + + drmMapDumb[i].handle = drmCreateDumb[i].handle; + + if( e33_ioctl( __display.devFd, (int)DRM_IOCTL_MODE_MAP_DUMB, drmMapDumb + i ) == -1 ) + { + LOGE( "Failed to map dumb buffer." ); + return E33_EXIT_FAILURE; + } + + __display.fb.map[i] = + mmap( 0, drmCreateDumb[i].size, PROT_READ | PROT_WRITE, + MAP_SHARED, __display.devFd, drmMapDumb[i].offset ); + + if( __display.fb.map[i] == MAP_FAILED ) { + LOGE( "Failed to map framebuffer." ); + return E33_EXIT_FAILURE; + } + } + + return E33_EXIT_SUCCESS; +} + +static void _vt_release( void ) +{ + LOGI( "VT release signal."); + + if( ioctl( __display.devFd, DRM_IOCTL_DROP_MASTER, 0 ) ) { + LOGW( "Could not drop DRM master." ); + } + + if( ioctl(__display.ttyFd, VT_RELDISP, 1) < 0 ) { + LOGW( "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 ) { + LOGW( "(vt_acquire) Failed to acquire VT."); + } + + if( ioctl( __display.devFd, (int)DRM_IOCTL_MODE_SETCRTC, &__display.crtc ) == -1 ) { + LOGW( "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 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 vtMode = {0,}; + sigset_t set; + + + __display.ttyFd = -1; + + if( pipe2(vtPipe, 0) == -1 ) + { + vtPipe[0] = vtPipe[1] = -1; + LOGW( "Could not set VT pipes."); + return E33_EXIT_FAILURE; + } + + if( _set_pipe(vtPipe[0]) ) { + LOGW( "Could not set VT read pipe." ); + return E33_EXIT_FAILURE; + } + if( _set_pipe(vtPipe[1]) ) { + LOGW( "Could not set VT write pipe." ); + return E33_EXIT_FAILURE; + } + + + if( __display.ttyFd = open("/dev/tty", O_RDWR ) < 0 ) { + LOGW( "Could not open TTY for VT control." ); + return E33_EXIT_FAILURE; + } + + + if( e33_has_signal(REL_SIGNAL) ) { + LOGW( "VT release signal is already in use."); + return E33_EXIT_FAILURE; + } + if( e33_has_signal(ACQ_SIGNAL) ) { + LOGW( "VT acquire signal is already in use."); + return E33_EXIT_FAILURE; + } + + if( e33_set_signal( REL_SIGNAL, _vt_switch_sighandler ) ) { + LOGW( "Could not set relese signal handler."); + return E33_EXIT_FAILURE; + } + if( e33_set_signal( ACQ_SIGNAL, _vt_switch_sighandler ) ) { + LOGW( "Could not set acquire signal handler."); + return E33_EXIT_FAILURE; + } + + + if( ioctl(__display.ttyFd, VT_GETMODE, &vtModeOld) < 0 ) { + LOGW( "Could not get VT mode." ); + return E33_EXIT_FAILURE; + } + + vtMode = vtModeOld; + vtMode.mode = VT_PROCESS; + vtMode.relsig = REL_SIGNAL; + vtMode.acqsig = ACQ_SIGNAL; + vtMode.frsig = SIGIO; + + if( ioctl(__display.ttyFd, VT_SETMODE, &vtMode) < 0 ) { + LOGW( "Could not set VT mode." ); + return E33_EXIT_FAILURE; + } + + return E33_EXIT_SUCCESS; +} + + + + + diff --git a/src/input33.c b/src/input33.c new file mode 100644 index 0000000..1ba1ff2 --- /dev/null +++ b/src/input33.c @@ -0,0 +1,232 @@ +#include "fcntl.h" +#include "dirent.h" +#include "stdio.h" +#include "stdlib.h" +#include "unistd.h" +#include "string.h" +#include "sys/stat.h" +#include "sys/kd.h" +#include +#include + +#include "input33.h" +#include "logger33.h" +#include "strings33.h" + + +#define _INPUT_DEVICES_MAX 8 +#define _POLL_EVENTS_MAX 16 + + +Input33 __input = {0}; + + +static int _is_char_device( const struct dirent *f ); +static Boolean _is_keyboard( Size fd ); +static Boolean _is_mouse( Size fd ); +static Size _has_key( Size fd, unsigned int event ); +static Size _has_rel( Size fd, unsigned int event ); +static u64 _has_evbits( Size fd, unsigned int type ); + + +Error input33_init( void ) +{ + Size i, deviceCount; + Boolean hasKeyboard = E33_FALSE; + Boolean hasMouse = E33_FALSE; + struct dirent **evfs; + + deviceCount = scandir( "/dev/input", &evfs, _is_char_device, 0 ); + + if( deviceCount <= 0 ) { + LOGE( "No valid character devices found." ); + return E33_EXIT_FAILURE; + } + + for( i = 0; i < deviceCount; ++i ) + { + Size j; + Size devFd; + char path[ _STRING_MAX ]; + + snprintf( path, _STRING_MAX , "%s%s", "/dev/input/", evfs[i]->d_name ); + free( evfs[i] ); + + devFd = open( path, O_RDONLY | O_NONBLOCK ); + if( devFd == -1 ) { + continue; + } + + if( _is_keyboard( devFd ) ) + { + hasKeyboard = E33_TRUE; + __input.devices[ __input.deviceCount++ ] = devFd; + } + else if( _is_mouse(devFd) ) + { + hasMouse = E33_TRUE; + __input.devices[ __input.deviceCount++ ] = devFd; + ioctl( devFd, EVIOCGRAB, 1 ); + } + else { + close( devFd ); + } + + if( __input.deviceCount == _INPUT_DEVICES_MAX ){ + break; + } + } + + free( evfs ); + + if( (hasKeyboard == E33_TRUE) && (hasMouse == E33_TRUE) ) { + return E33_EXIT_SUCCESS; + } + + return E33_EXIT_FAILURE; +} + +void input33_poll( void ) +{ + u16 i; + + for( i = 0; i < __input.deviceCount; ++i ) + { + Size j; + Size readBytes; + Size eventCount; + struct input_event events[ _POLL_EVENTS_MAX ]; + + __input.relStates[REL_X] = 0; + __input.relStates[REL_Y] = 0; + __input.relStates[REL_WHEEL] = 0; + + readBytes = read( __input.devices[i], events, + sizeof(struct input_event) * _POLL_EVENTS_MAX ); + + if( readBytes == -1 ) { + continue; + } + + eventCount = readBytes / sizeof( struct input_event ); + + for( j = 0; j < eventCount; ++j ) + { + switch( events[j].type ) + { + case EV_KEY: + __input.keyStates[ events[j].code ] = events[j].value; + + if( (events[j].value == _PRESS) || (events[j].value == _REPEAT) ) + { + __input.buffer[__input.tail++] = events[j].code; + __input.tail &= (_KBBUFF_LEN - 1); + + if( __input.tail == __input.head ) + { + ++__input.head; + __input.head &= (_KBBUFF_LEN - 1); + } + } + break; + + case EV_REL: + __input.relStates[ events[j].code ] = events[j].value; + break; + } + } + } + + __input.modFlags = 6; + ioctl( 0, TIOCLINUX, &__input.modFlags ); + ioctl( 0, KDGKBLED, &__input.cnsFlags ); +} + +void input33_term( void ) +{ + Size i; + + for( i = 0; i < __input.deviceCount; ++i ) { + close( __input.devices[i] ); + } +} + + +static u64 _has_evbits( Size fd, unsigned int type ) +{ + u64 kbb; + + if( ioctl( fd, EVIOCGBIT( 0, (int)sizeof(kbb) ), &kbb ) == -1 ) { + return 0; + } + + return (kbb & (1 << type)); +} + +static Size _has_key( Size fd, unsigned int event ) +{ + unsigned char bits[ (KEY_MAX >> 3) + 1 ]; + + if( ioctl( fd, EVIOCGBIT(EV_KEY, (int)sizeof(bits)), &bits ) == -1 ) { + return 0; + } + + return ( (bits[event >> 3] & (1 << (event % 8))) > 0 ); +} + +static Size _has_rel( Size fd, unsigned int event ) +{ + unsigned char bits[ (REL_MAX >> 3) + 1 ]; + + if( ioctl( fd, EVIOCGBIT(EV_REL, (int)sizeof(bits)), &bits ) == -1 ) { + return 0; + } + + return ( (bits[event >> 3] & (1 << (event % 8))) > 0 ); +} + +static Boolean _is_mouse( Size fd ) +{ + if( _has_evbits( fd, EV_KEY ) && + _has_evbits( fd, EV_REL ) ) + { + return( _has_rel( fd, REL_X ) & + _has_rel( fd, REL_Y ) & + _has_key( fd, BTN_LEFT ) & + _has_key( fd, BTN_RIGHT ) & 1 ); + } + + return E33_FALSE; +} + +static Boolean _is_keyboard( Size fd ) +{ + if( _has_evbits( fd, EV_KEY ) ) + { + return( _has_key( fd, KEY_W ) & + _has_key( fd, KEY_SPACE ) & + _has_key( fd, KEY_LEFTSHIFT ) & + _has_key( fd, KEY_I ) & 1 ); + } + + return E33_FALSE; +} + +static int _is_char_device( const struct dirent *f ) +{ + struct stat fstat; + char path[512]; + + if( strncmp( f->d_name, "event", 5 ) ) { + return 0; + } + + snprintf( path, 512, "%s%s", "/dev/input/", f->d_name ); + + if( stat( path, &fstat ) ) { + return 0; + } + + return S_ISCHR( fstat.st_mode ); +} + diff --git a/src/logger.c b/src/logger.c deleted file mode 100644 index c90f364..0000000 --- a/src/logger.c +++ /dev/null @@ -1,103 +0,0 @@ -#include - -#include "fcntl.h" -#include "stdarg.h" -#include "errno.h" -#include "time.h" -#include "unistd.h" -#include "stdio.h" -#include "string.h" - -#include "logger.h" -#include "options.h" -#include "ui33.h" - -Logger __logger; - - -static char *ansiColourPrefix[5] = { - "[\x1b[36mD\x1b[37m]", - "[\x1b[32mI\x1b[37m]", - "[\x1b[35mW\x1b[37m]", - "[\x1b[33mE\x1b[37m]", - "[\x1b[31mFl\x1b[37m]", -}; - -static char uiColourPrefix[5][11] = { - { 6, '[', 'D', 'e', 'b', 'u', 'g', ']', ' ', 1, '\0' }, - { 3, '[', 'I', 'n', 'f', 'o', ']', ' ', 1, '\0', ' ' }, - { 5, '[', 'W', 'a', 'r', 'n', ']', ' ', 1, '\0', ' ' }, - { 8, '[', 'E', 'r', 'r', 'o', 'r', ']', ' ', 1, '\0' }, - { 2, '[', 'F', 'a', 't', 'a', 'l', ']', ' ', 1, '\0' } -}; - -Size logger_init( void ) -{ - String logfile[512]; - - if( LOG_PATH[0] == '~' ) { - snprintf(logfile, 512, "%s/%s", getenv("HOME"), LOG_PATH+1); - } else { - snprintf(logfile, 512, "%s", LOG_PATH); - } - - __logger.fd = open(logfile, - O_CREAT | O_TRUNC | O_WRONLY | O_NOCTTY | O_TTY_INIT, - 0644 ); - - if( __logger.fd < 0 ) { - printf( "Unable to initialize logger. Exiting." ); - return E33_EXIT_FAILURE; - } - - __logger.func = 0; - - ui_add_message( "Welcome to Engine33" ); - dprintf( __logger.fd, "\033[3J\033[1;1HWelcome to Engine33!\r\n\r\n" ); - - return E33_EXIT_SUCCESS; -} - -void logger_term( void ) -{ - logi( "Goodbye!" ); - close( __logger.fd ); -} - -void logger( Size level, const char *fmt, ... ) -{ - static char uiString[256]; - - time_t currentTime; - struct tm *m_time; - - - va_list args; - va_start(args, fmt); - - time(¤tTime); - m_time = localtime(¤tTime); - - snprintf( uiString, 256, "%s%s", uiColourPrefix[level], fmt ); - - dprintf( __logger.fd, "Engine33 [%02d:%02d:%02d] -", - m_time->tm_hour, m_time->tm_min, m_time->tm_sec ); - - dprintf( __logger.fd, " %s ", ansiColourPrefix[level] ); - vdprintf(__logger.fd, fmt, args); - - if( (level > LOG_INFO) && errno ) - { - String strerr = strerror(errno); - dprintf( __logger.fd, ". Reason: %s", strerr ); - snprintf( uiString, 256, "%s >> %s", uiString, strerr ); - errno = 0; - } - - dprintf( __logger.fd, ".\r\n" ); - - ui_add_message( uiString, args ); - - va_end(args); -} - diff --git a/src/logger33.c b/src/logger33.c new file mode 100644 index 0000000..d9b0d8d --- /dev/null +++ b/src/logger33.c @@ -0,0 +1,111 @@ +#include + +#include "fcntl.h" +#include "stdarg.h" +#include "errno.h" +#include "time.h" +#include "unistd.h" +#include "stdio.h" +#include "string.h" + +#include "options33.h" +#include "strings33.h" +#include "logger33.h" +#include "ui33.h" + + +typedef struct { + Size fd; +} Logger; + +Logger logger_t; + + +static char *_ansiColourPrefix[5] = { + "[\x1b[36mD\x1b[37m]", + "[\x1b[32mI\x1b[37m]", + "[\x1b[35mW\x1b[37m]", + "[\x1b[33mE\x1b[37m]", + "[\x1b[31mF\x1b[37m]" +}; + +static char _uiColourPrefix[5][5] = { + { UI33_CYAN, 'D', UI33_WHITE, ':', '\0' }, + { UI33_GREEN, 'I', UI33_WHITE, ':', '\0' }, + { UI33_YELLOW, 'W', UI33_WHITE, ':', '\0' }, + { UI33_ORANGE, 'E', UI33_WHITE, ':', '\0' }, + { UI33_RED, 'F', UI33_WHITE, ':', '\0' } +}; + + +Size logger33_init( void ) +{ + String logFile[ _STRING_MAX ]; + + if( E33_LOG_FILE[0] == '~' ) { + snprintf(logFile, _STRING_MAX , "%s/%s", getenv("HOME"), E33_LOG_FILE+1); + } else { + snprintf(logFile, _STRING_MAX , "%s", E33_LOG_FILE); + } + + logger_t.fd = open(logFile, + O_CREAT | O_TRUNC | O_WRONLY | O_NOCTTY | O_TTY_INIT, + 0644 ); + + if( logger_t.fd < 0 ) { + printf( "Unable to initialize logger. Exiting." ); + return E33_EXIT_FAILURE; + } + + ui33_add_message( "Welcome to Engine33!" ); + dprintf( logger_t.fd, "\033[3J\033[1;1HWelcome to Engine33!\r\n\r\n" ); + + return E33_EXIT_SUCCESS; +} + +void logger33_term( void ) +{ + LOGI( "Goodbye!" ); + close( logger_t.fd ); +} + +void _logger( Size level, String file, int line , String func, const char *fmt, ... ) +{ + char uiStringTemp[ _STRING_MAX ]; + char uiString[ _STRING_MAX ]; + + time_t currentTime; + struct tm *mTime; + + + va_list args; + va_start(args, fmt); + + + time(¤tTime); + mTime = localtime(¤tTime); + + + dprintf( logger_t.fd, "Engine33 [%02d:%02d:%02d] [%s:%d @%s()] -", + mTime->tm_hour, mTime->tm_min, mTime->tm_sec, file, line, func ); + + dprintf( logger_t.fd, " %s ", _ansiColourPrefix[level] ); + vdprintf(logger_t.fd, fmt, args); + + if( (level > _INFO) && errno ) + { + dprintf( logger_t.fd, " [%s]", strerror(errno) ); + errno = 0; + } + dprintf( logger_t.fd, "\r\n" ); + + + snprintf( uiStringTemp, _STRING_MAX , "%s %s", _uiColourPrefix[level], fmt ); + vsnprintf( uiString, _STRING_MAX , uiStringTemp, args ); + + ui33_add_message( uiString ); + + + va_end(args); +} + diff --git a/src/main.c b/src/main.c index bac0cd6..a727b52 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,11 @@ -#include "display.h" -#include "clock.h" -#include "logger.h" -#include "system.h" #include "signal.h" + +#include "display33.h" +#include "clock33.h" +#include "logger33.h" +#include "system33.h" #include "strings33.h" +#include "input33.h" #include "ui33.h" static void _term_sighandler( int sig ); @@ -14,37 +16,60 @@ int main(int argc, char *argv[]) Size fps, FPS; long timeOld, time; - if( e33_set_signal( SIGHUP, _term_sighandler ) == -1 ) { logw( "SIGHUP not handled"); } - if( e33_set_signal( SIGINT, _term_sighandler ) == -1 ) { logw( "SIGINT not handled"); } - if( e33_set_signal( SIGTERM, _term_sighandler ) == -1 ) { logw( "SIGTERM not handled"); } + if( e33_set_signal( SIGHUP, _term_sighandler ) == -1 ) { LOGW( "SIGHUP not handled"); } + if( e33_set_signal( SIGINT, _term_sighandler ) == -1 ) { LOGW( "SIGINT not handled"); } + if( e33_set_signal( SIGTERM, _term_sighandler ) == -1 ) { LOGW( "SIGTERM not handled"); } timeOld = clock_get_us(); time = 0; fps = 0; FPS = 0; - if( logger_init() ) { + if( logger33_init() ) { return EXIT_FAILURE; } - if( display_init() ) { + if( input33_init() ) { return EXIT_FAILURE; } - logd( "This is a test." ); + if( display33_init() ) { + return EXIT_FAILURE; + } while(1) { - display_vtswitcher_poll(1); + display33_vtswitcher_poll(1); if( __display.active ) { - qsuprintf( 5, 5, "fps: %d", FPS-1 ); + input33_poll(); + + QPRINTF( 5, 5, "fps: %d", FPS-1 ); + + if( KEYDOWN(KEY_K) ) { ui33_add_message("Pressed '%c'", 'K'); } + + if( MOUSEX ) { + __mouse.x += MOUSEX; + } + if( MOUSEY ) { + __mouse.y += MOUSEY; + } - ui_draw_messages(); - display_flip(); + + if( __mouse.x < 0 ) __mouse.x = 0; + if( __mouse.y < 0 ) __mouse.y = 0; + if( __mouse.x >= __display.surface.w ) __mouse.x = __display.surface.w-1; + if( __mouse.y >= __display.surface.h ) __mouse.y = __display.surface.h-1; + ui33_draw_mouse(); + + QPRINTF( 100, 5, "M: x(%d), y(%d)", __mouse.x, __mouse.y ); + + + ui33_draw_messages(); + display33_flip(); } @@ -60,8 +85,10 @@ int main(int argc, char *argv[]) ++fps; } - display_term(); - logger_term(); + + display33_term(); + logger33_term(); + input33_term(); return EXIT_SUCCESS; @@ -70,8 +97,8 @@ int main(int argc, char *argv[]) static void _term_sighandler( int sig ) { - display_term(); - logger_term(); + display33_term(); + logger33_term(); exit(0); } diff --git a/src/strings33.c b/src/strings33.c index 8613c02..0291393 100644 --- a/src/strings33.c +++ b/src/strings33.c @@ -3,74 +3,69 @@ #include "string.h" #include "strings33.h" -#include "types.h" +#include "types33.h" -extern Font33 defFont; -extern Font33 bigFont; - static Font33 *fonts[2] = { &defFont, &bigFont }; static u32 textColours[9] = { - 0xff000000, - 0xffffffff, - 0xffff0000, - 0xff00ff00, - 0xff0000ff, - 0xffffff00, - 0xff00ffff, - 0xffff00ff, - 0xffffaa00, + BLACK, + RED, + GREEN, + BLUE, + YELLOW, + ORANGE, + MAGENTA, + CYAN, + WHITE }; -void e33_uprintf( Surface *surf, Size f, u32 col, Size x, Size y, const char *fmt, ... ) +void e33_uprintf( Surface33 *surf, Size f, u32 col, Size x, Size y, const char *fmt, ... ) { - static char tmp[512]; + static char tmp[ _STRING_MAX ]; va_list args; va_start(args, fmt); - vsprintf(tmp, fmt, args); + vsnprintf(tmp, _STRING_MAX, fmt, args); e33_uprint( surf, f, col, x, y, tmp ); va_end(args); } -void e33_uprint( Surface *surf, Size f, u32 col, Size x, Size y, const char *str ) +void e33_uprint( Surface33 *surf, Size f, u32 col, Size x, Size y, const char *str ) { Size i, j, ofs; Font33 *font = fonts[f]; Size sWidth = surf->w; Size sHeight = surf->h; FontGlyph33 *glyphs = font->glyphs; - Size fbw = surf->w; - Size fbh = surf->h; u32 *out; - uSize slen = strlen(str); + uSize stringLen = strlen(str); Size strWid = 0; - for( i = 0; i < slen; ++i ) { + for( i = 0; i < stringLen; ++i ) { if( str[i] < 0x20 ) continue; - strWid += glyphs[ str[i] - 0x20 ].width; + strWid += glyphs[ str[i] - 0x20 ].w; } if( (x + strWid) >= sWidth ) { x -= (strWid - (sWidth - x)); } - if( (y + font->height) >= sHeight ) { - y -= (font->height - (sHeight - y)); + if( (y + font->h) >= sHeight ) { + y -= (font->h- (sHeight - y)); } if(x < 0) { x = 0; } if(y < 0) { y = 0; } out = surf->data + (x + (y * surf->w)); - for( i = 0, ofs = 0; i < slen; ++i ) + for( i = 0, ofs = 0; i < stringLen; ++i ) { if( str[i] < 0x20 ) { @@ -79,14 +74,14 @@ void e33_uprint( Surface *surf, Size f, u32 col, Size x, Size y, const char *str } FontGlyph33 *glyph = &glyphs[ str[i] - 0x20 ]; - Size numPlots = glyph->num_plots; - Size gWidth = glyph->width; + Size numPlots = glyph->plotCount; + Size gWidth = glyph->w; u16 *plots = glyph->plots; for( j = 0; j < numPlots; ++j ) { Size plot = plots[j]; - Size offset = (((plot & font->yAnd) * fbw) + (plot >> font->xShift)) + ofs; + Size offset = (((plot & font->yAnd) * sWidth) + (plot >> font->xShift)) + ofs; memcpy( out + offset, &col, sizeof(u32) ); } diff --git a/src/system.c b/src/system.c deleted file mode 100644 index 9a9a80e..0000000 --- a/src/system.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "sys/ioctl.h" -#include "errno.h" - -#include "stdarg.h" -#include "stdio.h" -#include "unistd.h" -#include "string.h" -#include "signal.h" - -#include "types.h" - - -err e33_ioctl( Size fd, unsigned long req, void *arg ) -{ - Size ret; - - do { - ret = ioctl(fd, req, arg); - } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); - - return ret; -} - -boolean e33_strcmp( String s1, String s2 ) -{ - while( (*s1 != '\0') && (*s2 != '\0') ) - { - if( (*s1++) != (*s2++) ) { - return E33_FALSE; - } - } - - return E33_TRUE; -} - -err e33_has_signal(Size signo) -{ - struct sigaction sact = {0}; - sigaction(signo, 0, &sact); - return sact.sa_handler != 0; -} - -err e33_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); -} diff --git a/src/system33.c b/src/system33.c new file mode 100644 index 0000000..c533503 --- /dev/null +++ b/src/system33.c @@ -0,0 +1,50 @@ +#include "sys/ioctl.h" +#include "errno.h" + +#include "stdarg.h" +#include "stdio.h" +#include "unistd.h" +#include "signal.h" +#include "string.h" + +#include "types33.h" + + +Error e33_ioctl( Size fd, unsigned long req, void *arg ) +{ + Size ret; + + do { + ret = ioctl(fd, req, arg); + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); + + return ret; +} + +Boolean e33_strcmp( String s1, String s2 ) +{ + while( (*s1 != '\0') && (*s2 != '\0') ) + { + if( (*s1++) != (*s2++) ) { + return E33_FALSE; + } + } + + return E33_TRUE; +} + +Error e33_has_signal(Size signo) +{ + struct sigaction sact = {0}; + sigaction(signo, 0, &sact); + return sact.sa_handler != 0; +} + +Error e33_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); +} diff --git a/src/ui33.c b/src/ui33.c index 9e9795a..e093086 100644 --- a/src/ui33.c +++ b/src/ui33.c @@ -1,42 +1,58 @@ -#include "string.h" #include "stdarg.h" #include "stdio.h" +#include "string.h" -#include "types.h" +#include "types33.h" +#include "ui33.h" #include "strings33.h" -#include "logger.h" +#include "logger33.h" + + +#define _MBOX_SIZE 9 +#define _PADDING 4 +#define _SPACING 2 -#define MB_MAX 6 +static char messageBox[ _MBOX_SIZE ][ _STRING_MAX ] = { 0, }; +static Size head = 0; +static Size tail = 0; -static char messageBox[MB_MAX][256] = { 0, }; -static Size A = 0; -static Size P = 0; +Mouse33 __mouse = {0,}; -void ui_add_message( String fmt, ... ) +void ui33_add_message( String fmt, ... ) { va_list args; va_start(args, fmt); - vsnprintf( messageBox[P++], 256, fmt, args ); - if( P == MB_MAX ) P = 0; - if( P == A ) ++A; - if( A == MB_MAX ) A = 0; + vsnprintf( messageBox[tail++], _STRING_MAX, fmt, args ); + if( tail == _MBOX_SIZE ) tail = 0; + if( tail == head ) ++head; + if( head == _MBOX_SIZE ) head = 0; va_end(args); } -void ui_draw_messages( void ) +void ui33_draw_messages( void ) { - Size start = __display.surface.h - 5 - 8; - Size i = P-1; + Size fontHeight = defFont.h; + Size stringCoord = __display.surface.h - _PADDING - fontHeight; + Size i = tail-1; do { - if( i < 0 ) i = MB_MAX-1; - qsuprint( messageBox[i], 5, start ); - start -= 18; - } while( (i--) != A ); + if( i < 0 ) i = _MBOX_SIZE-1; + QPRINT( messageBox[i], _PADDING, stringCoord ); + stringCoord -= (_SPACING + fontHeight); + } while( (i--) != head ); +} + +void ui33_draw_mouse( void ) +{ + Size x = __mouse.x; + Size y = __mouse.y; + Size w = __display.surface.w; + + __display.surface.data[ x + y * w ] = YELLOW; } -- cgit v1.2.3