Detect whether the terminal has a display and a keyboard layout.
A new ioctl TIOCGDISPLAYS allow detecting which displays the terminal has associated. The ability to set a keyboard layout can be detected with tcgetblob kblayout. Improve the user-space multi-monitor support while here. The kernel now sets TERM rather than init(8). This is a compatible ABI change riding on the previous commit's bump.
This commit is contained in:
parent
db7182ddc3
commit
6ef5a5cee3
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2012, 2016 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -29,6 +29,7 @@ struct dispd_framebuffer
|
||||||
int bpp;
|
int bpp;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
uint64_t fb_location;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2012, 2013, 2014, 2016 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -17,9 +17,10 @@
|
||||||
* Handles session management.
|
* Handles session management.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -34,9 +35,6 @@
|
||||||
|
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
static const uint64_t ONE_AND_ONLY_DEVICE = 0;
|
|
||||||
static const uint64_t ONE_AND_ONLY_CONNECTOR = 0;
|
|
||||||
|
|
||||||
struct dispd_session* global_session = NULL;
|
struct dispd_session* global_session = NULL;
|
||||||
|
|
||||||
bool dispd__session_initialize(int* argc, char*** argv)
|
bool dispd__session_initialize(int* argc, char*** argv)
|
||||||
|
@ -48,8 +46,21 @@ bool dispd__session_initialize(int* argc, char*** argv)
|
||||||
if ( !global_session )
|
if ( !global_session )
|
||||||
return false;
|
return false;
|
||||||
memset(global_session, 0, sizeof(*global_session));
|
memset(global_session, 0, sizeof(*global_session));
|
||||||
global_session->device = ONE_AND_ONLY_DEVICE;
|
int tty_fd = open("/dev/tty", O_RDWR);
|
||||||
global_session->connector = ONE_AND_ONLY_CONNECTOR;
|
if ( tty_fd < 0 )
|
||||||
|
return free(global_session), false;
|
||||||
|
struct tiocgdisplay display;
|
||||||
|
struct tiocgdisplays gdisplays;
|
||||||
|
memset(&gdisplays, 0, sizeof(gdisplays));
|
||||||
|
gdisplays.count = 1;
|
||||||
|
gdisplays.displays = &display;
|
||||||
|
bool fail = ioctl(tty_fd, TIOCGDISPLAYS, &gdisplays) < 0 ||
|
||||||
|
gdisplays.count == 0;
|
||||||
|
close(tty_fd);
|
||||||
|
if ( fail )
|
||||||
|
return free(global_session), false;
|
||||||
|
global_session->device = display.device;
|
||||||
|
global_session->connector = display.connector;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2012, 2013, 2014, 2016 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -17,8 +17,8 @@
|
||||||
* Handles windows.
|
* Handles windows.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ioleast.h>
|
#include <ioleast.h>
|
||||||
|
@ -102,6 +102,7 @@ struct dispd_framebuffer* dispd_begin_render(struct dispd_window* window)
|
||||||
fb->pitch = fb->width * fb->bpp / 8;
|
fb->pitch = fb->width * fb->bpp / 8;
|
||||||
fb->datasize = fb->pitch * fb->height;
|
fb->datasize = fb->pitch * fb->height;
|
||||||
fb->data = (uint8_t*) request_buffer(window, fb->datasize);
|
fb->data = (uint8_t*) request_buffer(window, fb->datasize);
|
||||||
|
fb->fb_location = msg.mode.fb_location;
|
||||||
if ( !fb->data ) { free(fb); return NULL; }
|
if ( !fb->data ) { free(fb); return NULL; }
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +114,7 @@ bool dispd_finish_render(struct dispd_framebuffer* fb)
|
||||||
struct dispmsg_write_memory msg;
|
struct dispmsg_write_memory msg;
|
||||||
msg.msgid = DISPMSG_WRITE_MEMORY;
|
msg.msgid = DISPMSG_WRITE_MEMORY;
|
||||||
msg.device = window->session->device;
|
msg.device = window->session->device;
|
||||||
msg.offset = 0;
|
msg.offset = fb->fb_location;
|
||||||
msg.size = fb->datasize;
|
msg.size = fb->datasize;
|
||||||
msg.src = fb->data;
|
msg.src = fb->data;
|
||||||
if ( dispmsg_issue(&msg, sizeof(msg)) == 0 )
|
if ( dispmsg_issue(&msg, sizeof(msg)) == 0 )
|
||||||
|
|
36
init/init.c
36
init/init.c
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -429,6 +430,14 @@ static void set_hostname(void)
|
||||||
|
|
||||||
static void set_kblayout(void)
|
static void set_kblayout(void)
|
||||||
{
|
{
|
||||||
|
int tty_fd = open("/dev/tty", O_RDWR);
|
||||||
|
if ( !tty_fd )
|
||||||
|
return warning("unable to set keyboard layout: /dev/tty: %m");
|
||||||
|
bool unsupported = tcgetblob(tty_fd, "kblayout", NULL, 0) < 0 &&
|
||||||
|
(errno == ENOTTY || errno == ENOENT);
|
||||||
|
close(tty_fd);
|
||||||
|
if ( unsupported )
|
||||||
|
return;
|
||||||
FILE* fp = fopen("/etc/kblayout", "r");
|
FILE* fp = fopen("/etc/kblayout", "r");
|
||||||
if ( !fp && errno == ENOENT )
|
if ( !fp && errno == ENOENT )
|
||||||
return;
|
return;
|
||||||
|
@ -440,7 +449,11 @@ static void set_kblayout(void)
|
||||||
return warning("unable to set keyboard layout: /etc/kblayout: %m");
|
return warning("unable to set keyboard layout: /etc/kblayout: %m");
|
||||||
pid_t child_pid = fork();
|
pid_t child_pid = fork();
|
||||||
if ( child_pid < 0 )
|
if ( child_pid < 0 )
|
||||||
return warning("unable to set keyboard layout: fork: %m");
|
{
|
||||||
|
free(kblayout);
|
||||||
|
warning("unable to set keyboard layout: fork: %m");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ( !child_pid )
|
if ( !child_pid )
|
||||||
{
|
{
|
||||||
execlp("chkblayout", "chkblayout", "--", kblayout, (const char*) NULL);
|
execlp("chkblayout", "chkblayout", "--", kblayout, (const char*) NULL);
|
||||||
|
@ -454,6 +467,19 @@ static void set_kblayout(void)
|
||||||
|
|
||||||
static void set_videomode(void)
|
static void set_videomode(void)
|
||||||
{
|
{
|
||||||
|
int tty_fd = open("/dev/tty", O_RDWR);
|
||||||
|
if ( !tty_fd )
|
||||||
|
return warning("unable to set video mode: /dev/tty: %m");
|
||||||
|
struct tiocgdisplay display;
|
||||||
|
struct tiocgdisplays gdisplays;
|
||||||
|
memset(&gdisplays, 0, sizeof(gdisplays));
|
||||||
|
gdisplays.count = 1;
|
||||||
|
gdisplays.displays = &display;
|
||||||
|
bool unsupported = ioctl(tty_fd, TIOCGDISPLAYS, &gdisplays) < 0 ||
|
||||||
|
gdisplays.count == 0;
|
||||||
|
close(tty_fd);
|
||||||
|
if ( unsupported )
|
||||||
|
return;
|
||||||
FILE* fp = fopen("/etc/videomode", "r");
|
FILE* fp = fopen("/etc/videomode", "r");
|
||||||
if ( !fp && errno == ENOENT )
|
if ( !fp && errno == ENOENT )
|
||||||
return;
|
return;
|
||||||
|
@ -476,8 +502,8 @@ static void set_videomode(void)
|
||||||
struct dispmsg_get_crtc_mode get_mode;
|
struct dispmsg_get_crtc_mode get_mode;
|
||||||
memset(&get_mode, 0, sizeof(get_mode));
|
memset(&get_mode, 0, sizeof(get_mode));
|
||||||
get_mode.msgid = DISPMSG_GET_CRTC_MODE;
|
get_mode.msgid = DISPMSG_GET_CRTC_MODE;
|
||||||
get_mode.device = 0;
|
get_mode.device = display.device;
|
||||||
get_mode.connector = 0;
|
get_mode.connector = display.connector;
|
||||||
// Don't set the resolution if it's already correct.
|
// Don't set the resolution if it's already correct.
|
||||||
if ( dispmsg_issue(&get_mode, sizeof(get_mode)) == 0 )
|
if ( dispmsg_issue(&get_mode, sizeof(get_mode)) == 0 )
|
||||||
{
|
{
|
||||||
|
@ -530,10 +556,6 @@ static void init_early(void)
|
||||||
// Set up the PATH variable.
|
// Set up the PATH variable.
|
||||||
if ( setenv("PATH", "/bin:/sbin", 1) < 0 )
|
if ( setenv("PATH", "/bin:/sbin", 1) < 0 )
|
||||||
fatal("setenv: %m");
|
fatal("setenv: %m");
|
||||||
|
|
||||||
// Set the terminal type.
|
|
||||||
if ( setenv("TERM", "sortix", 1) < 0 )
|
|
||||||
fatal("setenv: %m");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_chain_init_mountpoint(const struct mountpoint* mountpoint)
|
static bool is_chain_init_mountpoint(const struct mountpoint* mountpoint)
|
||||||
|
|
|
@ -161,6 +161,18 @@ struct dispmsg_read_memory
|
||||||
uint8_t* dst; // in, *out
|
uint8_t* dst; // in, *out
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tiocgdisplay
|
||||||
|
{
|
||||||
|
uint64_t device;
|
||||||
|
uint64_t connector;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tiocgdisplays
|
||||||
|
{
|
||||||
|
size_t count; // in, out
|
||||||
|
struct tiocgdisplay* displays; // in, *out
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,5 +38,6 @@
|
||||||
#define TIOCGPTLCK __IOCTL(5, __IOCTL_TYPE_PTR)
|
#define TIOCGPTLCK __IOCTL(5, __IOCTL_TYPE_PTR)
|
||||||
#define TIOCGNAME __IOCTL(6, __IOCTL_TYPE_PTR)
|
#define TIOCGNAME __IOCTL(6, __IOCTL_TYPE_PTR)
|
||||||
#define TIOCGPTN __IOCTL(7, __IOCTL_TYPE_PTR)
|
#define TIOCGPTN __IOCTL(7, __IOCTL_TYPE_PTR)
|
||||||
|
#define TIOCGDISPLAYS __IOCTL(8, __IOCTL_TYPE_PTR)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -719,8 +719,8 @@ static void InitThread(void* /*user*/)
|
||||||
|
|
||||||
Log::PrintF("\r\e[m\e[J");
|
Log::PrintF("\r\e[m\e[J");
|
||||||
|
|
||||||
int envc = 0;
|
int envc = 1;
|
||||||
const char* envp[] = { NULL };
|
const char* envp[] = { "TERM=sortix", NULL };
|
||||||
struct thread_registers regs;
|
struct thread_registers regs;
|
||||||
assert((((uintptr_t) ®s) & (alignof(regs)-1)) == 0);
|
assert((((uintptr_t) ®s) & (alignof(regs)-1)) == 0);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#include <sortix/display.h>
|
||||||
#include <sortix/fcntl.h>
|
#include <sortix/fcntl.h>
|
||||||
#include <sortix/ioctl.h>
|
#include <sortix/ioctl.h>
|
||||||
#include <sortix/keycodes.h>
|
#include <sortix/keycodes.h>
|
||||||
|
@ -332,6 +333,27 @@ int LogTerminal::ioctl(ioctx_t* ctx, int cmd, uintptr_t arg)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if ( cmd == TIOCGDISPLAYS )
|
||||||
|
{
|
||||||
|
struct tiocgdisplays* input = (struct tiocgdisplays*) arg;
|
||||||
|
struct tiocgdisplays gdisplays;
|
||||||
|
if ( !ctx->copy_from_src(&gdisplays, input, sizeof(gdisplays)) )
|
||||||
|
return -1;
|
||||||
|
if ( 0 < gdisplays.count )
|
||||||
|
{
|
||||||
|
struct tiocgdisplay display;
|
||||||
|
memset(&display, 0, sizeof(display));
|
||||||
|
display.device = 0;
|
||||||
|
display.connector = 0;
|
||||||
|
if ( !ctx->copy_to_dest(gdisplays.displays, &display,
|
||||||
|
sizeof(display)) )
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
gdisplays.count = 1;
|
||||||
|
if ( !ctx->copy_to_dest(input, &gdisplays, sizeof(gdisplays)) )
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
lock.Reset();
|
lock.Reset();
|
||||||
return TTY::ioctl(ctx, cmd, arg);
|
return TTY::ioctl(ctx, cmd, arg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
#include <sys/kernelinfo.h>
|
#include <sys/kernelinfo.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/termmode.h>
|
#include <sys/termmode.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -106,17 +107,21 @@ struct glogin
|
||||||
bool pointer_working;
|
bool pointer_working;
|
||||||
struct termios old_tio;
|
struct termios old_tio;
|
||||||
bool has_old_tio;
|
bool has_old_tio;
|
||||||
|
uint64_t device;
|
||||||
|
uint64_t connector;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct glogin state;
|
static struct glogin state;
|
||||||
|
|
||||||
static bool get_graphical_mode(struct dispmsg_crtc_mode* mode)
|
static bool get_graphical_mode(uint64_t device,
|
||||||
|
uint64_t connector,
|
||||||
|
struct dispmsg_crtc_mode* mode)
|
||||||
{
|
{
|
||||||
struct dispmsg_get_crtc_mode msg;
|
struct dispmsg_get_crtc_mode msg;
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.msgid = DISPMSG_GET_CRTC_MODE;
|
msg.msgid = DISPMSG_GET_CRTC_MODE;
|
||||||
msg.device = 0; // TODO: Multi-screen support!
|
msg.device = device;
|
||||||
msg.connector = 0; // TODO: Multi-screen support!
|
msg.connector = connector;
|
||||||
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
|
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
|
||||||
{
|
{
|
||||||
warn("dispmsg_issue: DISPMSG_GET_CRTC_MODE");
|
warn("dispmsg_issue: DISPMSG_GET_CRTC_MODE");
|
||||||
|
@ -496,8 +501,8 @@ static bool screen_capture(struct glogin* state, struct framebuffer* fb)
|
||||||
struct dispmsg_write_memory msg;
|
struct dispmsg_write_memory msg;
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.msgid = DISPMSG_READ_MEMORY;
|
msg.msgid = DISPMSG_READ_MEMORY;
|
||||||
msg.device = 0; // TODO: Multi-screen support!
|
msg.device = state->device;
|
||||||
msg.offset = 0; // TODO: mode.fb_location!
|
msg.offset = state->mode.fb_location;
|
||||||
msg.size = fb->xres * fb->yres * sizeof(fb->buffer[0]);
|
msg.size = fb->xres * fb->yres * sizeof(fb->buffer[0]);
|
||||||
msg.src = (uint8_t*) fb->buffer;
|
msg.src = (uint8_t*) fb->buffer;
|
||||||
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
|
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
|
||||||
|
@ -510,7 +515,7 @@ static bool screen_capture(struct glogin* state, struct framebuffer* fb)
|
||||||
|
|
||||||
static bool begin_render(struct glogin* state, struct framebuffer* fb)
|
static bool begin_render(struct glogin* state, struct framebuffer* fb)
|
||||||
{
|
{
|
||||||
if ( !get_graphical_mode(&state->mode) )
|
if ( !get_graphical_mode(state->device, state->connector, &state->mode) )
|
||||||
return false;
|
return false;
|
||||||
fb->xres = state->mode.view_xres;
|
fb->xres = state->mode.view_xres;
|
||||||
fb->yres = state->mode.view_yres;
|
fb->yres = state->mode.view_yres;
|
||||||
|
@ -530,8 +535,8 @@ static bool finish_render(struct glogin* state, struct framebuffer* fb)
|
||||||
struct dispmsg_write_memory msg;
|
struct dispmsg_write_memory msg;
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.msgid = DISPMSG_WRITE_MEMORY;
|
msg.msgid = DISPMSG_WRITE_MEMORY;
|
||||||
msg.device = 0; // TODO: Multi-screen support!
|
msg.device = state->device;
|
||||||
msg.offset = 0; // TODO: mode.fb_location!
|
msg.offset = state->mode.fb_location;
|
||||||
msg.size = sizeof(uint32_t) * fb->xres * fb->yres;
|
msg.size = sizeof(uint32_t) * fb->xres * fb->yres;
|
||||||
msg.src = (uint8_t*) fb->buffer;
|
msg.src = (uint8_t*) fb->buffer;
|
||||||
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
|
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
|
||||||
|
@ -730,8 +735,19 @@ bool glogin_init(struct glogin* state)
|
||||||
{
|
{
|
||||||
memset(state, 0, sizeof(*state));
|
memset(state, 0, sizeof(*state));
|
||||||
state->fd_mouse = -1;
|
state->fd_mouse = -1;
|
||||||
|
struct tiocgdisplay display;
|
||||||
if ( !get_graphical_mode(&state->mode) )
|
struct tiocgdisplays gdisplays;
|
||||||
|
memset(&gdisplays, 0, sizeof(gdisplays));
|
||||||
|
gdisplays.count = 1;
|
||||||
|
gdisplays.displays = &display;
|
||||||
|
if ( ioctl(1, TIOCGDISPLAYS, &gdisplays) < 0 || gdisplays.count == 0 )
|
||||||
|
{
|
||||||
|
glogin_destroy(state);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
state->device = display.device;
|
||||||
|
state->connector = display.connector;
|
||||||
|
if ( !get_graphical_mode(state->device, state->connector, &state->mode) )
|
||||||
{
|
{
|
||||||
warn("dispmsg_issue");
|
warn("dispmsg_issue");
|
||||||
glogin_destroy(state);
|
glogin_destroy(state);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/kernelinfo.h>
|
#include <sys/kernelinfo.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -37,6 +38,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
// Sortix libc doesn't have its own proper <limits.h> at this time.
|
// Sortix libc doesn't have its own proper <limits.h> at this time.
|
||||||
|
@ -472,7 +474,8 @@ int main(void)
|
||||||
|
|
||||||
install_configurationf("upgrade.conf", "a", "src = yes\n");
|
install_configurationf("upgrade.conf", "a", "src = yes\n");
|
||||||
|
|
||||||
while ( true )
|
bool kblayout_setable = 0 <= tcgetblob(0, "kblayout", NULL, 0);
|
||||||
|
while ( kblayout_setable )
|
||||||
{
|
{
|
||||||
// TODO: Detect the name of the current keyboard layout.
|
// TODO: Detect the name of the current keyboard layout.
|
||||||
prompt(input, sizeof(input),
|
prompt(input, sizeof(input),
|
||||||
|
@ -510,6 +513,8 @@ int main(void)
|
||||||
if ( execute(argv, "f") == 0 )
|
if ( execute(argv, "f") == 0 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if ( kblayout_setable )
|
||||||
|
{
|
||||||
if ( !input[0] || !strcmp(input, "default") )
|
if ( !input[0] || !strcmp(input, "default") )
|
||||||
text("/etc/kblayout will not be created (default).\n");
|
text("/etc/kblayout will not be created (default).\n");
|
||||||
else
|
else
|
||||||
|
@ -521,14 +526,23 @@ int main(void)
|
||||||
umask(old_umask);
|
umask(old_umask);
|
||||||
}
|
}
|
||||||
text("\n");
|
text("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tiocgdisplay display;
|
||||||
|
struct tiocgdisplays gdisplays;
|
||||||
|
memset(&gdisplays, 0, sizeof(gdisplays));
|
||||||
|
gdisplays.count = 1;
|
||||||
|
gdisplays.displays = &display;
|
||||||
struct dispmsg_get_driver_name dgdn = { 0 };
|
struct dispmsg_get_driver_name dgdn = { 0 };
|
||||||
dgdn.msgid = DISPMSG_GET_DRIVER_NAME;
|
dgdn.msgid = DISPMSG_GET_DRIVER_NAME;
|
||||||
dgdn.device = 0;
|
dgdn.device = 0;
|
||||||
dgdn.driver_index = 0;
|
dgdn.driver_index = 0;
|
||||||
dgdn.name.byte_size = 0;
|
dgdn.name.byte_size = 0;
|
||||||
dgdn.name.str = NULL;
|
dgdn.name.str = NULL;
|
||||||
if ( dispmsg_issue(&dgdn, sizeof(dgdn)) == 0 || errno != ENODEV )
|
if ( ioctl(1, TIOCGDISPLAYS, &gdisplays) == 0 &&
|
||||||
|
1 < gdisplays.count &&
|
||||||
|
(dgdn.device = display.device, true) &&
|
||||||
|
(dispmsg_issue(&dgdn, sizeof(dgdn)) == 0 || errno != ENODEV) )
|
||||||
{
|
{
|
||||||
while ( true )
|
while ( true )
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
@ -32,6 +33,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <termios.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -379,7 +381,8 @@ int main(void)
|
||||||
prompt(input, sizeof(input), "Ready?", ready);
|
prompt(input, sizeof(input), "Ready?", ready);
|
||||||
text("\n");
|
text("\n");
|
||||||
|
|
||||||
while ( true )
|
bool kblayout_setable = 0 <= tcgetblob(0, "kblayout", NULL, 0);
|
||||||
|
while ( kblayout_setable )
|
||||||
{
|
{
|
||||||
// TODO: Detect the name of the current keyboard layout.
|
// TODO: Detect the name of the current keyboard layout.
|
||||||
prompt(input, sizeof(input),
|
prompt(input, sizeof(input),
|
||||||
|
@ -417,15 +420,24 @@ int main(void)
|
||||||
if ( execute(argv, "f") == 0 )
|
if ( execute(argv, "f") == 0 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if ( kblayout_setable )
|
||||||
text("\n");
|
text("\n");
|
||||||
|
|
||||||
|
struct tiocgdisplay display;
|
||||||
|
struct tiocgdisplays gdisplays;
|
||||||
|
memset(&gdisplays, 0, sizeof(gdisplays));
|
||||||
|
gdisplays.count = 1;
|
||||||
|
gdisplays.displays = &display;
|
||||||
struct dispmsg_get_driver_name dgdn = { 0 };
|
struct dispmsg_get_driver_name dgdn = { 0 };
|
||||||
dgdn.msgid = DISPMSG_GET_DRIVER_NAME;
|
dgdn.msgid = DISPMSG_GET_DRIVER_NAME;
|
||||||
dgdn.device = 0;
|
dgdn.device = 0;
|
||||||
dgdn.driver_index = 0;
|
dgdn.driver_index = 0;
|
||||||
dgdn.name.byte_size = 0;
|
dgdn.name.byte_size = 0;
|
||||||
dgdn.name.str = NULL;
|
dgdn.name.str = NULL;
|
||||||
if ( dispmsg_issue(&dgdn, sizeof(dgdn)) == 0 || errno != ENODEV )
|
if ( ioctl(1, TIOCGDISPLAYS, &gdisplays) == 0 &&
|
||||||
|
1 < gdisplays.count &&
|
||||||
|
(dgdn.device = display.device, true) &&
|
||||||
|
(dispmsg_issue(&dgdn, sizeof(dgdn)) == 0 || errno != ENODEV) )
|
||||||
{
|
{
|
||||||
while ( true )
|
while ( true )
|
||||||
{
|
{
|
||||||
|
@ -439,8 +451,8 @@ int main(void)
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
text("\n");
|
text("\n");
|
||||||
|
}
|
||||||
|
|
||||||
struct release new_release;
|
struct release new_release;
|
||||||
if ( !os_release_load(&new_release, "/etc/sortix-release",
|
if ( !os_release_load(&new_release, "/etc/sortix-release",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2013, 2014 Jonas 'Sortie' Termansen.
|
* Copyright (c) 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
@ -18,12 +18,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/display.h>
|
#include <sys/display.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/keycodes.h>
|
#include <sys/keycodes.h>
|
||||||
#include <sys/termmode.h>
|
#include <sys/termmode.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -34,6 +36,9 @@
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static uint64_t device;
|
||||||
|
static uint64_t connector;
|
||||||
|
|
||||||
bool SetCurrentMode(struct dispmsg_crtc_mode mode)
|
bool SetCurrentMode(struct dispmsg_crtc_mode mode)
|
||||||
{
|
{
|
||||||
struct dispmsg_set_crtc_mode msg;
|
struct dispmsg_set_crtc_mode msg;
|
||||||
|
@ -324,6 +329,22 @@ int main(int argc, char* argv[])
|
||||||
|
|
||||||
compact_arguments(&argc, &argv);
|
compact_arguments(&argc, &argv);
|
||||||
|
|
||||||
|
int tty_fd = open("/dev/tty", O_RDWR);
|
||||||
|
if ( tty_fd < 0 )
|
||||||
|
error(1, errno, "/dev/tty");
|
||||||
|
struct tiocgdisplay display;
|
||||||
|
struct tiocgdisplays gdisplays;
|
||||||
|
memset(&gdisplays, 0, sizeof(gdisplays));
|
||||||
|
gdisplays.count = 1;
|
||||||
|
gdisplays.displays = &display;
|
||||||
|
if ( ioctl(1, TIOCGDISPLAYS, &gdisplays) < 0 || gdisplays.count == 0 )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "No video devices are associated with this terminal.\n");
|
||||||
|
exit(13);
|
||||||
|
}
|
||||||
|
device = display.device;
|
||||||
|
connector = display.connector;
|
||||||
|
|
||||||
size_t num_modes = 0;
|
size_t num_modes = 0;
|
||||||
struct dispmsg_crtc_mode* modes = GetAvailableModes(&num_modes);
|
struct dispmsg_crtc_mode* modes = GetAvailableModes(&num_modes);
|
||||||
if ( !modes )
|
if ( !modes )
|
||||||
|
|
Loading…
Reference in New Issue