Yay I can create a window -v-

This commit is contained in:
Casey 2024-04-09 12:13:23 +03:00
parent 7dec667c7d
commit be95de08bb
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
7 changed files with 266 additions and 3 deletions

View File

@ -1,10 +1,13 @@
CFLAGS +=
LDFLAGS := -lm
OBJECTS :=
LDFLAGS := -lm -lX11 -lSDL2 -lSDL2_image
OBJECTS := obj/rootwindow.o obj/sdl_xroot.o
livewp: lib
$(CC) $(CFLAGS) $(OBJECTS) src/main.c $(LDFLAGS) -o livewp
testrun: all
./livewp
all: livewp
lib: $(OBJECTS)

37
example.lua Normal file
View File

@ -0,0 +1,37 @@
local img = assert(image_load("/home/hkc/images/wallpapers/wallpaper.png"))
local font = assert(font_load("/usr/share/fonts/TTF/TerminusTTF.ttf"))
function tick()
-- Background
clear_screen(0xFF131313)
-- Color ARGB, x, y
draw_pixel(0xFFFF0000, 30, 30)
-- Color ARGB, thickness, x1, y1, x2, y2, xn, yn, ...
draw_line(0xFFFF00FF, 8, 100, 100, 200, 400, 300, 600) --> { Vec2, ... }
-- Color ARGB, thickness, x1, y1, x2, y2, xn, yn, ...
draw_poly(0xFFFF00FF, 8, 100, 100, 200, 400, 300, 600) --> Rect
-- Color ARGB, radius, x, y, start, end
draw_circle(0xFFFF0000, 20, 300, 300) --> Rect
-- Color ARGB, outer, inner, x, y, start, end
draw_ring(0xFF00FF00, 30, 20, 300, 300) --> Rect
-- Color ARGB, x, y, w, h
draw_rect_fill(0xFF00FFFF, 100, 700, 320, 240) --> Rect
-- Color ARGB, thickness, x, y, w, h
draw_rect(0xFFFF00FF, 8, 100, 700, 320, 240) --> Rect
-- font, text, size, x, y, Color ARGB
draw_text(font, "Hello, world!", 32, 400, 400, 0xFFFF00FF) --> Rect
-- image ptr x, y, w, h, src_x, src_y, src_w, src_h
draw_image( img, 0, 0) --> Rect
end
function unload()
image_free(img)
font_free(font)
end

View File

@ -1,6 +1,45 @@
#include <SDL2/SDL.h>
#include <signal.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include "sdl_xroot.h"
struct sdlxroot_context ctx;
SDL_Renderer *renderer;
volatile bool running = true;
void cleanup(void) {
SDL_DestroyRenderer(renderer);
sdlxroot_close(&ctx);
}
void sighandler(int sig) {
running = false;
}
int main(void) {
printf("Hi!\n");
if (!sdlxroot_create(NULL, &ctx)) {
fprintf(stderr, "Failed creating window or something\n");
return EXIT_FAILURE;
}
atexit(cleanup);
signal(SIGINT, sighandler);
renderer = SDL_CreateRenderer(ctx.window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
while (running) {
SDL_SetRenderDrawColor(renderer, 0x13, 0x13, 0x13, 0);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0xff, 0x00, 0x00, 0xff);
SDL_RenderDrawLine(renderer, 200, 200, 600, 600);
SDL_RenderPresent(renderer);
usleep(1000);
}
return EXIT_SUCCESS;
}

119
src/rootwindow.c Normal file
View File

@ -0,0 +1,119 @@
#include "rootwindow.h"
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define ATOM(a) XInternAtom(display, #a, False)
Window find_desktop_window(Display *display, int screen, Window *ptr_root, Window *ptr_desktop);
Window find_subwindow(Display *display, Window win, int w, int h, int dw, int dh);
Window create_root_window(Display *display, int screen) {
// below, sticky, fullscreen, skip_taskbar, skip_pager, noFocus, override,
// set_desktop_type
XSetWindowAttributes attrs = {
ParentRelative, 0L, 0, 0L, 0, 0, Always, 0L, 0L, False, StructureNotifyMask | ExposureMask, 0L, True, 0, 0
};
int screen_w = DisplayWidth(display, screen),
screen_h = DisplayHeight(display, screen);
Window root, desktop;
if (!find_desktop_window(display, screen, &root, &desktop)) {
fprintf(stderr, "find_desktop_window() failed\n");
return 0;
}
Window window = XCreateWindow(display, desktop, 0, 0, screen_w, screen_h, 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect | CWBackingStore, &attrs);
if (!window) {
fprintf(stderr, "XCreateWindow() failed: %s\n", strerror(errno));
}
XLowerWindow(display, window);
XMapWindow(display, window);
XSync(display, window);
return window;
}
// from xwinwrap
Window find_subwindow(Display *display, Window win, int w, int h, int dw, int dh) {
unsigned int i, j;
Window troot, parent, *children;
unsigned int n;
/* search subwindows with same size as display or work area */
for (i = 0; i < 10; i++) {
XQueryTree(display, win, &troot, &parent, &children, &n);
for (j = 0; j < n; j++) {
XWindowAttributes attrs;
if (XGetWindowAttributes(display, children[j], &attrs)) {
/* Window must be mapped and same size as display or
* work space */
if (attrs.map_state != 0 &&
((attrs.width == dw && attrs.height == dh) ||
(attrs.width == w && attrs.height == h))) {
win = children[j];
break;
}
}
}
XFree(children);
if (j == n) {
break;
}
}
return win;
}
Window find_desktop_window(Display *display, int screen, Window *ptr_root, Window *ptr_desktop) {
int display_width, display_height;
Atom type;
int format;
unsigned long n_items, n_bytes;
unsigned char *buf = NULL;
Window root = RootWindow(display, screen);
Window win = root;
Window tmp_root, parent, *children;
unsigned int n_windows;
XQueryTree(display, root, &tmp_root, &parent, &children, &n_windows);
for (int i = 0; i < (int)n_windows; i++) {
if (XGetWindowProperty(display, children[i], ATOM(__SWM_VROOT), 0, 1, False, XA_WINDOW, &type, &format, &n_items, &n_bytes, &buf) == Success && type == XA_WINDOW) {
win = *(Window *)buf;
XFree(buf);
XFree(children);
*ptr_root = win;
*ptr_desktop = win;
return win;
}
if (buf) {
XFree(buf);
buf = NULL;
}
}
XFree(children);
win = find_subwindow(display, root, -1, -1, display_width, display_height);
display_width = DisplayWidth(display, screen);
display_height = DisplayHeight(display, screen);
win = find_subwindow(display, win, display_width, display_height, display_width, display_height);
if (buf) {
XFree(buf);
buf = NULL;
}
*ptr_root = root;
*ptr_desktop = win;
return win;
}

8
src/rootwindow.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _ROOTWINDOW_H_
#define _ROOTWINDOW_H_
#include <X11/Xlib.h>
Window create_root_window(Display *display, int screen);
#endif

40
src/sdl_xroot.c Normal file
View File

@ -0,0 +1,40 @@
#include "sdl_xroot.h"
#include "rootwindow.h"
#include <SDL2/SDL.h>
#include <X11/X.h>
#include <stdio.h>
bool sdlxroot_create(const char *display_name, struct sdlxroot_context *ctx) {
Display *display = XOpenDisplay(display_name);
if (!display) return false;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
// TODO: error handling
// FIXME: what is the invalid value for `Window`? -1? 0? some other value?
// docs aren't clear about it, or i'm just blind
ctx->x11_screen = DefaultScreen(display);
Window root_window = create_root_window(display, ctx->x11_screen);
if (!root_window) {
XCloseDisplay(display);
fprintf(stderr, "create_root_window() failed\n");
return false;
}
ctx->x11_display = display;
ctx->x11_window = root_window;
ctx->window = SDL_CreateWindowFrom((void *)ctx->x11_window);
if (!ctx->window) {
fprintf(stderr, "SDL_CreateWindowFrom(0x%08lx) failed\n", ctx->x11_window);
}
return ctx->window != NULL;
}
void sdlxroot_close(struct sdlxroot_context *ctx) {
SDL_DestroyWindow(ctx->window);
XDestroyWindow((Display *)ctx->x11_display, (Window)ctx->x11_window);
XCloseDisplay((Display *)ctx->x11_display);
}

17
src/sdl_xroot.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _SDL_XROOT_H_
#define _SDL_XROOT_H_
#include <SDL2/SDL.h>
#include <stdbool.h>
struct sdlxroot_context {
SDL_Window *window;
void *x11_display;
unsigned long x11_window;
int x11_screen;
};
bool sdlxroot_create(const char *display_name, struct sdlxroot_context *ctx);
void sdlxroot_close(struct sdlxroot_context *ctx);
#endif