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 +=
|
CFLAGS +=
|
||||||
LDFLAGS := -lm
|
LDFLAGS := -lm -lX11 -lSDL2 -lSDL2_image
|
||||||
OBJECTS :=
|
OBJECTS := obj/rootwindow.o obj/sdl_xroot.o
|
||||||
|
|
||||||
livewp: lib
|
livewp: lib
|
||||||
$(CC) $(CFLAGS) $(OBJECTS) src/main.c $(LDFLAGS) -o livewp
|
$(CC) $(CFLAGS) $(OBJECTS) src/main.c $(LDFLAGS) -o livewp
|
||||||
|
|
||||||
|
testrun: all
|
||||||
|
./livewp
|
||||||
|
|
||||||
all: livewp
|
all: livewp
|
||||||
|
|
||||||
lib: $(OBJECTS)
|
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 <stdio.h>
|
||||||
#include <math.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) {
|
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