diff --git a/OpenTK/Platform/X11/X11Window.cs b/OpenTK/Platform/X11/X11Window.cs index fa533575d..46204dfbe 100644 --- a/OpenTK/Platform/X11/X11Window.cs +++ b/OpenTK/Platform/X11/X11Window.cs @@ -40,19 +40,17 @@ namespace OpenTK.Platform.X11 { // TODO: What happens if we can't disable decorations through motif? // TODO: Mouse/keyboard grabbing/wrapping. - const int _min_width = 30, _min_height = 30; - IntPtr wm_destroy; - IntPtr net_wm_state; + IntPtr wm_destroy, net_wm_state; IntPtr net_wm_state_minimized; IntPtr net_wm_state_fullscreen; IntPtr net_wm_state_maximized_horizontal; - IntPtr net_wm_state_maximized_vertical; - + IntPtr net_wm_state_maximized_vertical; IntPtr net_wm_icon, net_frame_extents; - IntPtr xa_clipboard, xa_targets, xa_utf8_string, xa_atom, xa_data_sel; + IntPtr xa_clipboard, xa_targets, xa_utf8_string, xa_data_sel; string clipboard_paste_text, clipboard_copy_text; + static readonly IntPtr xa_atom = (IntPtr)4; static readonly IntPtr xa_cardinal = (IntPtr)6; static readonly IntPtr _remove = (IntPtr)0; static readonly IntPtr _add = (IntPtr)1; @@ -88,8 +86,6 @@ namespace OpenTK.Platform.X11 { Debug.Print("Opening render window... "); XSetWindowAttributes attributes = new XSetWindowAttributes(); - attributes.background_pixel = IntPtr.Zero; - attributes.border_pixel = IntPtr.Zero; attributes.colormap = API.XCreateColormap(API.DefaultDisplay, API.RootWindow, VisualInfo.Visual, 0/*AllocNone*/); eventMask = EventMask.StructureNotifyMask /*| EventMask.SubstructureNotifyMask*/ | EventMask.ExposureMask | @@ -155,7 +151,6 @@ namespace OpenTK.Platform.X11 { xa_clipboard = API.XInternAtom(display, "CLIPBOARD", false); xa_targets = API.XInternAtom(display, "TARGETS", false); xa_utf8_string = API.XInternAtom(display, "UTF8_STRING", false); - xa_atom = API.XInternAtom(display, "ATOM", false); xa_data_sel = API.XInternAtom(display, "CS_SEL_DATA", false); } diff --git a/src/Client/Game.c b/src/Client/Game.c index 370c54462..c53dc03fa 100644 --- a/src/Client/Game.c +++ b/src/Client/Game.c @@ -755,8 +755,9 @@ Stopwatch game_renderTimer; void Game_Run(Int32 width, Int32 height, STRING_REF String* title, struct DisplayDevice* device) { Int32 x = device->Bounds.X + (device->Bounds.Width - width) / 2; Int32 y = device->Bounds.Y + (device->Bounds.Height - height) / 2; + struct GraphicsMode mode = GraphicsMode_MakeDefault(); - Window_Create(x, y, width, height, title, device); + Window_Create(x, y, width, height, title, &mode, device); Window_SetVisible(true); Game_Load(); Event_RaiseVoid(&WindowEvents_Resized); diff --git a/src/Client/WinWindow.c b/src/Client/WinWindow.c index ee0e08c2a..9d8eb5da9 100644 --- a/src/Client/WinWindow.c +++ b/src/Client/WinWindow.c @@ -388,7 +388,8 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara } -void Window_Create(Int32 x, Int32 y, Int32 width, Int32 height, STRING_REF String* title, struct DisplayDevice* device) { +void Window_Create(Int32 x, Int32 y, Int32 width, Int32 height, STRING_REF String* title, + struct GraphicsMode* mode, struct DisplayDevice* device) { win_Instance = GetModuleHandleA(NULL); /* TODO: UngroupFromTaskbar(); */ diff --git a/src/Client/Window.h b/src/Client/Window.h index 801ecb2e5..8fa130012 100644 --- a/src/Client/Window.h +++ b/src/Client/Window.h @@ -38,7 +38,8 @@ #define WINDOW_STATE_MAXIMISED 2 #define WINDOW_STATE_FULLSCREEN 3 -void Window_Create(Int32 x, Int32 y, Int32 width, Int32 height, STRING_REF String* title, struct DisplayDevice* device); +void Window_Create(Int32 x, Int32 y, Int32 width, Int32 height, STRING_REF String* title, + struct GraphicsMode* mode, struct DisplayDevice* device); void Window_GetClipboardText(STRING_TRANSIENT String* value); void Window_SetClipboardText(STRING_PURE String* value); /* TODO: IMPLEMENT void Window_SetIcon(Bitmap* bmp); */ diff --git a/src/Client/X11Window.c b/src/Client/X11Window.c index 5d379c481..1033b51b8 100644 --- a/src/Client/X11Window.c +++ b/src/Client/X11Window.c @@ -11,6 +11,10 @@ #include #include +#define _NET_WM_STATE_REMOVE 0 +#define _NET_WM_STATE_ADD 1 +#define _NET_WM_STATE_TOGGLE 2 + /* TODO: Move to Platform code */ Display* win_display; Window win_rootWin; @@ -19,8 +23,20 @@ int win_screen; Window win_handle; XVisualInfo win_visual; Int32 borderLeft, borderRight, borderTop, borderBottom; +bool win_isExiting; + +Atom wm_destroy, net_wm_state; +Atom net_wm_state_minimized; +Atom net_wm_state_fullscreen; +Atom net_wm_state_maximized_horizontal; +Atom net_wm_state_maximized_vertical; +Atom net_wm_icon, net_frame_extents; -static Key Window_MapKey(int key) { +Atom xa_clipboard, xa_targets, xa_utf8_string, xa_data_sel; +Atom xa_atom = 4, xa_cardinal = 6; +long win_eventMask; + +static Key Window_MapKey(KeySym key) { if (key >= XK_F1 && key <= XK_F35) { return Key_F1 + (key - XK_F1); } if (key >= XK_0 && key <= XK_9) { return Key_0 + (key - XK_0); } if (key >= XK_A && key <= XK_Z) { return Key_A + (key - XK_A); } @@ -114,7 +130,79 @@ static Key Window_MapKey(int key) { return Key_None; } -void Window_Create(Int32 x, Int32 y, Int32 width, Int32 height, STRING_REF String* title, struct DisplayDevice* device); +void Window_RegisterAtoms(void) { + Display* display = win_display; + wm_destroy = XInternAtom(display, "WM_DELETE_WINDOW", true); + net_wm_state = XInternAtom(display, "_NET_WM_STATE", false); + net_wm_state_minimized = XInternAtom(display, "_NET_WM_STATE_MINIMIZED", false); + net_wm_state_fullscreen = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", false); + net_wm_state_maximized_horizontal = XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", false); + net_wm_state_maximized_vertical = XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", false); + net_wm_icon = XInternAtom(display, "_NEW_WM_ICON", false); + net_frame_extents = XInternAtom(display, "_NET_FRAME_EXTENTS", false); + + xa_clipboard = XInternAtom(display, "CLIPBOARD", false); + xa_targets = XInternAtom(display, "TARGETS", false); + xa_utf8_string = XInternAtom(display, "UTF8_STRING", false); + xa_data_sel = XInternAtom(display, "CS_SEL_DATA", false); +} + +static XVisualInfo GLContext_SelectVisual(struct GraphicsMode* mode); +void Window_Create(Int32 x, Int32 y, Int32 width, Int32 height, STRING_REF String* title, + struct GraphicsMode* mode, struct DisplayDevice* device) { + /* Open a display connection to the X server, and obtain the screen and root window */ + UInt64 addr = (UInt64)win_display; + Platform_Log3("Display: %y, Screen %i, Root window: %y", &addr, &win_screen, &win_rootWin); + + Window_RegisterAtoms(); + win_visual = GLContext_SelectVisual(mode); + Platform_LogConst("Opening render window... "); + + XSetWindowAttributes attributes = { 0 }; + attributes.colormap = XCreateColormap(win_display, win_rootWin, win_visual.visual, AllocNone); + + win_eventMask = StructureNotifyMask /*| SubstructureNotifyMask*/ | ExposureMask | + KeyReleaseMask | KeyPressMask | KeymapStateMask | PointerMotionMask | + FocusChangeMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | + LeaveWindowMask | PropertyChangeMask; + attributes.event_mask = win_eventMask; + + long mask = CWColormap | CWEventMask | CWBackPixel | CWBorderPixel; + win_handle = XCreateWindow(win_display, win_rootWin, x, y, width, height, + 0, win_visual.depth /* CopyFromParent*/, InputOutput, win_visual.visual, mask, &attributes); + + if (win_handle == NULL) ErrorHandler_Fail("XCreateWindow call failed"); + if (title->length > 0) { + XStoreName(win_display, win_handle, title->buffer); + } + + XSizeHints hints = { 0 }; + hints.base_width = width; + hints.base_height = height; + hints.flags = PSize | PPosition; + XSetWMNormalHints(win_display, win_handle, &hints); + + /* Register for window destroy notification */ + Atom atoms[1] = { wm_destroy }; + XSetWMProtocols(win_display, win_handle, atoms, 1); + + /* Set the initial window size to ensure X, Y, Width, Height and the rest + return the correct values inside the constructor and the Load event. */ + XEvent e = { 0 }; + e.xconfigure.x = x; + e.xconfigure.y = y; + e.xconfigure.width = width; + e.xconfigure.height = height; + Window_RefreshBounds(&e); + + /* Request that auto-repeat is only set on devices that support it physically. + This typically means that it's turned off for keyboards (which is what we want). + We prefer this method over XAutoRepeatOff/On, because the latter needs to + be reset before the program exits. */ + bool supported; + XkbSetDetectableAutoRepeat(win_display, true, &supported); + Window_Exists = true; +} UChar clipboard_copy_buffer[String_BufferSize(256)]; String clipboard_copy_text = String_FromEmptyArray(clipboard_copy_buffer); @@ -174,7 +262,7 @@ UInt8 Window_GetWindowState(void) { Int32 maximised = 0, i; /* TODO: Check this works right */ - if (items > 0 && prop != NULL) { + if (items > 0 && data != NULL) { for (i = 0; i < items; i++) { Atom atom = data[i]; @@ -187,7 +275,7 @@ UInt8 Window_GetWindowState(void) { fullscreen = true; } } - XFree(prop); + XFree(data); } if (minimised) return WINDOW_STATE_MINIMISED; @@ -198,16 +286,16 @@ UInt8 Window_GetWindowState(void) { void Window_SendNetWMState(long op, Atom a1, Atom a2) { XEvent ev = { 0 }; - ev.ClientMessageEvent.type = ClientMessage; - ev.ClientMessageEvent.send_event = true; - ev.ClientMessageEvent.window = win_handle; - ev.ClientMessageEvent.message_type = net_wm_state; - ev.ClientMessageEvent.format = 32; - ev.ClientMessageEvent.l[0] = op; - ev.ClientMessageEvent.l[1] = a1; - ev.ClientMessageEvent.l[2] = a2; + ev.xclient.type = ClientMessage; + ev.xclient.send_event = true; + ev.xclient.window = win_handle; + ev.xclient.message_type = net_wm_state; + ev.xclient.format = 32; + ev.xclient.data.l[0] = op; + ev.xclient.data.l[1] = a1; + ev.xclient.data.l[2] = a2; - XSendEvent(win_display, win_rootWindow, false, + XSendEvent(win_display, win_rootWin, false, SubstructureRedirectMask | SubstructureNotifyMask, &ev); } @@ -280,29 +368,78 @@ void Window_SetClientSize(struct Size2D size) { void Window_Close(void) { XEvent ev = { 0 }; ev.type = ClientMessage; - ev.ClientMessageEvent.format = 32; - ev.ClientMessageEvent.display = win_display; - ev.ClientMessageEvent.window = win_handle; - ev.ClientMessageEvent.l[0] = wm_destroy; + ev.xclient.format = 32; + ev.xclient.display = win_display; + ev.xclient.window = win_handle; + ev.xclient.data.l[0] = wm_destroy; XSendEvent(win_display, win_handle, false, 0, &ev); XFlush(win_display); } -bool Window_GetPendingEvent(XEvent* e) { - return XCheckWindowEvent(win_display, win_handle, eventMask, e) || - XCheckTypedWindowEvent(win_display, win_handle, ClientMessage, e) || - XCheckTypedWindowEvent(win_display, win_handle, SelectionNotify, e) || - XCheckTypedWindowEvent(win_display, win_handle, SelectionRequest, e); +void Window_RefreshBorders(void) { + Atom prop_type; + int prop_format; + long items, bytes_after; + long* borders = NULL; + + XGetWindowProperty(win_display, win_handle, net_frame_extents, 0, 16, false, + xa_cardinal, &prop_type, &prop_format, &items, &bytes_after, &borders); + + if (borders == NULL) return; + if (items == 4) { + borderLeft = borders[0]; borderRight = borders[1]; + borderTop = borders[2]; borderBottom = borders[3]; + } + XFree(borders); } +void Window_RefreshBounds(XEvent* e) { + Window_RefreshBorders(); + + struct Point2D curLoc = Window_GetLocation(); + struct Point2D loc = { e->xconfigure.x - borderLeft, e->xconfigure.y - borderTop }; + if (loc.X != curLoc.X || loc.Y != curLoc.Y) { + Window_Bounds.X = loc.X; Window_Bounds.Y = loc.Y; + Event_RaiseVoid(&WindowEvents_Moved); + } + + /* Note: width and height denote the internal (client) size. + To get the external (window) size, we need to add the border size. */ + struct Size2D curSize = Window_GetSize(); + struct Size2D size = { + e->xconfigure.width + borderLeft + borderRight, + e->xconfigure.height + borderTop + borderBottom }; + + if (curSize.Width != size.Width || curSize.Height != size.Height) { + Window_Bounds.Width = size.Width; Window_Bounds.Height = size.Height; + Window_ClientSize = Size2D_Make(e->xconfigure.width, e->xconfigure.height); + Event_RaiseVoid(&WindowEvents_Resized); + } +} + +void Window_ToggleKey(XKeyEvent* keyEvent, bool pressed) { + KeySym keysym1 = XLookupKeysym(keyEvent, 0); + KeySym keysym2 = XLookupKeysym(keyEvent, 1); + + Key key = Window_MapKey(keysym1); + if (key == Key_None) key = Window_MapKey(keysym2); + if (key != Key_None) Keyboard_Set(key, pressed); +} Atom Window_GetSelectionProperty(XEvent* e) { - Atom property = e.SelectionRequestEvent.property; + Atom property = e->xselectionrequest.property; if (property != NULL) return property; /* For obsolete clients. See ICCCM spec, selections chapter for reasoning. */ - return e.SelectionRequestEvent.target; + return e->xselectionrequest.target; +} + +bool Window_GetPendingEvent(XEvent* e) { + return XCheckWindowEvent(win_display, win_handle, win_eventMask, e) || + XCheckTypedWindowEvent(win_display, win_handle, ClientMessage, e) || + XCheckTypedWindowEvent(win_display, win_handle, SelectionNotify, e) || + XCheckTypedWindowEvent(win_display, win_handle, SelectionRequest, e); } void Window_ProcessEvents(void) { @@ -322,11 +459,11 @@ void Window_ProcessEvents(void) { } break; case ClientMessage: - if (!isExiting && e.ClientMessageEvent.l[0] == wm_destroy) { + if (!win_isExiting && e.xclient.data.l[0] == wm_destroy) { Platform_LogConst("Exit message received."); RaiseClosing(); - isExiting = true; + win_isExiting = true; Window_Destroy(); RaiseClosed(); } break; @@ -342,44 +479,46 @@ void Window_ProcessEvents(void) { case KeyPress: { - ToggleKey(&e.KeyEvent, true); - int status = XLookupString(&e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero); - Encoding.Default.GetChars(ascii, 0, status, chars, 0); + ToggleKey(&e.xkey, true); + UInt8 data[16]; + int status = XLookupString(&e.xkey, data, Array_Elems(data), NULL, NULL); - Int32 i; - for (i = 0; i < status; i++) { - /* ignore NULL char after non-ASCII input char, like ä or å on Finnish keyboard layout */ - if (chars[i] == '\0') continue; - RaiseKeyPress(chars[i]); + String name = String_FromConst("Translate key press"); + struct Stream mem; Stream_ReadonlyMemory(&mem, data, status, &name); + + /* TODO: Is this even right... */ + UInt16 codepoint; + while (Stream_ReadUtf8Char(&mem, &codepoint)) { + Event_RaiseInt(&KeyEvents_Press, Convert_UnicodeToCP437(codepoint)); } } break; case KeyRelease: /* TODO: raise KeyPress event. Use code from */ /* http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs?view=markup */ - ToggleKey(&e.KeyEvent, false); + ToggleKey(&e.xkey, false); break; case ButtonPress: - if (e.ButtonEvent.button == 1) Mouse.Set(MouseButton.Left, true); - else if (e.ButtonEvent.button == 2) Mouse.Set(MouseButton.Middle, true); - else if (e.ButtonEvent.button == 3) Mouse.Set(MouseButton.Right, true); - else if (e.ButtonEvent.button == 4) Mouse.SetWheel(Mouse.Wheel + 1); - else if (e.ButtonEvent.button == 5) Mouse.SetWheel(Mouse.Wheel - 1); - else if (e.ButtonEvent.button == 6) Keyboard.Set(Key.XButton1, true); - else if (e.ButtonEvent.button == 7) Keyboard.Set(Key.XButton2, true); + if (e.xbutton.button == 1) Mouse_Set(MouseButton_Left, true); + else if (e.xbutton.button == 2) Mouse_Set(MouseButton_Middle, true); + else if (e.xbutton.button == 3) Mouse_Set(MouseButton_Right, true); + else if (e.xbutton.button == 4) Mouse_SetWheel(Mouse_Wheel + 1); + else if (e.xbutton.button == 5) Mouse_SetWheel(Mouse_Wheel - 1); + else if (e.xbutton.button == 6) Keyboard_Set(Key_XButton1, true); + else if (e.xbutton.button == 7) Keyboard_Set(Key_XButton2, true); break; case ButtonRelease: - if (e.ButtonEvent.button == 1) Mouse.Set(MouseButton.Left, false); - else if (e.ButtonEvent.button == 2) Mouse.Set(MouseButton.Middle, false); - else if (e.ButtonEvent.button == 3) Mouse.Set(MouseButton.Right, false); - else if (e.ButtonEvent.button == 6) Keyboard.Set(Key.XButton1, false); - else if (e.ButtonEvent.button == 7) Keyboard.Set(Key.XButton2, false); + if (e.xbutton.button == 1) Mouse_Set(MouseButton_Left, false); + else if (e.xbutton.button == 2) Mouse_Set(MouseButton_Middle, false); + else if (e.xbutton.button == 3) Mouse_Set(MouseButton_Right, false); + else if (e.xbutton.button == 6) Keyboard_Set(Key_XButton1, false); + else if (e.xbutton.button == 7) Keyboard_Set(Key_XButton2, false); break; case MotionNotify: - Mouse_SetPos(e.MotionEvent.x, e.MotionEvent.y); + Mouse_SetPos(e.xmotion.x, e.xmotion.y); break; case FocusIn: @@ -394,18 +533,18 @@ void Window_ProcessEvents(void) { case MappingNotify: /* 0 == MappingModifier, 1 == MappingKeyboard */ - if (e.MappingEvent.request == 0 || e.MappingEvent.request == 1) { + if (e.xmapping.request == 0 || e.xmapping.request == 1) { Platform_LogConst("keybard mapping refreshed"); - XRefreshKeyboardMapping(&e.MappingEvent); + XRefreshKeyboardMapping(&e.xmapping); } break; case PropertyNotify: - if (e.PropertyEvent.atom == net_wm_state) { + if (e.xproperty.atom == net_wm_state) { RaiseWindowStateChanged(); } - //if (e.PropertyEvent.atom == net_frame_extents) { + //if (e.xproperty.atom == net_frame_extents) { // RefreshWindowBorders(); //} break; @@ -413,24 +552,27 @@ void Window_ProcessEvents(void) { case SelectionNotify: String_Clear(&clipboard_paste_text); - if (e.SelectionEvent.selection == xa_clipboard && e.SelectionEvent.target == xa_utf8_string && e.SelectionEvent.property == xa_data_sel) { + if (e.xselection.selection == xa_clipboard && e.xselection.target == xa_utf8_string && e.xselection.property == xa_data_sel) { Atom prop_type; int prop_format; - long num_items, bytes_after; - UChar* data = NULL; + long items, bytes_after; + UInt8* data = NULL; XGetWindowProperty(win_display, win_handle, xa_data_sel, 0, 1024, false, NULL, - &prop_type, &prop_format, &num_items, &bytes_after, &data); + &prop_type, &prop_format, items, &bytes_after, &data); XDeleteProperty(win_display, win_handle, xa_data_sel); - if (num_items == 0) break; + if (items == 0) break; if (prop_type == xa_utf8_string) { - byte[] dst = new byte[(int)num_items]; - byte* src = (byte*)data; - for (int i = 0; i < dst.Length; i++) { dst[i] = src[i]; } + String name = String_FromConst("Clipboard get"); + struct Stream mem; Stream_ReadonlyMemory(&mem, data, items, &name); - clipboard_paste_text = Encoding.UTF8.GetString(dst); + String_Clear(&clipboard_paste_text); + UInt16 codepoint; + while (Stream_ReadUtf8Char(&mem, &codepoint)) { + String_append(&clipboard_paste_text, Convert_UnicodeToCP437(codepoint)); + } } XFree(data); } @@ -439,31 +581,36 @@ void Window_ProcessEvents(void) { case SelectionRequest: { XEvent reply = { 0 }; - reply.SelectionEvent.type = SelectionNotify; - reply.SelectionEvent.send_event = true; - reply.SelectionEvent.display = win_display; - reply.SelectionEvent.requestor = e.SelectionRequestEvent.requestor; - reply.SelectionEvent.selection = e.SelectionRequestEvent.selection; - reply.SelectionEvent.target = e.SelectionRequestEvent.target; - reply.SelectionEvent.property = NULL; - reply.SelectionEvent.time = e.SelectionRequestEvent.time; + reply.xselection.type = SelectionNotify; + reply.xselection.send_event = true; + reply.xselection.display = win_display; + reply.xselection.requestor = e.xselectionrequest.requestor; + reply.xselection.selection = e.xselectionrequest.selection; + reply.xselection.target = e.xselectionrequest.target; + reply.xselection.property = NULL; + reply.xselection.time = e.xselectionrequest.time; - if (e.SelectionRequestEvent.selection == xa_clipboard && e.SelectionRequestEvent.target == xa_utf8_string && clipboard_copy_text.length > 0) { - reply.SelectionEvent.property = Window_GetSelectionProperty(&e); + if (e.xselectionrequest.selection == xa_clipboard && e.xselectionrequest.target == xa_utf8_string && clipboard_copy_text.length > 0) { + reply.xselection.property = Window_GetSelectionProperty(&e); + UInt8 data[1024]; + Int32 i, len = 0; - byte[] utf8_data = Encoding.UTF8.GetBytes(clipboard_copy_text); - fixed(byte* utf8_ptr = utf8_data) { - XChangeProperty(win_display, reply.SelectionEvent.requestor, reply.SelectionEvent.property, xa_utf8_string, 8, - PropModeReplace, (IntPtr)utf8_ptr, utf8_data.Length); + for (i = 0; i < clipboard_copy_text.length; i++) { + UInt16 codepoint = Convert_CP437ToUnicode(clipboard_copy_text.buffer[i]); + UInt8* cur = data + len; + len += Stream_WriteUtf8(cur, codepoint); } - } else if (e.SelectionRequestEvent.selection == xa_clipboard && e.SelectionRequestEvent.target == xa_targets) { - reply.SelectionEvent.property = Window_GetSelectionProperty(&e); + + XChangeProperty(win_display, reply.xselection.requestor, reply.xselection.property, xa_utf8_string, 8, + PropModeReplace, data, len); + } else if (e.xselectionrequest.selection == xa_clipboard && e.xselectionrequest.target == xa_targets) { + reply.xselection.property = Window_GetSelectionProperty(&e); Atom data[2] = { xa_utf8_string, xa_targets }; - XChangeProperty(win_display, reply.SelectionEvent.requestor, reply.SelectionEvent.property, xa_atom, 32, + XChangeProperty(win_display, reply.xselection.requestor, reply.xselection.property, xa_atom, 32, PropModeReplace, data, 2); } - XSendEvent(win_display, e.SelectionRequestEvent.requestor, true, 0, &reply); + XSendEvent(win_display, e.xselectionrequest.requestor, true, 0, &reply); } break; } } @@ -505,7 +652,7 @@ void Window_SetCursorVisible(bool visible) { } else { if (win_blankCursor == NULL) { XColor col = { 0 }; - Pixmap pixmap = XCreatePixmap(win_display, win_rootWindow, 1, 1, 1); + Pixmap pixmap = XCreatePixmap(win_display, win_rootWin, 1, 1, 1); win_blankCursor = XCreatePixmapCursor(win_display, pixmap, pixmap, &col, &col, 0, 0); XFreePixmap(win_display, pixmap); } @@ -603,9 +750,9 @@ static void GLContext_GetAttribs(struct GraphicsMode mode, Int32* attribs) { attribs[i++] = 0; } -static XVisualInfo GLContext_SelectVisual(struct GraphicsMode mode) { +static XVisualInfo GLContext_SelectVisual(struct GraphicsMode* mode) { Int32 attribs[20]; - GLContext_GetAttribs(mode, attribs); + GLContext_GetAttribs(*mode, attribs); Int32 major = 0, minor = 0, fbcount; if (!glXQueryVersion(win_display, &major, &minor)) { ErrorHandler_Fail("glXQueryVersion failed");