Skip to content

Commit

Permalink
Window resize support
Browse files Browse the repository at this point in the history
  • Loading branch information
CardealRusso committed Oct 19, 2024
1 parent 3d2f3b0 commit 05c7aaa
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 30 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@

Code is distributed under MIT license, feel free to use it in your proprietary projects as well.

### Main changes
## Main changes
- Source split by system
- Platform-agnostic structure for audio
- Mouse: Left, Right, Middle, Scrollup/down
- Window resize (buf size is handled internally)
- Added: fenster_sync
- Changed: array on modkeys, mouse pos

```C
struct fenster {
const char *title;
const int width;
const int height;
uint32_t *buf;
int width;
int height;
int keys[256]; // keys are mostly ASCII, but arrows are 17..20
int modkeys[4]; // ctrl, shift, alt, meta
int mpos[2]; // mouse x, y
Expand All @@ -28,4 +28,4 @@ struct fenster {
};

FENSTER_API void fenster_sync(struct fenster *f, int fps);
```
```
29 changes: 8 additions & 21 deletions examples/mousebuttons-c/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,17 @@
#include <stdio.h>
#include <string.h>

#define W 320
#define H 240

/* ============================================================
* Mouse buttons states example:
* - Opens a window
* - Starts a loop
* - Print current state of mouse buttons (clicked and holding)
* only if there's a change
* - Closes a window
* ============================================================ */
static int run() {
uint32_t buf[W * H];
struct fenster f = {
.title = "Mouse Buttons",
.width = W,
.height = H,
.buf = buf,
};
struct fenster f = {.title = "Mouse Buttons",.width = 320,.height = 240,};
fenster_open(&f);
while (fenster_loop(&f) == 0) {
printf("Click: L:%d R:%d M:%d SU:%d SD:%d | \n",
f.mclick[0], f.mclick[1], f.mclick[2], f.mclick[3], f.mclick[4]);
fenster_sync(&f, 60);
for (int i = 0; i < f.width; i++) {
for (int j = 0; j < f.height; j++) {
fenster_pixel(&f, i, j) = rand();
}
}
printf("Click: L:%d R:%d M:%d SU:%d SD:%d | \n",f.mclick[0], f.mclick[1], f.mclick[2], f.mclick[3], f.mclick[4]);
fenster_sync(&f, 60);
}

fenster_close(&f);
Expand Down
6 changes: 4 additions & 2 deletions src/fenster/fenster.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#include <windows.h>
#else
#define _DEFAULT_SOURCE 1
#include <stdlib.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <time.h>
#endif
Expand All @@ -21,8 +23,8 @@

struct fenster {
const char *title;
const int width;
const int height;
int width;
int height;
uint32_t *buf;
int keys[256]; // keys are mostly ASCII, but arrows are 17..20
int modkeys[4]; // ctrl, shift, alt, meta
Expand Down
17 changes: 17 additions & 0 deletions src/fenster/fenster_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ static Atom wmDeleteWindow;
// clang-format on

FENSTER_API int fenster_open(struct fenster *f) {
f->buf = (uint32_t*)malloc(f->width * f->height * sizeof(uint32_t));
f->dpy = XOpenDisplay(NULL);
int screen = DefaultScreen(f->dpy);
f->w = XCreateSimpleWindow(f->dpy, RootWindow(f->dpy, screen), 0, 0, f->width,
Expand Down Expand Up @@ -39,6 +40,22 @@ FENSTER_API int fenster_loop(struct fenster *f) {
while (XPending(f->dpy)) {
XNextEvent(f->dpy, &ev);
switch (ev.type) {
case ConfigureNotify: {
if (ev.xconfigure.width != f->width || ev.xconfigure.height != f->height) {
uint32_t *new_buf = realloc(f->buf, ev.xconfigure.width * ev.xconfigure.height * sizeof(uint32_t));
if (!new_buf) break;

f->img->data = NULL;
XDestroyImage(f->img);

f->buf = new_buf;
f->width = ev.xconfigure.width;
f->height = ev.xconfigure.height;

f->img = XCreateImage(f->dpy, DefaultVisual(f->dpy, 0), 24, ZPixmap, 0,
(char *)f->buf, f->width, f->height, 32, 0);
}
} break;
case ClientMessage:
if ((Atom)ev.xclient.data.l[0] == wmDeleteWindow) {
return 1;
Expand Down
24 changes: 23 additions & 1 deletion src/fenster/fenster_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@
extern id const NSDefaultRunLoopMode;
extern id const NSApp;

static void fenster_window_resize(id v, SEL s, id note) {
(void)s;
struct fenster *f = (struct fenster *)objc_getAssociatedObject(v, "fenster");
CGRect frame = msg(CGRect, msg(id, note, "object"), "frame");

uint32_t *new_buf = realloc(f->buf, frame.size.width * frame.size.height * sizeof(uint32_t));
if (!new_buf) return;

f->buf = new_buf;
f->width = frame.size.width;
f->height = frame.size.height;
}

static void fenster_draw_rect(id v, SEL s, CGRect r) {
(void)r, (void)s;
struct fenster *f = (struct fenster *)objc_getAssociatedObject(v, "fenster");
Expand All @@ -42,6 +55,8 @@ static BOOL fenster_should_close(id v, SEL s, id w) {
}

FENSTER_API int fenster_open(struct fenster *f) {
f->buf = malloc(f->width * f->height * sizeof(uint32_t));
if (!f->buf) return -1;
msg(id, cls("NSApplication"), "sharedApplication");
msg1(void, NSApp, "setActivationPolicy:", NSInteger, 0);
f->wnd = msg4(id, msg(id, cls("NSWindow"), "alloc"),
Expand Down Expand Up @@ -69,11 +84,18 @@ FENSTER_API int fenster_open(struct fenster *f) {
msg1(void, f->wnd, "makeKeyAndOrderFront:", id, nil);
msg(void, f->wnd, "center");
msg1(void, NSApp, "activateIgnoringOtherApps:", BOOL, YES);
class_addMethod(c, sel_getUid("windowDidResize:"), (IMP)fenster_window_resize, "v@:@");
msg4(void, msg(id, cls("NSNotificationCenter"), "defaultCenter"),
"addObserver:selector:name:object:", id, v,
SEL, sel_getUid("windowDidResize:"),
id, msg1(id, cls("NSString"), "stringWithUTF8String:", const char*, "NSWindowDidResizeNotification"),
id, f->wnd);
return 0;
}

FENSTER_API void fenster_close(struct fenster *f) {
msg(void, f->wnd, "close");
free(f->buf);
msg(void, f->wnd, "close");
}

// clang-format off
Expand Down
21 changes: 20 additions & 1 deletion src/fenster/fenster_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ static LRESULT CALLBACK fenster_wndproc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam) {
struct fenster *f = (struct fenster *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
switch (msg) {
case WM_SIZE: {
RECT rect;
GetClientRect(hwnd, &rect);
int new_width = rect.right - rect.left;
int new_height = rect.bottom - rect.top;

if (new_width != f->width || new_height != f->height) {
uint32_t *new_buf = realloc(f->buf, new_width * new_height * sizeof(uint32_t));
if (!new_buf) break;

f->buf = new_buf;
f->width = new_width;
f->height = new_height;
}
} break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
Expand Down Expand Up @@ -81,6 +96,7 @@ static LRESULT CALLBACK fenster_wndproc(HWND hwnd, UINT msg, WPARAM wParam,
}

FENSTER_API int fenster_open(struct fenster *f) {
f->buf = (uint32_t*)malloc(f->width * f->height * sizeof(uint32_t));
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
Expand All @@ -101,7 +117,10 @@ FENSTER_API int fenster_open(struct fenster *f) {
return 0;
}

FENSTER_API void fenster_close(struct fenster *f) { (void)f; }
FENSTER_API void fenster_close(struct fenster *f) {
free(f->buf);
(void)f;
}

FENSTER_API int fenster_loop(struct fenster *f) {
memset(f->mclick, 0, sizeof(f->mclick));
Expand Down

0 comments on commit 05c7aaa

Please sign in to comment.