Dactyloidae Milsko Widget initial commit

This commit is contained in:
wuggy 2026-07-28 23:21:45 +01:00
commit 91b45c0d14
410 changed files with 204246 additions and 0 deletions

View file

@ -0,0 +1,229 @@
/*!
* @file Mw/LowLevel/Cairo.h
* @brief Cairo Backend
* @warning This is used MEGA internally.
*/
#ifndef __MW_LOWLEVEL_CAIRO_H__
#define __MW_LOWLEVEL_CAIRO_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h>
#include <Mw/Abstract/Dynamic.h>
#include <cairo/cairo.h>
#ifdef __cplusplus
extern "C" {
#endif
MWDECL int MwLLCairoCallInit(void);
#ifdef __cplusplus
}
#endif
#define CSD_BORDER_FRAME_LEFT 5
#define CSD_BORDER_FRAME_RIGHT 5
#define CSD_BORDER_FRAME_TOP 23
#define CSD_BORDER_FRAME_BOTTOM 4
typedef struct cairo_call_table {
void* cairo_lib;
void (*cairo_set_line_width)(cairo_t* cr,
double width);
void (*cairo_scale)(cairo_t* cr,
double sx,
double sy);
cairo_t* (*cairo_create)(cairo_surface_t* target);
void (*cairo_move_to)(cairo_t* cr,
double x,
double y);
void (*cairo_rectangle)(cairo_t* cr,
double x,
double y,
double width,
double height);
void (*cairo_new_path)(cairo_t* cr);
void (*cairo_set_line_cap)(cairo_t* cr,
cairo_line_cap_t line_cap);
void (*cairo_set_source_rgba)(cairo_t* cr,
double red,
double green,
double blue,
double alpha);
void (*cairo_set_source_rgb)(cairo_t* cr,
double red,
double green,
double blue);
void (*cairo_reset_clip)(cairo_t* cr);
unsigned char* (*cairo_image_surface_get_data)(cairo_surface_t* surface);
void (*cairo_line_to)(cairo_t* cr,
double x,
double y);
cairo_status_t (*cairo_surface_write_to_png)(cairo_surface_t* surface, const char* filename);
void (*cairo_surface_destroy)(cairo_surface_t* surface);
cairo_surface_t* (*cairo_image_surface_create_for_data)(unsigned char* data,
cairo_format_t format,
int width,
int height,
int stride);
cairo_surface_t* (*cairo_image_surface_create)(cairo_format_t format,
int width,
int height);
void (*cairo_destroy)(cairo_t* cr);
cairo_pattern_t* (*cairo_get_source)(cairo_t* cr);
void (*cairo_close_path)(cairo_t* cr);
void (*cairo_paint)(cairo_t* cr);
void (*cairo_surface_flush)(cairo_surface_t* surface);
void (*cairo_clip)(cairo_t* cr);
void (*cairo_save)(cairo_t* cr);
void (*cairo_restore)(cairo_t* cr);
void (*cairo_surface_mark_dirty)(cairo_surface_t* surface);
void (*cairo_stroke)(cairo_t* cr);
void (*cairo_set_source_surface)(cairo_t* cr,
cairo_surface_t* surface,
double x,
double y);
void (*cairo_fill)(cairo_t* cr);
void (*cairo_pattern_set_filter)(cairo_pattern_t* pattern,
cairo_filter_t filter);
void (*cairo_set_antialias)(cairo_t*, cairo_antialias_t);
void (*cairo_set_operator)(cairo_t* cr, cairo_operator_t op);
} cairo_call_table_t;
extern cairo_call_table_t cairo_call_tbl;
/* defined inline right here so that it doesn't conflict with the other macros */
MwInline int cairo_load_funcs() {
#ifdef __APPLE__
cairo_call_tbl.cairo_lib = MwDynamicOpen("libcairo.dylib");
#else
cairo_call_tbl.cairo_lib = MwDynamicOpen("libcairo.so");
#endif
if(!cairo_call_tbl.cairo_lib) {
printf("(libcairo not found, cannot use Wayland or Cairo backend.)\n");
return 1;
}
#define CAIRO_FUNC(x) \
cairo_call_tbl.x = MwDynamicSymbol(cairo_call_tbl.cairo_lib, #x); \
if(!cairo_call_tbl.x) { \
printf("WARNING: Could use Wayland/Cairo backend if " #x " was not found. Do you have libcairo?\n"); \
return 1; \
};
CAIRO_FUNC(cairo_set_line_width);
CAIRO_FUNC(cairo_scale);
CAIRO_FUNC(cairo_create);
CAIRO_FUNC(cairo_move_to);
CAIRO_FUNC(cairo_rectangle);
CAIRO_FUNC(cairo_new_path);
CAIRO_FUNC(cairo_set_line_cap);
CAIRO_FUNC(cairo_set_antialias);
CAIRO_FUNC(cairo_set_source_rgba);
CAIRO_FUNC(cairo_set_source_rgb);
CAIRO_FUNC(cairo_reset_clip);
CAIRO_FUNC(cairo_image_surface_get_data);
CAIRO_FUNC(cairo_line_to);
CAIRO_FUNC(cairo_surface_write_to_png);
CAIRO_FUNC(cairo_surface_destroy);
CAIRO_FUNC(cairo_image_surface_create_for_data);
CAIRO_FUNC(cairo_image_surface_create);
CAIRO_FUNC(cairo_destroy);
CAIRO_FUNC(cairo_get_source);
CAIRO_FUNC(cairo_close_path);
CAIRO_FUNC(cairo_paint);
CAIRO_FUNC(cairo_surface_flush);
CAIRO_FUNC(cairo_clip);
CAIRO_FUNC(cairo_save);
CAIRO_FUNC(cairo_restore);
CAIRO_FUNC(cairo_surface_mark_dirty);
CAIRO_FUNC(cairo_stroke);
CAIRO_FUNC(cairo_set_source_surface);
CAIRO_FUNC(cairo_fill);
CAIRO_FUNC(cairo_set_operator);
CAIRO_FUNC(cairo_pattern_set_filter);
#undef CAIRO_FUNC
return 0;
}
#define cairo_set_line_width cairo_call_tbl.cairo_set_line_width
#define cairo_scale cairo_call_tbl.cairo_scale
#define cairo_create cairo_call_tbl.cairo_create
#define cairo_move_to cairo_call_tbl.cairo_move_to
#define cairo_rectangle cairo_call_tbl.cairo_rectangle
#define cairo_new_path cairo_call_tbl.cairo_new_path
#define cairo_set_line_cap cairo_call_tbl.cairo_set_line_cap
#define cairo_set_antialias cairo_call_tbl.cairo_set_antialias
#define cairo_set_source_rgba cairo_call_tbl.cairo_set_source_rgba
#define cairo_set_source_rgb cairo_call_tbl.cairo_set_source_rgb
#define cairo_reset_clip cairo_call_tbl.cairo_reset_clip
#define cairo_image_surface_get_data cairo_call_tbl.cairo_image_surface_get_data
#define cairo_line_to cairo_call_tbl.cairo_line_to
#define cairo_surface_write_to_png cairo_call_tbl.cairo_surface_write_to_png
#define cairo_surface_destroy cairo_call_tbl.cairo_surface_destroy
#define cairo_image_surface_create_for_data cairo_call_tbl.cairo_image_surface_create_for_data
#define cairo_image_surface_create cairo_call_tbl.cairo_image_surface_create
#define cairo_destroy cairo_call_tbl.cairo_destroy
#define cairo_get_source cairo_call_tbl.cairo_get_source
#define cairo_close_path cairo_call_tbl.cairo_close_path
#define cairo_paint cairo_call_tbl.cairo_paint
#define cairo_surface_flush cairo_call_tbl.cairo_surface_flush
#define cairo_clip cairo_call_tbl.cairo_clip
#define cairo_save cairo_call_tbl.cairo_save
#define cairo_restore cairo_call_tbl.cairo_restore
#define cairo_surface_mark_dirty cairo_call_tbl.cairo_surface_mark_dirty
#define cairo_stroke cairo_call_tbl.cairo_stroke
#define cairo_set_source_surface cairo_call_tbl.cairo_set_source_surface
#define cairo_fill cairo_call_tbl.cairo_fill
#define cairo_set_operator cairo_call_tbl.cairo_set_operator
#define cairo_pattern_set_filter cairo_call_tbl.cairo_pattern_set_filter
struct _MwLLCairo {
struct _MwLLCommon common;
cairo_surface_t* front_cs;
cairo_surface_t* back_cs;
cairo_t* front_cairo;
cairo_t* back_cairo;
/* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
cairo_t* selected_cairo;
int x;
int y;
int width;
int height;
MwBool toplevel;
MwLL parent;
};
struct _MwLLCairoColor {
struct _MwLLCommonColor common;
};
struct _MwLLCairoPixmap {
struct _MwLLCommonPixmap common;
cairo_surface_t* cs;
};
void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height);
void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height);
void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo);
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo);
void MwLLCairoPolygon(struct _MwLLCairo handle, MwPoint* points, int points_count, MwLLColor color);
void MwLLCairoLine(struct _MwLLCairo handle, MwPoint* points, MwLLColor color);
MwLLPixmap MwLLCairoCreatePixmap(struct _MwLLCairo handle, unsigned char* data, int width, int height);
void MwLLCairoPixmapUpdate(MwLLPixmap handle);
void MwLLCairoDestroyPixmap(MwLLPixmap pixmap);
void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixmap);
void MwLLCairoDestroy(struct _MwLLCairo handle);
#endif

View file

@ -0,0 +1,43 @@
/*!
* @file Mw/LowLevel/ClassicMacOS.h
* @brief ClassicMacOS Backend
* @warning This is used internally
*/
#ifndef __MW_LOWLEVEL_ClassicMacOS_H__
#define __MW_LOWLEVEL_ClassicMacOS_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h>
#ifdef __cplusplus
extern "C" {
#endif
struct _MwLLClassicMacOS {
struct _MwLLCommon common;
MwLL parent;
WindowRef window;
ControlHandle control;
EventRecord event;
Rect winRect;
};
struct _MwLLClassicMacOSColor {
struct _MwLLCommonColor common;
};
struct _MwLLClassicMacOSPixmap {
struct _MwLLCommonPixmap common;
BitMap bmp;
};
MWDECL int MwLLClassicMacOSCallInit(void);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,189 @@
/*!
* @file Mw/LowLevel/Cocoa.h
* @brief Work in progress Cocoa Backend
* @warning This is used internally.
*/
#ifndef __MW_LOWLEVEL_COCOA_H__
#define __MW_LOWLEVEL_COCOA_H__
#include <Mw/LowLevel.h>
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
typedef struct {
enum {
COCOA_DRAW_COMMAND_POLY = 0,
COCOA_DRAW_COMMAND_LINES,
COCOA_DRAW_COMMAND_PIXMAP,
} type;
union {
struct {
MwPoint* points;
int points_count;
struct _MwLLCommonColor color;
} poly;
struct {
MwPoint* points;
struct _MwLLCommonColor color;
} lines;
struct {
MwRect rect;
MwLLPixmap pixmap;
} pixmap;
};
} draw_command;
#ifdef __OBJC__
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSGeometry.h>
@interface MilskoCocoaApplication : NSApplication {
MwBool doPending;
}
- (MwBool)pending;
@end
// Note: implements NSApplicationDelegate
@interface MilskoCocoaApplicationDelegate : NSObject {
MilskoCocoaApplication* appl;
}
- (MilskoCocoaApplicationDelegate*)initWithAppl:(MilskoCocoaApplication*)appl;
@end
@interface MilskoCocoaWindow : NSWindow {
}
@end
// Note: implements NSWindowDelegate
@interface MilskoCocoaWindowDelegate : NSObject {
NSWindow* w;
}
- (MilskoCocoaWindowDelegate*)initWithWin:(NSWindow*)win;
@end
/*
So we want to associate each NSWindow with its corresponding MwLL handle. The
conventional way of doing this is through "associative pointers", however
this is a feature that Apple added in 10.6 (marketted back then as "Objective
C 2" iirc). For 10.4 compatibility, we have to do a bit of an ugly hack that
might seem like horrifically undefined behavior, but I've tested this on
both 10.4 and modern Mac OS and as long as we're careful there's no
problems: we override NSView, use NSView's "frame" property to store the
pointer, and then override functions appropriately so that this frame is never
actually used. This can then be attached to an NSWindow with addSubview and
retrieved appropriately.
*/
@interface MilskoFakePointer : NSView {
void* ptr;
}
- (void)setPointer:(void*)ptr;
- (void*)pointer;
@end
@interface MilskoCocoaPixmap : NSObject {
@public
MwBool valid;
int width;
int height;
unsigned char* buf;
NSImage* image;
NSBitmapImageRep* rep;
}
+ (MilskoCocoaPixmap*)newWithWidth:(int)width height:(int)height;
- (void)updateWithData:(unsigned char*)data;
- (void)destroy;
/* using @property to create instance variables fucks up 10.4 gcc for some
* reason? */
- (NSImage*)image;
@end
@interface MilskoCocoaView : NSView {
MwBool _child;
@public
draw_command* commands;
}
- (void)destroy;
- (void)setChild;
@end
@interface MilskoCocoaSubView : MilskoCocoaView {
}
@end
@interface MilskoCocoa : NSObject {
@public
MilskoCocoaApplication* application;
MwBool _forceRender;
MwBool _eventsPending;
MwBool isClosing;
NSWindow* window;
NSRect rect;
MilskoCocoaView* view;
MwLL parent;
MilskoFakePointer* handle;
unsigned int strHash;
NSEvent* lastEvent;
MilskoCocoaPixmap* cursorPixmap;
NSCursor* cursor;
NSModalSession modalSession;
MwBool pointerLocked;
MwBool mouseMoved;
MwBool rejectFirstTest;
}
- (void)destroy;
- (void)sendClipboardEvent;
- (MwLL)getParent;
- (NSView*)getView;
- (NSWindow*)getWindow;
- (void)nudge;
- (void)pushCursor;
- (void)popCursor;
- (MilskoFakePointer*)getHandle;
@end
#define OBJC(x) x
#else
#define OBJC(x) void*
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct _MwLLCocoa {
struct _MwLLCommon common;
OBJC(MilskoCocoa*)
real;
};
struct _MwLLCocoaColor {
struct _MwLLCommonColor common;
};
struct _MwLLCocoaPixmap {
struct _MwLLCommonPixmap common;
OBJC(MilskoCocoaPixmap*)
real;
};
MWDECL int MwLLCocoaCallInit(void);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,57 @@
/*!
* @file Mw/LowLevel/GDI.h
* @brief GDI Backend
* @warning This is used internally
*/
#ifndef __MW_LOWLEVEL_GDI_H__
#define __MW_LOWLEVEL_GDI_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h>
#ifdef __cplusplus
extern "C" {
#endif
struct _MwLLGDI {
struct _MwLLCommon common;
HINSTANCE hInstance;
HWND hWnd;
HDC hDC;
HCURSOR cursor;
HICON icon;
HRGN clip;
int grabbed;
int force_render;
int get_clipboard;
int get_darktheme;
};
struct _MwLLGDIColor {
struct _MwLLCommonColor common;
COLORREF color;
HBRUSH brush;
};
struct _MwLLGDIPixmap {
struct _MwLLCommonPixmap common;
RGBQUAD* quad;
HBITMAP hBitmap;
HBITMAP hMask;
HBITMAP hMask2;
};
MWDECL int MwLLGDICallInit(void);
MWDECL HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,173 @@
/*!
* @file Mw/LowLevel/Haiku.h
* @brief Haiku Backend
* @warning This is used internally
*/
#ifndef __MW_LOWLEVEL_HAIKU_H__
#define __MW_LOWLEVEL_HAIKU_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
class MwApplication;
class MwView;
class MwWindow;
class MwApplication : public BApplication {
public:
MwApplication(MwRect rc, MwLL handle);
~MwApplication();
void MessageReceived(BMessage* message);
};
class MwView : public BView {
public:
MwLL handle;
BLocker* locker;
uint32 buttons;
BBitmap* bitmap;
MwView(MwLL handle, BRect rc, uint32 resizingMode, uint32 flags);
~MwView();
void MessageReceived(BMessage* message);
void PostMessage(BMessage* message);
void PostMessage(uint32 command);
status_t SendMessage(BMessage* message);
status_t SendMessage(uint32 command);
void Invalidate();
void AttachedToWindow();
void Draw(BRect updateRect);
void FrameResized(float width, float height);
void MouseDown(BPoint point);
void MouseUp(BPoint point);
void MouseMoved(BPoint point, uint32 transit, const BMessage* message);
void SetColor(MwLLColor color);
};
class MwWindow : public BWindow {
public:
MwWindow(BRect rc, window_type type, uint32 flags);
void MessageReceived(BMessage* message);
void FrameMoved(BPoint newLocation);
bool QuitRequested();
};
typedef BBitmap MwBBitmap;
#else
typedef void MwApplication;
typedef void MwView;
typedef void MwWindow;
typedef void MwBBitmap;
#endif
typedef union _MwLLHaikuEvent MwLLHaikuEvent;
enum BAPP_MW_WHAT {
BAPP_MW_DESTROY = 0
};
enum BVIEW_MW_WHAT {
BVIEW_MW_DESTROY = 0,
BVIEW_MW_DETACH,
BVIEW_MW_RESIZE,
BVIEW_MW_MOVE,
BVIEW_MW_SHOW,
BVIEW_MW_HIDE,
BVIEW_MW_SET_COLOR,
BVIEW_MW_POLYGON,
BVIEW_MW_LINE,
BVIEW_MW_BITMAP,
BVIEW_MW_RENDER,
BVIEW_MW_RAISE,
BVIEW_MW_GET_MOUSE
};
enum BWIN_MW_WHAT {
BWIN_MW_DESTROY = 0,
BWIN_MW_SET_TITLE,
BWIN_MW_SET_TYPE
};
enum MwLLHAIKU_EVENT {
MwLLHAIKU_EVENT_DRAW = 0,
MwLLHAIKU_EVENT_CLOSE,
MwLLHAIKU_EVENT_FRAMERESIZED,
MwLLHAIKU_EVENT_FRAMEMOVED,
MwLLHAIKU_EVENT_MOUSEDOWN,
MwLLHAIKU_EVENT_MOUSEUP,
MwLLHAIKU_EVENT_MOUSEMOVED
};
struct _MwLLHaikuEventMouse {
int type;
MwPoint point;
int button;
};
struct _MwLLHaikuEventFrameResized {
int type;
float width;
float height;
};
struct _MwLLHaikuEventFrameMoved {
int type;
MwPoint point;
};
union _MwLLHaikuEvent {
int type;
struct _MwLLHaikuEventMouse mouse;
struct _MwLLHaikuEventFrameResized frame_resized;
struct _MwLLHaikuEventFrameMoved frame_moved;
};
struct _MwLLHaiku {
struct _MwLLCommon common;
int type;
int x;
int y;
int width;
int height;
MwLL parent;
MwApplication* app;
MwWindow* window;
MwView* view;
thread_id app_thread;
int force_render;
MwLLHaikuEvent* events;
};
struct _MwLLHaikuColor {
struct _MwLLCommonColor common;
};
struct _MwLLHaikuPixmap {
struct _MwLLCommonPixmap common;
MwBBitmap* bitmap;
};
MWDECL int MwLLHaikuCallInit(void);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,517 @@
/*!
* @file Mw/LowLevel/Wayland.h
* @brief Wayland Backend
* @warning This is used internally.
*/
#ifndef __MW_LOWLEVEL_WAYLAND_H__
#define __MW_LOWLEVEL_WAYLAND_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h>
#include <Mw/Abstract/Dynamic.h>
#include <Mw/LowLevel/Cairo.h>
#include <xkbcommon/xkbcommon.h>
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
MWDECL int MwLLWaylandCallInit(void);
#ifdef __cplusplus
}
#endif
#define CSD_BORDER_FRAME_LEFT 5
#define CSD_BORDER_FRAME_RIGHT 5
#define CSD_BORDER_FRAME_TOP 23
#define CSD_BORDER_FRAME_BOTTOM 4
struct _MwLLWayland;
#include <wayland-client-core.h>
#if WAYLAND_LOAD_OPENGL
#include <EGL/egl.h>
#include <wayland-egl-core.h>
#endif
typedef struct wayland_call_table {
void* lib;
void* xkb_lib;
#ifdef USE_DBUS
MwLLDBusFuncTable dbus;
MwBool has_dbus;
#endif
int (*wl_display_dispatch)(struct wl_display* display);
int (*wl_display_dispatch_pending)(struct wl_display* display);
void (*wl_display_disconnect)(struct wl_display* display);
void (*wl_display_cancel_read)(struct wl_display* display);
int (*wl_display_prepare_read)(struct wl_display* display);
int (*wl_display_read_events)(struct wl_display* display);
int (*wl_display_flush)(struct wl_display* display);
int (*wl_display_get_fd)(struct wl_display* display);
int (*wl_display_roundtrip)(struct wl_display* display);
int (*wl_proxy_add_listener)(struct wl_proxy* proxy, void (**implementation)(void), void* data);
void (*wl_proxy_destroy)(struct wl_proxy* proxy);
void (*wl_log_set_handler_client)(wl_log_func_t handler);
struct wl_proxy* (*wl_proxy_marshal_flags)(struct wl_proxy* proxy, uint32_t opcode,
const struct wl_interface* interface,
uint32_t version,
uint32_t flags, ...);
struct wl_display* (*wl_display_connect)(const char* name);
uint32_t (*wl_proxy_get_version)(struct wl_proxy* proxy);
struct wl_display* (*wl_display_connect_to_fd)(int fd);
int (*wl_display_get_error)(struct wl_display* display);
struct xkb_context* (*xkb_context_new)(enum xkb_context_flags flags);
void (*xkb_context_unref)(struct xkb_context* context);
struct xkb_state* (*xkb_state_new)(struct xkb_keymap* keymap);
void (*xkb_state_unref)(struct xkb_state* state);
struct xkb_keymap* (*xkb_keymap_new_from_string)(struct xkb_context* context, const char* string, enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags);
xkb_level_index_t (*xkb_keymap_num_levels_for_key)(struct xkb_keymap* keymap, xkb_keycode_t key, xkb_layout_index_t layout);
int (*xkb_keymap_key_get_syms_by_level)(struct xkb_keymap* keymap, xkb_keycode_t key, xkb_layout_index_t layout, xkb_level_index_t level, const xkb_keysym_t** syms_out);
xkb_layout_index_t (*xkb_state_key_get_layout)(struct xkb_state* state, xkb_keycode_t key);
void (*xkb_keymap_unref)(struct xkb_keymap* keymap);
} wayland_call_table_t;
extern wayland_call_table_t wl_call_tbl;
#ifdef MW_VULKAN
extern MwBool MwWaylandVulkan;
#else
#define MwWaylandVulkan 0
#endif
MWDECL MwBool MwWaylandCairoOnly;
/* defined inline right here so that it doesn't conflict with the other macros */
MwInline int wayland_load_funcs() {
#ifdef __APPLE__
wl_call_tbl.lib = MwDynamicOpen("libwayland-client.dylib");
#else
wl_call_tbl.lib = MwDynamicOpen("libwayland-client.so");
#endif
if(!wl_call_tbl.lib) {
printf("(libwayland-client not found, falling back to X11)\n");
return 1;
}
#ifdef __APPLE__
wl_call_tbl.xkb_lib = MwDynamicOpen("libxkbcommon.dylib");
#else
wl_call_tbl.xkb_lib = MwDynamicOpen("libxkbcommon.so");
#endif
if(!wl_call_tbl.xkb_lib) {
printf("(libxkbcommon not found, cannot use Wayland backend.)\n");
return 1;
}
#define WAYLAND_FUNC(x) \
wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.lib, #x); \
if(!wl_call_tbl.x) { \
printf("WARNING: Could use Wayland backend if " #x " was found.\n"); \
return 1; \
};
WAYLAND_FUNC(wl_display_dispatch)
WAYLAND_FUNC(wl_display_dispatch_pending)
WAYLAND_FUNC(wl_display_disconnect)
WAYLAND_FUNC(wl_display_cancel_read)
WAYLAND_FUNC(wl_display_prepare_read)
WAYLAND_FUNC(wl_display_read_events)
WAYLAND_FUNC(wl_display_flush)
WAYLAND_FUNC(wl_display_get_fd)
WAYLAND_FUNC(wl_display_roundtrip)
WAYLAND_FUNC(wl_proxy_add_listener)
WAYLAND_FUNC(wl_proxy_destroy)
WAYLAND_FUNC(wl_log_set_handler_client)
WAYLAND_FUNC(wl_proxy_marshal_flags)
WAYLAND_FUNC(wl_display_connect)
WAYLAND_FUNC(wl_proxy_get_version)
WAYLAND_FUNC(wl_display_connect_to_fd)
WAYLAND_FUNC(wl_display_get_error)
#undef WAYLAND_FUNC
#define XKB_FUNC(x) \
wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.xkb_lib, #x); \
if(!wl_call_tbl.x) { \
printf("WARNING: Could use Wayland backend if " #x " was found. Do you have libxkbcommon?\n"); \
return 1; \
};
XKB_FUNC(xkb_state_unref)
XKB_FUNC(xkb_context_new)
XKB_FUNC(xkb_context_unref)
XKB_FUNC(xkb_state_new)
XKB_FUNC(xkb_keymap_new_from_string)
XKB_FUNC(xkb_keymap_unref)
XKB_FUNC(xkb_keymap_num_levels_for_key)
XKB_FUNC(xkb_keymap_key_get_syms_by_level)
XKB_FUNC(xkb_state_key_get_layout)
#undef XKB_FUNC
if(cairo_load_funcs() != 0) {
return 1;
}
#ifdef USE_DBUS
wl_call_tbl.has_dbus = MwLLDBusFuncSetup(&wl_call_tbl.dbus);
#endif
return 0;
}
#define wl_display_dispatch wl_call_tbl.wl_display_dispatch
#define wl_display_dispatch_pending wl_call_tbl.wl_display_dispatch_pending
#define wl_display_disconnect wl_call_tbl.wl_display_disconnect
#define wl_display_cancel_read wl_call_tbl.wl_display_cancel_read
#define wl_display_prepare_read wl_call_tbl.wl_display_prepare_read
#define wl_display_read_events wl_call_tbl.wl_display_read_events
#define wl_display_flush wl_call_tbl.wl_display_flush
#define wl_display_get_fd wl_call_tbl.wl_display_get_fd
#define wl_display_roundtrip wl_call_tbl.wl_display_roundtrip
#define wl_proxy_add_listener wl_call_tbl.wl_proxy_add_listener
#define wl_proxy_destroy wl_call_tbl.wl_proxy_destroy
#define wl_log_set_handler_client wl_call_tbl.wl_log_set_handler_client
#define wl_proxy_marshal_flags wl_call_tbl.wl_proxy_marshal_flags
#define wl_display_connect wl_call_tbl.wl_display_connect
#define wl_proxy_get_version wl_call_tbl.wl_proxy_get_version
#define wl_display_connect_to_fd wl_call_tbl.wl_display_connect_to_fd
#define wl_display_get_error wl_call_tbl.wl_display_get_error
#define xkb_state_unref wl_call_tbl.xkb_state_unref
#define xkb_context_new wl_call_tbl.xkb_context_new
#define xkb_context_unref wl_call_tbl.xkb_context_unref
#define xkb_state_new wl_call_tbl.xkb_state_new
#define xkb_keymap_new_from_string wl_call_tbl.xkb_keymap_new_from_string
#define xkb_keymap_unref wl_call_tbl.xkb_keymap_unref
#define xkb_keymap_num_levels_for_key wl_call_tbl.xkb_keymap_num_levels_for_key
#define xkb_keymap_key_get_syms_by_level wl_call_tbl.xkb_keymap_key_get_syms_by_level
#define xkb_state_key_get_layout wl_call_tbl.xkb_state_key_get_layout
#ifndef WL_PROTOCOLS_DEFINED
#define WL_PROTOCOLS_DEFINED
#include "Wayland/wayland-core-protocol.h"
#include "Wayland/xdg-shell-client-protocol.h"
#include "Wayland/viewporter-client-protocol.h"
#include "Wayland/xdg-decoration-client-protocol.h"
#include "Wayland/cursor-shape-client-protocol.h"
#include "Wayland/primary-selection-client-protocol.h"
#include "Wayland/pointer-constraints-client-protocol.h"
#include "Wayland/relative-pointer-client-protocol.h"
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
#include "Wayland/wlr-layer-shell-client-protocol.h"
#endif
typedef struct wayland_protocol {
void* listener;
void* context;
} wayland_protocol_t;
typedef wayland_protocol_t*(wl_setup_func)(MwU32, struct _MwLLWayland*, MwU32 version);
typedef void(wl_destroy_func)(struct _MwLLWayland* wayland, wayland_protocol_t* data);
typedef struct wayland_protocol_callback_table {
wl_setup_func* setup;
wl_destroy_func* destroy;
} wayland_protocol_callback_table_t;
struct _MwLLWaylandTopLevel {
struct xdg_surface* xdg_surface;
struct xdg_toplevel* xdg_top_level;
struct xdg_toplevel_listener xdg_toplevel_listener;
struct xdg_surface_listener xdg_surface_listener;
MwBool maxim_state;
MwBool compositor_created;
MwBool xdg_wm_base_created;
MwBool xdg_surface_created;
struct wl_subsurface* ssurface;
struct wl_subcompositor* scompositor;
};
struct _MwLLWaylandSublevel {
struct wl_subsurface* subsurface;
struct wl_subcompositor* subcompositor;
MwLL parent;
struct xdg_surface* xdg_surface;
};
struct _MwLLWaylandPopup {
struct xdg_surface* xdg_surface;
struct xdg_popup* xdg_popup;
struct xdg_positioner* xdg_positioner;
struct xdg_surface_listener xdg_surface_listener;
struct xdg_wm_base* xdg_wm_base;
MwLL topmost_parent;
};
struct _MwLLWaylandLayerSurface {
struct zwlr_layer_surface_v1* surface;
};
/* Shared set of anything needed for a shm buffer. */
struct _MwLLWaylandShmBuffer {
struct wl_shm* shm;
struct wl_shm_pool* shm_pool;
struct wl_buffer* shm_buffer;
struct wl_shm_pool* shm_pool_back;
struct wl_buffer* shm_buffer_back;
struct wl_surface* surface;
struct wl_output* output;
MwU8* buf;
MwU8* buf_back;
MwU64 buf_size;
int fd;
int fd_back;
MwBool setup;
};
enum _MwLLWaylandType {
MwLL_WAYLAND_UNKNOWN = 0,
MwLL_WAYLAND_TOPLEVEL,
MwLL_WAYLAND_SUBLEVEL,
MwLL_WAYLAND_POPUP,
MwLL_WAYLAND_LAYER_SURFACE,
};
typedef struct wl_clipboard_device_context {
struct {
struct wl_data_device* wl;
struct zwp_primary_selection_device_v1* zwp;
} device;
struct {
struct wl_data_offer* wl;
struct zwp_primary_selection_offer_v1* zwp;
} offer;
MwLL ll;
// struct wl_seat* seat;
} wl_clipboard_device_context_t;
struct _MwLLWayland {
struct _MwLLCommon common;
struct _MwLLCairo cairo;
union {
/* Pointer for data that's only loaded if the widget is a toplevel */
struct _MwLLWaylandTopLevel* toplevel;
/* Pointer for data that's only loaded if the widget is a sublevel */
struct _MwLLWaylandSublevel* sublevel;
/* Pointer for data that's only loaded if the widget is a popup */
struct _MwLLWaylandPopup* popup;
/* Pointer for data that's only loaded if the widget is a layer surface */
struct _MwLLWaylandLayerSurface* layer_surface;
};
enum _MwLLWaylandType type;
enum _MwLLWaylandType type_to_be;
MwRect clipping_rect;
MwBool no;
MwBool changing;
MwBool detatching;
MwPoint detach_point;
MwBool did_initial_resize;
MwBool is_toplevel;
MwBool is_clipping;
MwRect clip;
/* Map of Wayland interfaces to their relevant setup functions. */
struct {
char* key;
wayland_protocol_callback_table_t* value;
}* wl_protocol_setup_map;
/* Map of Wayland interfaces to any information we keep about them once we've registered them. */
struct {
char* key;
wayland_protocol_t* value;
}* wl_protocol_map;
MwBool do_csd;
MwBool has_decorations;
char title[256];
struct xkb_context* xkb_context;
struct xkb_keymap* xkb_keymap;
struct xkb_state* xkb_state;
struct wl_display* display;
struct wl_registry* registry;
struct wl_compositor* compositor;
struct wl_registry_listener registry_listener;
struct wl_region* o_region;
struct wl_region* region;
struct wl_output* output;
struct wp_viewport* vp;
MwBool do_lock_pointer;
struct zwp_pointer_constraints_v1* pointer_constraints;
struct zwp_relative_pointer_manager_v1* relative_pointer_manager;
struct zwp_relative_pointer_v1* relative_pointer;
struct zwp_locked_pointer_v1* locked_pointer;
MwBool pointer_constrained;
MwBool valid;
#ifdef USE_DBUS
MwLLDBusContext dbus;
#endif
MwBool dark_theme_detection;
MwU32 dark_theme;
/* clipboard related stuff.
* Note that unlike most interfaces, we don't keep zwp_primary_selection stuff in a wayland_protocol_t because we use wl_data_device as a fallback and want to have it share memory space.*/
struct {
struct wl_data_device_manager* wl;
struct zwp_primary_selection_device_manager_v1* zwp;
} clipboard_manager;
union {
struct wl_data_source* wl;
struct zwp_primary_selection_source_v1* zwp;
} clipboard_source;
char* clipboard_buffer;
MwBool supports_zwp;
MwBool zwp_setup;
uint32_t clipboard_serial;
wl_clipboard_device_context_t** clipboard_devices_wl;
wl_clipboard_device_context_t** clipboard_devices_zwp;
struct wl_pointer* pointer;
MwU32 pointer_serial;
struct wl_seat* pointer_seat;
struct wl_keyboard* keyboard;
MwU32 keyboard_serial;
MwU64 events_pending;
MwU32 mod_state;
MwBool configured; /* Whether or not xdg_toplevel_configure has run once */
MwBool held_down;
MwI32 x, y;
MwI32 ox, oy;
MwU32 ww, wh; /* Window position */
MwPoint cur_mouse_pos; /* Currently known mouse position */
MwLL currentlyHeldWidget;
MwLL focusedWidget;
int resizing;
int setting_wh;
MwU32 mw, mh; /* Monitor width and height as advertised by wl_output.mode */
MwLL parent;
MwBool force_render;
MwBool did_event_loop_early;
MwBool dispatching_resize;
MwBool is_toplevel_menu;
struct _MwLLWaylandShmBuffer framebuffer;
struct _MwLLWaylandShmBuffer backbuffer;
struct _MwLLWaylandShmBuffer cursor;
struct _MwLLWaylandShmBuffer* icon;
MwLLPixmap icon_pixmap;
pthread_mutex_t eventsMutex;
int cancelEvent;
int numCallbacksRunning;
uint32_t last_time;
MwBool moving;
MwI64 keyboard_rate;
MwI32 keyboard_delay;
int last_pressed_key;
MwBool holding_key;
MwU64 next_elapsed;
long start_time;
long end_time;
};
struct _MwLLWaylandColor {
struct _MwLLCommonColor common;
};
#define _MwLLWaylandPixmap _MwLLCairoPixmap
/* Setup the framebuffer with the saved width/height */
void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland);
/* Destroy the framebuffer */
void MwLLWaylandFramebufferDestroy(struct _MwLLWayland* handle);
/* Setup the framebuffer with the saved width/height */
void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland);
/* Destroy the backbuffer */
void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* handle);
void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height);
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer);
void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer);
void MwLLWaylandRegionSetup(MwLL handle);
void MwLLWaylandRegionInvalidate(MwLL handle);
void MwLLWaylandHangUntilConfigured(MwLL handle);
MwBool MwLLWaylandWidgetIsDestroyed(MwLL self);
void MwLLWaylandWidgetUndestroy(MwLL self);
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland);
void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_type);
/* Flush Wayland events */
void MwLLWaylandFlush(MwLL handle);
/* Standard procedure before event callbacks in Wayland */
#define WAYLAND_EVENT_OP_START(self) \
if(MwLLWaylandWidgetIsDestroyed(self)) { \
return; \
}
/* Footer for WAYLAND_EVENT_OP_START */
#define WAYLAND_EVENT_OP_END(self)
#define WIDGET_CHECK(handle) \
if(!handle->wayland.valid) { \
return; \
}
/* the two decoration manager constructs */
typedef struct zxdg_decoration_manager_v1_context {
struct zxdg_decoration_manager_v1* manager;
struct zxdg_toplevel_decoration_v1* decoration;
} zxdg_decoration_manager_v1_context_t;
extern struct zwp_relative_pointer_v1_listener MwLLWaylandRelativePointerListener;
#endif

View file

@ -0,0 +1 @@
*protocol.h

View file

@ -0,0 +1 @@
Folder for wayland-scanner to place any of its files.

View file

@ -0,0 +1,97 @@
/*!
* @file Mw/LowLevel/X11.h
* @brief X11 Backend
* @warning This is used internally
*/
#ifndef __MW_LOWLEVEL_X11_H__
#define __MW_LOWLEVEL_X11_H__
#include <Mw/MachDep.h>
#include <Mw/TypeDefs.h>
#include <Mw/LowLevel.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#ifdef USE_XRENDER
#include <X11/extensions/Xrender.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct _MwLLX11 {
struct _MwLLCommon common;
unsigned int width;
unsigned int height;
Display* display;
Window window;
Pixmap pixmap;
GC gc;
Colormap colormap;
Atom wm_delete;
Atom wm_protocols;
Atom utf8_string;
Atom compound_text;
Atom text;
Atom clipboard;
Atom selection;
XIM xim;
XIC xic;
long clipboard_time;
int clipboard_pending; /* 1 if UTF8_STRING, 2 if COMPOUND_TEXT, 3 if TEXT, 4 if STRING, otherwise 0 */
int top;
int toplevel;
int grabbed;
int force_render;
unsigned long red_mask;
unsigned long red_max;
unsigned long red_shift;
unsigned long green_mask;
unsigned long green_max;
unsigned long green_shift;
unsigned long blue_mask;
unsigned long blue_max;
unsigned long blue_shift;
#ifdef USE_DBUS
MwLLDBusContext dbus;
#endif
MwBool dark_theme_detection;
};
struct _MwLLX11Color {
struct _MwLLCommonColor common;
unsigned long pixel;
};
struct _MwLLX11Pixmap {
struct _MwLLCommonPixmap common;
int depth;
unsigned char* data;
MwLL handle;
int use_xrender;
Display* display;
XImage* image;
XImage* mask;
};
MWDECL int MwLLX11CallInit(void);
MWDECL Cursor MwLLX11CreateCursor(Display* display, MwCursor* image, MwCursor* mask);
#ifdef __cplusplus
}
#endif
#endif