Compare commits

...

4 Commits

Author SHA1 Message Date
Jonas 'Sortie' Termansen 08b581914d fixup! Add display server. 2023-06-13 23:34:13 +02:00
Jonas 'Sortie' Termansen 371f0dcd80 fixup! Add display server. 2023-06-13 23:12:10 +02:00
Jonas 'Sortie' Termansen 7afc8f50df fixup! Add display server. 2023-06-11 21:46:00 +02:00
Jonas 'Sortie' Termansen 485e932deb squash! Add display server.
Remove the obsolete dispd.
2023-06-11 17:07:28 +02:00
18 changed files with 651 additions and 565 deletions

View File

@ -6,7 +6,6 @@ include build-aux/version.mak
MODULES=\
libc \
libm \
dispd \
libdisplay \
libmount \
libui \

3
dispd/.gitignore vendored
View File

@ -1,3 +0,0 @@
*.a
*.o
server/dispd

View File

@ -1,53 +0,0 @@
SOFTWARE_MEANT_FOR_SORTIX=1
include ../build-aux/platform.mak
include ../build-aux/compiler.mak
include ../build-aux/version.mak
include ../build-aux/dirs.mak
OPTLEVEL?=$(DEFAULT_OPTLEVEL)
CFLAGS?=$(OPTLEVEL)
CFLAGS:=$(CFLAGS) -Wall -Wextra
CPPFLAGS:=$(CPPFLAGS) -I include
CLIENT_OBJS:=\
client/library.o \
client/session.o \
client/window.o \
BINS:=client/libdispd.a
all: $(BINS)
.PHONY: all headers client clean install install-include-dirs \
install-headers install-client-dirs install-client
headers:
client: client/libdispd.a
client/libdispd.a: $(CLIENT_OBJS)
$(AR) rcs $@ $(CLIENT_OBJS)
clean:
rm -f $(CLIENT_OBJS)
rm -f $(BINS)
rm -f *.o client/*.o
%.o: %.c
$(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) -c $< -o $@
# Installation into sysroot
install: install-headers install-client
install-include-dirs: headers
mkdir -p $(DESTDIR)$(INCLUDEDIR)
install-headers: install-include-dirs headers
cp -RTv include $(DESTDIR)$(INCLUDEDIR)
install-client-dirs:
mkdir -p $(DESTDIR)$(LIBDIR)
install-client: install-client-dirs client
cp -P client/libdispd.a $(DESTDIR)$(LIBDIR)

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) 2012, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* framebuffer.h
* Keeps track of framebuffers.
*/
#ifndef INCLUDE_DISPD_FRAMEBUFFER_H
#define INCLUDE_DISPD_FRAMEBUFFER_H
struct dispd_framebuffer
{
struct dispd_window* window;
uint8_t* data;
size_t datasize;
size_t pitch;
int bpp;
int width;
int height;
uint64_t fb_location;
};
#endif

View File

@ -1,33 +0,0 @@
/*
* Copyright (c) 2012 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* library.c
* Main entry point of the Sortix Display Daemon.
*/
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <dispd.h>
#include "session.h"
bool dispd_initialize(int* argc, char*** argv)
{
if ( !dispd__session_initialize(argc, argv) )
return false;
return true;
}

View File

@ -1,130 +0,0 @@
/*
* Copyright (c) 2012, 2013, 2014, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* session.c
* Handles session management.
*/
#include <sys/ioctl.h>
#include <sys/display.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <err.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dispd.h>
#include "session.h"
struct dispd_session* global_session = NULL;
bool dispd__session_initialize(int* argc, char*** argv)
{
(void) argc;
(void) argv;
size_t size = sizeof(struct dispd_session);
global_session = (struct dispd_session*) malloc(size);
if ( !global_session )
return false;
memset(global_session, 0, sizeof(*global_session));
int tty_fd = open("/dev/tty", O_RDWR);
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;
}
struct dispd_session* dispd_attach_default_session()
{
global_session->refcount++;
return global_session;
}
bool dispd_detach_session(struct dispd_session* session)
{
session->refcount--;
return true;
}
bool dispd_session_setup_game_rgba(struct dispd_session* session)
{
if ( session->is_rgba )
return true;
if ( session->current_window )
return false;
struct dispmsg_get_crtc_mode msg;
msg.msgid = DISPMSG_GET_CRTC_MODE;
msg.device = session->device;
msg.connector = session->connector;
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
return false;
if ( !(msg.mode.control & 1) || msg.mode.fb_format != 32 )
{
pid_t childpid = fork();
if ( childpid < 0 )
return false;
if ( childpid )
{
int status;
waitpid(childpid, &status, 0);
return session->is_rgba = (WIFEXITED(status) && !WEXITSTATUS(status));
}
const char* chvideomode = "chvideomode";
#if 1
// TODO chvideomode currently launches --bpp 32 as a program...
execlp(chvideomode, chvideomode, (const char*) NULL);
#else
execlp(chvideomode, chvideomode,
"--bpp", "32",
"--show-graphics", "true",
"--show-text", "false",
(const char*) NULL);
#endif
err(127, "%s", chvideomode);
}
// HACK: The console may be rendered asynchronously and it might still be
// rendering to the framebuffer, however this process is about to do
// bitmapped graphics to the framebuffer as well. Since there is no
// synchronization with the terminal except not writing to it, there
// is a small window where both are fighting for the framebuffer.
// We can resolve this issue by simply fsync()ing the terminal, which
// causes the scheduled console rendering to finish before returning.
int tty_fd = open("/dev/tty", O_WRONLY);
if ( 0 <= tty_fd )
{
fsync(tty_fd);
close(tty_fd);
}
return session->is_rgba = true;
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2012 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* session.h
* Handles session management.
*/
#ifndef INCLUDE_DISPD_SESSION_H
#define INCLUDE_DISPD_SESSION_H
#if defined(__cplusplus)
extern "C" {
#endif
struct dispd_session
{
size_t refcount;
uint64_t device;
uint64_t connector;
struct dispd_window* current_window;
bool is_rgba;
};
bool dispd__session_initialize(int* argc, char*** argv);
#if defined(__cplusplus)
} /* extern "C" */
#endif
#endif

View File

@ -1,150 +0,0 @@
/*
* Copyright (c) 2012, 2013, 2014, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* window.c
* Handles windows.
*/
#include <sys/display.h>
#include <sys/types.h>
#include <fcntl.h>
#include <ioleast.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dispd.h>
#include "framebuffer.h"
#include "session.h"
#include "window.h"
struct dispd_window* dispd_create_window_game_rgba(struct dispd_session* session)
{
if ( session->current_window )
return NULL;
if ( !session->is_rgba )
return NULL;
size_t size = sizeof(struct dispd_window);
struct dispd_window* window = (struct dispd_window*) malloc(size);
if ( !window )
return NULL;
memset(window, 0, sizeof(*window));
window->session = session;
return session->current_window = window;
}
bool dispd_destroy_window(struct dispd_window* window)
{
free(window->cached_buffer);
free(window);
return true;
}
static uint8_t* request_buffer(struct dispd_window* window, size_t size)
{
if ( window->cached_buffer )
{
if ( window->cached_buffer_size == size )
{
uint8_t* ret = window->cached_buffer;
window->cached_buffer = NULL;
window->cached_buffer_size = 0;
return ret;
}
free(window->cached_buffer);
window->cached_buffer = NULL;
window->cached_buffer_size = 0;
}
return (uint8_t*) malloc(size);
}
static void return_buffer(struct dispd_window* window, uint8_t* b, size_t size)
{
free(window->cached_buffer);
window->cached_buffer = b;
window->cached_buffer_size = size;
}
struct dispd_framebuffer* dispd_begin_render(struct dispd_window* window)
{
struct dispmsg_get_crtc_mode msg;
msg.msgid = DISPMSG_GET_CRTC_MODE;
msg.device = window->session->device;
msg.connector = window->session->connector;
if ( dispmsg_issue(&msg, sizeof(msg)) != 0 )
return NULL;
size_t size = sizeof(struct dispd_framebuffer);
struct dispd_framebuffer* fb = (struct dispd_framebuffer*) malloc(size);
if ( !fb )
return NULL;
memset(fb, 0, sizeof(*fb));
fb->window = window;
fb->width = msg.mode.view_xres;
fb->height = msg.mode.view_yres;
fb->bpp = 32;
fb->pitch = fb->width * fb->bpp / 8;
fb->datasize = fb->pitch * fb->height;
fb->data = (uint8_t*) request_buffer(window, fb->datasize);
fb->fb_location = msg.mode.fb_location;
if ( !fb->data ) { free(fb); return NULL; }
return fb;
}
bool dispd_finish_render(struct dispd_framebuffer* fb)
{
struct dispd_window* window = fb->window;
bool ret = false;
struct dispmsg_write_memory msg;
msg.msgid = DISPMSG_WRITE_MEMORY;
msg.device = window->session->device;
msg.offset = fb->fb_location;
msg.size = fb->datasize;
msg.src = fb->data;
if ( dispmsg_issue(&msg, sizeof(msg)) == 0 )
ret = true;
return_buffer(window, fb->data, fb->datasize);
free(fb);
return ret;
}
uint8_t* dispd_get_framebuffer_data(struct dispd_framebuffer* fb)
{
return fb->data;
}
size_t dispd_get_framebuffer_pitch(struct dispd_framebuffer* fb)
{
return fb->pitch;
}
int dispd_get_framebuffer_format(struct dispd_framebuffer* fb)
{
return fb->bpp;
}
int dispd_get_framebuffer_height(struct dispd_framebuffer* fb)
{
return fb->height;
}
int dispd_get_framebuffer_width(struct dispd_framebuffer* fb)
{
return fb->width;
}

View File

@ -1,38 +0,0 @@
/*
* Copyright (c) 2012 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* window.h
* Handles windows.
*/
#ifndef INCLUDE_DISPD_WINDOW_H
#define INCLUDE_DISPD_WINDOW_H
#if defined(__cplusplus)
extern "C" {
#endif
struct dispd_window
{
struct dispd_session* session;
uint8_t* cached_buffer;
size_t cached_buffer_size;
};
#if defined(__cplusplus)
} /* extern "C" */
#endif
#endif

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2012 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* dispd.h
* Interface to the Sortix Display Daemon.
*/
#ifndef INCLUDE_DISPD_H
#define INCLUDE_DISPD_H
#if !defined(__cplusplus)
#include <stdbool.h>
#endif
#include <stddef.h>
#include <stdint.h>
#if defined(__cplusplus)
extern "C" {
#endif
struct dispd_session;
struct dispd_window;
struct dispd_framebuffer;
bool dispd_initialize(int* argc, char*** argv);
struct dispd_session* dispd_attach_default_session(void);
bool dispd_detach_session(struct dispd_session* session);
bool dispd_session_setup_game_rgba(struct dispd_session* session);
struct dispd_window* dispd_create_window_game_rgba(struct dispd_session* session);
bool dispd_destroy_window(struct dispd_window* window);
struct dispd_framebuffer* dispd_begin_render(struct dispd_window* window);
bool dispd_finish_render(struct dispd_framebuffer* framebuffer);
uint8_t* dispd_get_framebuffer_data(struct dispd_framebuffer* framebuffer);
size_t dispd_get_framebuffer_pitch(struct dispd_framebuffer* framebuffer);
int dispd_get_framebuffer_format(struct dispd_framebuffer* framebuffer);
int dispd_get_framebuffer_height(struct dispd_framebuffer* framebuffer);
int dispd_get_framebuffer_width(struct dispd_framebuffer* framebuffer);
#if defined(__cplusplus)
} /* extern "C" */
#endif
#endif

View File

@ -9,6 +9,8 @@ CFLAGS?=$(OPTLEVEL)
CFLAGS:=$(CFLAGS) -Wall -Wextra
PROGRAM=display
MANPAGES1 = display.1
MANPAGES5 = displayrc.5
OBJS=\
connection.o \
@ -29,6 +31,10 @@ install: all
mkdir -p $(DESTDIR)$(SYSCONFDIR)/default
printf '#!sh\nexec terminal\n' > $(DESTDIR)$(SYSCONFDIR)/default/displayrc
chmod +x $(DESTDIR)$(SYSCONFDIR)/default/displayrc
mkdir -p $(DESTDIR)$(MANDIR)/man1
install $(MANPAGES1) $(DESTDIR)$(MANDIR)/man1
mkdir -p $(DESTDIR)$(MANDIR)/man5
install $(MANPAGES5) $(DESTDIR)$(MANDIR)/man5
$(PROGRAM): $(OBJS)
$(CC) -std=gnu11 $(CFLAGS) $(CPPFLAGS) $(OBJS) -o $@ $(LIBS)

161
display/display.1 Normal file
View File

@ -0,0 +1,161 @@
.Dd June 11, 2023
.Dt DISPLAY 8
.Os
.Sh NAME
.Nm display
.Nd desktop environment
.Sh SYNOPSIS
.Nm
.Op Ar session ...
.Sh DESCRIPTION
.Nm
is a desktop environment and windowing system compositor.
Applications talk to the
.Nm
server process to receive user input and show their graphical user interfaces
in windows.
.Pp
The user's preferred startup applications are launched on startup by launching
the
.Xr session
program (if set) or otherwise the
.Xr displayrc 5
script in the background.
.Pp
.Nm
exits when Control + Alt + Delete is pressed.
.Pp
The keyboard shortcuts are as follows:
.Bl -tag -width "Control + Alt + Delete"
.It Alt + F4
Quit the current window.
.It Alt + F10
Maximize (or restore) the current window.
.It Alt + Tab
Switch to the next window.
.It Alt + Drag
Drag the current window.
.It Control + Alt + Delete
Exit the desktop environment.
.It Control + Alt + T
Launch the
.Xr terminal 1
application.
.It Super + Left
Tile the current window leftwards.
.It Super + Right
Tile the current window rightwards.
.It Super + Up
Tile the current window upwards.
.It Super + Down
Tile the current window downwards.
.It F11
Grab input for the current window.
.It F12
Release the input grab on the current window.
.El
.Pp
The mouse gestures are as follow:
.Bl -bullet
.It
Clicking on a window brings it to the foreground.
.It
Dragging the window title bar moves the window.
.It
Clicking on the rectangle icon in the title bar maximizes (or restores) the
window.
.It
Clicking on the X icon in the title bar closes the window.
.It
Dragging the edges of a window resizes it.
.It
Windows can be tiled by moving them when the cursor meets the left, right, top,
and bottom edges or any corner.
.El
.Pp
The keyboard layout can be changed with the
.Xr chkblayout 1
program.
The display resolution can be changed with the
.Xr chvideomode 1
program.
.Sh ENVIRONMENT
.Bl -tag -width "DISPLAY_SOCKET"
.It Ev DISPLAY_SOCKET
.Nm
sets
.Ev DISPLAY_SOCKET
to the path of the
.Xr unix 4
socket where it listens for connections from applications.
Applications use
.Ev DISPLAY_SOCKET
to connect to
.Nm
or
.Pa /run/display
by default.
.El
.Sh FILES
.Bl -tag -width 12345678 -compact
.It Pa ~/.displayrc , /etc/displayrc , /etc/default/displayrc
.Xr displayrc 5
script that spawns the user's preferred startup applications.
.It Pa /run/display
.Xr unix 4
socket where
.Nm
listens for connections from applications, as advertised in the
.Ev DISPLAY_SOCKET
environment variable.
.El
.Sh ASYNCHRONOUS EVENTS
.Bl -tag -width "SIGTERM"
.It Dv SIGTERM
Request daemon termination.
.El
.Sh EXIT STATUS
.Nm
runs as a
.Xr daemon 7
until stopped by
.Dv SIGTERM ,
the user explicitly exits the desktop environment, or an application asks
it to exit.
.Nm
signals readiness on the
.Ev READYFD
file descriptor when the display server is ready to receive connections from
applications.
.Nm
will exit non-zero on any fatal startup error.
.Sh EXAMPLES
.Nm
can be selected as the user's graphical user interface with this executable
.Pa ~/.session
script:
.Bd -literal -offset indent
#!/bin/sh
exec display
.Ed
.Pp
.Xr chkblayout 1 ,
.Xr chvideomode 1 ,
.Xr display 1
will run the
.Xr displayrc 5
script on startup, which can be used to start applications.
.Sh SEE ALSO
.Xr terminal 1 ,
.Xr displayrc 5 ,
.Xr session 5
.Sh BUGS
The following features are not yet implemented:
.Bl -bullet -compact
.It
Windows cannot be minimized.
.It
Applications cannot receive mouse events.
.It
The wallpaper is random and cannot be controlled.
.El

77
display/displayrc.5 Normal file
View File

@ -0,0 +1,77 @@
.Dd June 11, 2023
.Dt DISPLAYRC 5
.Os
.Sh NAME
.Nm displayrc
.Nd startup graphical applications
.Sh SYNOPSIS
.Nm ~/.displayrc
.Nm /etc/displayrc
.Nm /etc/default/displayrc
.Sh DESCRIPTION
.Xr display 1
runs the
.Nm
script to launch the user's startup applications and prepare the desktop
environment according to the user's preferences.
.Pp
.Xr display 1
continues running after
.Nm
finishes running and any launched applications should be run as background
processes.
.Pp
The
.Nm
script is found by searching for an executable script in the following paths:
.Bl -bullet -compact
.It
.Pa ~/.displayrc
.It
.Pa /etc/displayrc
.It
.Pa /etc/default/displayrc
.El
.Pp
.Nm
is not executed if no script is found.
.Sh ENVIRONMENT
.Nm
is executed with the following environment:
.Bl -tag -width "DISPLAY_SOCKET"
.It Ev DISPLAY_SOCKET
The path of the
.Xr unix 4 socket
where
.Xr display 1
is listening for connections from applications.
.El
.Sh FILES
.Bl -tag -width "/etc/default/displayrc" -compact
.It Pa ~/.displayrc
The user's
.Nm
script.
.It Pa /etc/displayrc
The system administor provided
.Nm
script.
.It Pa /etc/default/displayrc
The operating system provided
.Nm
script.
.El
.Sh EXAMPLES
Launch a terminal with a text editor, another terminal with the user's default
shell, and launch the asteroids game.
.Bd -literal -offset indent
terminal editor &
terminal &
asteroids &
.Ed
.Sh SEE ALSO
.Xr display 1 ,
.Xr terminal 1 ,
.Xr profile 5 ,
.Xr session 5 ,
.Xr shrc 5

View File

@ -1,3 +1,26 @@
diff -Paur --no-dereference -- libSDL.upstream/configure libSDL/configure
--- libSDL.upstream/configure
+++ libSDL/configure
@@ -19338,7 +19338,7 @@
#include <stddef.h>
#include <stdint.h>
- #include <dispd.h>
+ #include <display.h>
int
main ()
@@ -19362,8 +19362,8 @@
SOURCES="$SOURCES $srcdir/src/video/sortix/*.c"
have_video=yes
- EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldispd"
- SDL_LIBS="$SDL_LIBS -ldispd"
+ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldisplay"
+ SDL_LIBS="$SDL_LIBS -ldisplay"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for display support" >&5
$as_echo_n "checking for display support... " >&6; }
diff -Paur --no-dereference -- libSDL.upstream/make.sortix libSDL/make.sortix
--- libSDL.upstream/make.sortix
+++ libSDL/make.sortix
@ -10,3 +33,358 @@ diff -Paur --no-dereference -- libSDL.upstream/make.sortix libSDL/make.sortix
+if [ "$1" = "install" ]; then
+rm -fv "$DESTDIR/$EXEC_PREFIX/bin/sdl-config"
+fi
diff -Paur --no-dereference -- libSDL.upstream/sdl.pc libSDL/sdl.pc
--- libSDL.upstream/sdl.pc
+++ libSDL/sdl.pc
@@ -10,6 +10,6 @@
Version: 1.2.15
Requires:
Conflicts:
-Libs: -L${libdir} -lSDL -ldispd -ldisplay
-Libs.private: -lSDL -ldispd -ldisplay -liconv -lm -ldispd -ldisplay
-Cflags: -I${includedir}/SDL
+Libs: -L${libdir} -lSDL -ldisplay -ldisplay
+Libs.private: -lSDL -ldisplay -ldisplay -liconv -lm -ldisplay -ldisplay
+Cflags: -I${includedir}/SDL -D_GNU_SOURCE=1
diff -Paur --no-dereference -- libSDL.upstream/src/video/sortix/SDL_dispd.c libSDL/src/video/sortix/SDL_dispd.c
--- libSDL.upstream/src/video/sortix/SDL_dispd.c
+++ libSDL/src/video/sortix/SDL_dispd.c
@@ -28,14 +28,11 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
-#include <dispd.h>
-#if __has_include(<display.h>)
-#define DISPLAY
-#include <display.h>
-#endif
#include <fcntl.h>
#include <unistd.h>
+#include <display.h>
+
#include "SDL_video.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_sysevents.h"
@@ -64,30 +61,12 @@
static void DispD_DeleteDevice(SDL_VideoDevice *device)
{
-#ifdef DISPLAY
if ( device->hidden->connection ) {
display_destroy_window(device->hidden->connection,
device->hidden->window_id);
display_disconnect(device->hidden->connection);
device->hidden->connection = NULL;
}
-#endif
- if ( device->hidden->fbinfo ) {
- dispd_finish_render(device->hidden->fbinfo);
- device->hidden->fbinfo = NULL;
- }
- if ( device->hidden->window ) {
- dispd_destroy_window(device->hidden->window);
- device->hidden->window = NULL;
- }
- if ( device->hidden->session ) {
- dispd_detach_session(device->hidden->session);
- device->hidden->session = NULL;
- }
- if ( 0 < device->hidden->tty_fd ) {
- close(device->hidden->tty_fd);
- device->hidden->tty_fd = -1;
- }
SDL_free(device->hidden);
SDL_free(device);
}
@@ -112,68 +91,20 @@
}
SDL_memset(device->hidden, 0, (sizeof *device->hidden));
-#ifdef DISPLAY
- if ( (device->hidden->connection = display_connect_default()) ) {
- device->hidden->disconnected = 0;
- device->hidden->window_id = 0;
- device->hidden->window_width = 0;
- device->hidden->window_height = 0;
- display_create_window(device->hidden->connection,
- device->hidden->window_id);
- } else {
-#endif
- static int has_initialized_dispd = 0;
- if ( !has_initialized_dispd ) {
- if ( !dispd_initialize(NULL, NULL) ) {
- return(0);
- }
- has_initialized_dispd = 1;
- }
- if ( (device->hidden->tty_fd = open("/dev/tty", O_RDONLY)) < 0 ) {
- DispD_DeleteDevice(device);
- return(0);
- }
-
- if ( (device->hidden->session = dispd_attach_default_session()) == NULL ) {
- DispD_DeleteDevice(device);
- return(0);
- }
-
- if ( !(dispd_session_setup_game_rgba(device->hidden->session)) ) {
- DispD_DeleteDevice(device);
- return(0);
- }
+ if ( !(device->hidden->connection = display_connect_default()) ) {
+ return(0);
+ }
- if ( (device->hidden->window =
- dispd_create_window_game_rgba(device->hidden->session)) == NULL ) {
- DispD_DeleteDevice(device);
- return(0);
- }
+ device->hidden->disconnected = 0;
+ device->hidden->window_id = 0;
+ device->hidden->window_width = 0;
+ device->hidden->window_height = 0;
+ display_create_window(device->hidden->connection,
+ device->hidden->window_id);
- if ( (device->hidden->fbinfo =
- dispd_begin_render(device->hidden->window)) == NULL ) {
- DispD_DeleteDevice(device);
- return(0);
- }
-#ifdef DISPLAY
- }
-#endif
+ device->hidden->current_mode.w = 800;
+ device->hidden->current_mode.h = 600;
- device->hidden->current_mode.x = 0;
- device->hidden->current_mode.y = 0;
-#ifdef DISPLAY
- if ( device->hidden->connection ) {
- device->hidden->current_mode.w = 800;
- device->hidden->current_mode.h = 600;
- } else {
-#endif
- device->hidden->current_mode.w =
- dispd_get_framebuffer_width(device->hidden->fbinfo);
- device->hidden->current_mode.h =
- dispd_get_framebuffer_height(device->hidden->fbinfo);
-#ifdef DISPLAY
- }
-#endif
device->hidden->mode_list[0] = &device->hidden->current_mode;
device->hidden->mode_list[1] = NULL;
@@ -217,13 +148,8 @@
SDL_Rect **DispD_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
// TODO: Return NULL if the format isn't 32-bit supported.
-#ifdef DISPLAY
- if ( this->hidden->connection ) {
- // TODO: qemu seems to pick too little a resolution due to this.
- return((SDL_Rect **)-1);
- }
-#endif
- return(this->hidden->mode_list);
+ // TODO: qemu seems to pick too little a resolution due to this.
+ return((SDL_Rect **)-1);
}
SDL_Surface *DispD_SetVideoMode(_THIS, SDL_Surface *current,
@@ -234,28 +160,16 @@
bpp = 32;
-#ifdef DISPLAY
- if ( this->hidden->connection ) {
- current->flags = SDL_RESIZABLE;
- size_t size = (size_t)width * (size_t)width * (bpp / 8);
- data = SDL_malloc(size);
- if ( !data )
- return(NULL);
- this->hidden->window_width = width;
- this->hidden->window_height = height;
- display_resize_window(this->hidden->connection,
- this->hidden->window_id, width, height);
- pitch = (size_t) width * (bpp / 8);
- } else {
-#endif
- data = dispd_get_framebuffer_data(this->hidden->fbinfo);
- width = dispd_get_framebuffer_width(this->hidden->fbinfo);
- height = dispd_get_framebuffer_height(this->hidden->fbinfo);
- pitch = dispd_get_framebuffer_pitch(this->hidden->fbinfo);
- current->flags = SDL_FULLSCREEN;
-#ifdef DISPLAY
- }
-#endif
+ current->flags = SDL_RESIZABLE;
+ size_t size = (size_t)width * (size_t)width * (bpp / 8);
+ data = SDL_malloc(size);
+ if ( !data )
+ return(NULL);
+ this->hidden->window_width = width;
+ this->hidden->window_height = height;
+ display_resize_window(this->hidden->connection,
+ this->hidden->window_id, width, height);
+ pitch = (size_t) width * (bpp / 8);
int y;
for ( y = 0; y < height; y++ )
@@ -270,7 +184,7 @@
assert(current->format);
assert(current->format->BitsPerPixel == 32);
current->pitch = pitch;
- // TODO: Memory leak of old buffer?
+ free(current->pixels);
current->pixels = data;
current->w = width;
current->h = height;
@@ -291,12 +205,8 @@
static void DispD_SetCaption(_THIS, const char *title, const char *icon)
{
-#ifdef DISPLAY
- if ( this->hidden->connection) {
- display_title_window(this->hidden->connection,
- this->hidden->window_id, title);
- }
-#endif
+ display_title_window(this->hidden->connection,
+ this->hidden->window_id, title);
}
/* We need to wait for vertical retrace on page flipped displays */
@@ -312,26 +222,13 @@
static void DispD_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
{
-#ifdef DISPLAY
- if ( this->hidden->connection) {
- for ( size_t i = 3; i < (size_t)SDL_VideoSurface->w * (size_t)SDL_VideoSurface->h * 4; i += 4 )
- ((unsigned char*)SDL_VideoSurface->pixels)[i] = 255;
- display_render_window(this->hidden->connection, this->hidden->window_id,
- 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h,
- SDL_VideoSurface->pixels);
- display_show_window(this->hidden->connection, this->hidden->window_id);
- return;
- }
-#endif
- uint8_t* old_data = dispd_get_framebuffer_data(this->hidden->fbinfo);
- if ( !dispd_finish_render(this->hidden->fbinfo) ) {
- abort();
- }
- if ( !(this->hidden->fbinfo = dispd_begin_render(this->hidden->window)) ) {
- abort();
- }
- uint8_t* new_data = dispd_get_framebuffer_data(this->hidden->fbinfo);
- assert(old_data == new_data);
+ size_t size = (size_t)SDL_VideoSurface->w * (size_t)SDL_VideoSurface->h * 4;
+ for ( size_t i = 3; i < size; i += 4 )
+ ((unsigned char*)SDL_VideoSurface->pixels)[i] = 255;
+ display_render_window(this->hidden->connection, this->hidden->window_id,
+ 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h,
+ SDL_VideoSurface->pixels);
+ display_show_window(this->hidden->connection, this->hidden->window_id);
}
int DispD_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
@@ -345,6 +242,7 @@
*/
void DispD_VideoQuit(_THIS)
{
+ free(this->screen->pixels);
this->screen->pixels = NULL;
}
@@ -424,7 +322,6 @@
return 0;
}
-#ifdef DISPLAY
static void on_disconnect(void* ctx)
{
struct SDL_PrivateVideoData* hidden = (struct SDL_PrivateVideoData*) ctx;
@@ -463,48 +360,19 @@
keysym.unicode = 0;
SDL_PrivateKeyboard(kbkey < 0 ? SDL_RELEASED : SDL_PRESSED, &keysym);
}
-#endif
void DispD_PumpEvents(_THIS)
{
-#ifdef DISPLAY
- if ( this->hidden->connection) {
- struct display_event_handlers handlers;
- memset(&handlers, 0, sizeof(handlers));
- handlers.context = this->hidden;
- handlers.disconnect_handler = on_disconnect;
- handlers.quit_handler = on_quit;
- handlers.resize_handler = on_resize;
- handlers.keyboard_handler = on_keyboard;
- while ( !this->hidden->disconnected ) {
- if ( display_poll_event(this->hidden->connection, &handlers) < 0 )
- break;
- }
- return;
- }
-#endif
-
- // Read the keyboard input from the user.
- const unsigned termmode = TERMMODE_KBKEY
- | TERMMODE_UNICODE
- | TERMMODE_SIGNAL
- | TERMMODE_NONBLOCK;
- if ( settermmode(0, termmode) ) {
- return;
- }
- uint32_t codepoint;
- ssize_t numbytes;
- while ( 0 < (numbytes = read(0, &codepoint, sizeof(codepoint))) )
- {
- int kbkey = KBKEY_DECODE(codepoint);
- int abskbkey = kbkey < 0 ? -kbkey : kbkey;
- int key = TranslateKey(abskbkey);
- SDL_keysym keysym;
- keysym.scancode = abskbkey;
- keysym.sym = key;
- keysym.mod = 0;
- keysym.unicode = 0;
- SDL_PrivateKeyboard(kbkey < 0 ? SDL_RELEASED : SDL_PRESSED, &keysym);
+ struct display_event_handlers handlers;
+ memset(&handlers, 0, sizeof(handlers));
+ handlers.context = this->hidden;
+ handlers.disconnect_handler = on_disconnect;
+ handlers.quit_handler = on_quit;
+ handlers.resize_handler = on_resize;
+ handlers.keyboard_handler = on_keyboard;
+ while ( !this->hidden->disconnected ) {
+ if ( display_poll_event(this->hidden->connection, &handlers) < 0 )
+ break;
}
}
diff -Paur --no-dereference -- libSDL.upstream/src/video/sortix/SDL_dispd.h libSDL/src/video/sortix/SDL_dispd.h
--- libSDL.upstream/src/video/sortix/SDL_dispd.h
+++ libSDL/src/video/sortix/SDL_dispd.h
@@ -33,19 +33,13 @@
/* Private display data */
struct SDL_PrivateVideoData {
-#ifdef DISPLAY
struct display_connection *connection;
uint32_t window_id;
uint32_t window_width;
uint32_t window_height;
int disconnected;
-#endif
- struct dispd_session *session;
- struct dispd_window *window;
- struct dispd_framebuffer *fbinfo;
SDL_Rect current_mode;
SDL_Rect *mode_list[2];
- int tty_fd;
};
#endif /* _SDL_nullvideo_h */

View File

@ -122,7 +122,7 @@ Like
but runs the root shell in
.Xr terminal 1
inside the
.Xr display 8
.Xr display 1
graphical user interface environment.
This operating system mode is insecure because it boots straight to root access
without a password.
@ -145,7 +145,7 @@ Like
but runs it in
.Xr terminal 1
inside the
.Xr display 8
.Xr display 1
graphical user interface environment.
This operating system mode is insecure because it boots straight to root access
without a password.

View File

@ -50,7 +50,7 @@ exec display
.Xr display 1
will run the
.Xr displayrc 5
script on startup, which can be used to start programs.
script on startup, which can be used to start applications.
.Ss Trianglix
.Xr trianglix 1
can be selected as the user's triangle environment with this executable

View File

@ -527,6 +527,7 @@ fragment instead.
.Sh SEE ALSO
.Xr chkblayout 1 ,
.Xr chvideomode 1 ,
.Xr display 1 ,
.Xr man 1 ,
.Xr fstab 5 ,
.Xr group 5 ,

View File

@ -14,26 +14,34 @@ The installation process is covered in
Bootable cdrom releases will offer the options of running a live environment,
installing the operating system, or upgrading an existing installation.
.Pp
You will be presented a with standard Unix command line environment upon login or
booting the live environment.
.Ss Shutdown
.Xr init 8
spawns a session after boot.
This is
.Xr login 8
if the system is booted in multi-user mode.
This is a root shell if booted in single-user mode.
You will be presented with a graphical Unix-like command line environment upon
login or booting the live environment.
.Ss Desktop Environment
The
.Xr display 1
desktop environment is automatically started when booting the live environment
or after logging into an installation.
.Pp
To power off the computer login as user
.Sy poweroff
or run
The desktop environment can be exited by pressing Control + Alt + Delete,
which will return to the login screen (in installations) or power off the
computer (in the live environment).
.Pp
A new
.Xr terminal 1
can be launched by pressing Control + Alt + F1.
.Pp
See
.Xr display 1
for all the available keyboard shortcuts.
.Ss Shutdown
To power off the computer, run
.Xr poweroff 8
after logging in.
To reboot the computer login as user
.Sy reboot
or run
or login as
.Sy poweroff .
To reboot the computter, run
.Xr reboot 8
after logging in.
or login as
.Sy reboot .
.Ss Keyboard Layout
The kernel has a default US keyboard layout compiled into it.
.Pp