xlib_playground

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 5930554875887db46b4745f7e6fc38136d118fe0
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Thu, 15 Dec 2022 09:27:42 +0900

first commit

Diffstat:
A.gitignore | 1+
AMakefile | 11+++++++++++
Amain.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aobj.c | 22++++++++++++++++++++++
Aobj.h | 9+++++++++
5 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +main diff --git a/Makefile b/Makefile @@ -0,0 +1,11 @@ +INCS=-I/usr/X11R6/include +CFLAGS=-Wall -Wextra -std=c11 +LIBS=-L/usr/X11R6/lib -lX11 -lXext +IN=*.c +OUT=main + +all: main.c + $(CC) $(INCS) $(CFLAGS) -o $(OUT) $(IN) $(LIBS) + +run: all + ./$(OUT) diff --git a/main.c b/main.c @@ -0,0 +1,110 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +#include <X11/Xlib.h> + +#include "obj.h" + +#define INIT_WIDTH 800 +#define INIT_HEIGHT 600 +#define FPS 60 +#define RECT_WIDTH 300 +#define RECT_HEIGHT 300 + +int +main(void) +{ + Display *display; + Window window; + unsigned int win_width = INIT_WIDTH, win_height = INIT_HEIGHT; + GC gc; + Pixmap pm; + Atom wm_delete_window; + Obj square = {1, 1, 100, 100, 20, 20}; + + if((display = XOpenDisplay(NULL)) == NULL){ + fprintf(stderr, "ERROR: could not open display\n"); + exit(1); + } + window = XCreateSimpleWindow( + display, + XDefaultRootWindow(display), + 0, 0, + win_width, win_height, + 0, 0, + 0); + XStoreName(display, window, "UNKO"); + gc = XCreateGC(display, window, 0, NULL); + pm = XCreatePixmap(display, window, win_width, win_height, + DefaultDepth(display, DefaultScreen(display))); + + wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(display, window, &wm_delete_window, 1); + + XSelectInput(display, window, KeyPressMask); + + XMapWindow(display, window); + + int quit = 0; + while (!quit) { + while (XPending(display) > 0) { + XEvent event = {0}; + XNextEvent(display, &event); + switch (event.type) { + case KeyPress: { + switch (XLookupKeysym(&event.xkey, 0)) { + case 'q': + quit = 1; + break; + default: + break; + } + } break; + case ClientMessage: { + if ((Atom) event.xclient.data.l[0] == wm_delete_window) { + quit = 1; + } + } break; + } + } + + XSetForeground(display, gc, 0); + XFillRectangle(display, pm, gc, 0, 0, win_width, win_height); + + XWindowAttributes window_attributes_return; + XGetWindowAttributes(display, window, &window_attributes_return); + win_width = window_attributes_return.width; + win_height = window_attributes_return.height; + + + if(square.px <= 0){ + square.px = 0; + square.vx *= -1; + } + if(win_width <= square.px + square.width){ + square.px = win_width - square.width; + square.vx *= -1; + } + if(square.py <= 0){ + square.py = 0; + square.vy *= -1; + } + if(win_height <= square.py + square.height){ + square.py = win_height - square.height; + square.vy *= -1; + } + obj_accel(&square, 0, 9.8); + obj_next_tick(&square, 1.0/FPS); + XSetForeground(display, gc, 0x00FF00); + XFillRectangle(display, pm, gc, square.px, square.py, square.width, square.height); + + XCopyArea(display, pm, window, gc, 0, 0, win_width, win_height, 0, 0); + + struct timespec timetosleep = {0, 1000*1000*1000/FPS}; //not accurate + nanosleep(&timetosleep, NULL); + } + + XCloseDisplay(display); + return 0; +} diff --git a/obj.c b/obj.c @@ -0,0 +1,22 @@ +#include "obj.h" + +void +obj_move(Obj *obj, float px, float py) +{ + obj->px = px; + obj->py = py; +} + +void +obj_next_tick(Obj *obj, float dt) +{ + obj->px += obj->vx * dt; + obj->py += obj->vy * dt; +} + +void +obj_accel(Obj *obj, float ax, float ay) +{ + obj->vx += ax; + obj->vy += ay; +} diff --git a/obj.h b/obj.h @@ -0,0 +1,9 @@ +typedef struct Obj{ + float px, py; + float vx, vy; + float width, height; +} Obj; + +void obj_move(Obj *obj, float px, float py); // move obj to the pos +void obj_next_tick(Obj *obj, float dt); // move obj by velocity * dt +void obj_accel(Obj *obj, float ax, float ay); // accelerate obj by accel