summaryrefslogtreecommitdiffstats
path: root/tools/platform
diff options
context:
space:
mode:
Diffstat (limited to 'tools/platform')
-rw-r--r--tools/platform/gui.cpp3
-rw-r--r--tools/platform/linux/x11-key-code.cpp247
-rw-r--r--tools/platform/linux/x11-window.cpp474
-rw-r--r--tools/platform/placeholder/placeholder-window.cpp33
-rw-r--r--tools/platform/window.h60
-rw-r--r--tools/platform/windows/win-window.cpp2
6 files changed, 800 insertions, 19 deletions
diff --git a/tools/platform/gui.cpp b/tools/platform/gui.cpp
index 5c210f460..f2f9561d5 100644
--- a/tools/platform/gui.cpp
+++ b/tools/platform/gui.cpp
@@ -34,7 +34,6 @@ LRESULT CALLBACK guiWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam
return handled;
}
-void setNativeWindowHook(Window* window, WNDPROC proc);
#endif
@@ -51,8 +50,6 @@ GUI::GUI(
#ifdef _WIN32
ImGui_ImplWin32_Init((HWND)window->getNativeHandle().handleValues[0]);
-
- setNativeWindowHook(window, &guiWindowProc);
#endif
// Let's do the initialization work required for our graphics API
diff --git a/tools/platform/linux/x11-key-code.cpp b/tools/platform/linux/x11-key-code.cpp
new file mode 100644
index 000000000..ce4e8945c
--- /dev/null
+++ b/tools/platform/linux/x11-key-code.cpp
@@ -0,0 +1,247 @@
+#if defined(SLANG_ENABLE_XLIB)
+
+#include "core/slang-basic.h"
+#include "../window.h"
+#include <X11/keysym.h>
+#include <X11/Xlib.h>
+
+#ifdef None
+#undef None
+#endif
+
+// Translates X11 key code values to Win32 Virtual Key values
+
+using namespace Slang;
+
+namespace platform
+{
+ Dictionary<int, KeyCode> keyCodeMap;
+
+ struct Win32KeyCode
+ {
+ KeyCode vKeyCode;
+ int keySym;
+ };
+
+ Win32KeyCode keys[] =
+ {
+ {KeyCode::Left, XK_Left},
+ {KeyCode::Up, XK_Up},
+ {KeyCode::Down, XK_Down},
+ {KeyCode::Right, XK_Right},
+ {KeyCode::Escape, XK_Escape},
+ {KeyCode::Return, XK_Return},
+ {KeyCode::Space, XK_space},
+ {KeyCode::Shift, XK_Shift_L},
+ {KeyCode::Shift, XK_Shift_R},
+ {KeyCode::Ctrl, XK_Control_L},
+ {KeyCode::Ctrl, XK_Control_R},
+ {KeyCode::Alt, XK_Alt_L},
+ {KeyCode::Alt, XK_Alt_R},
+ {KeyCode::Backspace, XK_BackSpace},
+ {KeyCode::Delete, XK_Delete},
+ {KeyCode::Home, XK_Home},
+ {KeyCode::End, XK_End},
+ {KeyCode::PageUp, XK_Page_Up},
+ {KeyCode::PageDown, XK_Page_Down},
+ {KeyCode::Insert, XK_Insert},
+ {KeyCode::Tab, XK_Tab},
+ {KeyCode::A, 0x41},
+ {KeyCode::B, 0x42},
+ {KeyCode::C, 0x43},
+ {KeyCode::D, 0x44},
+ {KeyCode::E, 0x45},
+ {KeyCode::F, 0x46},
+ {KeyCode::G, 0x47},
+ {KeyCode::H, 0x48},
+ {KeyCode::I, 0x49},
+ {KeyCode::J, 0x4A},
+ {KeyCode::K, 0x4B},
+ {KeyCode::L, 0x4C},
+ {KeyCode::M, 0x4D},
+ {KeyCode::N, 0x4E},
+ {KeyCode::O, 0x4F},
+ {KeyCode::P, 0x50},
+ {KeyCode::Q, 0x51},
+ {KeyCode::R, 0x52},
+ {KeyCode::S, 0x53},
+ {KeyCode::T, 0x54},
+ {KeyCode::U, 0x55},
+ {KeyCode::V, 0x56},
+ {KeyCode::W, 0x57},
+ {KeyCode::X, 0x58},
+ {KeyCode::Y, 0x59},
+ {KeyCode::Z, 0x5A},
+ {KeyCode::Semicolon, XK_semicolon},
+ {KeyCode::Comma, XK_comma},
+ {KeyCode::Dot, XK_period},
+ {KeyCode::Slash, XK_slash},
+ {KeyCode::Quote, XK_apostrophe},
+ {KeyCode::LBracket, XK_bracketleft},
+ {KeyCode::RBracket, XK_bracketright},
+ {KeyCode::Backslash, XK_backslash},
+ {KeyCode::Minus, XK_minus},
+ {KeyCode::Plus, XK_equal},
+ {KeyCode::Tilde, XK_asciitilde},
+ {KeyCode::Key0, 0x30},
+ {KeyCode::Key1, 0x31},
+ {KeyCode::Key2, 0x32},
+ {KeyCode::Key3, 0x33},
+ {KeyCode::Key4, 0x34},
+ {KeyCode::Key5, 0x35},
+ {KeyCode::Key6, 0x36},
+ {KeyCode::Key7, 0x37},
+ {KeyCode::Key8, 0x38},
+ {KeyCode::Key9, 0x39},
+ {KeyCode::F1, XK_F1},
+ {KeyCode::F2, XK_F2},
+ {KeyCode::F3, XK_F3},
+ {KeyCode::F4, XK_F4},
+ {KeyCode::F5, XK_F5},
+ {KeyCode::F6, XK_F6},
+ {KeyCode::F7, XK_F7},
+ {KeyCode::F8, XK_F8},
+ {KeyCode::F9, XK_F9},
+ {KeyCode::F10, XK_F10},
+ {KeyCode::F11, XK_F11},
+ {KeyCode::F12, XK_F12}
+ };
+
+ void initKeyCodeTranslationTable(Display* display)
+ {
+ for (auto entry : keys)
+ {
+ auto systemKeyCode = XKeysymToKeycode(display, entry.keySym);
+ keyCodeMap[systemKeyCode] = entry.vKeyCode;
+ }
+ }
+
+ void freeKeyCodeTranslationTable()
+ {
+ keyCodeMap = decltype(keyCodeMap)();
+ }
+
+ KeyCode translateKeyCode(int keyCode)
+ {
+ KeyCode result = KeyCode::None;
+ keyCodeMap.TryGetValue(keyCode, result);
+ return result;
+ }
+
+ int getKeyChar(KeyCode keyCode, int keyState)
+ {
+ bool shift = (keyState & ShiftMask) != 0;
+ if (keyCode >= KeyCode::A && keyCode <= KeyCode::Z )
+ {
+ bool capslock = (keyState & LockMask) != 0;
+ bool isCapital = capslock ^ shift;
+ if (isCapital)
+ return (int)keyCode;
+ else
+ return (int)keyCode + ('a'-'A');
+ }
+ else if (keyCode == KeyCode::Space)
+ {
+ return ' ';
+ }
+ else if (keyCode == KeyCode::Return)
+ {
+ return (int)keyCode;
+ }
+ else if (keyCode >= KeyCode::Key0 && keyCode <= KeyCode::Key9)
+ {
+ if (!shift)
+ return (int)keyCode;
+ else
+ {
+ switch (keyCode)
+ {
+ case KeyCode::Key0:
+ return ')';
+ case KeyCode::Key1:
+ return '!';
+ case KeyCode::Key2:
+ return '@';
+ case KeyCode::Key3:
+ return '#';
+ case KeyCode::Key4:
+ return '$';
+ case KeyCode::Key5:
+ return '%';
+ case KeyCode::Key6:
+ return '^';
+ case KeyCode::Key7:
+ return '&';
+ case KeyCode::Key8:
+ return '*';
+ case KeyCode::Key9:
+ return '(';
+ default:
+ return 0;
+ }
+ }
+ }
+ if (shift)
+ {
+ switch (keyCode)
+ {
+ case KeyCode::Semicolon:
+ return ':';
+ case KeyCode::Comma:
+ return '<';
+ case KeyCode::Dot:
+ return '>';
+ case KeyCode::Slash:
+ return '?';
+ case KeyCode::Quote:
+ return '\"';
+ case KeyCode::LBracket:
+ return '{';
+ case KeyCode::RBracket:
+ return '}';
+ case KeyCode::Backslash:
+ return '|';
+ case KeyCode::Minus:
+ return '_';
+ case KeyCode::Plus:
+ return '+';
+ case KeyCode::Tilde:
+ return '~';
+ default:
+ return 0;
+ }
+ }
+ else
+ {
+ switch (keyCode)
+ {
+ case KeyCode::Semicolon:
+ return ';';
+ case KeyCode::Comma:
+ return ',';
+ case KeyCode::Dot:
+ return '.';
+ case KeyCode::Slash:
+ return '/';
+ case KeyCode::Quote:
+ return '\'';
+ case KeyCode::LBracket:
+ return '[';
+ case KeyCode::RBracket:
+ return ']';
+ case KeyCode::Backslash:
+ return '\\';
+ case KeyCode::Minus:
+ return '-';
+ case KeyCode::Plus:
+ return '=';
+ case KeyCode::Tilde:
+ return '`';
+ default:
+ return 0;
+ }
+ }
+ }
+} // namespace platform
+
+#endif
diff --git a/tools/platform/linux/x11-window.cpp b/tools/platform/linux/x11-window.cpp
new file mode 100644
index 000000000..2721c00f3
--- /dev/null
+++ b/tools/platform/linux/x11-window.cpp
@@ -0,0 +1,474 @@
+#ifdef SLANG_ENABLE_XLIB
+
+#include "../window.h"
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+
+#ifdef None
+#undef None
+#endif
+
+#include "core/slang-basic.h"
+
+using namespace Slang;
+
+namespace platform
+{
+typedef ::Window X11WindowHandle;
+class X11PlatformWindow;
+
+void initKeyCodeTranslationTable(Display *display);
+void freeKeyCodeTranslationTable();
+KeyCode translateKeyCode(int keyCode);
+int getKeyChar(KeyCode keyCode, int keyState);
+
+const int kKeyStateTableSize = 256;
+
+enum class KeyState
+{
+ Released,
+ Pressed,
+ Hold
+};
+
+enum class KeyEvent
+{
+ Press, Release
+};
+
+enum class MouseEvent
+{
+ Move, Down, Up, Scroll
+};
+
+class X11AppContext
+{
+public:
+ static bool isTerminated;
+ static RefPtr<Window> mainWindow;
+ static OrderedDictionary<X11WindowHandle, X11PlatformWindow*> windows;
+ static X11WindowHandle mainWindowHandle;
+ static Display* xdisplay;
+ static KeyState keyStates[kKeyStateTableSize];
+ static X11PlatformWindow *currentMouseEventWindow;
+};
+
+bool X11AppContext::isTerminated = false;
+RefPtr<Window> X11AppContext::mainWindow;
+OrderedDictionary<X11WindowHandle, X11PlatformWindow*> X11AppContext::windows;
+X11WindowHandle X11AppContext::mainWindowHandle;
+Display* X11AppContext::xdisplay = nullptr;
+KeyState X11AppContext::keyStates[kKeyStateTableSize] = {};
+X11PlatformWindow* X11AppContext::currentMouseEventWindow = nullptr;
+
+void Application::init()
+{
+
+}
+
+static void doEventsImpl(bool waitForEvents);
+
+void Application::doEvents() { doEventsImpl(false); }
+
+void Application::quit() { X11AppContext::isTerminated = true; }
+
+void Application::dispose()
+{
+ X11AppContext::mainWindow = nullptr;
+ X11AppContext::windows = decltype(X11AppContext::windows)();
+ freeKeyCodeTranslationTable();
+}
+
+void Application::run(Window* mainWindow, bool waitForEvents)
+{
+ if (mainWindow)
+ {
+ X11AppContext::mainWindow = mainWindow;
+ X11AppContext::mainWindowHandle = (X11WindowHandle)mainWindow->getNativeHandle().handleValues[1];
+ mainWindow->show();
+ while (!X11AppContext::isTerminated)
+ {
+ doEventsImpl(waitForEvents);
+ if (!X11AppContext::isTerminated)
+ mainWindow->events.mainLoop();
+ }
+ }
+}
+
+class X11PlatformWindow : public Window
+{
+public:
+ X11WindowHandle handle;
+ bool visible = false;
+ int currentWidth = 0;
+ int currentHeight = 0;
+ bool fixedSized = false;
+ X11PlatformWindow(const WindowDesc &desc)
+ {
+ currentWidth = desc.width;
+ currentHeight = desc.height;
+
+ int blackColor = BlackPixel(X11AppContext::xdisplay, DefaultScreen(X11AppContext::xdisplay));
+ int whiteColor = WhitePixel(X11AppContext::xdisplay, DefaultScreen(X11AppContext::xdisplay));
+ handle = XCreateSimpleWindow(X11AppContext::xdisplay, DefaultRootWindow(X11AppContext::xdisplay), 0, 0,
+ desc.width, desc.height, 0, blackColor, blackColor);
+ X11AppContext::windows[handle] = this;
+ Atom wmDelete = XInternAtom(X11AppContext::xdisplay, "WM_DELETE_WINDOW", True);
+ XSetWMProtocols(X11AppContext::xdisplay, handle, &wmDelete, 1);
+ XSelectInput(X11AppContext::xdisplay, handle, StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
+ ButtonPressMask | ButtonReleaseMask | ExposureMask | FocusChangeMask);
+
+ if (desc.style == WindowStyle::FixedSize)
+ {
+ fixedSized = true;
+ setFixedSizeHint(desc.width, desc.height);
+ }
+ setText(desc.title);
+ }
+
+ ~X11PlatformWindow()
+ {
+ close();
+ }
+
+ void setFixedSizeHint(int w, int h)
+ {
+ auto sizeHints = XAllocSizeHints();
+ sizeHints->flags = PMinSize | PMaxSize;
+ sizeHints->min_width = sizeHints->max_width = w;
+ sizeHints->min_height = sizeHints->max_height = h;
+ XSetWMNormalHints(X11AppContext::xdisplay, handle, sizeHints);
+ XFree(sizeHints);
+ }
+
+ virtual void setClientSize(uint32_t width, uint32_t height) override
+ {
+ if (fixedSized)
+ setFixedSizeHint(width, height);
+ XResizeWindow(X11AppContext::xdisplay, handle, width, height);
+ handleResizeEvent(width, height);
+ }
+
+ virtual Rect getClientRect() override
+ {
+ Rect rect = {};
+ if (!handle)
+ return rect;
+ X11WindowHandle winRoot = 0, winParent = 0;
+ X11WindowHandle* winChildren = nullptr;
+ unsigned int numChilren = 0;
+ XQueryTree(X11AppContext::xdisplay, handle, &winRoot, &winParent, &winChildren, &numChilren);
+ unsigned borderWidth, depth;
+ XGetGeometry(X11AppContext::xdisplay, handle, &winRoot, &rect.x, &rect.y, (uint32_t*)&rect.width, (uint32_t*)&rect.height, &borderWidth, &depth);
+ return rect;
+ }
+
+ virtual void centerScreen() override
+ {
+ auto currentRect = getClientRect();
+ XWindowAttributes attributes;
+ XGetWindowAttributes(X11AppContext::xdisplay, handle, &attributes);
+ int screenWidth = WidthOfScreen(attributes.screen);
+ int screenHeight = HeightOfScreen(attributes.screen);
+ int x = (screenWidth - currentRect.width) / 2;
+ int y = (screenHeight - currentRect.height) / 2;
+ XMoveWindow(X11AppContext::xdisplay, handle, x, y);
+ }
+ virtual void close() override
+ {
+ if (handle)
+ {
+ X11AppContext::windows.Remove(handle);
+ XDestroyWindow(X11AppContext::xdisplay, handle);
+ handle = 0;
+ }
+ }
+ virtual bool getFocused() override
+ {
+ if (!handle) return false;
+ int revertTo;
+ X11WindowHandle focusedWindow;
+ XGetInputFocus(X11AppContext::xdisplay, &focusedWindow, &revertTo);
+ return focusedWindow == handle;
+ }
+ virtual WindowHandle getNativeHandle() override
+ {
+ WindowHandle rs;
+ rs.type = WindowHandle::Type::XLibHandle;
+ rs.handleValues[0] = (intptr_t)X11AppContext::xdisplay;
+ rs.handleValues[1] = (intptr_t)handle;
+ return rs;
+ }
+ virtual void setText(String text) override
+ {
+ if (!handle) return;
+ XStoreName(X11AppContext::xdisplay, handle, text.getBuffer());
+ XClassHint* hint = XAllocClassHint();
+ hint->res_class = (char *)"Slang platform window";
+ hint->res_name = (char *)"Slang platform window";
+ XSetClassHint(X11AppContext::xdisplay, handle, hint);
+ XFree(hint);
+ }
+ virtual bool getVisible() override
+ {
+ return visible;
+ }
+ virtual void show() override
+ {
+ XMapWindow(X11AppContext::xdisplay, handle);
+ visible = true;
+ }
+ virtual void hide() override
+ {
+ if (!handle) return;
+ XUnmapWindow(X11AppContext::xdisplay, handle);
+ visible = false;
+ }
+ virtual int getCurrentDpi() override
+ {
+ char *resourceString = XResourceManagerString(X11AppContext::xdisplay);
+ XrmDatabase db;
+ XrmValue value;
+ char *type = NULL;
+ double dpi = 96.0;
+ db = XrmGetStringDatabase(resourceString);
+ if (resourceString)
+ {
+ if (XrmGetResource(db, "Xft.dpi", "String", &type, &value))
+ {
+ if (value.addr)
+ {
+ dpi = atof(value.addr);
+ }
+ }
+ }
+ return (int)dpi;
+ }
+ void handleResizeEvent(int w, int h)
+ {
+ if (w != currentWidth || h != currentHeight)
+ {
+ currentWidth = w;
+ currentHeight = h;
+ events.sizeChanged();
+ }
+ }
+
+ static void addButtonState(ButtonState::Enum& state, ButtonState::Enum newState)
+ {
+ state = ButtonState::Enum((int)state | (int)newState);
+ }
+
+ ButtonState::Enum getButtonState(int state)
+ {
+ ButtonState::Enum buttonState = ButtonState::Enum::None;
+ if (state & ShiftMask) addButtonState(buttonState, ButtonState::Enum::Shift);
+ if (state & ControlMask) addButtonState(buttonState, ButtonState::Enum::Control);
+ if (state & Mod1Mask) addButtonState(buttonState, ButtonState::Enum::Alt);
+ if (state & Button1Mask) addButtonState(buttonState, ButtonState::Enum::LeftButton);
+ if (state & Button2Mask) addButtonState(buttonState, ButtonState::Enum::MiddleButton);
+ if (state & Button3Mask) addButtonState(buttonState, ButtonState::Enum::RightButton);
+ return buttonState;
+ }
+
+ void handleKeyEvent(KeyEvent eventType, KeyCode keyCode, int keyChar, int state)
+ {
+ KeyEventArgs e;
+ e.buttons = getButtonState(state);
+ e.cancelEvent = false;
+ e.key = keyCode;
+ e.keyChar = keyChar;
+ if (eventType == KeyEvent::Press)
+ {
+ events.keyDown(e);
+ if (keyChar)
+ events.keyPress(e);
+ }
+ else
+ {
+ events.keyUp(e);
+ }
+ }
+
+ void handleMouseEvent(MouseEvent eventType, int x, int y, int delta, int button, int state, unsigned long time)
+ {
+ auto buttonState = getButtonState(state);
+ if (button == Button1)
+ addButtonState(buttonState, ButtonState::Enum::LeftButton);
+ else if (button == Button2)
+ addButtonState(buttonState, ButtonState::Enum::MiddleButton);
+ else if (button == Button3)
+ addButtonState(buttonState, ButtonState::Enum::RightButton);
+ MouseEventArgs e;
+ e.buttons = buttonState;
+ e.delta = delta;
+ e.x = x;
+ e.y = y;
+
+ switch (eventType)
+ {
+ case MouseEvent::Down:
+ events.mouseDown(e);
+ break;
+ case MouseEvent::Up:
+ events.mouseUp(e);
+ break;
+ case MouseEvent::Move:
+ events.mouseMove(e);
+ break;
+ case MouseEvent::Scroll:
+ events.mouseWheel(e);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void handleCloseEvent()
+ {
+ hide();
+ if (X11AppContext::mainWindowHandle == handle)
+ Application::quit();
+ }
+
+ void handleExposeEvent()
+ {
+ }
+
+ void handleFocus(bool focus)
+ {
+ }
+
+};
+
+Window* Application::createWindow(const WindowDesc& desc)
+{
+ if (!X11AppContext::xdisplay)
+ {
+ XInitThreads();
+ XrmInitialize();
+ X11AppContext::xdisplay = XOpenDisplay(nullptr);
+ initKeyCodeTranslationTable(X11AppContext::xdisplay);
+ if (!X11AppContext::xdisplay)
+ printf("Failed to open XDisplay.\n");
+ }
+ return new X11PlatformWindow(desc);
+}
+
+void doEventsImpl(bool waitForEvents)
+{
+ auto xdisplay = X11AppContext::xdisplay;
+ if (!X11AppContext::xdisplay)
+ return;
+
+ static bool supressInvokeTasks = false;
+ X11PlatformWindow* sysWindow = nullptr;
+ KeyCode vKeyCode = KeyCode::None;
+ int iKeyCode = 0;
+ while (XPending(xdisplay))
+ {
+ XEvent nextEvent;
+ XNextEvent(xdisplay, &nextEvent);
+ switch (nextEvent.type)
+ {
+ case KeyPress:
+ vKeyCode = translateKeyCode(nextEvent.xkey.keycode);
+ iKeyCode = (int)vKeyCode;
+ if (iKeyCode < kKeyStateTableSize)
+ {
+ if (X11AppContext::keyStates[iKeyCode] == KeyState::Released)
+ X11AppContext::keyStates[iKeyCode] = KeyState::Pressed;
+ else if (X11AppContext::keyStates[iKeyCode] == KeyState::Pressed)
+ X11AppContext::keyStates[iKeyCode] = KeyState::Hold;
+ }
+ if (X11AppContext::windows.TryGetValue(nextEvent.xkey.window, sysWindow))
+ {
+ wchar_t keyChar = getKeyChar(vKeyCode, nextEvent.xkey.state);
+ sysWindow->handleKeyEvent(KeyEvent::Press, vKeyCode, keyChar, nextEvent.xkey.state);
+ }
+ break;
+ case KeyRelease:
+ vKeyCode = translateKeyCode(nextEvent.xkey.keycode);
+ iKeyCode = (int)vKeyCode;
+ if (iKeyCode < kKeyStateTableSize)
+ {
+ X11AppContext::keyStates[iKeyCode] = KeyState::Released;
+ }
+ if (X11AppContext::windows.TryGetValue(nextEvent.xkey.window, sysWindow))
+ {
+ sysWindow->handleKeyEvent(KeyEvent::Release, vKeyCode, 0, nextEvent.xkey.state);
+ }
+ break;
+ case MotionNotify:
+ if (X11AppContext::windows.TryGetValue(nextEvent.xmotion.window, sysWindow))
+ {
+ X11AppContext::currentMouseEventWindow = sysWindow;
+ sysWindow->handleMouseEvent(MouseEvent::Move, nextEvent.xmotion.x, nextEvent.xmotion.y, 0,
+ 0, nextEvent.xmotion.state, nextEvent.xmotion.time);
+ }
+ break;
+ case ButtonPress:
+ if (X11AppContext::windows.TryGetValue(nextEvent.xbutton.window, sysWindow))
+ {
+ X11AppContext::currentMouseEventWindow = sysWindow;
+ if (nextEvent.xbutton.button <= Button3)
+ sysWindow->handleMouseEvent(MouseEvent::Down, nextEvent.xbutton.x, nextEvent.xbutton.y, 0,
+ nextEvent.xbutton.button, nextEvent.xbutton.state, nextEvent.xbutton.time);
+ else if (nextEvent.xbutton.button == Button4)
+ sysWindow->handleMouseEvent(MouseEvent::Scroll, nextEvent.xbutton.x, nextEvent.xbutton.y, 120,
+ nextEvent.xbutton.button, nextEvent.xbutton.state, nextEvent.xbutton.time);
+ else if (nextEvent.xbutton.button == Button5)
+ sysWindow->handleMouseEvent(MouseEvent::Scroll, nextEvent.xbutton.x, nextEvent.xbutton.y, -120,
+ nextEvent.xbutton.button, nextEvent.xbutton.state, nextEvent.xbutton.time);
+ }
+ break;
+ case ButtonRelease:
+ if (X11AppContext::windows.TryGetValue(nextEvent.xbutton.window, sysWindow))
+ {
+ X11AppContext::currentMouseEventWindow = sysWindow;
+ sysWindow->handleMouseEvent(MouseEvent::Up, nextEvent.xbutton.x, nextEvent.xbutton.y, 0,
+ nextEvent.xbutton.button, nextEvent.xbutton.state, nextEvent.xbutton.time);
+ }
+ break;
+ case ConfigureNotify:
+ if (X11AppContext::windows.TryGetValue(nextEvent.xconfigure.window, sysWindow))
+ {
+ sysWindow->handleResizeEvent(nextEvent.xconfigure.width, nextEvent.xconfigure.height);
+ }
+ break;
+ case Expose:
+ if (X11AppContext::windows.TryGetValue(nextEvent.xexpose.window, sysWindow))
+ {
+ sysWindow->handleExposeEvent();
+ }
+ break;
+ case ClientMessage:
+ if (X11AppContext::windows.TryGetValue(nextEvent.xclient.window, sysWindow))
+ {
+ Atom wmDelete = XInternAtom(X11AppContext::xdisplay, "WM_DELETE_WINDOW", True);
+ if (nextEvent.xclient.data.l[0] == wmDelete)
+ {
+ sysWindow->handleCloseEvent();
+ }
+ }
+ break;
+ case FocusIn:
+ if (X11AppContext::windows.TryGetValue(nextEvent.xfocus.window, sysWindow))
+ {
+ sysWindow->handleFocus(true);
+ }
+ break;
+ case FocusOut:
+ if (X11AppContext::windows.TryGetValue(nextEvent.xfocus.window, sysWindow))
+ {
+ sysWindow->handleFocus(false);
+ }
+ break;
+ }
+ }
+}
+
+}
+
+#endif
diff --git a/tools/platform/placeholder/placeholder-window.cpp b/tools/platform/placeholder/placeholder-window.cpp
new file mode 100644
index 000000000..a94287d55
--- /dev/null
+++ b/tools/platform/placeholder/placeholder-window.cpp
@@ -0,0 +1,33 @@
+#if !defined(_WIN32) && !defined(SLANG_ENABLE_XLIB)
+
+#include "../window.h"
+
+using namespace Slang;
+
+namespace platform
+{
+
+void Application::init()
+{
+}
+
+void Application::doEvents() { }
+
+void Application::quit() { }
+
+void Application::dispose()
+{
+}
+
+void Application::run(Window* mainWindow, bool waitForEvents)
+{
+ SLANG_UNUSED(mainWindow);
+ SLANG_UNUSED(waitForEvents);
+}
+
+Window* Application::createWindow(const WindowDesc& desc) { return nullptr; }
+
+
+} // namespace platform
+
+#endif
diff --git a/tools/platform/window.h b/tools/platform/window.h
index e4a867f0b..884f28b0d 100644
--- a/tools/platform/window.h
+++ b/tools/platform/window.h
@@ -5,6 +5,25 @@
#include "source/core/slang-basic.h"
#include "source/core/slang-func-ptr.h"
+#if defined(SLANG_PLATFORM_DYNAMIC)
+# if defined(_MSC_VER)
+# ifdef SLANG_PLATFORM_DYNAMIC_EXPORT
+# define SLANG_PLATFORM_API SLANG_DLL_EXPORT
+# else
+# define SLANG_PLATFORM_API __declspec(dllimport)
+# endif
+# else
+// TODO: need to consider compiler capabilities
+//# ifdef SLANG_DYNAMIC_EXPORT
+# define SLANG_PLATFORM_API SLANG_DLL_EXPORT
+//# endif
+# endif
+#endif
+
+#ifndef SLANG_PLATFORM_API
+# define SLANG_PLATFORM_API
+#endif
+
namespace platform {
enum class KeyCode : uint32_t
@@ -99,14 +118,14 @@ struct WindowHandle
};
Type type;
intptr_t handleValues[2];
- static WindowHandle FromHwnd(void* hwnd)
+ static WindowHandle fromHwnd(void* hwnd)
{
WindowHandle handle = {};
handle.type = WindowHandle::Type::Win32Handle;
handle.handleValues[0] = (intptr_t)(hwnd);
return handle;
}
- static WindowHandle FromXWindow(void* xdisplay, uint32_t xwindow)
+ static WindowHandle fromXWindow(void* xdisplay, uint32_t xwindow)
{
WindowHandle handle = {};
handle.type = WindowHandle::Type::XLibHandle;
@@ -114,6 +133,15 @@ struct WindowHandle
handle.handleValues[1] = xwindow;
return handle;
}
+ template<typename T>
+ T convert()
+ {
+ T result;
+ result.type = (decltype(result.type))type;
+ result.handleValues[0] = handleValues[0];
+ result.handleValues[1] = handleValues[1];
+ return result;
+ }
};
struct ButtonState
@@ -174,6 +202,7 @@ public:
Slang::Action<MouseEventArgs> mouseMove;
Slang::Action<MouseEventArgs> mouseUp;
Slang::Action<MouseEventArgs> mouseDown;
+ Slang::Action<MouseEventArgs> mouseWheel;
};
Events events;
@@ -194,12 +223,12 @@ public:
class Application
{
public:
- static Window* createWindow(const WindowDesc& desc);
- static void init();
- static void run(Window* mainWindow, bool waitForEvents = false);
- static void quit();
- static void doEvents();
- static void dispose();
+ static SLANG_PLATFORM_API Window* createWindow(const WindowDesc& desc);
+ static SLANG_PLATFORM_API void init();
+ static SLANG_PLATFORM_API void run(Window* mainWindow, bool waitForEvents = false);
+ static SLANG_PLATFORM_API void quit();
+ static SLANG_PLATFORM_API void doEvents();
+ static SLANG_PLATFORM_API void dispose();
};
} // namespace platform
@@ -230,12 +259,13 @@ public:
#else
-# define PLATFORM_UI_MAIN(APPLICATION_ENTRY) \
- int main() \
- { \
- platform::Application::init(); \
- auto rs - APPLICATION_ENTRY(); \
- platform::Application::dispose(); \
- }
+#define PLATFORM_UI_MAIN(APPLICATION_ENTRY) \
+ int main() \
+ { \
+ platform::Application::init(); \
+ auto rs = APPLICATION_ENTRY(); \
+ platform::Application::dispose(); \
+ return rs; \
+ }
#endif
diff --git a/tools/platform/windows/win-window.cpp b/tools/platform/windows/win-window.cpp
index 8822a6393..0d80eda7b 100644
--- a/tools/platform/windows/win-window.cpp
+++ b/tools/platform/windows/win-window.cpp
@@ -406,7 +406,7 @@ public:
virtual bool getVisible() override { return visible; }
virtual WindowHandle getNativeHandle() override
{
- return WindowHandle::FromHwnd(handle);
+ return WindowHandle::fromHwnd(handle);
}
virtual void setText(Slang::String text) override
{