Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust the window size for desired client area and fix build error on Windows 11 #39

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ a.out
zig-cache
zig-out
Makefile.local
cmake-build*
.idea
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.30)
project(fenster VERSION 1.0.0)

set(CMAKE_CXX_STANDARD 20)

include_directories(include)

add_library(fenster
STATIC
src/fenster.cpp
)
47 changes: 47 additions & 0 deletions include/fenster.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once

#if defined(__APPLE__)
#include <CoreGraphics/CoreGraphics.h>
#include <objc/NSObjCRuntime.h>
#include <objc/objc-runtime.h>
#elif defined(_WIN32)
#include <windows.h>
#else
#define _DEFAULT_SOURCE 1
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <time.h>
#endif

#include <stdint.h>
#include <stdlib.h>

struct fenster {
const char *title;
const int width;
const int height;
uint32_t *buf;
int keys[256]; /* keys are mostly ASCII, but arrows are 17..20 */
int mod; /* mod is 4 bits mask, ctrl=1, shift=2, alt=4, meta=8 */
int x;
int y;
int mouse;
#if defined(__APPLE__)
id wnd;
#elif defined(_WIN32)
HWND hwnd;
#else
Display *dpy;
Window w;
GC gc;
XImage *img;
#endif
};

int fenster_open(struct fenster *f);
int fenster_loop(struct fenster *f);
void fenster_close(struct fenster *f);
void fenster_sleep(int64_t ms);
int64_t fenster_time(void);
#define fenster_pixel(f, x, y) ((f)->buf[((y) * (f)->width) + (x)])
File renamed without changes.
95 changes: 24 additions & 71 deletions fenster.h → src/fenster.cpp
Original file line number Diff line number Diff line change
@@ -1,56 +1,5 @@
#ifndef FENSTER_H
#define FENSTER_H
#include <fenster.hpp>

#if defined(__APPLE__)
#include <CoreGraphics/CoreGraphics.h>
#include <objc/NSObjCRuntime.h>
#include <objc/objc-runtime.h>
#elif defined(_WIN32)
#include <windows.h>
#else
#define _DEFAULT_SOURCE 1
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <time.h>
#endif

#include <stdint.h>
#include <stdlib.h>

struct fenster {
const char *title;
const int width;
const int height;
uint32_t *buf;
int keys[256]; /* keys are mostly ASCII, but arrows are 17..20 */
int mod; /* mod is 4 bits mask, ctrl=1, shift=2, alt=4, meta=8 */
int x;
int y;
int mouse;
#if defined(__APPLE__)
id wnd;
#elif defined(_WIN32)
HWND hwnd;
#else
Display *dpy;
Window w;
GC gc;
XImage *img;
#endif
};

#ifndef FENSTER_API
#define FENSTER_API extern
#endif
FENSTER_API int fenster_open(struct fenster *f);
FENSTER_API int fenster_loop(struct fenster *f);
FENSTER_API void fenster_close(struct fenster *f);
FENSTER_API void fenster_sleep(int64_t ms);
FENSTER_API int64_t fenster_time(void);
#define fenster_pixel(f, x, y) ((f)->buf[((y) * (f)->width) + (x)])

#ifndef FENSTER_HEADER
#if defined(__APPLE__)
#define msg(r, o, s) ((r(*)(id, SEL))objc_msgSend)(o, sel_getUid(s))
#define msg1(r, o, s, A, a) \
Expand Down Expand Up @@ -92,7 +41,7 @@ static BOOL fenster_should_close(id v, SEL s, id w) {
return YES;
}

FENSTER_API int fenster_open(struct fenster *f) {
int fenster_open(struct fenster *f) {
msg(id, cls("NSApplication"), "sharedApplication");
msg1(void, NSApp, "setActivationPolicy:", NSInteger, 0);
f->wnd = msg4(id, msg(id, cls("NSWindow"), "alloc"),
Expand Down Expand Up @@ -123,14 +72,14 @@ FENSTER_API int fenster_open(struct fenster *f) {
return 0;
}

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

// clang-format off
static const uint8_t FENSTER_KEYCODES[128] = {65,83,68,70,72,71,90,88,67,86,0,66,81,87,69,82,89,84,49,50,51,52,54,53,61,57,55,45,56,48,93,79,85,91,73,80,10,76,74,39,75,59,92,44,47,78,77,46,9,32,96,8,0,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,2,3,127,0,5,0,4,0,20,19,18,17,0};
// clang-format on
FENSTER_API int fenster_loop(struct fenster *f) {
int fenster_loop(struct fenster *f) {
msg1(void, msg(id, f->wnd, "contentView"), "setNeedsDisplay:", BOOL, YES);
id ev = msg4(id, NSApp,
"nextEventMatchingMask:untilDate:inMode:dequeue:", NSUInteger,
Expand Down Expand Up @@ -181,7 +130,7 @@ static LRESULT CALLBACK fenster_wndproc(HWND hwnd, UINT msg, WPARAM wParam,
HDC hdc = BeginPaint(hwnd, &ps);
HDC memdc = CreateCompatibleDC(hdc);
HBITMAP hbmp = CreateCompatibleBitmap(hdc, f->width, f->height);
HBITMAP oldbmp = SelectObject(memdc, hbmp);
HBITMAP oldbmp = static_cast<HBITMAP>(SelectObject(memdc, hbmp));
BINFO bi = {{sizeof(bi), f->width, -f->height, 1, 32, BI_BITFIELDS}};
bi.bmiColors[0].rgbRed = 0xff;
bi.bmiColors[1].rgbGreen = 0xff;
Expand Down Expand Up @@ -221,7 +170,7 @@ static LRESULT CALLBACK fenster_wndproc(HWND hwnd, UINT msg, WPARAM wParam,
return 0;
}

FENSTER_API int fenster_open(struct fenster *f) {
int fenster_open(struct fenster *f) {
HINSTANCE hInstance = GetModuleHandle(NULL);
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
Expand All @@ -230,9 +179,13 @@ FENSTER_API int fenster_open(struct fenster *f) {
wc.hInstance = hInstance;
wc.lpszClassName = f->title;
RegisterClassEx(&wc);
RECT desiredRect = {0, 0, f->width, f->height};
AdjustWindowRectEx(&desiredRect, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_CLIENTEDGE);
int adjustedWidth = desiredRect.right - desiredRect.left;
int adjustedHeight = desiredRect.bottom - desiredRect.top;
f->hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, f->title, f->title,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
f->width, f->height, NULL, NULL, hInstance, NULL);
adjustedWidth, adjustedHeight, NULL, NULL, hInstance, NULL);

if (f->hwnd == NULL)
return -1;
Expand All @@ -242,9 +195,12 @@ FENSTER_API int fenster_open(struct fenster *f) {
return 0;
}

FENSTER_API void fenster_close(struct fenster *f) { (void)f; }
void fenster_close(struct fenster *f) {
PostMessage(f->hwnd, WM_CLOSE, 0, 0);
(void)f;
}

FENSTER_API int fenster_loop(struct fenster *f) {
int fenster_loop(struct fenster *f) {
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
Expand All @@ -259,7 +215,7 @@ FENSTER_API int fenster_loop(struct fenster *f) {
// clang-format off
static int FENSTER_KEYCODES[124] = {XK_BackSpace,8,XK_Delete,127,XK_Down,18,XK_End,5,XK_Escape,27,XK_Home,2,XK_Insert,26,XK_Left,20,XK_Page_Down,4,XK_Page_Up,3,XK_Return,10,XK_Right,19,XK_Tab,9,XK_Up,17,XK_apostrophe,39,XK_backslash,92,XK_bracketleft,91,XK_bracketright,93,XK_comma,44,XK_equal,61,XK_grave,96,XK_minus,45,XK_period,46,XK_semicolon,59,XK_slash,47,XK_space,32,XK_a,65,XK_b,66,XK_c,67,XK_d,68,XK_e,69,XK_f,70,XK_g,71,XK_h,72,XK_i,73,XK_j,74,XK_k,75,XK_l,76,XK_m,77,XK_n,78,XK_o,79,XK_p,80,XK_q,81,XK_r,82,XK_s,83,XK_t,84,XK_u,85,XK_v,86,XK_w,87,XK_x,88,XK_y,89,XK_z,90,XK_0,48,XK_1,49,XK_2,50,XK_3,51,XK_4,52,XK_5,53,XK_6,54,XK_7,55,XK_8,56,XK_9,57};
// clang-format on
FENSTER_API int fenster_open(struct fenster *f) {
int fenster_open(struct fenster *f) {
f->dpy = XOpenDisplay(NULL);
int screen = DefaultScreen(f->dpy);
f->w = XCreateSimpleWindow(f->dpy, RootWindow(f->dpy, screen), 0, 0, f->width,
Expand All @@ -276,8 +232,8 @@ FENSTER_API int fenster_open(struct fenster *f) {
(char *)f->buf, f->width, f->height, 32, 0);
return 0;
}
FENSTER_API void fenster_close(struct fenster *f) { XCloseDisplay(f->dpy); }
FENSTER_API int fenster_loop(struct fenster *f) {
void fenster_close(struct fenster *f) { XCloseDisplay(f->dpy); }
int fenster_loop(struct fenster *f) {
XEvent ev;
XPutImage(f->dpy, f->w, f->gc, f->img, 0, 0, 0, 0, f->width, f->height);
XFlush(f->dpy);
Expand Down Expand Up @@ -311,21 +267,21 @@ FENSTER_API int fenster_loop(struct fenster *f) {
#endif

#ifdef _WIN32
FENSTER_API void fenster_sleep(int64_t ms) { Sleep(ms); }
FENSTER_API int64_t fenster_time() {
void fenster_sleep(int64_t ms) { Sleep(ms); }
int64_t fenster_time() {
LARGE_INTEGER freq, count;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&count);
return (int64_t)(count.QuadPart * 1000.0 / freq.QuadPart);
}
#else
FENSTER_API void fenster_sleep(int64_t ms) {
void fenster_sleep(int64_t ms) {
struct timespec ts;
ts.tv_sec = ms / 1000;
ts.tv_nsec = (ms % 1000) * 1000000;
nanosleep(&ts, NULL);
}
FENSTER_API int64_t fenster_time(void) {
int64_t fenster_time(void) {
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
return time.tv_sec * 1000 + (time.tv_nsec / 1000000);
Expand Down Expand Up @@ -365,7 +321,4 @@ class Fenster {
int mouse() { return this->f.mouse; }
int mod() { return this->f.mod; }
};
#endif /* __cplusplus */

#endif /* !FENSTER_HEADER */
#endif /* FENSTER_H */
#endif /* __cplusplus */