Add multiple windows2 (#19)
* MacOSX with input events and mfb_set_viewport * Windows with input events and mfb_set_viewport * Minor changes in macosx and windows * X11 with input and mfb_set_viewport * Minor changes on X11 * Fix bug in X11 resize event * Fix bug in windows resize * added scale image to X11 * Added stretch_image with & without bilinear interpolation * moved MiniFB_internal.h * Added wayland events * minor changes * unify a bit the window structs * More work on wayland * Added cmake file * minor fix on windows * modified test * Fix on wayland. Unset wayland as default for linux * Use stdbool instead of our own macro eBool Remove prefix e from all enums * Remove _ex sufix in common files * merge X11MiniFB_ex.c into X11MiniFB.c * Merge WaylandMiniFB_ex.c into WaylandMiniFB.c * Add user_data to callbacks * Merge WinMiniFB_ex.c into WinMiniFB.c * Some minor changes on Windows * Fix bug on Wayland * Multiple Windows for MacOS X & Linux * Multiple Windows for Windows Refactor * Refactor * Added mfb_get_key_name * remove some warnings * Events per window working on MacOS & Linux (maybe Windows) * Fix on Windows * Added default key callback on macos & wayland * Unify keyboard_default on all platforms * keyboard_default on all platforms
This commit is contained in:
parent
8b6148cf97
commit
21d9377822
@ -1,10 +1,11 @@
|
||||
cmake_minimum_required(VERSION 2.8.9)
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
project (noise)
|
||||
|
||||
include_directories(include src)
|
||||
|
||||
file(GLOB SrcLib "src/*.c"
|
||||
"src/*.cpp"
|
||||
"src/*.h"
|
||||
"include/*.h")
|
||||
file(GLOB SrcWindows "src/windows/*.c"
|
||||
"src/windows/*.h")
|
||||
@ -17,7 +18,7 @@ file(GLOB SrcWayland "src/wayland/*.c")
|
||||
file(GLOB SrcX11 "src/x11/*.c")
|
||||
|
||||
if (NOT MSVC)
|
||||
set (CMAKE_C_FLAGS "-g -Wall -Wextra -Wno-switch -Wno-unused-function")
|
||||
set (CMAKE_C_FLAGS "-g -Wall -Wextra -pedantic -Wno-switch -Wno-unused-function")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11")
|
||||
set (CMAKE_OBJC_FLAGS "${CMAKE_C_FLAGS}")
|
||||
set (CMAKE_OBJCXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
@ -9,43 +9,35 @@ extern "C" {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MFB_RGB(r, g, b) (((unsigned int)r) << 16) | (((unsigned int)g) << 8) | b
|
||||
#define MFB_RGB(r, g, b) (((unsigned int) r) << 16) | (((unsigned int) g) << 8) | (b)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Create a window that is used to display the buffer sent into the mfb_update function, returns 0 if fails
|
||||
int mfb_open(const char* name, int width, int height);
|
||||
int mfb_open_ex(const char* name, int width, int height, int flags);
|
||||
struct Window *mfb_open(const char *title, int width, int height);
|
||||
struct Window *mfb_open_ex(const char *title, int width, int height, int flags);
|
||||
|
||||
// Update the display. Input buffer is assumed to be a 32-bit buffer of the size given in the open call
|
||||
// Will return -1 when ESC key is pressed (later on will return keycode and -1 on other close signal)
|
||||
int mfb_update(void* buffer);
|
||||
// Will return a negative status if something went wrong or the user want to exit.
|
||||
UpdateState mfb_update(struct Window *window, void* buffer);
|
||||
|
||||
// Close the window
|
||||
void mfb_close();
|
||||
void mfb_close(struct Window *window);
|
||||
|
||||
// Set user data
|
||||
void mfb_set_user_data(void *user_data);
|
||||
void mfb_set_user_data(struct Window *window, void *user_data);
|
||||
void *mfb_get_user_data(struct Window *window);
|
||||
|
||||
// Set viewport (useful when resize)
|
||||
bool mfb_set_viewport(unsigned offset_x, unsigned offset_y, unsigned width, unsigned height);
|
||||
bool mfb_set_viewport(struct Window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height);
|
||||
|
||||
// Event callbacks
|
||||
typedef void(*mfb_active_func)(void *user_data, bool isActive);
|
||||
typedef void(*mfb_resize_func)(void *user_data, int width, int height);
|
||||
typedef void(*mfb_keyboard_func)(void *user_data, Key key, KeyMod mod, bool isPressed);
|
||||
typedef void(*mfb_char_input_func)(void *user_data, unsigned int code);
|
||||
typedef void(*mfb_mouse_btn_func)(void *user_data, MouseButton button, KeyMod mod, bool isPressed);
|
||||
typedef void(*mfb_mouse_move_func)(void *user_data, int x, int y);
|
||||
typedef void(*mfb_mouse_scroll_func)(void *user_data, KeyMod mod, float deltaX, float deltaY);
|
||||
|
||||
void mfb_active_callback(mfb_active_func callback);
|
||||
void mfb_resize_callback(mfb_resize_func callback);
|
||||
void mfb_keyboard_callback(mfb_keyboard_func callback);
|
||||
void mfb_char_input_callback(mfb_char_input_func callback);
|
||||
void mfb_mouse_button_callback(mfb_mouse_btn_func callback);
|
||||
void mfb_mouse_move_callback(mfb_mouse_move_func callback);
|
||||
void mfb_mouse_scroll_callback(mfb_mouse_scroll_func callback);
|
||||
void mfb_active_callback(struct Window *window, mfb_active_func callback);
|
||||
void mfb_resize_callback(struct Window *window, mfb_resize_func callback);
|
||||
void mfb_keyboard_callback(struct Window *window, mfb_keyboard_func callback);
|
||||
void mfb_char_input_callback(struct Window *window, mfb_char_input_func callback);
|
||||
void mfb_mouse_button_callback(struct Window *window, mfb_mouse_btn_func callback);
|
||||
void mfb_mouse_move_callback(struct Window *window, mfb_mouse_move_func callback);
|
||||
void mfb_mouse_scroll_callback(struct Window *window, mfb_mouse_scroll_func callback);
|
||||
|
||||
const char *mfb_get_key_name(Key key);
|
||||
|
||||
|
@ -6,119 +6,129 @@
|
||||
#include "MiniFB.h"
|
||||
|
||||
template <class T>
|
||||
void mfb_active_callback(T *obj, void (T::*method)(void *, bool));
|
||||
void mfb_active_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, bool));
|
||||
|
||||
template <class T>
|
||||
void mfb_resize_callback(T *obj, void (T::*method)(void *, int, int));
|
||||
void mfb_resize_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, int, int));
|
||||
|
||||
template <class T>
|
||||
void mfb_keyboard_callback(T *obj, void (T::*method)(void *, Key, KeyMod, bool));
|
||||
void mfb_keyboard_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, Key, KeyMod, bool));
|
||||
|
||||
template <class T>
|
||||
void mfb_char_input_callback(T *obj, void (T::*method)(void *, unsigned int));
|
||||
void mfb_char_input_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, unsigned int));
|
||||
|
||||
template <class T>
|
||||
void mfb_mouse_button_callback(T *obj, void (T::*method)(void *, MouseButton, KeyMod, bool));
|
||||
void mfb_mouse_button_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, MouseButton, KeyMod, bool));
|
||||
|
||||
template <class T>
|
||||
void mfb_mouse_move_callback(T *obj, void (T::*method)(void *, int, int));
|
||||
void mfb_mouse_move_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, int, int));
|
||||
|
||||
template <class T>
|
||||
void mfb_mouse_scroll_callback(T *obj, void (T::*method)(void *, KeyMod, float, float));
|
||||
void mfb_mouse_scroll_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, KeyMod, float, float));
|
||||
|
||||
//-------------------------------------
|
||||
// To avoid clumsy hands
|
||||
//-------------------------------------
|
||||
class Stub {
|
||||
template <class T>
|
||||
friend void mfb_active_callback(T *obj, void (T::*method)(void *, bool));
|
||||
friend void mfb_active_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, bool));
|
||||
template <class T>
|
||||
friend void mfb_resize_callback(T *obj, void (T::*method)(void *, int, int));
|
||||
friend void mfb_resize_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, int, int));
|
||||
template <class T>
|
||||
friend void mfb_mouse_button_callback(T *obj, void (T::*method)(void *, MouseButton, KeyMod, bool));
|
||||
friend void mfb_mouse_button_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, MouseButton, KeyMod, bool));
|
||||
template <class T>
|
||||
friend void mfb_keyboard_callback(T *obj, void (T::*method)(void *, Key, KeyMod, bool));
|
||||
friend void mfb_keyboard_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, Key, KeyMod, bool));
|
||||
template <class T>
|
||||
friend void mfb_char_input_callback(T *obj, void (T::*method)(void *, unsigned int));
|
||||
friend void mfb_char_input_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, unsigned int));
|
||||
template <class T>
|
||||
friend void mfb_mouse_button_callback(T *obj, void (T::*method)(void *, MouseButton, KeyMod, bool));
|
||||
friend void mfb_mouse_button_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, MouseButton, KeyMod, bool));
|
||||
template <class T>
|
||||
friend void mfb_mouse_move_callback(T *obj, void (T::*method)(void *, int, int));
|
||||
friend void mfb_mouse_move_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, int, int));
|
||||
template <class T>
|
||||
friend void mfb_mouse_scroll_callback(T *obj, void (T::*method)(void *, KeyMod, float, float));
|
||||
friend void mfb_mouse_scroll_callback(struct Window *window, T *obj, void (T::*method)(struct Window *, KeyMod, float, float));
|
||||
|
||||
static void active_stub(void *user_data, bool isActive);
|
||||
static void resize_stub(void *user_data, int width, int height);
|
||||
static void keyboard_stub(void *user_data, Key key, KeyMod mod, bool isPressed);
|
||||
static void char_input_stub(void *user_data, unsigned int);
|
||||
static void mouse_btn_stub(void *user_data, MouseButton button, KeyMod mod, bool isPressed);
|
||||
static void mouse_move_stub(void *user_data, int x, int y);
|
||||
static void scroll_stub(void *user_data, KeyMod mod, float deltaX, float deltaY);
|
||||
static Stub *GetInstance(struct Window *window);
|
||||
|
||||
static std::function<void(void *user_data, bool)> m_active;
|
||||
static std::function<void(void *user_data, int, int)> m_resize;
|
||||
static std::function<void(void *user_data, Key, KeyMod, bool)> m_keyboard;
|
||||
static std::function<void(void *user_data, unsigned int)> m_char_input;
|
||||
static std::function<void(void *user_data, MouseButton, KeyMod, bool)> m_mouse_btn;
|
||||
static std::function<void(void *user_data, int, int)> m_mouse_move;
|
||||
static std::function<void(void *user_data, KeyMod, float, float)> m_scroll;
|
||||
static void active_stub(struct Window *window, bool isActive);
|
||||
static void resize_stub(struct Window *window, int width, int height);
|
||||
static void keyboard_stub(struct Window *window, Key key, KeyMod mod, bool isPressed);
|
||||
static void char_input_stub(struct Window *window, unsigned int);
|
||||
static void mouse_btn_stub(struct Window *window, MouseButton button, KeyMod mod, bool isPressed);
|
||||
static void mouse_move_stub(struct Window *window, int x, int y);
|
||||
static void scroll_stub(struct Window *window, KeyMod mod, float deltaX, float deltaY);
|
||||
|
||||
struct Window *m_window;
|
||||
std::function<void(struct Window *window, bool)> m_active;
|
||||
std::function<void(struct Window *window, int, int)> m_resize;
|
||||
std::function<void(struct Window *window, Key, KeyMod, bool)> m_keyboard;
|
||||
std::function<void(struct Window *window, unsigned int)> m_char_input;
|
||||
std::function<void(struct Window *window, MouseButton, KeyMod, bool)> m_mouse_btn;
|
||||
std::function<void(struct Window *window, int, int)> m_mouse_move;
|
||||
std::function<void(struct Window *window, KeyMod, float, float)> m_scroll;
|
||||
};
|
||||
|
||||
//-------------------------------------
|
||||
template <class T>
|
||||
inline void mfb_active_callback(T *obj, void (T::*method)(void *user_data, bool)) {
|
||||
inline void mfb_active_callback(struct Window *window, T *obj, void (T::*method)(struct Window *window, bool)) {
|
||||
using namespace std::placeholders;
|
||||
|
||||
Stub::m_active = std::bind(method, obj, _1, _2);
|
||||
mfb_active_callback(Stub::active_stub);
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_active = std::bind(method, obj, _1, _2);
|
||||
mfb_active_callback(window, Stub::active_stub);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void mfb_resize_callback(T *obj, void (T::*method)(void *user_data, int, int)) {
|
||||
inline void mfb_resize_callback(struct Window *window, T *obj, void (T::*method)(struct Window *window, int, int)) {
|
||||
using namespace std::placeholders;
|
||||
|
||||
Stub::m_resize = std::bind(method, obj, _1, _2, _3);
|
||||
mfb_resize_callback(Stub::resize_stub);
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_resize = std::bind(method, obj, _1, _2, _3);
|
||||
mfb_resize_callback(window, Stub::resize_stub);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void mfb_keyboard_callback(T *obj, void (T::*method)(void *user_data, Key, KeyMod, bool)) {
|
||||
inline void mfb_keyboard_callback(struct Window *window, T *obj, void (T::*method)(struct Window *window, Key, KeyMod, bool)) {
|
||||
using namespace std::placeholders;
|
||||
|
||||
Stub::m_keyboard = std::bind(method, obj, _1, _2, _3, _4);
|
||||
mfb_keyboard_callback(Stub::keyboard_stub);
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_keyboard = std::bind(method, obj, _1, _2, _3, _4);
|
||||
mfb_keyboard_callback(window, Stub::keyboard_stub);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void mfb_char_input_callback(T *obj, void (T::*method)(void *user_data, unsigned int)) {
|
||||
inline void mfb_char_input_callback(struct Window *window, T *obj, void (T::*method)(struct Window *window, unsigned int)) {
|
||||
using namespace std::placeholders;
|
||||
|
||||
Stub::m_char_input = std::bind(method, obj, _1, _2);
|
||||
mfb_char_input_callback(Stub::char_input_stub);
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_char_input = std::bind(method, obj, _1, _2);
|
||||
mfb_char_input_callback(window, Stub::char_input_stub);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void mfb_mouse_button_callback(T *obj, void (T::*method)(void *user_data, MouseButton, KeyMod, bool)) {
|
||||
inline void mfb_mouse_button_callback(struct Window *window, T *obj, void (T::*method)(struct Window *window, MouseButton, KeyMod, bool)) {
|
||||
using namespace std::placeholders;
|
||||
|
||||
Stub::m_mouse_btn = std::bind(method, obj, _1, _2, _3, _4);
|
||||
mfb_mouse_button_callback(Stub::mouse_btn_stub);
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_mouse_btn = std::bind(method, obj, _1, _2, _3, _4);
|
||||
mfb_mouse_button_callback(window, Stub::mouse_btn_stub);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void mfb_mouse_move_callback(T *obj, void (T::*method)(void *user_data, int, int)) {
|
||||
inline void mfb_mouse_move_callback(struct Window *window, T *obj, void (T::*method)(struct Window *window, int, int)) {
|
||||
using namespace std::placeholders;
|
||||
|
||||
Stub::m_mouse_move = std::bind(method, obj, _1, _2, _3);
|
||||
mfb_mouse_move_callback(Stub::mouse_move_stub);
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_mouse_move = std::bind(method, obj, _1, _2, _3);
|
||||
mfb_mouse_move_callback(window, Stub::mouse_move_stub);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void mfb_mouse_scroll_callback(T *obj, void (T::*method)(void *user_data, KeyMod, float, float)) {
|
||||
inline void mfb_mouse_scroll_callback(struct Window *window, T *obj, void (T::*method)(struct Window *window, KeyMod, float, float)) {
|
||||
using namespace std::placeholders;
|
||||
|
||||
Stub::m_scroll = std::bind(method, obj, _1, _2, _3, _4);
|
||||
mfb_mouse_scroll_callback(Stub::scroll_stub);
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_scroll = std::bind(method, obj, _1, _2, _3, _4);
|
||||
mfb_mouse_scroll_callback(window, Stub::scroll_stub);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2,6 +2,15 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// Enums
|
||||
typedef enum {
|
||||
STATE_OK = 0,
|
||||
STATE_EXIT = -1,
|
||||
STATE_INVALID_WINDOW = -2,
|
||||
STATE_INVALID_BUFFER = -3,
|
||||
STATE_INTERNAL_ERROR = -4,
|
||||
} UpdateState;
|
||||
|
||||
typedef enum {
|
||||
MOUSE_BTN_0, // No mouse button
|
||||
MOUSE_BTN_1,
|
||||
@ -161,3 +170,16 @@ typedef enum {
|
||||
WF_BORDERLESS = 0x08,
|
||||
WF_ALWAYS_ON_TOP = 0x10,
|
||||
} WindowFlags;
|
||||
|
||||
// Opaque pointer
|
||||
struct Window;
|
||||
|
||||
// Event callbacks
|
||||
typedef void(*mfb_active_func)(struct Window *window, bool isActive);
|
||||
typedef void(*mfb_resize_func)(struct Window *window, int width, int height);
|
||||
typedef void(*mfb_keyboard_func)(struct Window *window, Key key, KeyMod mod, bool isPressed);
|
||||
typedef void(*mfb_char_input_func)(struct Window *window, unsigned int code);
|
||||
typedef void(*mfb_mouse_btn_func)(struct Window *window, MouseButton button, KeyMod mod, bool isPressed);
|
||||
typedef void(*mfb_mouse_move_func)(struct Window *window, int x, int y);
|
||||
typedef void(*mfb_mouse_scroll_func)(struct Window *window, KeyMod mod, float deltaX, float deltaY);
|
||||
|
||||
|
@ -1,56 +1,101 @@
|
||||
#include "MiniFB.h"
|
||||
#include "WindowData.h"
|
||||
#include <MiniFB_internal.h>
|
||||
|
||||
//-------------------------------------
|
||||
mfb_active_func g_active_func = 0x0;
|
||||
mfb_resize_func g_resize_func = 0x0;
|
||||
mfb_keyboard_func g_keyboard_func = 0x0;
|
||||
mfb_char_input_func g_char_input_func = 0x0;
|
||||
mfb_mouse_btn_func g_mouse_btn_func = 0x0;
|
||||
mfb_mouse_move_func g_mouse_move_func = 0x0;
|
||||
mfb_mouse_scroll_func g_mouse_wheel_func = 0x0;
|
||||
|
||||
void *g_user_data = 0x0;
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_active_callback(mfb_active_func callback) {
|
||||
g_active_func = callback;
|
||||
void mfb_active_callback(struct Window *window, mfb_active_func callback) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->active_func = callback;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_resize_callback(mfb_resize_func callback) {
|
||||
g_resize_func = callback;
|
||||
void mfb_resize_callback(struct Window *window, mfb_resize_func callback) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->resize_func = callback;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_keyboard_callback(mfb_keyboard_func callback) {
|
||||
g_keyboard_func = callback;
|
||||
void mfb_keyboard_callback(struct Window *window, mfb_keyboard_func callback) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->keyboard_func = callback;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_char_input_callback(mfb_char_input_func callback) {
|
||||
g_char_input_func = callback;
|
||||
void mfb_char_input_callback(struct Window *window, mfb_char_input_func callback) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->char_input_func = callback;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_mouse_button_callback(mfb_mouse_btn_func callback) {
|
||||
g_mouse_btn_func = callback;
|
||||
void mfb_mouse_button_callback(struct Window *window, mfb_mouse_btn_func callback) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->mouse_btn_func = callback;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_mouse_move_callback(mfb_mouse_move_func callback) {
|
||||
g_mouse_move_func = callback;
|
||||
void mfb_mouse_move_callback(struct Window *window, mfb_mouse_move_func callback) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->mouse_move_func = callback;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_mouse_scroll_callback(mfb_mouse_scroll_func callback) {
|
||||
g_mouse_wheel_func = callback;
|
||||
void mfb_mouse_scroll_callback(struct Window *window, mfb_mouse_scroll_func callback) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->mouse_wheel_func = callback;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_set_user_data(void *user_data) {
|
||||
g_user_data = user_data;
|
||||
void mfb_set_user_data(struct Window *window, void *user_data) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->user_data = user_data;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void *mfb_get_user_data(struct Window *window) {
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
return window_data->user_data;
|
||||
}
|
||||
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void mfb_close(struct Window *window)
|
||||
{
|
||||
if(window != 0x0) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->close = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void keyboard_default(struct Window *window, Key key, KeyMod mod, bool isPressed) {
|
||||
kUnused(mod);
|
||||
kUnused(isPressed);
|
||||
if (key == KB_KEY_ESCAPE) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
window_data->close = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
const char *mfb_get_key_name(Key key) {
|
||||
|
||||
|
@ -1,38 +1,54 @@
|
||||
#include <MiniFB_cpp.h>
|
||||
#include <MiniFB_enums.h>
|
||||
#include <vector>
|
||||
|
||||
std::function<void(void *, bool)> Stub::m_active;
|
||||
std::function<void(void *, int, int)> Stub::m_resize;
|
||||
std::function<void(void *, Key, KeyMod, bool)> Stub::m_keyboard;
|
||||
std::function<void(void *, unsigned int)> Stub::m_char_input;
|
||||
std::function<void(void *, MouseButton, KeyMod, bool)> Stub::m_mouse_btn;
|
||||
std::function<void(void *, int, int)> Stub::m_mouse_move;
|
||||
std::function<void(void *, KeyMod, float, float)> Stub::m_scroll;
|
||||
Stub *
|
||||
Stub::GetInstance(struct Window *window) {
|
||||
static std::vector<Stub *> s_instances;
|
||||
|
||||
void Stub::active_stub(void *user_data, bool isActive) {
|
||||
m_active(user_data, isActive);
|
||||
for(Stub *instance : s_instances) {
|
||||
if(instance->m_window == window) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
s_instances.push_back(new Stub);
|
||||
s_instances.back()->m_window = window;
|
||||
|
||||
return s_instances.back();
|
||||
}
|
||||
|
||||
void Stub::resize_stub(void *user_data, int width, int height) {
|
||||
m_resize(user_data, width, height);
|
||||
void Stub::active_stub(struct Window *window, bool isActive) {
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_active(window, isActive);
|
||||
}
|
||||
|
||||
void Stub::keyboard_stub(void *user_data, Key key, KeyMod mod, bool isPressed) {
|
||||
m_keyboard(user_data, key, mod, isPressed);
|
||||
void Stub::resize_stub(struct Window *window, int width, int height) {
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_resize(window, width, height);
|
||||
}
|
||||
|
||||
void Stub::char_input_stub(void *user_data, unsigned int code) {
|
||||
m_char_input(user_data, code);
|
||||
void Stub::keyboard_stub(struct Window *window, Key key, KeyMod mod, bool isPressed) {
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_keyboard(window, key, mod, isPressed);
|
||||
}
|
||||
|
||||
void Stub::mouse_btn_stub(void *user_data, MouseButton button, KeyMod mod, bool isPressed) {
|
||||
m_mouse_btn(user_data, button, mod, isPressed);
|
||||
void Stub::char_input_stub(struct Window *window, unsigned int code) {
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_char_input(window, code);
|
||||
}
|
||||
|
||||
void Stub::mouse_move_stub(void *user_data, int x, int y) {
|
||||
m_mouse_move(user_data, x, y);
|
||||
void Stub::mouse_btn_stub(struct Window *window, MouseButton button, KeyMod mod, bool isPressed) {
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_mouse_btn(window, button, mod, isPressed);
|
||||
}
|
||||
|
||||
void Stub::scroll_stub(void *user_data, KeyMod mod, float deltaX, float deltaY) {
|
||||
m_scroll(user_data, mod, deltaX, deltaY);
|
||||
void Stub::mouse_move_stub(struct Window *window, int x, int y) {
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_mouse_move(window, x, y);
|
||||
}
|
||||
|
||||
void Stub::scroll_stub(struct Window *window, KeyMod mod, float deltaX, float deltaY) {
|
||||
Stub *stub = Stub::GetInstance(window);
|
||||
stub->m_scroll(window, mod, deltaX, deltaY);
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "MiniFB.h"
|
||||
#include "MiniFB_enums.h"
|
||||
|
||||
extern void *g_user_data;
|
||||
|
||||
#define kCall(f, ...) if((f)) (f)(g_user_data, __VA_ARGS__);
|
||||
#define kCall(func, ...) if(window_data && window_data->func) window_data->func((struct Window *) window_data, __VA_ARGS__);
|
||||
#define kUnused(var) (void) var;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@ -13,15 +12,7 @@ extern "C" {
|
||||
|
||||
short int keycodes[512];
|
||||
void init_keycodes();
|
||||
void keyboard_default(void *user_data, Key key, KeyMod mod, bool isPressed);
|
||||
|
||||
extern mfb_active_func g_active_func;
|
||||
extern mfb_resize_func g_resize_func;
|
||||
extern mfb_keyboard_func g_keyboard_func;
|
||||
extern mfb_char_input_func g_char_input_func;
|
||||
extern mfb_mouse_btn_func g_mouse_btn_func;
|
||||
extern mfb_mouse_move_func g_mouse_move_func;
|
||||
extern mfb_mouse_scroll_func g_mouse_wheel_func;
|
||||
void keyboard_default(struct Window *window, Key key, KeyMod mod, bool isPressed);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
33
src/WindowData.h
Normal file
33
src/WindowData.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <MiniFB_enums.h>
|
||||
|
||||
typedef struct {
|
||||
void *specific;
|
||||
void *user_data;
|
||||
|
||||
mfb_active_func active_func;
|
||||
mfb_resize_func resize_func;
|
||||
mfb_keyboard_func keyboard_func;
|
||||
mfb_char_input_func char_input_func;
|
||||
mfb_mouse_btn_func mouse_btn_func;
|
||||
mfb_mouse_move_func mouse_move_func;
|
||||
mfb_mouse_scroll_func mouse_wheel_func;
|
||||
|
||||
uint32_t window_width;
|
||||
uint32_t window_height;
|
||||
|
||||
uint32_t dst_offset_x;
|
||||
uint32_t dst_offset_y;
|
||||
uint32_t dst_width;
|
||||
uint32_t dst_height;
|
||||
|
||||
void *draw_buffer;
|
||||
uint32_t buffer_width;
|
||||
uint32_t buffer_height;
|
||||
uint32_t buffer_stride;
|
||||
uint32_t mod_keys;
|
||||
bool close;
|
||||
} SWindowData;
|
@ -1,6 +1,6 @@
|
||||
#include "OSXWindow.h"
|
||||
#include "OSXWindowFrameView.h"
|
||||
#include "OSXWindowData.h"
|
||||
#include "WindowData_OSX.h"
|
||||
#include <MiniFB.h>
|
||||
#include <MiniFB_enums.h>
|
||||
#include <MiniFB_internal.h>
|
||||
@ -11,15 +11,11 @@
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
SWindowData g_window_data = { 0 };
|
||||
|
||||
void init_keycodes();
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
extern id<MTLDevice> g_metal_device;
|
||||
extern id<MTLCommandQueue> g_command_queue;
|
||||
extern id<MTLLibrary> g_library;
|
||||
extern id<MTLRenderPipelineState> g_pipeline_state;
|
||||
id<MTLDevice> g_metal_device;
|
||||
id<MTLLibrary> g_library;
|
||||
|
||||
Vertex gVertices[4] = {
|
||||
{-1.0, -1.0, 0, 1},
|
||||
@ -89,9 +85,9 @@ NSString* g_shadersSrc = @
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
static bool create_shaders() {
|
||||
static bool create_shaders(SWindowData_OSX *window_data_osx) {
|
||||
// Error
|
||||
NSError* nsError = NULL;
|
||||
NSError* nsError = 0x0;
|
||||
NSError** nsErrorPtr = &nsError;
|
||||
|
||||
id<MTLLibrary> library = [g_metal_device newLibraryWithSource:g_shadersSrc
|
||||
@ -127,9 +123,9 @@ static bool create_shaders() {
|
||||
pipelineStateDescriptor.fragmentFunction = fragment_shader_func;
|
||||
pipelineStateDescriptor.colorAttachments[0].pixelFormat = 80; //bgra8Unorm;
|
||||
|
||||
NSError *error = NULL;
|
||||
g_pipeline_state = [g_metal_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error];
|
||||
if (!g_pipeline_state)
|
||||
NSError *error = 0x0;
|
||||
window_data_osx->metal.pipeline_state = [g_metal_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error];
|
||||
if (!window_data_osx->metal.pipeline_state)
|
||||
{
|
||||
NSLog(@"Failed to created pipeline state, error %@", error);
|
||||
}
|
||||
@ -140,27 +136,35 @@ static bool create_shaders() {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_open(const char* name, int width, int height)
|
||||
struct Window *mfb_open(const char *title, int width, int height)
|
||||
{
|
||||
return mfb_open_ex(name, width, height, 0);
|
||||
return mfb_open_ex(title, width, height, 0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_open_ex(const char* name, int width, int height, int flags)
|
||||
struct Window *mfb_open_ex(const char *title, int width, int height, int flags)
|
||||
{
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
init_keycodes();
|
||||
|
||||
g_window_data.window_width = width;
|
||||
g_window_data.window_height = height;
|
||||
SWindowData *window_data = malloc(sizeof(SWindowData));
|
||||
memset(window_data, 0, sizeof(SWindowData));
|
||||
|
||||
g_window_data.dst_width = width;
|
||||
g_window_data.dst_height = height;
|
||||
SWindowData_OSX *window_data_osx = malloc(sizeof(SWindowData_OSX));
|
||||
memset(window_data_osx, 0, sizeof(SWindowData_OSX));
|
||||
window_data->specific = window_data_osx;
|
||||
|
||||
g_window_data.buffer_width = width;
|
||||
g_window_data.buffer_height = height;
|
||||
window_data->window_width = width;
|
||||
window_data->window_height = height;
|
||||
|
||||
window_data->dst_width = width;
|
||||
window_data->dst_height = height;
|
||||
|
||||
window_data->buffer_width = width;
|
||||
window_data->buffer_height = height;
|
||||
window_data->buffer_stride = width * 4;
|
||||
|
||||
[NSApplication sharedApplication];
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
@ -170,11 +174,11 @@ int mfb_open_ex(const char* name, int width, int height, int flags)
|
||||
|
||||
if (!g_metal_device) {
|
||||
printf("Your device/OS doesn't support Metal.");
|
||||
return -1;
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
if (!create_shaders()) {
|
||||
return -2;
|
||||
if (!create_shaders((SWindowData_OSX *) window_data->specific)) {
|
||||
return 0x0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -187,18 +191,18 @@ int mfb_open_ex(const char* name, int width, int height, int flags)
|
||||
styles |= NSWindowStyleMaskResizable;
|
||||
|
||||
NSRect rectangle = NSMakeRect(0, 0, width, height);
|
||||
g_window_data.window = [[OSXWindow alloc] initWithContentRect:rectangle styleMask:styles backing:NSBackingStoreBuffered defer:NO];
|
||||
if (!g_window_data.window)
|
||||
return -3;
|
||||
window_data_osx->window = [[OSXWindow alloc] initWithContentRect:rectangle styleMask:styles backing:NSBackingStoreBuffered defer:NO windowData:window_data];
|
||||
if (!window_data_osx->window)
|
||||
return 0x0;
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
g_window_data.draw_buffer = malloc(width * height * 4);
|
||||
window_data->draw_buffer = malloc(width * height * 4);
|
||||
|
||||
if (!g_window_data.draw_buffer)
|
||||
return -4;
|
||||
if (!window_data->draw_buffer)
|
||||
return 0x0;
|
||||
|
||||
// Setup command queue
|
||||
g_command_queue = [g_metal_device newCommandQueue];
|
||||
window_data_osx->metal.command_queue = [g_metal_device newCommandQueue];
|
||||
|
||||
WindowViewController* viewController = [WindowViewController new];
|
||||
|
||||
@ -220,7 +224,7 @@ int mfb_open_ex(const char* name, int width, int height, int flags)
|
||||
|
||||
// Used for syncing the CPU and GPU
|
||||
viewController->m_semaphore = dispatch_semaphore_create(MaxBuffersInFlight);
|
||||
viewController->m_draw_buffer = g_window_data.draw_buffer;
|
||||
viewController->m_draw_buffer = window_data->draw_buffer;
|
||||
viewController->m_width = width;
|
||||
viewController->m_height = height;
|
||||
|
||||
@ -228,20 +232,21 @@ int mfb_open_ex(const char* name, int width, int height, int flags)
|
||||
view.device = g_metal_device;
|
||||
view.delegate = viewController;
|
||||
view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
||||
[g_window_data.window.contentView addSubview:view];
|
||||
[window_data_osx->window.contentView addSubview:view];
|
||||
|
||||
g_window_data.buffer_width = width;
|
||||
g_window_data.buffer_height = height;
|
||||
//window_data->buffer_width = width;
|
||||
//window_data->buffer_height = height;
|
||||
//window_data->buffer_stride = width * 4;
|
||||
|
||||
//[g_window_data.window updateSize];
|
||||
//[window_data->window updateSize];
|
||||
#endif
|
||||
|
||||
[g_window_data.window setTitle:[NSString stringWithUTF8String:name]];
|
||||
[g_window_data.window setReleasedWhenClosed:NO];
|
||||
[g_window_data.window performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:nil waitUntilDone:YES];
|
||||
[g_window_data.window setAcceptsMouseMovedEvents:YES];
|
||||
[window_data_osx->window setTitle:[NSString stringWithUTF8String:title]];
|
||||
[window_data_osx->window setReleasedWhenClosed:NO];
|
||||
[window_data_osx->window performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:nil waitUntilDone:YES];
|
||||
[window_data_osx->window setAcceptsMouseMovedEvents:YES];
|
||||
|
||||
[g_window_data.window center];
|
||||
[window_data_osx->window center];
|
||||
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
@ -249,9 +254,7 @@ int mfb_open_ex(const char* name, int width, int height, int flags)
|
||||
[NSApp finishLaunching];
|
||||
#endif
|
||||
|
||||
if (g_keyboard_func == 0x0) {
|
||||
mfb_keyboard_callback(keyboard_default);
|
||||
}
|
||||
mfb_keyboard_callback((struct Window *) window_data, keyboard_default);
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
NSLog(@"Window created using Metal API");
|
||||
@ -261,35 +264,36 @@ int mfb_open_ex(const char* name, int width, int height, int flags)
|
||||
|
||||
[pool drain];
|
||||
|
||||
return 1;
|
||||
return (struct Window *) window_data;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void keyboard_default(void *user_data, Key key, KeyMod mod, bool isPressed) {
|
||||
kUnused(user_data);
|
||||
kUnused(mod);
|
||||
kUnused(isPressed);
|
||||
if (key == KB_KEY_ESCAPE)
|
||||
g_window_data.close = true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void mfb_close()
|
||||
static void destroy_window_data(SWindowData *window_data)
|
||||
{
|
||||
if(window_data == 0x0)
|
||||
return;
|
||||
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
g_window_data.close = true;
|
||||
if (g_window_data.window)
|
||||
[g_window_data.window close];
|
||||
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
|
||||
if(window_data_osx != 0x0) {
|
||||
OSXWindow *window = window_data_osx->window;
|
||||
[window removeWindowData];
|
||||
[window performClose:nil];
|
||||
|
||||
memset(window_data_osx, 0, sizeof(SWindowData_OSX));
|
||||
free(window_data_osx);
|
||||
}
|
||||
memset(window_data, 0, sizeof(SWindowData));
|
||||
free(window_data);
|
||||
|
||||
[pool drain];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int update_events()
|
||||
static void update_events(SWindowData *window_data)
|
||||
{
|
||||
NSEvent* event;
|
||||
|
||||
@ -301,57 +305,67 @@ static int update_events()
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
}
|
||||
while ((g_window_data.close == false) && event);
|
||||
while ((window_data->close == false) && event);
|
||||
|
||||
[pool release];
|
||||
|
||||
if(g_window_data.close == true)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_update(void* buffer)
|
||||
UpdateState mfb_update(struct Window *window, void* buffer)
|
||||
{
|
||||
if(buffer == 0x0)
|
||||
return -2;
|
||||
if(window == 0x0) {
|
||||
return STATE_INVALID_WINDOW;
|
||||
}
|
||||
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
if(window_data->close) {
|
||||
destroy_window_data(window_data);
|
||||
return STATE_EXIT;
|
||||
}
|
||||
|
||||
if(buffer == 0x0) {
|
||||
return STATE_INVALID_BUFFER;
|
||||
}
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
memcpy(g_window_data.draw_buffer, buffer, g_window_data.buffer_width * g_window_data.buffer_height * 4);
|
||||
memcpy(window_data->draw_buffer, buffer, window_data->buffer_width * window_data->buffer_height * 4);
|
||||
#else
|
||||
g_window_data.draw_buffer = buffer;
|
||||
window_data->draw_buffer = buffer;
|
||||
#endif
|
||||
|
||||
int state = update_events();
|
||||
if(g_window_data.close == false)
|
||||
[[g_window_data.window contentView] setNeedsDisplay:YES];
|
||||
update_events(window_data);
|
||||
if(window_data->close == false) {
|
||||
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
|
||||
[[window_data_osx->window contentView] setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
return state;
|
||||
return STATE_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool mfb_set_viewport(unsigned offset_x, unsigned offset_y, unsigned width, unsigned height)
|
||||
bool mfb_set_viewport(struct Window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height)
|
||||
{
|
||||
if(offset_x + width > g_window_data.window_width) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
|
||||
if(offset_x + width > window_data->window_width) {
|
||||
return false;
|
||||
}
|
||||
if(offset_y + height > g_window_data.window_height) {
|
||||
if(offset_y + height > window_data->window_height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_window_data.dst_offset_x = offset_x;
|
||||
g_window_data.dst_offset_y = offset_y;
|
||||
g_window_data.dst_width = width;
|
||||
g_window_data.dst_height = height;
|
||||
window_data->dst_offset_x = offset_x;
|
||||
window_data->dst_offset_y = offset_y;
|
||||
window_data->dst_width = width;
|
||||
window_data->dst_height = height;
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
float x1 = ((float) offset_x / g_window_data.window_width) * 2.0f - 1.0f;
|
||||
float x2 = (((float) offset_x + width) / g_window_data.window_width) * 2.0f - 1.0f;
|
||||
float y1 = ((float) offset_y / g_window_data.window_height) * 2.0f - 1.0f;
|
||||
float y2 = (((float) offset_y + height) / g_window_data.window_height) * 2.0f - 1.0f;
|
||||
float x1 = ((float) offset_x / window_data->window_width) * 2.0f - 1.0f;
|
||||
float x2 = (((float) offset_x + width) / window_data->window_width) * 2.0f - 1.0f;
|
||||
float y1 = ((float) offset_y / window_data->window_height) * 2.0f - 1.0f;
|
||||
float y2 = (((float) offset_y + height) / window_data->window_height) * 2.0f - 1.0f;
|
||||
|
||||
gVertices[0].x = x1;
|
||||
gVertices[0].y = y1;
|
||||
|
@ -1,10 +1,18 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include <WindowData.h>
|
||||
// @class OSXWindowFrameView;
|
||||
|
||||
@interface OSXWindow : NSWindow<NSWindowDelegate>
|
||||
{
|
||||
NSView *childContentView;
|
||||
@public SWindowData *window_data;
|
||||
}
|
||||
|
||||
- (id)initWithContentRect:(NSRect)contentRect
|
||||
styleMask:(NSWindowStyleMask)windowStyle
|
||||
backing:(NSBackingStoreType)bufferingType
|
||||
defer:(BOOL)deferCreation
|
||||
windowData:(SWindowData *) windowData;
|
||||
|
||||
- (void) removeWindowData;
|
||||
@end
|
||||
|
@ -1,14 +1,11 @@
|
||||
#import "OSXWindow.h"
|
||||
#import "OSXWindowFrameView.h"
|
||||
#include "OSXWindowData.h"
|
||||
#include "WindowData_OSX.h"
|
||||
#include <MiniFB_internal.h>
|
||||
#include <MiniFB_enums.h>
|
||||
|
||||
extern SWindowData g_window_data;
|
||||
extern short int g_keycodes[512];
|
||||
|
||||
bool gActive = false;
|
||||
|
||||
@implementation OSXWindow
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -17,6 +14,7 @@ bool gActive = false;
|
||||
styleMask:(NSWindowStyleMask)windowStyle
|
||||
backing:(NSBackingStoreType)bufferingType
|
||||
defer:(BOOL)deferCreation
|
||||
windowData:(SWindowData *) windowData
|
||||
{
|
||||
self = [super
|
||||
initWithContentRect:contentRect
|
||||
@ -30,12 +28,24 @@ bool gActive = false;
|
||||
[self setBackgroundColor:[NSColor clearColor]];
|
||||
|
||||
self.delegate = self;
|
||||
|
||||
self->window_data = windowData;
|
||||
OSXWindowFrameView *view = (OSXWindowFrameView *) self->childContentView.superview;
|
||||
view->window_data = windowData;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void) removeWindowData {
|
||||
self->window_data = 0x0;
|
||||
OSXWindowFrameView *view = (OSXWindowFrameView *) self->childContentView.superview;
|
||||
view->window_data = 0x0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
@ -62,7 +72,7 @@ bool gActive = false;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
-(void)flagsChanged:(NSEvent *)event
|
||||
- (void)flagsChanged:(NSEvent *)event
|
||||
{
|
||||
const uint32_t flags = [event modifierFlags];
|
||||
uint32_t mod_keys = 0, mod_keys_aux = 0;
|
||||
@ -88,32 +98,31 @@ bool gActive = false;
|
||||
mod_keys |= KB_MOD_NUM_LOCK;
|
||||
}
|
||||
|
||||
if(mod_keys != g_window_data.mod_keys) {
|
||||
if(mod_keys != window_data->mod_keys) {
|
||||
short int keyCode = keycodes[[event keyCode] & 0x1ff];
|
||||
if(keyCode != KB_KEY_UNKNOWN) {
|
||||
mod_keys_aux = mod_keys ^ g_window_data.mod_keys;
|
||||
mod_keys_aux = mod_keys ^ window_data->mod_keys;
|
||||
if(mod_keys_aux & KB_MOD_CAPS_LOCK) {
|
||||
kCall(g_keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_CAPS_LOCK) != 0);
|
||||
kCall(keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_CAPS_LOCK) != 0);
|
||||
}
|
||||
if(mod_keys_aux & KB_MOD_SHIFT) {
|
||||
kCall(g_keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_SHIFT) != 0);
|
||||
kCall(keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_SHIFT) != 0);
|
||||
}
|
||||
if(mod_keys_aux & KB_MOD_CONTROL) {
|
||||
kCall(g_keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_CONTROL) != 0);
|
||||
kCall(keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_CONTROL) != 0);
|
||||
}
|
||||
if(mod_keys_aux & KB_MOD_ALT) {
|
||||
kCall(g_keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_ALT) != 0);
|
||||
kCall(keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_ALT) != 0);
|
||||
}
|
||||
if(mod_keys_aux & KB_MOD_SUPER) {
|
||||
kCall(g_keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_SUPER) != 0);
|
||||
kCall(keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_SUPER) != 0);
|
||||
}
|
||||
if(mod_keys_aux & KB_MOD_NUM_LOCK) {
|
||||
kCall(g_keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_NUM_LOCK) != 0);
|
||||
kCall(keyboard_func, keyCode, mod_keys, (mod_keys & KB_MOD_NUM_LOCK) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_window_data.mod_keys = mod_keys;
|
||||
//NSLog(@"KeyCode: %d (%x) - %x", [event keyCode], [event keyCode], flags);
|
||||
window_data->mod_keys = mod_keys;
|
||||
|
||||
[super flagsChanged:event];
|
||||
}
|
||||
@ -123,7 +132,7 @@ bool gActive = false;
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
short int keyCode = keycodes[[event keyCode] & 0x1ff];
|
||||
kCall(g_keyboard_func, keyCode, g_window_data.mod_keys, true);
|
||||
kCall(keyboard_func, keyCode, window_data->mod_keys, true);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -131,7 +140,7 @@ bool gActive = false;
|
||||
- (void)keyUp:(NSEvent *)event
|
||||
{
|
||||
short int keyCode = keycodes[[event keyCode] & 0x1ff];
|
||||
kCall(g_keyboard_func, keyCode, g_window_data.mod_keys, false);
|
||||
kCall(keyboard_func, keyCode, window_data->mod_keys, false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -155,7 +164,7 @@ bool gActive = false;
|
||||
if ((code & 0xff00) == 0xf700)
|
||||
continue;
|
||||
|
||||
kCall(g_char_input_func, code);
|
||||
kCall(char_input_func, code);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,9 +174,10 @@ bool gActive = false;
|
||||
{
|
||||
kUnused(notification);
|
||||
|
||||
if(gActive == true) {
|
||||
gActive = false;
|
||||
kCall(g_active_func, false);
|
||||
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
|
||||
if(window_data_osx->active == true) {
|
||||
window_data_osx->active = false;
|
||||
kCall(active_func, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,18 +227,20 @@ bool gActive = false;
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification
|
||||
{
|
||||
kUnused(notification);
|
||||
kCall(g_active_func, true);
|
||||
kCall(active_func, true);
|
||||
}
|
||||
|
||||
- (void)windowDidResignKey:(NSNotification *)notification
|
||||
{
|
||||
kUnused(notification);
|
||||
kCall(g_active_func, false);
|
||||
kCall(active_func, false);
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification {
|
||||
kUnused(notification);
|
||||
g_window_data.close = true;
|
||||
if(window_data) {
|
||||
window_data->close = true;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -258,7 +270,7 @@ bool gActive = false;
|
||||
|
||||
- (void)willClose
|
||||
{
|
||||
g_window_data.close = true;
|
||||
window_data->close = true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -267,10 +279,10 @@ bool gActive = false;
|
||||
kUnused(notification);
|
||||
CGSize size = [self contentRectForFrameRect:[self frame]].size;
|
||||
|
||||
g_window_data.window_width = size.width;
|
||||
g_window_data.window_height = size.height;
|
||||
window_data->window_width = size.width;
|
||||
window_data->window_height = size.height;
|
||||
|
||||
kCall(g_resize_func, size.width, size.height);
|
||||
kCall(resize_func, size.width, size.height);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <MiniFB_enums.h>
|
||||
|
||||
@class OSXWindow;
|
||||
|
||||
typedef struct {
|
||||
OSXWindow *window;
|
||||
uint32_t window_width;
|
||||
uint32_t window_height;
|
||||
|
||||
uint32_t dst_offset_x;
|
||||
uint32_t dst_offset_y;
|
||||
uint32_t dst_width;
|
||||
uint32_t dst_height;
|
||||
|
||||
void *draw_buffer;
|
||||
uint32_t buffer_width;
|
||||
uint32_t buffer_height;
|
||||
uint32_t mod_keys;
|
||||
bool close;
|
||||
} SWindowData;
|
@ -1,5 +1,7 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "WindowData.h"
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
#import <MetalKit/MetalKit.h>
|
||||
|
||||
@ -8,7 +10,7 @@ typedef struct Vertex {
|
||||
} Vertex;
|
||||
|
||||
// Number of textures in flight (tripple buffered)
|
||||
static const int MaxBuffersInFlight = 3;
|
||||
enum { MaxBuffersInFlight = 3 };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -30,6 +32,7 @@ static const int MaxBuffersInFlight = 3;
|
||||
|
||||
@interface OSXWindowFrameView : NSView
|
||||
{
|
||||
@public SWindowData *window_data;
|
||||
#if defined(USE_METAL_API)
|
||||
@private NSTrackingArea* trackingArea;
|
||||
#endif
|
||||
|
@ -1,31 +1,32 @@
|
||||
#import "OSXWindowFrameView.h"
|
||||
#import "OSXWindow.h"
|
||||
#include "OSXWindowData.h"
|
||||
#include "WindowData_OSX.h"
|
||||
#include <MiniFB_internal.h>
|
||||
|
||||
extern SWindowData g_window_data;
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
#import <MetalKit/MetalKit.h>
|
||||
|
||||
id<MTLDevice> g_metal_device;
|
||||
id<MTLCommandQueue> g_command_queue;
|
||||
id<MTLLibrary> g_library;
|
||||
id<MTLRenderPipelineState> g_pipeline_state;
|
||||
extern id<MTLDevice> g_metal_device;
|
||||
extern id<MTLLibrary> g_library;
|
||||
|
||||
extern Vertex gVertices[4];
|
||||
|
||||
@implementation WindowViewController
|
||||
|
||||
-(void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||
{
|
||||
(void)view;
|
||||
(void)size;
|
||||
// resize
|
||||
}
|
||||
|
||||
-(void)drawInMTKView:(nonnull MTKView *)view
|
||||
- (void)drawInMTKView:(nonnull MTKView *)view
|
||||
{
|
||||
OSXWindow *window = (OSXWindow *) view.window;
|
||||
if(window->window_data == 0x0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait to ensure only MaxBuffersInFlight number of frames are getting proccessed
|
||||
// by any stage in the Metal pipeline (App, Metal, Drivers, GPU, etc)
|
||||
dispatch_semaphore_wait(m_semaphore, DISPATCH_TIME_FOREVER);
|
||||
@ -42,7 +43,8 @@ extern Vertex gVertices[4];
|
||||
mipmapLevel:0 withBytes:m_draw_buffer bytesPerRow:bytesPerRow];
|
||||
|
||||
// Create a new command buffer for each render pass to the current drawable
|
||||
id<MTLCommandBuffer> commandBuffer = [g_command_queue commandBuffer];
|
||||
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window->window_data->specific;
|
||||
id<MTLCommandBuffer> commandBuffer = [window_data_osx->metal.command_queue commandBuffer];
|
||||
commandBuffer.label = @"minifb_command_buffer";
|
||||
|
||||
// Add completion hander which signals _inFlightSemaphore when Metal and the GPU has fully
|
||||
@ -69,7 +71,9 @@ extern Vertex gVertices[4];
|
||||
renderEncoder.label = @"minifb_command_encoder";
|
||||
|
||||
// Set render command encoder state
|
||||
[renderEncoder setRenderPipelineState:g_pipeline_state];
|
||||
OSXWindow *window = (OSXWindow *) view.window;
|
||||
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window->window_data->specific;
|
||||
[renderEncoder setRenderPipelineState:window_data_osx->metal.pipeline_state];
|
||||
|
||||
[renderEncoder setVertexBytes:gVertices
|
||||
length:sizeof(gVertices)
|
||||
@ -103,7 +107,7 @@ extern Vertex gVertices[4];
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
-(void)updateTrackingAreas
|
||||
- (void)updateTrackingAreas
|
||||
{
|
||||
if(trackingArea != nil) {
|
||||
[self removeTrackingArea:trackingArea];
|
||||
@ -142,16 +146,20 @@ extern Vertex gVertices[4];
|
||||
{
|
||||
(void)rect;
|
||||
|
||||
if (!g_window_data.window || !g_window_data.draw_buffer)
|
||||
if(!window_data)
|
||||
return;
|
||||
|
||||
SWindowData_OSX *window_data_osx = (SWindowData_OSX *) window_data->specific;
|
||||
if (!window_data_osx || !window_data_osx->window || !window_data->draw_buffer)
|
||||
return;
|
||||
|
||||
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, g_window_data.draw_buffer, g_window_data.buffer_width * g_window_data.buffer_height * 4, NULL);
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithData(0x0, window_data->draw_buffer, window_data->buffer_width * window_data->buffer_height * 4, 0x0);
|
||||
|
||||
CGImageRef img = CGImageCreate(g_window_data.buffer_width, g_window_data.buffer_height, 8, 32, g_window_data.buffer_width * 4, space, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
|
||||
provider, NULL, false, kCGRenderingIntentDefault);
|
||||
CGImageRef img = CGImageCreate(window_data->buffer_width, window_data->buffer_height, 8, 32, window_data->buffer_width * 4, space, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little,
|
||||
provider, 0x0, false, kCGRenderingIntentDefault);
|
||||
|
||||
const CGFloat components[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
const CGColorRef black = CGColorCreate(space, components);
|
||||
@ -159,12 +167,12 @@ extern Vertex gVertices[4];
|
||||
CGColorSpaceRelease(space);
|
||||
CGDataProviderRelease(provider);
|
||||
|
||||
if(g_window_data.dst_offset_x != 0 || g_window_data.dst_offset_y != 0 || g_window_data.dst_width != g_window_data.window_width || g_window_data.dst_height != g_window_data.window_height) {
|
||||
if(window_data->dst_offset_x != 0 || window_data->dst_offset_y != 0 || window_data->dst_width != window_data->window_width || window_data->dst_height != window_data->window_height) {
|
||||
CGContextSetFillColorWithColor(context, black);
|
||||
CGContextFillRect(context, CGRectMake(0, 0, g_window_data.window_width, g_window_data.window_height));
|
||||
CGContextFillRect(context, CGRectMake(0, 0, window_data->window_width, window_data->window_height));
|
||||
}
|
||||
|
||||
CGContextDrawImage(context, CGRectMake(g_window_data.dst_offset_x, g_window_data.dst_offset_y, g_window_data.dst_width, g_window_data.dst_height), img);
|
||||
CGContextDrawImage(context, CGRectMake(window_data->dst_offset_x, window_data->dst_offset_y, window_data->dst_width, window_data->dst_height), img);
|
||||
|
||||
CGImageRelease(img);
|
||||
}
|
||||
@ -183,7 +191,7 @@ extern Vertex gVertices[4];
|
||||
- (void)mouseDown:(NSEvent*)event
|
||||
{
|
||||
(void)event;
|
||||
kCall(g_mouse_btn_func, MOUSE_BTN_1, g_window_data.mod_keys, true);
|
||||
kCall(mouse_btn_func, MOUSE_BTN_1, window_data->mod_keys, true);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -191,7 +199,7 @@ extern Vertex gVertices[4];
|
||||
- (void)mouseUp:(NSEvent*)event
|
||||
{
|
||||
(void)event;
|
||||
kCall(g_mouse_btn_func, MOUSE_BTN_1, g_window_data.mod_keys, false);
|
||||
kCall(mouse_btn_func, MOUSE_BTN_1, window_data->mod_keys, false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -199,7 +207,7 @@ extern Vertex gVertices[4];
|
||||
- (void)rightMouseDown:(NSEvent*)event
|
||||
{
|
||||
(void)event;
|
||||
kCall(g_mouse_btn_func, MOUSE_BTN_2, g_window_data.mod_keys, true);
|
||||
kCall(mouse_btn_func, MOUSE_BTN_2, window_data->mod_keys, true);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -207,7 +215,7 @@ extern Vertex gVertices[4];
|
||||
- (void)rightMouseUp:(NSEvent*)event
|
||||
{
|
||||
(void)event;
|
||||
kCall(g_mouse_btn_func, MOUSE_BTN_1, g_window_data.mod_keys, false);
|
||||
kCall(mouse_btn_func, MOUSE_BTN_1, window_data->mod_keys, false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -215,7 +223,7 @@ extern Vertex gVertices[4];
|
||||
- (void)otherMouseDown:(NSEvent *)event
|
||||
{
|
||||
(void)event;
|
||||
kCall(g_mouse_btn_func, [event buttonNumber], g_window_data.mod_keys, true);
|
||||
kCall(mouse_btn_func, [event buttonNumber], window_data->mod_keys, true);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -223,14 +231,14 @@ extern Vertex gVertices[4];
|
||||
- (void)otherMouseUp:(NSEvent *)event
|
||||
{
|
||||
(void)event;
|
||||
kCall(g_mouse_btn_func, [event buttonNumber], g_window_data.mod_keys, false);
|
||||
kCall(mouse_btn_func, [event buttonNumber], window_data->mod_keys, false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)scrollWheel:(NSEvent *)event
|
||||
{
|
||||
kCall(g_mouse_wheel_func, g_window_data.mod_keys, [event deltaX], [event deltaY]);
|
||||
kCall(mouse_wheel_func, window_data->mod_keys, [event deltaX], [event deltaY]);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -254,7 +262,7 @@ extern Vertex gVertices[4];
|
||||
{
|
||||
NSPoint point = [event locationInWindow];
|
||||
//NSPoint localPoint = [self convertPoint:point fromView:nil];
|
||||
kCall(g_mouse_move_func, point.x, point.y);
|
||||
kCall(mouse_move_func, point.x, point.y);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
21
src/macosx/WindowData_OSX.h
Normal file
21
src/macosx/WindowData_OSX.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <MiniFB_enums.h>
|
||||
#include <WindowData.h>
|
||||
|
||||
#if defined(USE_METAL_API)
|
||||
#include <MetalKit/MetalKit.h>
|
||||
#endif
|
||||
|
||||
@class OSXWindow;
|
||||
|
||||
typedef struct {
|
||||
OSXWindow *window;
|
||||
#if defined(USE_METAL_API)
|
||||
struct {
|
||||
id<MTLCommandQueue> command_queue;
|
||||
id<MTLRenderPipelineState> pipeline_state;
|
||||
} metal;
|
||||
#endif
|
||||
bool active;
|
||||
} SWindowData_OSX;
|
@ -1,7 +1,8 @@
|
||||
#include <MiniFB.h>
|
||||
#include "MiniFB_internal.h"
|
||||
#include "MiniFB_enums.h"
|
||||
#include "WaylandWindowData.h"
|
||||
#include "WindowData.h"
|
||||
#include "WindowData_Way.h"
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-cursor.h>
|
||||
@ -18,29 +19,48 @@
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
SWindowData g_window_data = { 0 };
|
||||
static void
|
||||
destroy_window_data(SWindowData *window_data)
|
||||
{
|
||||
if(window_data == 0x0)
|
||||
return;
|
||||
|
||||
SWindowData_Way *window_data_way = (SWindowData_Way *) window_data->specific;
|
||||
if(window_data_way != 0x0) {
|
||||
memset(window_data_way, 0, sizeof(SWindowData_Way));
|
||||
free(window_data_way);
|
||||
}
|
||||
memset(window_data, 0, sizeof(SWindowData));
|
||||
free(window_data);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy(void)
|
||||
destroy(SWindowData *window_data)
|
||||
{
|
||||
if (! g_window_data.display)
|
||||
if(window_data == 0x0)
|
||||
return;
|
||||
|
||||
SWindowData_Way *window_data_way = (SWindowData_Way *) window_data->specific;
|
||||
if (window_data_way == 0x0 || window_data_way->display == 0x0) {
|
||||
destroy_window_data(window_data);
|
||||
return;
|
||||
}
|
||||
|
||||
#define KILL(NAME) \
|
||||
do \
|
||||
{ \
|
||||
if (g_window_data.NAME) \
|
||||
wl_##NAME##_destroy(g_window_data.NAME); \
|
||||
if (window_data_way->NAME) \
|
||||
wl_##NAME##_destroy(window_data_way->NAME); \
|
||||
} while (0); \
|
||||
g_window_data.NAME = 0x0;
|
||||
window_data_way->NAME = 0x0;
|
||||
|
||||
KILL(shell_surface);
|
||||
KILL(shell);
|
||||
KILL(surface);
|
||||
//KILL(buffer);
|
||||
if(g_window_data.draw_buffer) {
|
||||
wl_buffer_destroy(g_window_data.draw_buffer);
|
||||
g_window_data.draw_buffer = 0x0;
|
||||
if(window_data_way->draw_buffer) {
|
||||
wl_buffer_destroy(window_data_way->draw_buffer);
|
||||
window_data_way->draw_buffer = 0x0;
|
||||
}
|
||||
KILL(shm_pool);
|
||||
KILL(shm);
|
||||
@ -49,8 +69,9 @@ destroy(void)
|
||||
KILL(seat);
|
||||
KILL(registry);
|
||||
#undef KILL
|
||||
wl_display_disconnect(g_window_data.display);
|
||||
memset(&g_window_data, 0, sizeof(SWindowData));
|
||||
wl_display_disconnect(window_data_way->display);
|
||||
|
||||
destroy_window_data(window_data);
|
||||
}
|
||||
|
||||
// This event provides a file descriptor to the client which can be memory-mapped
|
||||
@ -75,12 +96,13 @@ keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int f
|
||||
static void
|
||||
keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(keyboard);
|
||||
kUnused(serial);
|
||||
kUnused(surface);
|
||||
kUnused(keys);
|
||||
kCall(g_active_func, true);
|
||||
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
kCall(active_func, true);
|
||||
}
|
||||
|
||||
// The leave notification is sent before the enter notification for the new focus.
|
||||
@ -89,11 +111,12 @@ keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct
|
||||
static void
|
||||
keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(keyboard);
|
||||
kUnused(serial);
|
||||
kUnused(surface);
|
||||
kCall(g_active_func, false);
|
||||
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
kCall(active_func, false);
|
||||
}
|
||||
|
||||
// A key was pressed or released. The time argument is a timestamp with
|
||||
@ -105,10 +128,11 @@ keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct
|
||||
static void
|
||||
keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(keyboard);
|
||||
kUnused(serial);
|
||||
kUnused(time);
|
||||
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
if(key < 512) {
|
||||
Key kb_key = (Key) keycodes[key];
|
||||
bool is_pressed = (bool) (state == WL_KEYBOARD_KEY_STATE_PRESSED);
|
||||
@ -117,37 +141,37 @@ keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t
|
||||
case KB_KEY_LEFT_SHIFT:
|
||||
case KB_KEY_RIGHT_SHIFT:
|
||||
if(is_pressed)
|
||||
g_window_data.mod_keys |= KB_MOD_SHIFT;
|
||||
window_data->mod_keys |= KB_MOD_SHIFT;
|
||||
else
|
||||
g_window_data.mod_keys &= ~KB_MOD_SHIFT;
|
||||
window_data->mod_keys &= ~KB_MOD_SHIFT;
|
||||
break;
|
||||
|
||||
case KB_KEY_LEFT_CONTROL:
|
||||
case KB_KEY_RIGHT_CONTROL:
|
||||
if(is_pressed)
|
||||
g_window_data.mod_keys |= KB_MOD_CONTROL;
|
||||
window_data->mod_keys |= KB_MOD_CONTROL;
|
||||
else
|
||||
g_window_data.mod_keys &= ~KB_MOD_CONTROL;
|
||||
window_data->mod_keys &= ~KB_MOD_CONTROL;
|
||||
break;
|
||||
|
||||
case KB_KEY_LEFT_ALT:
|
||||
case KB_KEY_RIGHT_ALT:
|
||||
if(is_pressed)
|
||||
g_window_data.mod_keys |= KB_MOD_ALT;
|
||||
window_data->mod_keys |= KB_MOD_ALT;
|
||||
else
|
||||
g_window_data.mod_keys &= ~KB_MOD_ALT;
|
||||
window_data->mod_keys &= ~KB_MOD_ALT;
|
||||
break;
|
||||
|
||||
case KB_KEY_LEFT_SUPER:
|
||||
case KB_KEY_RIGHT_SUPER:
|
||||
if(is_pressed)
|
||||
g_window_data.mod_keys |= KB_MOD_SUPER;
|
||||
window_data->mod_keys |= KB_MOD_SUPER;
|
||||
else
|
||||
g_window_data.mod_keys &= ~KB_MOD_SUPER;
|
||||
window_data->mod_keys &= ~KB_MOD_SUPER;
|
||||
break;
|
||||
}
|
||||
|
||||
kCall(g_keyboard_func, kb_key, (KeyMod)g_window_data.mod_keys, is_pressed);
|
||||
kCall(keyboard_func, kb_key, (KeyMod)window_data->mod_keys, is_pressed);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +213,7 @@ static const struct wl_keyboard_listener keyboard_listener = {
|
||||
.leave = keyboard_leave,
|
||||
.key = keyboard_key,
|
||||
.modifiers = keyboard_modifiers,
|
||||
.repeat_info = NULL,
|
||||
.repeat_info = 0x0,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -207,7 +231,6 @@ static const struct wl_keyboard_listener keyboard_listener = {
|
||||
static void
|
||||
pointer_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy)
|
||||
{
|
||||
kUnused(data);
|
||||
//kUnused(pointer);
|
||||
//kUnused(serial);
|
||||
kUnused(surface);
|
||||
@ -216,13 +239,16 @@ pointer_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl
|
||||
struct wl_buffer *buffer;
|
||||
struct wl_cursor_image *image;
|
||||
|
||||
image = g_window_data.default_cursor->images[0];
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
SWindowData_Way *window_data_way = (SWindowData_Way *) window_data->specific;
|
||||
|
||||
image = window_data_way->default_cursor->images[0];
|
||||
buffer = wl_cursor_image_get_buffer(image);
|
||||
|
||||
wl_pointer_set_cursor(pointer, serial, g_window_data.cursor_surface, image->hotspot_x, image->hotspot_y);
|
||||
wl_surface_attach(g_window_data.cursor_surface, buffer, 0, 0);
|
||||
wl_surface_damage(g_window_data.cursor_surface, 0, 0, image->width, image->height);
|
||||
wl_surface_commit(g_window_data.cursor_surface);
|
||||
wl_pointer_set_cursor(pointer, serial, window_data_way->cursor_surface, image->hotspot_x, image->hotspot_y);
|
||||
wl_surface_attach(window_data_way->cursor_surface, buffer, 0, 0);
|
||||
wl_surface_damage(window_data_way->cursor_surface, 0, 0, image->width, image->height);
|
||||
wl_surface_commit(window_data_way->cursor_surface);
|
||||
//fprintf(stderr, "Pointer entered surface %p at %d %d\n", surface, sx, sy);
|
||||
}
|
||||
|
||||
@ -239,6 +265,7 @@ pointer_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl
|
||||
kUnused(pointer);
|
||||
kUnused(serial);
|
||||
kUnused(surface);
|
||||
|
||||
//fprintf(stderr, "Pointer left surface %p\n", surface);
|
||||
}
|
||||
|
||||
@ -252,11 +279,12 @@ pointer_leave(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl
|
||||
static void
|
||||
pointer_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(pointer);
|
||||
kUnused(time);
|
||||
|
||||
//printf("Pointer moved at %f %f\n", sx / 256.0f, sy / 256.0f);
|
||||
kCall(g_mouse_move_func, sx >> 24, sy >> 24);
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
kCall(mouse_move_func, sx >> 24, sy >> 24);
|
||||
}
|
||||
|
||||
// Mouse button click and release notifications.
|
||||
@ -280,12 +308,13 @@ pointer_motion(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t
|
||||
static void
|
||||
pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(pointer);
|
||||
kUnused(serial);
|
||||
kUnused(time);
|
||||
|
||||
//printf("Pointer button '%d'(%d)\n", button, state);
|
||||
kCall(g_mouse_btn_func, button - BTN_MOUSE + 1, g_window_data.mod_keys, state == 1);
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
kCall(mouse_btn_func, button - BTN_MOUSE + 1, window_data->mod_keys, state == 1);
|
||||
}
|
||||
|
||||
// Scroll and other axis notifications.
|
||||
@ -311,16 +340,17 @@ pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t
|
||||
static void
|
||||
pointer_axis(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(pointer);
|
||||
kUnused(time);
|
||||
kUnused(axis);
|
||||
|
||||
//printf("Pointer handle axis: axis: %d (0x%x)\n", axis, value);
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
if(axis == 0) {
|
||||
kCall(g_mouse_wheel_func, g_window_data.mod_keys, 0.0f, -(value / 256.0f));
|
||||
kCall(mouse_wheel_func, window_data->mod_keys, 0.0f, -(value / 256.0f));
|
||||
}
|
||||
else if(axis == 1) {
|
||||
kCall(g_mouse_wheel_func, g_window_data.mod_keys, -(value / 256.0f), 0.0f);
|
||||
kCall(mouse_wheel_func, window_data->mod_keys, -(value / 256.0f), 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,10 +389,10 @@ static const struct wl_pointer_listener pointer_listener = {
|
||||
.motion = pointer_motion,
|
||||
.button = pointer_button,
|
||||
.axis = pointer_axis,
|
||||
.frame = NULL,
|
||||
.axis_source = NULL,
|
||||
.axis_stop = NULL,
|
||||
.axis_discrete = NULL,
|
||||
.frame = 0x0,
|
||||
.axis_source = 0x0,
|
||||
.axis_stop = 0x0,
|
||||
.axis_discrete = 0x0,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -371,26 +401,29 @@ static void
|
||||
seat_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
|
||||
{
|
||||
kUnused(data);
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !g_window_data.keyboard)
|
||||
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
SWindowData_Way *window_data_way = (SWindowData_Way *) window_data->specific;
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !window_data_way->keyboard)
|
||||
{
|
||||
g_window_data.keyboard = wl_seat_get_keyboard(seat);
|
||||
wl_keyboard_add_listener(g_window_data.keyboard, &keyboard_listener, NULL);
|
||||
window_data_way->keyboard = wl_seat_get_keyboard(seat);
|
||||
wl_keyboard_add_listener(window_data_way->keyboard, &keyboard_listener, window_data);
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && g_window_data.keyboard)
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && window_data_way->keyboard)
|
||||
{
|
||||
wl_keyboard_destroy(g_window_data.keyboard);
|
||||
g_window_data.keyboard = NULL;
|
||||
wl_keyboard_destroy(window_data_way->keyboard);
|
||||
window_data_way->keyboard = 0x0;
|
||||
}
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !g_window_data.pointer)
|
||||
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !window_data_way->pointer)
|
||||
{
|
||||
g_window_data.pointer = wl_seat_get_pointer(seat);
|
||||
wl_pointer_add_listener(g_window_data.pointer, &pointer_listener, NULL);
|
||||
window_data_way->pointer = wl_seat_get_pointer(seat);
|
||||
wl_pointer_add_listener(window_data_way->pointer, &pointer_listener, window_data);
|
||||
}
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && g_window_data.pointer)
|
||||
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && window_data_way->pointer)
|
||||
{
|
||||
wl_pointer_destroy(g_window_data.pointer);
|
||||
g_window_data.pointer = NULL;
|
||||
wl_pointer_destroy(window_data_way->pointer);
|
||||
window_data_way->pointer = 0x0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,7 +436,7 @@ seat_name(void *data, struct wl_seat *seat, const char *name) {
|
||||
|
||||
static const struct wl_seat_listener seat_listener = {
|
||||
.capabilities = seat_capabilities,
|
||||
.name = NULL,
|
||||
.name = 0x0,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -417,16 +450,18 @@ static const struct wl_seat_listener seat_listener = {
|
||||
static void
|
||||
shm_format(void *data, struct wl_shm *shm, uint32_t format)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(shm);
|
||||
if (g_window_data.shm_format == -1u)
|
||||
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
SWindowData_Way *window_data_way = (SWindowData_Way *) window_data->specific;
|
||||
if (window_data_way->shm_format == -1u)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
// We could do RGBA, but that would not be what is expected from minifb...
|
||||
// case WL_SHM_FORMAT_ARGB8888:
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
g_window_data.shm_format = format;
|
||||
window_data_way->shm_format = format;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -444,73 +479,112 @@ static const struct wl_shm_listener shm_listener = {
|
||||
static void
|
||||
registry_global(void *data, struct wl_registry *registry, uint32_t id, char const *iface, uint32_t version)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(version);
|
||||
|
||||
SWindowData *window_data = (SWindowData *) data;
|
||||
SWindowData_Way *window_data_way = (SWindowData_Way *) window_data->specific;
|
||||
if (strcmp(iface, "wl_compositor") == 0)
|
||||
{
|
||||
g_window_data.compositor = (struct wl_compositor *) wl_registry_bind(registry, id, &wl_compositor_interface, 1);
|
||||
window_data_way->compositor = (struct wl_compositor *) wl_registry_bind(registry, id, &wl_compositor_interface, 1);
|
||||
}
|
||||
else if (strcmp(iface, "wl_shm") == 0)
|
||||
{
|
||||
g_window_data.shm = (struct wl_shm *) wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
if (g_window_data.shm) {
|
||||
wl_shm_add_listener(g_window_data.shm, &shm_listener, NULL);
|
||||
g_window_data.cursor_theme = wl_cursor_theme_load(NULL, 32, g_window_data.shm);
|
||||
g_window_data.default_cursor = wl_cursor_theme_get_cursor(g_window_data.cursor_theme, "left_ptr");
|
||||
window_data_way->shm = (struct wl_shm *) wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
if (window_data_way->shm) {
|
||||
wl_shm_add_listener(window_data_way->shm, &shm_listener, window_data);
|
||||
window_data_way->cursor_theme = wl_cursor_theme_load(0x0, 32, window_data_way->shm);
|
||||
window_data_way->default_cursor = wl_cursor_theme_get_cursor(window_data_way->cursor_theme, "left_ptr");
|
||||
}
|
||||
}
|
||||
else if (strcmp(iface, "wl_shell") == 0)
|
||||
{
|
||||
g_window_data.shell = (struct wl_shell *) wl_registry_bind(registry, id, &wl_shell_interface, 1);
|
||||
window_data_way->shell = (struct wl_shell *) wl_registry_bind(registry, id, &wl_shell_interface, 1);
|
||||
}
|
||||
else if (strcmp(iface, "wl_seat") == 0)
|
||||
{
|
||||
g_window_data.seat = (struct wl_seat *) wl_registry_bind(registry, id, &wl_seat_interface, 1);
|
||||
if (g_window_data.seat)
|
||||
window_data_way->seat = (struct wl_seat *) wl_registry_bind(registry, id, &wl_seat_interface, 1);
|
||||
if (window_data_way->seat)
|
||||
{
|
||||
wl_seat_add_listener(g_window_data.seat, &seat_listener, NULL);
|
||||
wl_seat_add_listener(window_data_way->seat, &seat_listener, window_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
.global = registry_global,
|
||||
.global_remove = NULL,
|
||||
.global_remove = 0x0,
|
||||
};
|
||||
|
||||
static void
|
||||
handle_ping(void *data, struct wl_shell_surface *shell_surface, uint32_t serial)
|
||||
{
|
||||
kUnused(data);
|
||||
wl_shell_surface_pong(shell_surface, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, int32_t height)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(shell_surface);
|
||||
kUnused(edges);
|
||||
kUnused(width);
|
||||
kUnused(height);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
|
||||
{
|
||||
kUnused(data);
|
||||
kUnused(shell_surface);
|
||||
}
|
||||
|
||||
static const struct wl_shell_surface_listener shell_surface_listener = {
|
||||
handle_ping,
|
||||
handle_configure,
|
||||
handle_popup_done
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int
|
||||
mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
struct Window *
|
||||
mfb_open_ex(const char *title, int width, int height, int flags) {
|
||||
// TODO: Not yet
|
||||
kUnused(flags);
|
||||
return mfb_open(title, width, height);
|
||||
}
|
||||
|
||||
int
|
||||
struct Window *
|
||||
mfb_open(const char *title, int width, int height)
|
||||
{
|
||||
int fd = -1;
|
||||
|
||||
g_window_data.shm_format = -1u;
|
||||
SWindowData *window_data = malloc(sizeof(SWindowData));
|
||||
memset(window_data, 0, sizeof(SWindowData));
|
||||
|
||||
g_window_data.display = wl_display_connect(NULL);
|
||||
if (!g_window_data.display)
|
||||
return -1;
|
||||
g_window_data.registry = wl_display_get_registry(g_window_data.display);
|
||||
wl_registry_add_listener(g_window_data.registry, ®istry_listener, NULL);
|
||||
SWindowData_Way *window_data_way = malloc(sizeof(SWindowData_Way));
|
||||
memset(window_data_way, 0, sizeof(SWindowData_Way));
|
||||
window_data->specific = window_data_way;
|
||||
|
||||
window_data_way->shm_format = -1u;
|
||||
|
||||
window_data_way->display = wl_display_connect(0x0);
|
||||
if (!window_data_way->display)
|
||||
return 0x0;
|
||||
window_data_way->registry = wl_display_get_registry(window_data_way->display);
|
||||
wl_registry_add_listener(window_data_way->registry, ®istry_listener, window_data);
|
||||
|
||||
init_keycodes();
|
||||
|
||||
if (wl_display_dispatch(g_window_data.display) == -1 || wl_display_roundtrip(g_window_data.display) == -1)
|
||||
if (wl_display_dispatch(window_data_way->display) == -1 || wl_display_roundtrip(window_data_way->display) == -1)
|
||||
{
|
||||
return -1;
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
// did not get a format we want... meh
|
||||
if (g_window_data.shm_format == -1u)
|
||||
if (window_data_way->shm_format == -1u)
|
||||
goto out;
|
||||
if (!g_window_data.compositor)
|
||||
if (!window_data_way->compositor)
|
||||
goto out;
|
||||
|
||||
char const *xdg_rt_dir = getenv("XDG_RUNTIME_DIR");
|
||||
@ -529,71 +603,60 @@ mfb_open(const char *title, int width, int height)
|
||||
if (ftruncate(fd, length) == -1)
|
||||
goto out;
|
||||
|
||||
g_window_data.shm_ptr = (uint32_t *) mmap(NULL, length, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (g_window_data.shm_ptr == MAP_FAILED)
|
||||
window_data_way->shm_ptr = (uint32_t *) mmap(0x0, length, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (window_data_way->shm_ptr == MAP_FAILED)
|
||||
goto out;
|
||||
|
||||
g_window_data.window_width = width;
|
||||
g_window_data.window_height = height;
|
||||
g_window_data.buffer_width = width;
|
||||
g_window_data.buffer_height = height;
|
||||
g_window_data.buffer_stride = width * sizeof(uint32_t);
|
||||
g_window_data.dst_offset_x = 0;
|
||||
g_window_data.dst_offset_y = 0;
|
||||
g_window_data.dst_width = width;
|
||||
g_window_data.dst_height = height;
|
||||
window_data->window_width = width;
|
||||
window_data->window_height = height;
|
||||
window_data->buffer_width = width;
|
||||
window_data->buffer_height = height;
|
||||
window_data->buffer_stride = width * sizeof(uint32_t);
|
||||
window_data->dst_offset_x = 0;
|
||||
window_data->dst_offset_y = 0;
|
||||
window_data->dst_width = width;
|
||||
window_data->dst_height = height;
|
||||
|
||||
g_window_data.shm_pool = wl_shm_create_pool(g_window_data.shm, fd, length);
|
||||
g_window_data.draw_buffer = wl_shm_pool_create_buffer(g_window_data.shm_pool, 0,
|
||||
g_window_data.buffer_width, g_window_data.buffer_height,
|
||||
g_window_data.buffer_stride, g_window_data.shm_format);
|
||||
window_data_way->shm_pool = wl_shm_create_pool(window_data_way->shm, fd, length);
|
||||
window_data->draw_buffer = wl_shm_pool_create_buffer(window_data_way->shm_pool, 0,
|
||||
window_data->buffer_width, window_data->buffer_height,
|
||||
window_data->buffer_stride, window_data_way->shm_format);
|
||||
|
||||
close(fd);
|
||||
fd = -1;
|
||||
|
||||
g_window_data.surface = wl_compositor_create_surface(g_window_data.compositor);
|
||||
if (!g_window_data.surface)
|
||||
window_data_way->surface = wl_compositor_create_surface(window_data_way->compositor);
|
||||
if (!window_data_way->surface)
|
||||
goto out;
|
||||
|
||||
g_window_data.cursor_surface = wl_compositor_create_surface(g_window_data.compositor);
|
||||
window_data_way->cursor_surface = wl_compositor_create_surface(window_data_way->compositor);
|
||||
|
||||
// There should always be a shell, right?
|
||||
if (g_window_data.shell)
|
||||
if (window_data_way->shell)
|
||||
{
|
||||
g_window_data.shell_surface = wl_shell_get_shell_surface(g_window_data.shell, g_window_data.surface);
|
||||
if (!g_window_data.shell_surface)
|
||||
window_data_way->shell_surface = wl_shell_get_shell_surface(window_data_way->shell, window_data_way->surface);
|
||||
if (!window_data_way->shell_surface)
|
||||
goto out;
|
||||
|
||||
wl_shell_surface_set_title(g_window_data.shell_surface, title);
|
||||
wl_shell_surface_set_toplevel(g_window_data.shell_surface);
|
||||
wl_shell_surface_set_title(window_data_way->shell_surface, title);
|
||||
wl_shell_surface_add_listener(window_data_way->shell_surface, &shell_surface_listener, 0x0);
|
||||
wl_shell_surface_set_toplevel(window_data_way->shell_surface);
|
||||
}
|
||||
|
||||
wl_surface_attach(g_window_data.surface, g_window_data.draw_buffer, g_window_data.dst_offset_x, g_window_data.dst_offset_y);
|
||||
wl_surface_damage(g_window_data.surface, g_window_data.dst_offset_x, g_window_data.dst_offset_y, g_window_data.dst_width, g_window_data.dst_height);
|
||||
wl_surface_commit(g_window_data.surface);
|
||||
wl_surface_attach(window_data_way->surface, window_data->draw_buffer, window_data->dst_offset_x, window_data->dst_offset_y);
|
||||
wl_surface_damage(window_data_way->surface, window_data->dst_offset_x, window_data->dst_offset_y, window_data->dst_width, window_data->dst_height);
|
||||
wl_surface_commit(window_data_way->surface);
|
||||
|
||||
if (g_keyboard_func == 0x0) {
|
||||
mfb_keyboard_callback(keyboard_default);
|
||||
}
|
||||
mfb_keyboard_callback((struct Window *) window_data, keyboard_default);
|
||||
|
||||
printf("Window created using Wayland API\n");
|
||||
|
||||
return 1;
|
||||
return (struct Window *) window_data;
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
destroy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void keyboard_default(void *user_data, Key key, KeyMod mod, bool isPressed) {
|
||||
kUnused(user_data);
|
||||
kUnused(mod);
|
||||
kUnused(isPressed);
|
||||
if (key == KB_KEY_ESCAPE)
|
||||
g_window_data.close = true;
|
||||
destroy(window_data);
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
// done event
|
||||
@ -606,6 +669,7 @@ frame_done(void *data, struct wl_callback *callback, uint32_t cookie)
|
||||
{
|
||||
kUnused(cookie);
|
||||
wl_callback_destroy(callback);
|
||||
|
||||
*(uint32_t *)data = 1;
|
||||
}
|
||||
|
||||
@ -613,53 +677,50 @@ static const struct wl_callback_listener frame_listener = {
|
||||
.done = frame_done,
|
||||
};
|
||||
|
||||
int
|
||||
mfb_update(void *buffer)
|
||||
UpdateState
|
||||
mfb_update(struct Window *window, void *buffer)
|
||||
{
|
||||
uint32_t done = 0;
|
||||
|
||||
if (!g_window_data.display || wl_display_get_error(g_window_data.display) != 0)
|
||||
return -1;
|
||||
if(window == 0x0) {
|
||||
return STATE_INVALID_WINDOW;
|
||||
}
|
||||
|
||||
if (g_window_data.close == true)
|
||||
return -1;
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
if(window_data->close) {
|
||||
destroy(window_data);
|
||||
return STATE_EXIT;
|
||||
}
|
||||
|
||||
if(buffer == 0x0) {
|
||||
return STATE_INVALID_BUFFER;
|
||||
}
|
||||
|
||||
SWindowData_Way *window_data_way = (SWindowData_Way *) window_data->specific;
|
||||
if (!window_data_way->display || wl_display_get_error(window_data_way->display) != 0)
|
||||
return STATE_INTERNAL_ERROR;
|
||||
|
||||
// update shm buffer
|
||||
memcpy(g_window_data.shm_ptr, buffer, g_window_data.buffer_stride * g_window_data.buffer_height);
|
||||
memcpy(window_data_way->shm_ptr, buffer, window_data->buffer_stride * window_data->buffer_height);
|
||||
|
||||
wl_surface_attach(g_window_data.surface, g_window_data.draw_buffer, g_window_data.dst_offset_x, g_window_data.dst_offset_y);
|
||||
wl_surface_damage(g_window_data.surface, g_window_data.dst_offset_x, g_window_data.dst_offset_y, g_window_data.dst_width, g_window_data.dst_height);
|
||||
wl_surface_attach(window_data_way->surface, window_data->draw_buffer, window_data->dst_offset_x, window_data->dst_offset_y);
|
||||
wl_surface_damage(window_data_way->surface, window_data->dst_offset_x, window_data->dst_offset_y, window_data->dst_width, window_data->dst_height);
|
||||
struct wl_callback *frame_callback = wl_surface_frame(window_data_way->surface);
|
||||
if (!frame_callback) {
|
||||
return STATE_INTERNAL_ERROR;
|
||||
}
|
||||
wl_callback_add_listener(frame_callback, &frame_listener, &done);
|
||||
wl_surface_commit(window_data_way->surface);
|
||||
|
||||
struct wl_callback *frame = wl_surface_frame(g_window_data.surface);
|
||||
if (!frame)
|
||||
return -1;
|
||||
|
||||
wl_callback_add_listener(frame, &frame_listener, &done);
|
||||
|
||||
wl_surface_commit(g_window_data.surface);
|
||||
|
||||
while (!done && g_window_data.close == false) {
|
||||
if (wl_display_dispatch(g_window_data.display) == -1 || wl_display_roundtrip(g_window_data.display) == -1)
|
||||
while (!done && window_data->close == false) {
|
||||
if (wl_display_dispatch(window_data_way->display) == -1 || wl_display_roundtrip(window_data_way->display) == -1)
|
||||
{
|
||||
wl_callback_destroy(frame);
|
||||
return -1;
|
||||
wl_callback_destroy(frame_callback);
|
||||
return STATE_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
if(g_window_data.close == true) {
|
||||
destroy();
|
||||
}
|
||||
|
||||
//static int counter = 0;
|
||||
//printf("update!: %d\n", counter++);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
mfb_close(void) {
|
||||
g_window_data.close = true;
|
||||
return STATE_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -795,20 +856,22 @@ init_keycodes(void)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool
|
||||
mfb_set_viewport(unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) {
|
||||
mfb_set_viewport(struct Window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) {
|
||||
|
||||
if(offset_x + width > g_window_data.window_width) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
|
||||
if(offset_x + width > window_data->window_width) {
|
||||
return false;
|
||||
}
|
||||
if(offset_y + height > g_window_data.window_height) {
|
||||
if(offset_y + height > window_data->window_height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Not yet
|
||||
// g_window_data.dst_offset_x = offset_x;
|
||||
// g_window_data.dst_offset_y = offset_y;
|
||||
// g_window_data.dst_width = width;
|
||||
// g_window_data.dst_height = height;
|
||||
// window_data->dst_offset_x = offset_x;
|
||||
// window_data->dst_offset_y = offset_y;
|
||||
// window_data->dst_width = width;
|
||||
// window_data->dst_height = height;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -54,4 +54,4 @@ typedef struct
|
||||
|
||||
uint32_t mod_keys;
|
||||
bool close;
|
||||
} SWindowData;
|
||||
} SWindowData_Way;
|
@ -1,49 +1,55 @@
|
||||
#include <MiniFB.h>
|
||||
#include <MiniFB_internal.h>
|
||||
#include "WinWindowData.h"
|
||||
#include <WindowData.h>
|
||||
#include "WindowData_Win.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SWindowData g_window_data = { 0 };
|
||||
|
||||
long s_window_style = WS_POPUP | WS_SYSMENU | WS_CAPTION;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint32_t translate_mod();
|
||||
Key translate_key(unsigned int wParam, unsigned long lParam);
|
||||
void destroy_window_data(SWindowData *window_data);
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT res = 0;
|
||||
|
||||
SWindowData *window_data = (SWindowData *) GetWindowLongPtr(hWnd, GWL_USERDATA);
|
||||
SWindowData_Win *window_data_win = 0x0;
|
||||
if(window_data != 0x0) {
|
||||
window_data_win = (SWindowData_Win *) window_data->specific;
|
||||
}
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_PAINT:
|
||||
{
|
||||
if (g_window_data.draw_buffer)
|
||||
if (window_data && window_data->draw_buffer && window_data_win)
|
||||
{
|
||||
if (g_window_data.dst_offset_x > 0) {
|
||||
BitBlt(g_window_data.s_hdc, 0, g_window_data.dst_offset_y, g_window_data.dst_offset_x, g_window_data.dst_height, 0, 0, 0, BLACKNESS);
|
||||
}
|
||||
if (g_window_data.dst_offset_y > 0) {
|
||||
BitBlt(g_window_data.s_hdc, 0, 0, g_window_data.window_width, g_window_data.dst_offset_y, 0, 0, 0, BLACKNESS);
|
||||
}
|
||||
uint32_t offsetY = g_window_data.dst_offset_y + g_window_data.dst_height;
|
||||
if (offsetY < g_window_data.window_height) {
|
||||
BitBlt(g_window_data.s_hdc, 0, offsetY, g_window_data.window_width, g_window_data.window_height-offsetY, 0, 0, 0, BLACKNESS);
|
||||
}
|
||||
uint32_t offsetX = g_window_data.dst_offset_x + g_window_data.dst_width;
|
||||
if (offsetX < g_window_data.window_width) {
|
||||
BitBlt(g_window_data.s_hdc, offsetX, g_window_data.dst_offset_y, g_window_data.window_width-offsetX, g_window_data.dst_height, 0, 0, 0, BLACKNESS);
|
||||
}
|
||||
//if(window_data->dst_offset_x > 0) {
|
||||
// BitBlt(window_data_win->hdc, 0, window_data->dst_offset_y, window_data->dst_offset_x, window_data->dst_height, 0, 0, 0, BLACKNESS);
|
||||
//}
|
||||
//if(window_data->dst_offset_y > 0) {
|
||||
// BitBlt(window_data_win->hdc, 0, 0, window_data->window_width, window_data->dst_offset_y, 0, 0, 0, BLACKNESS);
|
||||
//}
|
||||
//uint32_t offsetY = window_data->dst_offset_y + window_data->dst_height;
|
||||
//if(offsetY < window_data->window_height) {
|
||||
// BitBlt(window_data_win->hdc, 0, offsetY, window_data->window_width, window_data->window_height - offsetY, 0, 0, 0, BLACKNESS);
|
||||
//}
|
||||
//uint32_t offsetX = window_data->dst_offset_x + window_data->dst_width;
|
||||
//if(offsetX < window_data->window_width) {
|
||||
// BitBlt(window_data_win->hdc, offsetX, window_data->dst_offset_y, window_data->window_width - offsetX, window_data->dst_height, 0, 0, 0, BLACKNESS);
|
||||
//}
|
||||
|
||||
StretchDIBits(g_window_data.s_hdc, g_window_data.dst_offset_x, g_window_data.dst_offset_y, g_window_data.dst_width, g_window_data.dst_height, 0, 0, g_window_data.buffer_width, g_window_data.buffer_height, g_window_data.draw_buffer,
|
||||
g_window_data.s_bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
|
||||
StretchDIBits(window_data_win->hdc, window_data->dst_offset_x, window_data->dst_offset_y, window_data->dst_width, window_data->dst_height, 0, 0, window_data->buffer_width, window_data->buffer_height, window_data->draw_buffer,
|
||||
window_data_win->bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
|
||||
|
||||
ValidateRect(hWnd, NULL);
|
||||
ValidateRect(hWnd, 0x0);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -52,7 +58,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_DESTROY:
|
||||
case WM_CLOSE:
|
||||
{
|
||||
g_window_data.close = true;
|
||||
if(window_data) {
|
||||
window_data->close = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -61,14 +69,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
if(window_data) {
|
||||
Key kb_key = translate_key((unsigned int)wParam, (unsigned long)lParam);
|
||||
int is_pressed = !((lParam >> 31) & 1);
|
||||
g_window_data.mod_keys = translate_mod();
|
||||
window_data->mod_keys = translate_mod();
|
||||
|
||||
if (kb_key == KB_KEY_UNKNOWN)
|
||||
return FALSE;
|
||||
|
||||
kCall(g_keyboard_func, kb_key, g_window_data.mod_keys, is_pressed);
|
||||
kCall(keyboard_func, kb_key, window_data->mod_keys, is_pressed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -77,13 +87,15 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_UNICHAR:
|
||||
{
|
||||
|
||||
if(window_data) {
|
||||
if(message == WM_UNICHAR && wParam == UNICODE_NOCHAR) {
|
||||
// WM_UNICHAR is not sent by Windows, but is sent by some third-party input method engine
|
||||
// Returning TRUE here announces support for this message
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
kCall(g_char_input_func, wParam);
|
||||
kCall(char_input_func, wParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -100,10 +112,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_XBUTTONDBLCLK:
|
||||
{
|
||||
if(window_data) {
|
||||
MouseButton button = MOUSE_BTN_0;
|
||||
g_window_data.mod_keys = translate_mod();
|
||||
window_data->mod_keys = translate_mod();
|
||||
int is_pressed = 0;
|
||||
switch (message) {
|
||||
switch(message) {
|
||||
case WM_LBUTTONDOWN:
|
||||
is_pressed = 1;
|
||||
case WM_LBUTTONUP:
|
||||
@ -122,27 +135,33 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
default:
|
||||
button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1 ? MOUSE_BTN_5 : MOUSE_BTN_6);
|
||||
if (message == WM_XBUTTONDOWN) {
|
||||
if(message == WM_XBUTTONDOWN) {
|
||||
is_pressed = 1;
|
||||
}
|
||||
}
|
||||
kCall(g_mouse_btn_func, button, g_window_data.mod_keys, is_pressed);
|
||||
kCall(mouse_btn_func, button, window_data->mod_keys, is_pressed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
kCall(g_mouse_wheel_func, translate_mod(), 0.0f, (SHORT)HIWORD(wParam) / (float)WHEEL_DELTA);
|
||||
if(window_data) {
|
||||
kCall(mouse_wheel_func, translate_mod(), 0.0f, (SHORT)HIWORD(wParam) / (float)WHEEL_DELTA);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEHWHEEL:
|
||||
// This message is only sent on Windows Vista and later
|
||||
// NOTE: The X-axis is inverted for consistency with macOS and X11
|
||||
kCall(g_mouse_wheel_func, translate_mod(), -((SHORT)HIWORD(wParam) / (float)WHEEL_DELTA), 0.0f);
|
||||
if(window_data) {
|
||||
kCall(mouse_wheel_func, translate_mod(), -((SHORT)HIWORD(wParam) / (float)WHEEL_DELTA), 0.0f);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if(g_window_data.s_mouse_inside == false) {
|
||||
g_window_data.s_mouse_inside = true;
|
||||
if(window_data) {
|
||||
if(window_data_win->mouse_inside == false) {
|
||||
window_data_win->mouse_inside = true;
|
||||
TRACKMOUSEEVENT tme;
|
||||
ZeroMemory(&tme, sizeof(tme));
|
||||
tme.cbSize = sizeof(tme);
|
||||
@ -150,31 +169,39 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
tme.hwndTrack = hWnd;
|
||||
TrackMouseEvent(&tme);
|
||||
}
|
||||
kCall(g_mouse_move_func, ((int)(short)LOWORD(lParam)), ((int)(short)HIWORD(lParam)));
|
||||
kCall(mouse_move_func, ((int)(short)LOWORD(lParam)), ((int)(short)HIWORD(lParam)));
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSELEAVE:
|
||||
g_window_data.s_mouse_inside = false;
|
||||
if(window_data) {
|
||||
window_data_win->mouse_inside = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
{
|
||||
g_window_data.dst_offset_x = 0;
|
||||
g_window_data.dst_offset_y = 0;
|
||||
g_window_data.dst_width = LOWORD(lParam);
|
||||
g_window_data.dst_height = HIWORD(lParam);
|
||||
g_window_data.window_width = g_window_data.dst_width;
|
||||
g_window_data.window_height = g_window_data.dst_height;
|
||||
kCall(g_resize_func, g_window_data.dst_width, g_window_data.dst_height);
|
||||
break;
|
||||
if(window_data) {
|
||||
window_data->dst_offset_x = 0;
|
||||
window_data->dst_offset_y = 0;
|
||||
window_data->dst_width = LOWORD(lParam);
|
||||
window_data->dst_height = HIWORD(lParam);
|
||||
window_data->window_width = window_data->dst_width;
|
||||
window_data->window_height = window_data->dst_height;
|
||||
BitBlt(window_data_win->hdc, 0, 0, window_data->window_width, window_data->window_height, 0, 0, 0, BLACKNESS);
|
||||
kCall(resize_func, window_data->dst_width, window_data->dst_height);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
kCall(g_active_func, true);
|
||||
if(window_data) {
|
||||
kCall(active_func, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
kCall(g_active_func, false);
|
||||
if(window_data) {
|
||||
kCall(active_func, false);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -188,14 +215,22 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
struct Window *mfb_open_ex(const char *title, int width, int height, int flags) {
|
||||
RECT rect = { 0 };
|
||||
int x, y;
|
||||
|
||||
init_keycodes();
|
||||
|
||||
g_window_data.buffer_width = width;
|
||||
g_window_data.buffer_height = height;
|
||||
SWindowData *window_data = malloc(sizeof(SWindowData));
|
||||
memset(window_data, 0, sizeof(SWindowData));
|
||||
|
||||
SWindowData_Win *window_data_win = malloc(sizeof(SWindowData_Win));
|
||||
memset(window_data_win, 0, sizeof(SWindowData_Win));
|
||||
window_data->specific = window_data_win;
|
||||
|
||||
window_data->buffer_width = width;
|
||||
window_data->buffer_height = height;
|
||||
window_data->buffer_stride = width * 4;
|
||||
|
||||
s_window_style = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME;
|
||||
if (flags & WF_FULLSCREEN) {
|
||||
@ -261,114 +296,117 @@ int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
y = (GetSystemMetrics(SM_CYSCREEN) - rect.bottom + rect.top) / 2;
|
||||
}
|
||||
|
||||
g_window_data.s_wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
|
||||
g_window_data.s_wc.lpfnWndProc = WndProc;
|
||||
g_window_data.s_wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
g_window_data.s_wc.lpszClassName = title;
|
||||
RegisterClass(&g_window_data.s_wc);
|
||||
window_data_win->wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
|
||||
window_data_win->wc.lpfnWndProc = WndProc;
|
||||
window_data_win->wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
window_data_win->wc.lpszClassName = title;
|
||||
RegisterClass(&window_data_win->wc);
|
||||
|
||||
if (g_window_data.dst_width == 0)
|
||||
g_window_data.dst_width = width;
|
||||
if (window_data->dst_width == 0)
|
||||
window_data->dst_width = width;
|
||||
|
||||
if (g_window_data.dst_height == 0)
|
||||
g_window_data.dst_height = height;
|
||||
if (window_data->dst_height == 0)
|
||||
window_data->dst_height = height;
|
||||
|
||||
g_window_data.window_width = rect.right;
|
||||
g_window_data.window_height = rect.bottom;
|
||||
window_data->window_width = rect.right;
|
||||
window_data->window_height = rect.bottom;
|
||||
|
||||
g_window_data.window = CreateWindowEx(
|
||||
window_data_win->window = CreateWindowEx(
|
||||
0,
|
||||
title, title,
|
||||
s_window_style,
|
||||
x, y,
|
||||
g_window_data.window_width, g_window_data.window_height,
|
||||
window_data->window_width, window_data->window_height,
|
||||
0, 0, 0, 0);
|
||||
|
||||
if (!g_window_data.window)
|
||||
return 0;
|
||||
if (!window_data_win->window)
|
||||
return 0x0;
|
||||
|
||||
SetWindowLongPtr(window_data_win->window, GWLP_USERDATA, (LONG_PTR) window_data);
|
||||
|
||||
if (flags & WF_ALWAYS_ON_TOP)
|
||||
SetWindowPos(g_window_data.window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
SetWindowPos(window_data_win->window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
||||
|
||||
ShowWindow(g_window_data.window, SW_NORMAL);
|
||||
ShowWindow(window_data_win->window, SW_NORMAL);
|
||||
|
||||
g_window_data.s_bitmapInfo = (BITMAPINFO *) calloc(1, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 3);
|
||||
g_window_data.s_bitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
g_window_data.s_bitmapInfo->bmiHeader.biPlanes = 1;
|
||||
g_window_data.s_bitmapInfo->bmiHeader.biBitCount = 32;
|
||||
g_window_data.s_bitmapInfo->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
g_window_data.s_bitmapInfo->bmiHeader.biWidth = g_window_data.buffer_width;
|
||||
g_window_data.s_bitmapInfo->bmiHeader.biHeight = -(LONG)g_window_data.buffer_height;
|
||||
g_window_data.s_bitmapInfo->bmiColors[0].rgbRed = 0xff;
|
||||
g_window_data.s_bitmapInfo->bmiColors[1].rgbGreen = 0xff;
|
||||
g_window_data.s_bitmapInfo->bmiColors[2].rgbBlue = 0xff;
|
||||
window_data_win->bitmapInfo = (BITMAPINFO *) calloc(1, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 3);
|
||||
window_data_win->bitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
window_data_win->bitmapInfo->bmiHeader.biPlanes = 1;
|
||||
window_data_win->bitmapInfo->bmiHeader.biBitCount = 32;
|
||||
window_data_win->bitmapInfo->bmiHeader.biCompression = BI_BITFIELDS;
|
||||
window_data_win->bitmapInfo->bmiHeader.biWidth = window_data->buffer_width;
|
||||
window_data_win->bitmapInfo->bmiHeader.biHeight = -(LONG)window_data->buffer_height;
|
||||
window_data_win->bitmapInfo->bmiColors[0].rgbRed = 0xff;
|
||||
window_data_win->bitmapInfo->bmiColors[1].rgbGreen = 0xff;
|
||||
window_data_win->bitmapInfo->bmiColors[2].rgbBlue = 0xff;
|
||||
|
||||
g_window_data.s_hdc = GetDC(g_window_data.window);
|
||||
window_data_win->hdc = GetDC(window_data_win->window);
|
||||
|
||||
if (g_keyboard_func == 0x0) {
|
||||
mfb_keyboard_callback(keyboard_default);
|
||||
}
|
||||
mfb_keyboard_callback((struct Window *) window_data, keyboard_default);
|
||||
|
||||
return 1;
|
||||
return (struct Window *) window_data;
|
||||
}
|
||||
|
||||
int mfb_open(const char* title, int width, int height) {
|
||||
struct Window *mfb_open(const char *title, int width, int height) {
|
||||
return mfb_open_ex(title, width, height, 0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_update(void* buffer)
|
||||
UpdateState mfb_update(struct Window *window, void* buffer)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
if (buffer == 0x0)
|
||||
return -2;
|
||||
if(window == 0x0) {
|
||||
return STATE_INVALID_WINDOW;
|
||||
}
|
||||
|
||||
if (g_window_data.close == true)
|
||||
return -1;
|
||||
SWindowData *window_data = (SWindowData *)window;
|
||||
if(window_data->close) {
|
||||
destroy_window_data(window_data);
|
||||
return STATE_EXIT;
|
||||
}
|
||||
|
||||
g_window_data.draw_buffer = buffer;
|
||||
if(buffer == 0x0) {
|
||||
return STATE_INVALID_BUFFER;
|
||||
}
|
||||
|
||||
InvalidateRect(g_window_data.window, NULL, TRUE);
|
||||
SendMessage(g_window_data.window, WM_PAINT, 0, 0);
|
||||
window_data->draw_buffer = buffer;
|
||||
|
||||
while (g_window_data.close == false && PeekMessage(&msg, g_window_data.window, 0, 0, PM_REMOVE))
|
||||
SWindowData_Win *window_data_win = (SWindowData_Win *) window_data->specific;
|
||||
InvalidateRect(window_data_win->window, 0x0, TRUE);
|
||||
SendMessage(window_data_win->window, WM_PAINT, 0, 0);
|
||||
|
||||
while (window_data->close == false && PeekMessage(&msg, window_data_win->window, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return STATE_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void mfb_close()
|
||||
{
|
||||
g_window_data.draw_buffer = 0x0;
|
||||
if (g_window_data.s_bitmapInfo != 0x0) {
|
||||
free(g_window_data.s_bitmapInfo);
|
||||
void destroy_window_data(SWindowData *window_data) {
|
||||
if(window_data == 0x0)
|
||||
return;
|
||||
|
||||
SWindowData_Win *window_data_win = (SWindowData_Win *) window_data->specific;
|
||||
|
||||
window_data->draw_buffer = 0x0;
|
||||
if(window_data_win->bitmapInfo != 0x0) {
|
||||
free(window_data_win->bitmapInfo);
|
||||
}
|
||||
if (g_window_data.window != 0 && g_window_data.s_hdc != 0) {
|
||||
ReleaseDC(g_window_data.window, g_window_data.s_hdc);
|
||||
DestroyWindow(g_window_data.window);
|
||||
if(window_data_win->window != 0 && window_data_win->hdc != 0) {
|
||||
ReleaseDC(window_data_win->window, window_data_win->hdc);
|
||||
DestroyWindow(window_data_win->window);
|
||||
}
|
||||
|
||||
g_window_data.window = 0;
|
||||
g_window_data.s_hdc = 0;
|
||||
g_window_data.s_bitmapInfo = 0x0;
|
||||
g_window_data.close = true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void keyboard_default(void *user_data, Key key, KeyMod mod, bool isPressed) {
|
||||
kUnused(user_data);
|
||||
kUnused(mod);
|
||||
kUnused(isPressed);
|
||||
if (key == KB_KEY_ESCAPE)
|
||||
g_window_data.close = true;
|
||||
window_data_win->window = 0;
|
||||
window_data_win->hdc = 0;
|
||||
window_data_win->bitmapInfo = 0x0;
|
||||
window_data->close = true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -536,7 +574,7 @@ Key translate_key(unsigned int wParam, unsigned long lParam) {
|
||||
return KB_KEY_RIGHT_CONTROL;
|
||||
|
||||
time = GetMessageTime();
|
||||
if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
|
||||
if (PeekMessageW(&next, 0x0, 0, 0, PM_NOREMOVE))
|
||||
if (next.message == WM_KEYDOWN || next.message == WM_SYSKEYDOWN || next.message == WM_KEYUP || next.message == WM_SYSKEYUP)
|
||||
if (next.wParam == VK_MENU && (next.lParam & 0x01000000) && next.time == time)
|
||||
return KB_KEY_UNKNOWN;
|
||||
@ -552,20 +590,22 @@ Key translate_key(unsigned int wParam, unsigned long lParam) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool mfb_set_viewport(unsigned offset_x, unsigned offset_y, unsigned width, unsigned height)
|
||||
bool mfb_set_viewport(struct Window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height)
|
||||
{
|
||||
if(offset_x + width > g_window_data.window_width) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
|
||||
if(offset_x + width > window_data->window_width) {
|
||||
return false;
|
||||
}
|
||||
if(offset_y + height > g_window_data.window_height) {
|
||||
if(offset_y + height > window_data->window_height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_window_data.dst_offset_x = offset_x;
|
||||
g_window_data.dst_offset_y = offset_y;
|
||||
window_data->dst_offset_x = offset_x;
|
||||
window_data->dst_offset_y = offset_y;
|
||||
|
||||
g_window_data.dst_width = width;
|
||||
g_window_data.dst_height = height;
|
||||
window_data->dst_width = width;
|
||||
window_data->dst_height = height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <MiniFB_enums.h>
|
||||
#include <stdint.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
HWND window;
|
||||
WNDCLASS s_wc;
|
||||
HDC s_hdc;
|
||||
BITMAPINFO *s_bitmapInfo;
|
||||
bool s_mouse_inside;
|
||||
|
||||
uint32_t window_width;
|
||||
uint32_t window_height;
|
||||
|
||||
uint32_t dst_offset_x;
|
||||
uint32_t dst_offset_y;
|
||||
uint32_t dst_width;
|
||||
uint32_t dst_height;
|
||||
|
||||
void *draw_buffer;
|
||||
uint32_t buffer_width;
|
||||
uint32_t buffer_height;
|
||||
|
||||
uint32_t mod_keys;
|
||||
bool close;
|
||||
} SWindowData;
|
15
src/windows/WindowData_Win.h
Normal file
15
src/windows/WindowData_Win.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <MiniFB_enums.h>
|
||||
#include <stdint.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
HWND window;
|
||||
WNDCLASS wc;
|
||||
HDC hdc;
|
||||
BITMAPINFO *bitmapInfo;
|
||||
bool mouse_inside;
|
||||
} SWindowData_Win;
|
@ -7,20 +7,6 @@
|
||||
|
||||
typedef struct {
|
||||
Window window;
|
||||
uint32_t window_width;
|
||||
uint32_t window_height;
|
||||
|
||||
uint32_t dst_offset_x;
|
||||
uint32_t dst_offset_y;
|
||||
uint32_t dst_width;
|
||||
uint32_t dst_height;
|
||||
|
||||
void *draw_buffer;
|
||||
uint32_t buffer_width;
|
||||
uint32_t buffer_height;
|
||||
|
||||
uint32_t mod_keys;
|
||||
bool close;
|
||||
|
||||
Display *display;
|
||||
int screen;
|
||||
@ -31,4 +17,4 @@ typedef struct {
|
||||
XImage *image_scaler;
|
||||
uint32_t image_scaler_width;
|
||||
uint32_t image_scaler_height;
|
||||
} SWindowData;
|
||||
} SWindowData_X11;
|
@ -4,41 +4,50 @@
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <MiniFB.h>
|
||||
#include <MiniFB_internal.h>
|
||||
#include "X11WindowData.h"
|
||||
#include "WindowData.h"
|
||||
#include "WindowData_X11.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SWindowData g_window_data = { 0 };
|
||||
|
||||
extern void
|
||||
stretch_image(uint32_t *srcImage, uint32_t srcX, uint32_t srcY, uint32_t srcWidth, uint32_t srcHeight, uint32_t srcPitch,
|
||||
uint32_t *dstImage, uint32_t dstX, uint32_t dstY, uint32_t dstWidth, uint32_t dstHeight, uint32_t dstPitch);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
struct Window *
|
||||
mfb_open_ex(const char *title, int width, int height, int flags) {
|
||||
int depth, i, formatCount, convDepth = -1;
|
||||
XPixmapFormatValues* formats;
|
||||
XSetWindowAttributes windowAttributes;
|
||||
XSizeHints sizeHints;
|
||||
Visual* visual;
|
||||
|
||||
g_window_data.display = XOpenDisplay(0);
|
||||
if (!g_window_data.display)
|
||||
return -1;
|
||||
SWindowData *window_data = (SWindowData *) malloc(sizeof(SWindowData));
|
||||
memset(window_data, 0, sizeof(SWindowData));
|
||||
|
||||
init_keycodes();
|
||||
SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) malloc(sizeof(SWindowData_X11));
|
||||
memset(window_data_x11, 0, sizeof(SWindowData_X11));
|
||||
window_data->specific = window_data_x11;
|
||||
|
||||
g_window_data.screen = DefaultScreen(g_window_data.display);
|
||||
window_data_x11->display = XOpenDisplay(0);
|
||||
if (!window_data_x11->display)
|
||||
return 0x0;
|
||||
|
||||
visual = DefaultVisual(g_window_data.display, g_window_data.screen);
|
||||
formats = XListPixmapFormats(g_window_data.display, &formatCount);
|
||||
depth = DefaultDepth(g_window_data.display, g_window_data.screen);
|
||||
init_keycodes(window_data_x11);
|
||||
|
||||
Window defaultRootWindow = DefaultRootWindow(g_window_data.display);
|
||||
window_data_x11->screen = DefaultScreen(window_data_x11->display);
|
||||
|
||||
visual = DefaultVisual(window_data_x11->display, window_data_x11->screen);
|
||||
formats = XListPixmapFormats(window_data_x11->display, &formatCount);
|
||||
depth = DefaultDepth(window_data_x11->display, window_data_x11->screen);
|
||||
|
||||
Window defaultRootWindow = DefaultRootWindow(window_data_x11->display);
|
||||
|
||||
for (i = 0; i < formatCount; ++i)
|
||||
{
|
||||
@ -54,28 +63,29 @@ int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
// We only support 32-bit right now
|
||||
if (convDepth != 32)
|
||||
{
|
||||
XCloseDisplay(g_window_data.display);
|
||||
return -1;
|
||||
XCloseDisplay(window_data_x11->display);
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
int screenWidth = DisplayWidth(g_window_data.display, g_window_data.screen);
|
||||
int screenHeight = DisplayHeight(g_window_data.display, g_window_data.screen);
|
||||
int screenWidth = DisplayWidth(window_data_x11->display, window_data_x11->screen);
|
||||
int screenHeight = DisplayHeight(window_data_x11->display, window_data_x11->screen);
|
||||
|
||||
windowAttributes.border_pixel = BlackPixel(g_window_data.display, g_window_data.screen);
|
||||
windowAttributes.background_pixel = BlackPixel(g_window_data.display, g_window_data.screen);
|
||||
windowAttributes.border_pixel = BlackPixel(window_data_x11->display, window_data_x11->screen);
|
||||
windowAttributes.background_pixel = BlackPixel(window_data_x11->display, window_data_x11->screen);
|
||||
windowAttributes.backing_store = NotUseful;
|
||||
|
||||
int posX, posY;
|
||||
int windowWidth, windowHeight;
|
||||
|
||||
g_window_data.window_width = width;
|
||||
g_window_data.window_height = height;
|
||||
g_window_data.buffer_width = width;
|
||||
g_window_data.buffer_height = height;
|
||||
g_window_data.dst_offset_x = 0;
|
||||
g_window_data.dst_offset_y = 0;
|
||||
g_window_data.dst_width = width;
|
||||
g_window_data.dst_height = height;
|
||||
window_data->window_width = width;
|
||||
window_data->window_height = height;
|
||||
window_data->buffer_width = width;
|
||||
window_data->buffer_height = height;
|
||||
window_data->buffer_stride = width * 4;
|
||||
window_data->dst_offset_x = 0;
|
||||
window_data->dst_offset_y = 0;
|
||||
window_data->dst_width = width;
|
||||
window_data->dst_height = height;
|
||||
|
||||
if (flags & WF_FULLSCREEN_DESKTOP) {
|
||||
posX = 0;
|
||||
@ -90,8 +100,8 @@ int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
windowHeight = height;
|
||||
}
|
||||
|
||||
g_window_data.window = XCreateWindow(
|
||||
g_window_data.display,
|
||||
window_data_x11->window = XCreateWindow(
|
||||
window_data_x11->display,
|
||||
defaultRootWindow,
|
||||
posX, posY,
|
||||
windowWidth, windowHeight,
|
||||
@ -101,10 +111,10 @@ int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
visual,
|
||||
CWBackPixel | CWBorderPixel | CWBackingStore,
|
||||
&windowAttributes);
|
||||
if (!g_window_data.window)
|
||||
return 0;
|
||||
if (!window_data_x11->window)
|
||||
return 0x0;
|
||||
|
||||
XSelectInput(g_window_data.display, g_window_data.window,
|
||||
XSelectInput(window_data_x11->display, window_data_x11->window,
|
||||
KeyPressMask | KeyReleaseMask
|
||||
| ButtonPressMask | ButtonReleaseMask | PointerMotionMask
|
||||
| StructureNotifyMask | ExposureMask
|
||||
@ -112,7 +122,7 @@ int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
| EnterWindowMask | LeaveWindowMask
|
||||
);
|
||||
|
||||
XStoreName(g_window_data.display, g_window_data.window, title);
|
||||
XStoreName(window_data_x11->display, window_data_x11->window, title);
|
||||
|
||||
if (flags & WF_BORDERLESS) {
|
||||
struct StyleHints {
|
||||
@ -128,18 +138,18 @@ int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
.inputMode = 0,
|
||||
.status = 0,
|
||||
};
|
||||
Atom sh_p = XInternAtom(g_window_data.display, "_MOTIF_WM_HINTS", True);
|
||||
XChangeProperty(g_window_data.display, g_window_data.window, sh_p, sh_p, 32, PropModeReplace, (unsigned char*)&sh, 5);
|
||||
Atom sh_p = XInternAtom(window_data_x11->display, "_MOTIF_WM_HINTS", True);
|
||||
XChangeProperty(window_data_x11->display, window_data_x11->window, sh_p, sh_p, 32, PropModeReplace, (unsigned char*)&sh, 5);
|
||||
}
|
||||
|
||||
if (flags & WF_ALWAYS_ON_TOP) {
|
||||
Atom sa_p = XInternAtom(g_window_data.display, "_NET_WM_STATE_ABOVE", False);
|
||||
XChangeProperty(g_window_data.display, g_window_data.window, XInternAtom(g_window_data.display, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *)&sa_p, 1);
|
||||
Atom sa_p = XInternAtom(window_data_x11->display, "_NET_WM_STATE_ABOVE", False);
|
||||
XChangeProperty(window_data_x11->display, window_data_x11->window, XInternAtom(window_data_x11->display, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *)&sa_p, 1);
|
||||
}
|
||||
|
||||
if (flags & WF_FULLSCREEN) {
|
||||
Atom sf_p = XInternAtom(g_window_data.display, "_NET_WM_STATE_FULLSCREEN", True);
|
||||
XChangeProperty(g_window_data.display, g_window_data.window, XInternAtom(g_window_data.display, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char*)&sf_p, 1);
|
||||
Atom sf_p = XInternAtom(window_data_x11->display, "_NET_WM_STATE_FULLSCREEN", True);
|
||||
XChangeProperty(window_data_x11->display, window_data_x11->window, XInternAtom(window_data_x11->display, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char*)&sf_p, 1);
|
||||
}
|
||||
|
||||
sizeHints.flags = PPosition | PMinSize | PMaxSize;
|
||||
@ -156,25 +166,24 @@ int mfb_open_ex(const char* title, int width, int height, int flags) {
|
||||
sizeHints.max_height = height;
|
||||
}
|
||||
|
||||
XSetWMNormalHints(g_window_data.display, g_window_data.window, &sizeHints);
|
||||
XClearWindow(g_window_data.display, g_window_data.window);
|
||||
XMapRaised(g_window_data.display, g_window_data.window);
|
||||
XFlush(g_window_data.display);
|
||||
XSetWMNormalHints(window_data_x11->display, window_data_x11->window, &sizeHints);
|
||||
XClearWindow(window_data_x11->display, window_data_x11->window);
|
||||
XMapRaised(window_data_x11->display, window_data_x11->window);
|
||||
XFlush(window_data_x11->display);
|
||||
|
||||
g_window_data.gc = DefaultGC(g_window_data.display, g_window_data.screen);
|
||||
window_data_x11->gc = DefaultGC(window_data_x11->display, window_data_x11->screen);
|
||||
|
||||
g_window_data.image = XCreateImage(g_window_data.display, CopyFromParent, depth, ZPixmap, 0, NULL, width, height, 32, width * 4);
|
||||
window_data_x11->image = XCreateImage(window_data_x11->display, CopyFromParent, depth, ZPixmap, 0, 0x0, width, height, 32, width * 4);
|
||||
|
||||
if (g_keyboard_func == 0x0) {
|
||||
mfb_keyboard_callback(keyboard_default);
|
||||
}
|
||||
mfb_keyboard_callback((struct Window *) window_data, keyboard_default);
|
||||
|
||||
printf("Window created using X11 API\n");
|
||||
|
||||
return 1;
|
||||
return (struct Window *) window_data;
|
||||
}
|
||||
|
||||
int mfb_open(const char* title, int width, int height)
|
||||
struct Window *
|
||||
mfb_open(const char *title, int width, int height)
|
||||
{
|
||||
return mfb_open_ex(title, width, height, 0);
|
||||
}
|
||||
@ -185,74 +194,75 @@ int translate_key(int scancode);
|
||||
int translate_mod(int state);
|
||||
int translate_mod_ex(int key, int state, int is_pressed);
|
||||
|
||||
static int processEvents()
|
||||
static void processEvents(SWindowData *window_data)
|
||||
{
|
||||
XEvent event;
|
||||
SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific;
|
||||
|
||||
while ((g_window_data.close == false) && XPending(g_window_data.display)) {
|
||||
XNextEvent(g_window_data.display, &event);
|
||||
while ((window_data->close == false) && XPending(window_data_x11->display)) {
|
||||
XNextEvent(window_data_x11->display, &event);
|
||||
|
||||
switch (event.type) {
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
{
|
||||
int kb_key = translate_key(event.xkey.keycode);
|
||||
Key kb_key = (Key) translate_key(event.xkey.keycode);
|
||||
int is_pressed = (event.type == KeyPress);
|
||||
g_window_data.mod_keys = translate_mod_ex(kb_key, event.xkey.state, is_pressed);
|
||||
window_data->mod_keys = translate_mod_ex(kb_key, event.xkey.state, is_pressed);
|
||||
|
||||
kCall(g_keyboard_func, kb_key, g_window_data.mod_keys, is_pressed);
|
||||
kCall(keyboard_func, kb_key, (KeyMod) window_data->mod_keys, is_pressed);
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
{
|
||||
MouseButton button = event.xbutton.button;
|
||||
MouseButton button = (MouseButton) event.xbutton.button;
|
||||
int is_pressed = (event.type == ButtonPress);
|
||||
g_window_data.mod_keys = translate_mod(event.xkey.state);
|
||||
window_data->mod_keys = translate_mod(event.xkey.state);
|
||||
switch (button) {
|
||||
case Button1:
|
||||
case Button2:
|
||||
case Button3:
|
||||
kCall(g_mouse_btn_func, button, g_window_data.mod_keys, is_pressed);
|
||||
kCall(mouse_btn_func, button, (KeyMod) window_data->mod_keys, is_pressed);
|
||||
break;
|
||||
|
||||
case Button4:
|
||||
kCall(g_mouse_wheel_func, g_window_data.mod_keys, 0.0f, 1.0f);
|
||||
kCall(mouse_wheel_func, (KeyMod) window_data->mod_keys, 0.0f, 1.0f);
|
||||
break;
|
||||
case Button5:
|
||||
kCall(g_mouse_wheel_func, g_window_data.mod_keys, 0.0f, -1.0f);
|
||||
kCall(mouse_wheel_func, (KeyMod) window_data->mod_keys, 0.0f, -1.0f);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
kCall(g_mouse_wheel_func, g_window_data.mod_keys, 1.0f, 0.0f);
|
||||
kCall(mouse_wheel_func, (KeyMod) window_data->mod_keys, 1.0f, 0.0f);
|
||||
break;
|
||||
case 7:
|
||||
kCall(g_mouse_wheel_func, g_window_data.mod_keys, -1.0f, 0.0f);
|
||||
kCall(mouse_wheel_func, (KeyMod) window_data->mod_keys, -1.0f, 0.0f);
|
||||
break;
|
||||
|
||||
default:
|
||||
kCall(g_mouse_btn_func, button - 4, g_window_data.mod_keys, is_pressed);
|
||||
kCall(mouse_btn_func, (MouseButton) (button - 4), (KeyMod) window_data->mod_keys, is_pressed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
kCall(g_mouse_move_func, event.xmotion.x, event.xmotion.y);
|
||||
kCall(mouse_move_func, event.xmotion.x, event.xmotion.y);
|
||||
break;
|
||||
|
||||
case ConfigureNotify:
|
||||
{
|
||||
g_window_data.window_width = event.xconfigure.width;
|
||||
g_window_data.window_height = event.xconfigure.height;
|
||||
g_window_data.dst_offset_x = 0;
|
||||
g_window_data.dst_offset_y = 0;
|
||||
g_window_data.dst_width = g_window_data.window_width;
|
||||
g_window_data.dst_height = g_window_data.window_height;
|
||||
window_data->window_width = event.xconfigure.width;
|
||||
window_data->window_height = event.xconfigure.height;
|
||||
window_data->dst_offset_x = 0;
|
||||
window_data->dst_offset_y = 0;
|
||||
window_data->dst_width = window_data->window_width;
|
||||
window_data->dst_height = window_data->window_height;
|
||||
|
||||
XClearWindow(g_window_data.display, g_window_data.window);
|
||||
kCall(g_resize_func, g_window_data.window_width, g_window_data.window_height);
|
||||
XClearWindow(window_data_x11->display, window_data_x11->window);
|
||||
kCall(resize_func, window_data->window_width, window_data->window_height);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -261,83 +271,95 @@ static int processEvents()
|
||||
break;
|
||||
|
||||
case FocusIn:
|
||||
kCall(g_active_func, true);
|
||||
kCall(active_func, true);
|
||||
break;
|
||||
|
||||
case FocusOut:
|
||||
kCall(g_active_func, false);
|
||||
kCall(active_func, false);
|
||||
break;
|
||||
|
||||
case DestroyNotify:
|
||||
return -1;
|
||||
window_data->close = true;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(g_window_data.close == true)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int mfb_update(void* buffer)
|
||||
void destroy(SWindowData *window_data);
|
||||
|
||||
UpdateState mfb_update(struct Window *window, void* buffer)
|
||||
{
|
||||
if (buffer == 0x0) {
|
||||
return -2;
|
||||
if(window == 0x0) {
|
||||
return STATE_INVALID_WINDOW;
|
||||
}
|
||||
|
||||
if (g_window_data.buffer_width != g_window_data.dst_width || g_window_data.buffer_height != g_window_data.dst_height) {
|
||||
if(g_window_data.image_scaler_width != g_window_data.dst_width || g_window_data.image_scaler_height != g_window_data.dst_height) {
|
||||
if(g_window_data.image_scaler != 0x0) {
|
||||
g_window_data.image_scaler->data = 0x0;
|
||||
XDestroyImage(g_window_data.image_scaler);
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
if(window_data->close) {
|
||||
destroy(window_data);
|
||||
return STATE_EXIT;
|
||||
}
|
||||
if(g_window_data.image_buffer != 0x0) {
|
||||
free(g_window_data.image_buffer);
|
||||
g_window_data.image_buffer = 0x0;
|
||||
|
||||
if(buffer == 0x0) {
|
||||
return STATE_INVALID_BUFFER;
|
||||
}
|
||||
int depth = DefaultDepth(g_window_data.display, g_window_data.screen);
|
||||
g_window_data.image_buffer = malloc(g_window_data.dst_width * g_window_data.dst_height * 4);
|
||||
g_window_data.image_scaler_width = g_window_data.dst_width;
|
||||
g_window_data.image_scaler_height = g_window_data.dst_height;
|
||||
g_window_data.image_scaler = XCreateImage(g_window_data.display, CopyFromParent, depth, ZPixmap, 0, NULL, g_window_data.image_scaler_width, g_window_data.image_scaler_height, 32, g_window_data.image_scaler_width * 4);
|
||||
|
||||
SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific;
|
||||
|
||||
if (window_data->buffer_width != window_data->dst_width || window_data->buffer_height != window_data->dst_height) {
|
||||
if(window_data_x11->image_scaler_width != window_data->dst_width || window_data_x11->image_scaler_height != window_data->dst_height) {
|
||||
if(window_data_x11->image_scaler != 0x0) {
|
||||
window_data_x11->image_scaler->data = 0x0;
|
||||
XDestroyImage(window_data_x11->image_scaler);
|
||||
}
|
||||
if(window_data_x11->image_buffer != 0x0) {
|
||||
free(window_data_x11->image_buffer);
|
||||
window_data_x11->image_buffer = 0x0;
|
||||
}
|
||||
int depth = DefaultDepth(window_data_x11->display, window_data_x11->screen);
|
||||
window_data_x11->image_buffer = malloc(window_data->dst_width * window_data->dst_height * 4);
|
||||
window_data_x11->image_scaler_width = window_data->dst_width;
|
||||
window_data_x11->image_scaler_height = window_data->dst_height;
|
||||
window_data_x11->image_scaler = XCreateImage(window_data_x11->display, CopyFromParent, depth, ZPixmap, 0, 0x0, window_data_x11->image_scaler_width, window_data_x11->image_scaler_height, 32, window_data_x11->image_scaler_width * 4);
|
||||
}
|
||||
}
|
||||
|
||||
if(g_window_data.image_scaler != 0x0) {
|
||||
stretch_image(buffer, 0, 0, g_window_data.buffer_width, g_window_data.buffer_height, g_window_data.buffer_width, g_window_data.image_buffer, 0, 0, g_window_data.dst_width, g_window_data.dst_height, g_window_data.dst_width);
|
||||
g_window_data.image_scaler->data = g_window_data.image_buffer;
|
||||
XPutImage(g_window_data.display, g_window_data.window, g_window_data.gc, g_window_data.image_scaler, 0, 0, g_window_data.dst_offset_x, g_window_data.dst_offset_y, g_window_data.dst_width, g_window_data.dst_height);
|
||||
if(window_data_x11->image_scaler != 0x0) {
|
||||
stretch_image((uint32_t *) buffer, 0, 0, window_data->buffer_width, window_data->buffer_height, window_data->buffer_width, (uint32_t *) window_data_x11->image_buffer, 0, 0, window_data->dst_width, window_data->dst_height, window_data->dst_width);
|
||||
window_data_x11->image_scaler->data = (char *) window_data_x11->image_buffer;
|
||||
XPutImage(window_data_x11->display, window_data_x11->window, window_data_x11->gc, window_data_x11->image_scaler, 0, 0, window_data->dst_offset_x, window_data->dst_offset_y, window_data->dst_width, window_data->dst_height);
|
||||
}
|
||||
else {
|
||||
g_window_data.image->data = (char *) buffer;
|
||||
XPutImage(g_window_data.display, g_window_data.window, g_window_data.gc, g_window_data.image, 0, 0, g_window_data.dst_offset_x, g_window_data.dst_offset_y, g_window_data.dst_width, g_window_data.dst_height);
|
||||
window_data_x11->image->data = (char *) buffer;
|
||||
XPutImage(window_data_x11->display, window_data_x11->window, window_data_x11->gc, window_data_x11->image, 0, 0, window_data->dst_offset_x, window_data->dst_offset_y, window_data->dst_width, window_data->dst_height);
|
||||
}
|
||||
XFlush(g_window_data.display);
|
||||
XFlush(window_data_x11->display);
|
||||
processEvents(window_data);
|
||||
|
||||
if (processEvents() < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return STATE_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void mfb_close(void)
|
||||
void destroy(SWindowData *window_data)
|
||||
{
|
||||
if(g_window_data.image != 0x0) {
|
||||
g_window_data.image->data = 0x0;
|
||||
XDestroyImage(g_window_data.image);
|
||||
XDestroyWindow(g_window_data.display, g_window_data.window);
|
||||
XCloseDisplay(g_window_data.display);
|
||||
|
||||
g_window_data.image = 0x0;
|
||||
g_window_data.display = 0x0;
|
||||
g_window_data.window = 0;
|
||||
if(window_data != 0x0) {
|
||||
if(window_data->specific != 0x0) {
|
||||
SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific;
|
||||
if(window_data_x11->image != 0x0) {
|
||||
window_data_x11->image->data = 0x0;
|
||||
XDestroyImage(window_data_x11->image);
|
||||
XDestroyWindow(window_data_x11->display, window_data_x11->window);
|
||||
XCloseDisplay(window_data_x11->display);
|
||||
}
|
||||
memset(window_data_x11, 0, sizeof(SWindowData_X11));
|
||||
free(window_data_x11);
|
||||
}
|
||||
memset(window_data, 0, sizeof(SWindowData));
|
||||
free(window_data);
|
||||
}
|
||||
g_window_data.close = true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -507,7 +529,7 @@ static int translateKeyCodeA(int keySym) {
|
||||
return KB_KEY_UNKNOWN;
|
||||
}
|
||||
|
||||
void init_keycodes() {
|
||||
void init_keycodes(SWindowData_X11 *window_data_x11) {
|
||||
size_t i;
|
||||
int keySym;
|
||||
|
||||
@ -518,10 +540,10 @@ void init_keycodes() {
|
||||
// Valid key code range is [8,255], according to the Xlib manual
|
||||
for(int i=8; i<=255; ++i) {
|
||||
// Try secondary keysym, for numeric keypad keys
|
||||
keySym = XkbKeycodeToKeysym(g_window_data.display, i, 0, 1);
|
||||
keySym = XkbKeycodeToKeysym(window_data_x11->display, i, 0, 1);
|
||||
keycodes[i] = translateKeyCodeB(keySym);
|
||||
if(keycodes[i] == KB_KEY_UNKNOWN) {
|
||||
keySym = XkbKeycodeToKeysym(g_window_data.display, i, 0, 0);
|
||||
keySym = XkbKeycodeToKeysym(window_data_x11->display, i, 0, 0);
|
||||
keycodes[i] = translateKeyCodeA(keySym);
|
||||
}
|
||||
}
|
||||
@ -604,29 +626,20 @@ int translate_mod_ex(int key, int state, int is_pressed) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void keyboard_default(void *user_data, Key key, KeyMod mod, bool isPressed) {
|
||||
kUnused(user_data);
|
||||
kUnused(mod);
|
||||
kUnused(isPressed);
|
||||
if (key == KB_KEY_ESCAPE) {
|
||||
g_window_data.close = true;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool mfb_set_viewport(unsigned offset_x, unsigned offset_y, unsigned width, unsigned height)
|
||||
bool mfb_set_viewport(struct Window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height)
|
||||
{
|
||||
if(offset_x + width > g_window_data.window_width) {
|
||||
SWindowData *window_data = (SWindowData *) window;
|
||||
|
||||
if(offset_x + width > window_data->window_width) {
|
||||
return false;
|
||||
}
|
||||
if(offset_y + height > g_window_data.window_height) {
|
||||
if(offset_y + height > window_data->window_height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_window_data.dst_offset_x = offset_x;
|
||||
g_window_data.dst_offset_y = offset_y;
|
||||
g_window_data.dst_width = width;
|
||||
g_window_data.dst_height = height;
|
||||
window_data->dst_offset_x = offset_x;
|
||||
window_data->dst_offset_y = offset_y;
|
||||
window_data->dst_width = width;
|
||||
window_data->dst_height = height;
|
||||
return true;
|
||||
}
|
||||
|
310
tests/noise.c
310
tests/noise.c
@ -4,63 +4,140 @@
|
||||
|
||||
#define kUnused(var) (void) var;
|
||||
|
||||
#define WIDTH 800
|
||||
#define HEIGHT 600
|
||||
static unsigned int s_buffer[WIDTH * HEIGHT];
|
||||
#define WIDTH_A 800
|
||||
#define HEIGHT_A 600
|
||||
static unsigned int g_buffer1[WIDTH_A * HEIGHT_A];
|
||||
|
||||
#define WIDTH_B 240
|
||||
#define HEIGHT_B 120
|
||||
static unsigned int g_buffer2[WIDTH_B * HEIGHT_B];
|
||||
|
||||
//-------------------------------------
|
||||
// C interface
|
||||
//-------------------------------------
|
||||
void active(void *user_data, bool isActive) {
|
||||
kUnused(user_data);
|
||||
fprintf(stdout, "active: %d\n", isActive);
|
||||
void active(struct Window *window, bool isActive) {
|
||||
int id = 0;
|
||||
if(window) {
|
||||
id = *(int *) mfb_get_user_data(window);
|
||||
}
|
||||
fprintf(stdout, "active %d: %d\n", id, isActive);
|
||||
}
|
||||
|
||||
void resize(void *user_data, int width, int height) {
|
||||
void resize(struct Window *window, int width, int height) {
|
||||
uint32_t x = 0;
|
||||
uint32_t y = 0;
|
||||
int id = 0;
|
||||
if(window) {
|
||||
id = *(int *) mfb_get_user_data(window);
|
||||
}
|
||||
|
||||
fprintf(stdout, "resize %d: %d, %d\n", id, width, height);
|
||||
if(width > WIDTH_A) {
|
||||
x = (width - WIDTH_A) >> 1;
|
||||
width = WIDTH_A;
|
||||
}
|
||||
if(height > HEIGHT_A) {
|
||||
y = (height - HEIGHT_A) >> 1;
|
||||
height = HEIGHT_A;
|
||||
}
|
||||
mfb_set_viewport(window, x, y, width, height);
|
||||
}
|
||||
|
||||
void keyboard(struct Window *window, Key key, KeyMod mod, bool isPressed) {
|
||||
int id = 0;
|
||||
if(window) {
|
||||
id = *(int *) mfb_get_user_data(window);
|
||||
}
|
||||
fprintf(stdout, "keyboard %d: key: %s (pressed: %d) [KeyMod: %x]\n", id, mfb_get_key_name(key), isPressed, mod);
|
||||
if(key == KB_KEY_ESCAPE) {
|
||||
mfb_close(window);
|
||||
}
|
||||
}
|
||||
|
||||
void char_input(struct Window *window, unsigned int charCode) {
|
||||
int id = 0;
|
||||
if(window) {
|
||||
id = *(int *) mfb_get_user_data(window);
|
||||
}
|
||||
fprintf(stdout, "charCode %d: %d\n", id, charCode);
|
||||
}
|
||||
|
||||
void mouse_btn(struct Window *window, MouseButton button, KeyMod mod, bool isPressed) {
|
||||
int id = 0;
|
||||
if(window) {
|
||||
id = *(int *) mfb_get_user_data(window);
|
||||
}
|
||||
fprintf(stdout, "mouse_btn %d: button: %d (pressed: %d) [KeyMod: %x]\n", id, button, isPressed, mod);
|
||||
}
|
||||
|
||||
void mouse_move(struct Window *window, int x, int y) {
|
||||
kUnused(window);
|
||||
kUnused(x);
|
||||
kUnused(y);
|
||||
// int id = 0;
|
||||
// if(window) {
|
||||
// id = *(int *) mfb_get_user_data(window);
|
||||
// }
|
||||
//fprintf(stdout, "mouse_move %d: %d, %d\n", id, x, y);
|
||||
}
|
||||
|
||||
void mouse_scroll(struct Window *window, KeyMod mod, float deltaX, float deltaY) {
|
||||
int id = 0;
|
||||
if(window) {
|
||||
id = *(int *) mfb_get_user_data(window);
|
||||
}
|
||||
fprintf(stdout, "mouse_scroll %d: x: %f, y: %f [KeyMod: %x]\n", id, deltaX, deltaY, mod);
|
||||
}
|
||||
|
||||
//--
|
||||
void active2(struct Window *window, bool isActive) {
|
||||
kUnused(window);
|
||||
fprintf(stdout, "active 2: %d\n", isActive);
|
||||
}
|
||||
|
||||
void resize2(struct Window *window, int width, int height) {
|
||||
uint32_t x = 0;
|
||||
uint32_t y = 0;
|
||||
|
||||
kUnused(user_data);
|
||||
fprintf(stdout, "resize: %d, %d\n", width, height);
|
||||
if(width > WIDTH) {
|
||||
x = (width - WIDTH) >> 1;
|
||||
width = WIDTH;
|
||||
fprintf(stdout, "resize 2: %d, %d\n", width, height);
|
||||
if(width > WIDTH_A) {
|
||||
x = (width - WIDTH_A) >> 1;
|
||||
width = WIDTH_A;
|
||||
}
|
||||
if(height > HEIGHT) {
|
||||
y = (height - HEIGHT) >> 1;
|
||||
height = HEIGHT;
|
||||
if(height > HEIGHT_A) {
|
||||
y = (height - HEIGHT_A) >> 1;
|
||||
height = HEIGHT_A;
|
||||
}
|
||||
mfb_set_viewport(x, y, width, height);
|
||||
mfb_set_viewport(window, x, y, width, height);
|
||||
}
|
||||
|
||||
void keyboard(void *user_data, Key key, KeyMod mod, bool isPressed) {
|
||||
kUnused(user_data);
|
||||
fprintf(stdout, "keyboard: key: %s (pressed: %d) [KeyMod: %x]\n", mfb_get_key_name(key), isPressed, mod);
|
||||
void keyboard2(struct Window *window, Key key, KeyMod mod, bool isPressed) {
|
||||
fprintf(stdout, "keyboard 2: key: %s (pressed: %d) [KeyMod: %x]\n", mfb_get_key_name(key), isPressed, mod);
|
||||
if(key == KB_KEY_ESCAPE) {
|
||||
mfb_close();
|
||||
mfb_close(window);
|
||||
}
|
||||
}
|
||||
|
||||
void char_input(void *user_data, unsigned int charCode) {
|
||||
kUnused(user_data);
|
||||
fprintf(stdout, "charCode: %d\n", charCode);
|
||||
void char_input2(struct Window *window, unsigned int charCode) {
|
||||
kUnused(window);
|
||||
fprintf(stdout, "charCode 2: %d\n", charCode);
|
||||
}
|
||||
|
||||
void mouse_btn(void *user_data, MouseButton button, KeyMod mod, bool isPressed) {
|
||||
kUnused(user_data);
|
||||
fprintf(stdout, "mouse_btn: button: %d (pressed: %d) [KeyMod: %x]\n", button, isPressed, mod);
|
||||
void mouse_btn2(struct Window *window, MouseButton button, KeyMod mod, bool isPressed) {
|
||||
kUnused(window);
|
||||
fprintf(stdout, "mouse_btn 2: button: %d (pressed: %d) [KeyMod: %x]\n", button, isPressed, mod);
|
||||
}
|
||||
|
||||
void mouse_move(void *user_data, int x, int y) {
|
||||
kUnused(user_data);
|
||||
void mouse_move2(struct Window *window, int x, int y) {
|
||||
kUnused(window);
|
||||
kUnused(x);
|
||||
kUnused(y);
|
||||
//fprintf(stdout, "mouse_move: %d, %d\n", x, y);
|
||||
}
|
||||
|
||||
void mouse_scroll(void *user_data, KeyMod mod, float deltaX, float deltaY) {
|
||||
kUnused(user_data);
|
||||
fprintf(stdout, "mouse_scroll: x: %f, y: %f [KeyMod: %x]\n", deltaX, deltaY, mod);
|
||||
void mouse_scroll2(struct Window *window, KeyMod mod, float deltaX, float deltaY) {
|
||||
kUnused(window);
|
||||
fprintf(stdout, "mouse_scroll 2: x: %f, y: %f [KeyMod: %x]\n", deltaX, deltaY, mod);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
@ -70,32 +147,77 @@ void mouse_scroll(void *user_data, KeyMod mod, float deltaX, float deltaY) {
|
||||
|
||||
class Events {
|
||||
public:
|
||||
void active(void *user_data, bool isActive) {
|
||||
::active(user_data, isActive);
|
||||
void active(struct Window *window, bool isActive) {
|
||||
printf("\nEvents 1 - ");
|
||||
::active(window, isActive);
|
||||
}
|
||||
|
||||
void resize(void *user_data, int width, int height) {
|
||||
::resize(user_data, width, height);
|
||||
void resize(struct Window *window, int width, int height) {
|
||||
printf("Events 1 - ");
|
||||
::resize(window, width, height);
|
||||
}
|
||||
|
||||
void keyboard(void *user_data, Key key, KeyMod mod, bool isPressed) {
|
||||
::keyboard(user_data, key, mod, isPressed);
|
||||
void keyboard(struct Window *window, Key key, KeyMod mod, bool isPressed) {
|
||||
printf("Events 1 - ");
|
||||
::keyboard(window, key, mod, isPressed);
|
||||
}
|
||||
|
||||
void char_input(void *user_data, unsigned int charCode) {
|
||||
::char_input(user_data, charCode);
|
||||
void char_input(struct Window *window, unsigned int charCode) {
|
||||
printf("Events 1 - ");
|
||||
::char_input(window, charCode);
|
||||
}
|
||||
|
||||
void mouse_btn(void *user_data, MouseButton button, KeyMod mod, bool isPressed) {
|
||||
::mouse_btn(user_data, button, mod, isPressed);
|
||||
void mouse_btn(struct Window *window, MouseButton button, KeyMod mod, bool isPressed) {
|
||||
printf("Events 1 - ");
|
||||
::mouse_btn(window, button, mod, isPressed);
|
||||
}
|
||||
|
||||
void mouse_move(void *user_data, int x, int y) {
|
||||
::mouse_move(user_data, x, y);
|
||||
void mouse_move(struct Window *window, int x, int y) {
|
||||
//printf("Events 1 - ");
|
||||
::mouse_move(window, x, y);
|
||||
}
|
||||
|
||||
void mouse_scroll(void *user_data, KeyMod mod, float deltaX, float deltaY) {
|
||||
::mouse_scroll(user_data, mod, deltaX, deltaY);
|
||||
void mouse_scroll(struct Window *window, KeyMod mod, float deltaX, float deltaY) {
|
||||
printf("Events 1 - ");
|
||||
::mouse_scroll(window, mod, deltaX, deltaY);
|
||||
}
|
||||
};
|
||||
|
||||
class Events2 {
|
||||
public:
|
||||
void active(struct Window *window, bool isActive) {
|
||||
printf("\nEvents 2 - ");
|
||||
::active(window, isActive);
|
||||
}
|
||||
|
||||
void resize(struct Window *window, int width, int height) {
|
||||
printf("Events 2 - ");
|
||||
::resize(window, width, height);
|
||||
}
|
||||
|
||||
void keyboard(struct Window *window, Key key, KeyMod mod, bool isPressed) {
|
||||
printf("Events 2 - ");
|
||||
::keyboard(window, key, mod, isPressed);
|
||||
}
|
||||
|
||||
void char_input(struct Window *window, unsigned int charCode) {
|
||||
printf("Events 2 - ");
|
||||
::char_input(window, charCode);
|
||||
}
|
||||
|
||||
void mouse_btn(struct Window *window, MouseButton button, KeyMod mod, bool isPressed) {
|
||||
printf("Events 2 - ");
|
||||
::mouse_btn(window, button, mod, isPressed);
|
||||
}
|
||||
|
||||
void mouse_move(struct Window *window, int x, int y) {
|
||||
//printf("Events 2 - ");
|
||||
::mouse_move(window, x, y);
|
||||
}
|
||||
|
||||
void mouse_scroll(struct Window *window, KeyMod mod, float deltaX, float deltaY) {
|
||||
printf("Events 2 - ");
|
||||
::mouse_scroll(window, mod, deltaX, deltaY);
|
||||
}
|
||||
};
|
||||
|
||||
@ -106,39 +228,75 @@ public:
|
||||
int main()
|
||||
{
|
||||
int noise, carry, seed = 0xbeef;
|
||||
int id1 = 1, id2 = 2;
|
||||
|
||||
struct Window *window1 = mfb_open_ex("Noise Test", WIDTH_A, HEIGHT_A, WF_RESIZABLE);
|
||||
if (!window1)
|
||||
return 0;
|
||||
|
||||
mfb_set_user_data(window1, &id1);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
Events e;
|
||||
|
||||
mfb_active_callback(&e, &Events::active);
|
||||
mfb_resize_callback(&e, &Events::resize);
|
||||
mfb_keyboard_callback(&e, &Events::keyboard);
|
||||
mfb_char_input_callback(&e, &Events::char_input);
|
||||
mfb_mouse_button_callback(&e, &Events::mouse_btn);
|
||||
mfb_mouse_move_callback(&e, &Events::mouse_move);
|
||||
mfb_mouse_scroll_callback(&e, &Events::mouse_scroll);
|
||||
mfb_active_callback(window1, &e, &Events::active);
|
||||
mfb_resize_callback(window1, &e, &Events::resize);
|
||||
mfb_keyboard_callback(window1, &e, &Events::keyboard);
|
||||
mfb_char_input_callback(window1, &e, &Events::char_input);
|
||||
mfb_mouse_button_callback(window1, &e, &Events::mouse_btn);
|
||||
mfb_mouse_move_callback(window1, &e, &Events::mouse_move);
|
||||
mfb_mouse_scroll_callback(window1, &e, &Events::mouse_scroll);
|
||||
|
||||
#else
|
||||
|
||||
mfb_active_callback(active);
|
||||
mfb_resize_callback(resize);
|
||||
mfb_keyboard_callback(keyboard);
|
||||
mfb_char_input_callback(char_input);
|
||||
mfb_mouse_button_callback(mouse_btn);
|
||||
mfb_mouse_move_callback(mouse_move);
|
||||
mfb_mouse_scroll_callback(mouse_scroll);
|
||||
mfb_active_callback(window1, active);
|
||||
mfb_resize_callback(window1, resize);
|
||||
mfb_keyboard_callback(window1, keyboard);
|
||||
mfb_char_input_callback(window1, char_input);
|
||||
mfb_mouse_button_callback(window1, mouse_btn);
|
||||
mfb_mouse_move_callback(window1, mouse_move);
|
||||
mfb_mouse_scroll_callback(window1, mouse_scroll);
|
||||
|
||||
#endif
|
||||
|
||||
if (!mfb_open_ex("Noise Test", WIDTH, HEIGHT, WF_RESIZABLE))
|
||||
struct Window *window2 = mfb_open_ex("Noise Test", WIDTH_B, HEIGHT_B, WF_RESIZABLE);
|
||||
if (!window2)
|
||||
return 0;
|
||||
|
||||
mfb_set_user_data(window2, &id2);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
Events2 e2;
|
||||
|
||||
mfb_active_callback(window2, &e2, &Events2::active);
|
||||
mfb_resize_callback(window2, &e2, &Events::resize);
|
||||
mfb_keyboard_callback(window2, &e2, &Events::keyboard);
|
||||
mfb_char_input_callback(window2, &e2, &Events::char_input);
|
||||
mfb_mouse_button_callback(window2, &e2, &Events::mouse_btn);
|
||||
mfb_mouse_move_callback(window2, &e2, &Events::mouse_move);
|
||||
mfb_mouse_scroll_callback(window2, &e2, &Events::mouse_scroll);
|
||||
|
||||
#else
|
||||
|
||||
mfb_active_callback(window2, active2);
|
||||
mfb_resize_callback(window2, resize2);
|
||||
mfb_keyboard_callback(window2, keyboard2);
|
||||
mfb_char_input_callback(window2, char_input2);
|
||||
mfb_mouse_button_callback(window2, mouse_btn2);
|
||||
mfb_mouse_move_callback(window2, mouse_move2);
|
||||
mfb_mouse_scroll_callback(window2, mouse_scroll2);
|
||||
|
||||
#endif
|
||||
mfb_keyboard_callback(window2, 0x0);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int i, state;
|
||||
int i;
|
||||
UpdateState state1, state2;
|
||||
|
||||
for (i = 0; i < WIDTH * HEIGHT; ++i)
|
||||
for (i = 0; i < WIDTH_A * HEIGHT_A; ++i)
|
||||
{
|
||||
noise = seed;
|
||||
noise >>= 3;
|
||||
@ -148,16 +306,36 @@ int main()
|
||||
seed >>= 1;
|
||||
seed |= (carry << 30);
|
||||
noise &= 0xFF;
|
||||
s_buffer[i] = MFB_RGB(noise, noise, noise);
|
||||
g_buffer1[i] = MFB_RGB(noise, noise, noise);
|
||||
}
|
||||
|
||||
state = mfb_update(s_buffer);
|
||||
for (i = 0; i < WIDTH_B * HEIGHT_B; ++i)
|
||||
{
|
||||
noise = seed;
|
||||
noise >>= 3;
|
||||
noise ^= seed;
|
||||
carry = noise & 1;
|
||||
noise >>= 1;
|
||||
seed >>= 1;
|
||||
seed |= (carry << 30);
|
||||
noise &= 0xFF;
|
||||
g_buffer2[i] = MFB_RGB(noise, (~noise) & 0xff, 255 - noise);
|
||||
}
|
||||
|
||||
if (state < 0)
|
||||
state1 = mfb_update(window1, g_buffer1);
|
||||
state2 = mfb_update(window2, g_buffer2);
|
||||
if (state1 != STATE_OK) {
|
||||
window1 = 0x0;
|
||||
}
|
||||
if (state2 != STATE_OK) {
|
||||
window2 = 0x0;
|
||||
}
|
||||
if (state1 != STATE_OK && state2 != STATE_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mfb_close();
|
||||
mfb_close(window1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user