Yay I can create a window -v-
This commit is contained in:
parent
7dec667c7d
commit
be95de08bb
7
Makefile
7
Makefile
|
@ -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)
|
||||
|
|
|
@ -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
|
41
src/main.c
41
src/main.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _ROOTWINDOW_H_
|
||||
#define _ROOTWINDOW_H_
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
Window create_root_window(Display *display, int screen);
|
||||
|
||||
#endif
|
|
@ -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);
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue