diff --git a/modules/juce_events/native/juce_linux_Messaging.cpp b/modules/juce_events/native/juce_linux_Messaging.cpp index a58a011a8d..b48358646c 100644 --- a/modules/juce_events/native/juce_linux_Messaging.cpp +++ b/modules/juce_events/native/juce_linux_Messaging.cpp @@ -31,8 +31,11 @@ Display* display = nullptr; Window juce_messageWindowHandle = None; XContext windowHandleXContext; // This is referenced from Windowing.cpp -extern void juce_windowMessageReceive (XEvent* event); // Defined in Windowing.cpp -extern void juce_handleSelectionRequest (XSelectionRequestEvent&); // Defined in Clipboard.cpp +typedef bool (*WindowMessageReceiveCallback) (XEvent&); +WindowMessageReceiveCallback dispatchWindowMessage = nullptr; + +typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); +SelectionRequestCallback handleSelectionRequest = nullptr; //============================================================================== ScopedXLock::ScopedXLock() { XLockDisplay (display); } @@ -165,10 +168,11 @@ private: XNextEvent (display, &evt); } - if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle) - juce_handleSelectionRequest (evt.xselectionrequest); - else if (evt.xany.window != juce_messageWindowHandle) - juce_windowMessageReceive (&evt); + if (evt.type == SelectionRequest && evt.xany.window == juce_messageWindowHandle + && handleSelectionRequest != nullptr) + handleSelectionRequest (evt.xselectionrequest); + else if (evt.xany.window != juce_messageWindowHandle && dispatchWindowMessage != nullptr) + dispatchWindowMessage (evt); return true; } diff --git a/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp b/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp index 3da4417918..190a2b0402 100644 --- a/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp +++ b/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp @@ -34,7 +34,7 @@ namespace ClipboardHelpers static Atom atom_TARGETS; //============================================================================== - void initSelectionAtoms() + static void initSelectionAtoms() { static bool isInitialised = false; if (! isInitialised) @@ -48,7 +48,7 @@ namespace ClipboardHelpers //============================================================================== // Read the content of a window property as either a locale-dependent string or an utf8 string // works only for strings shorter than 1000000 bytes - String readWindowProperty (Window window, Atom prop, Atom fmt) + static String readWindowProperty (Window window, Atom prop, Atom fmt) { String returnData; char* clipData; @@ -79,7 +79,7 @@ namespace ClipboardHelpers //============================================================================== // Send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) */ - bool requestSelectionContent (String& selectionContent, Atom selection, Atom requestedFormat) + static bool requestSelectionContent (String& selectionContent, Atom selection, Atom requestedFormat) { Atom property_name = XInternAtom (display, "JUCE_SEL", false); @@ -118,72 +118,86 @@ namespace ClipboardHelpers return false; } + + //============================================================================== + // Called from the event loop in juce_linux_Messaging in response to SelectionRequest events + static void handleSelection (XSelectionRequestEvent& evt) + { + ClipboardHelpers::initSelectionAtoms(); + + // the selection content is sent to the target window as a window property + XSelectionEvent reply; + reply.type = SelectionNotify; + reply.display = evt.display; + reply.requestor = evt.requestor; + reply.selection = evt.selection; + reply.target = evt.target; + reply.property = None; // == "fail" + reply.time = evt.time; + + HeapBlock data; + int propertyFormat = 0, numDataItems = 0; + + if (evt.selection == XA_PRIMARY || evt.selection == ClipboardHelpers::atom_CLIPBOARD) + { + if (evt.target == XA_STRING || evt.target == ClipboardHelpers::atom_UTF8_STRING) + { + // translate to utf8 + numDataItems = ClipboardHelpers::localClipboardContent.getNumBytesAsUTF8() + 1; + data.calloc (numDataItems + 1); + ClipboardHelpers::localClipboardContent.copyToUTF8 (data, numDataItems); + propertyFormat = 8; // bits/item + } + else if (evt.target == ClipboardHelpers::atom_TARGETS) + { + // another application wants to know what we are able to send + numDataItems = 2; + propertyFormat = 32; // atoms are 32-bit + data.calloc (numDataItems * 4); + Atom* atoms = reinterpret_cast (data.getData()); + atoms[0] = ClipboardHelpers::atom_UTF8_STRING; + atoms[1] = XA_STRING; + + evt.target = XA_ATOM; + } + } + else + { + DBG ("requested unsupported clipboard"); + } + + if (data != nullptr) + { + const int maxReasonableSelectionSize = 1000000; + + // for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss + if (evt.property != None && numDataItems < maxReasonableSelectionSize) + { + XChangeProperty (evt.display, evt.requestor, + evt.property, evt.target, + propertyFormat /* 8 or 32 */, PropModeReplace, + reinterpret_cast (data.getData()), numDataItems); + reply.property = evt.property; // " == success" + } + } + + XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply); + } } //============================================================================== -// Called from the event loop in juce_linux_Messaging in response to SelectionRequest events -void juce_handleSelectionRequest (XSelectionRequestEvent &evt) +typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&); +extern SelectionRequestCallback handleSelectionRequest; + +struct ClipboardCallbackInitialiser { - ClipboardHelpers::initSelectionAtoms(); - - // the selection content is sent to the target window as a window property - XSelectionEvent reply; - reply.type = SelectionNotify; - reply.display = evt.display; - reply.requestor = evt.requestor; - reply.selection = evt.selection; - reply.target = evt.target; - reply.property = None; // == "fail" - reply.time = evt.time; - - HeapBlock data; - int propertyFormat = 0, numDataItems = 0; - - if (evt.selection == XA_PRIMARY || evt.selection == ClipboardHelpers::atom_CLIPBOARD) + ClipboardCallbackInitialiser() { - if (evt.target == XA_STRING || evt.target == ClipboardHelpers::atom_UTF8_STRING) - { - // translate to utf8 - numDataItems = ClipboardHelpers::localClipboardContent.getNumBytesAsUTF8() + 1; - data.calloc (numDataItems + 1); - ClipboardHelpers::localClipboardContent.copyToUTF8 (data, numDataItems); - propertyFormat = 8; // bits/item - } - else if (evt.target == ClipboardHelpers::atom_TARGETS) - { - // another application wants to know what we are able to send - numDataItems = 2; - propertyFormat = 32; // atoms are 32-bit - data.calloc (numDataItems * 4); - Atom* atoms = reinterpret_cast (data.getData()); - atoms[0] = ClipboardHelpers::atom_UTF8_STRING; - atoms[1] = XA_STRING; - - evt.target = XA_ATOM; - } - } - else - { - DBG ("requested unsupported clipboard"); + handleSelectionRequest = ClipboardHelpers::handleSelection; } +}; - if (data != nullptr) - { - const int maxReasonableSelectionSize = 1000000; - - // for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss - if (evt.property != None && numDataItems < maxReasonableSelectionSize) - { - XChangeProperty (evt.display, evt.requestor, - evt.property, evt.target, - propertyFormat /* 8 or 32 */, PropModeReplace, - reinterpret_cast (data.getData()), numDataItems); - reply.property = evt.property; // " == success" - } - } - - XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply); -} +static ClipboardCallbackInitialiser clipboardInitialiser; //============================================================================== void SystemClipboard::copyTextToClipboard (const String& clipText) diff --git a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp index e5c462ca59..b206b82b6b 100644 --- a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp @@ -25,6 +25,9 @@ extern Display* display; extern XContext windowHandleXContext; +typedef void (*WindowMessageReceiveCallback) (XEvent&); +extern WindowMessageReceiveCallback dispatchWindowMessage; + //============================================================================== struct Atoms @@ -773,6 +776,7 @@ public: // it's dangerous to create a window on a thread other than the message thread.. jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); + dispatchWindowMessage = windowMessageReceive; repainter = new LinuxRepaintManager (this); createWindow (parentToAddTo); @@ -790,6 +794,21 @@ public: windowH = 0; } + // (this callback is hooked up in the messaging code) + static void windowMessageReceive (XEvent& event) + { + if (event.xany.window != None) + { + if (LinuxComponentPeer* const peer = getPeerFor (event.xany.window)) + peer->handleWindowMessage (event); + } + else if (event.xany.type == KeymapNotify) + { + const XKeymapEvent& keymapEvent = (const XKeymapEvent&) event.xkeymap; + memcpy (Keys::keyStates, keymapEvent.key_vector, 32); + } + } + //============================================================================== void* getNativeHandle() const { @@ -1219,24 +1238,24 @@ public: } //============================================================================== - void handleWindowMessage (XEvent* event) + void handleWindowMessage (XEvent& event) { - switch (event->xany.type) + switch (event.xany.type) { - case KeyPressEventType: handleKeyPressEvent ((XKeyEvent*) &event->xkey); break; - case KeyRelease: handleKeyReleaseEvent ((const XKeyEvent*) &event->xkey); break; - case ButtonPress: handleButtonPressEvent ((const XButtonPressedEvent*) &event->xbutton); break; - case ButtonRelease: handleButtonReleaseEvent ((const XButtonReleasedEvent*) &event->xbutton); break; - case MotionNotify: handleMotionNotifyEvent ((const XPointerMovedEvent*) &event->xmotion); break; - case EnterNotify: handleEnterNotifyEvent ((const XEnterWindowEvent*) &event->xcrossing); break; - case LeaveNotify: handleLeaveNotifyEvent ((const XLeaveWindowEvent*) &event->xcrossing); break; + case KeyPressEventType: handleKeyPressEvent (event.xkey); break; + case KeyRelease: handleKeyReleaseEvent (event.xkey); break; + case ButtonPress: handleButtonPressEvent (event.xbutton); break; + case ButtonRelease: handleButtonReleaseEvent (event.xbutton); break; + case MotionNotify: handleMotionNotifyEvent (event.xmotion); break; + case EnterNotify: handleEnterNotifyEvent (event.xcrossing); break; + case LeaveNotify: handleLeaveNotifyEvent (event.xcrossing); break; case FocusIn: handleFocusInEvent(); break; case FocusOut: handleFocusOutEvent(); break; - case Expose: handleExposeEvent ((XExposeEvent*) &event->xexpose); break; - case MappingNotify: handleMappingNotify ((XMappingEvent*) &event->xmapping); break; - case ClientMessage: handleClientMessageEvent ((XClientMessageEvent*) &event->xclient, event); break; + case Expose: handleExposeEvent (event.xexpose); break; + case MappingNotify: handleMappingNotify (event.xmapping); break; + case ClientMessage: handleClientMessageEvent (event.xclient, event); break; case SelectionNotify: handleDragAndDropSelection (event); break; - case ConfigureNotify: handleConfigureNotifyEvent ((XConfigureEvent*) &event->xconfigure); break; + case ConfigureNotify: handleConfigureNotifyEvent (event.xconfigure); break; case ReparentNotify: handleReparentNotifyEvent(); break; case GravityNotify: handleGravityNotify(); break; @@ -1263,7 +1282,7 @@ public: #if JUCE_USE_XSHM { ScopedXLock xlock; - if (event->xany.type == XShmGetEventBase (display)) + if (event.xany.type == XShmGetEventBase (display)) repainter->notifyPaintCompleted(); } #endif @@ -1271,7 +1290,7 @@ public: } } - void handleKeyPressEvent (XKeyEvent* const keyEvent) + void handleKeyPressEvent (XKeyEvent& keyEvent) { char utf8 [64] = { 0 }; juce_wchar unicodeChar = 0; @@ -1281,18 +1300,18 @@ public: { ScopedXLock xlock; - updateKeyStates (keyEvent->keycode, true); + updateKeyStates (keyEvent.keycode, true); const char* oldLocale = ::setlocale (LC_ALL, 0); ::setlocale (LC_ALL, ""); - XLookupString (keyEvent, utf8, sizeof (utf8), &sym, 0); + XLookupString (&keyEvent, utf8, sizeof (utf8), &sym, 0); ::setlocale (LC_ALL, oldLocale); unicodeChar = *CharPointer_UTF8 (utf8); keyCode = (int) unicodeChar; if (keyCode < 0x20) - keyCode = XkbKeycodeToKeysym (display, keyEvent->keycode, 0, currentModifiers.isShiftDown() ? 1 : 0); + keyCode = XkbKeycodeToKeysym (display, keyEvent.keycode, 0, currentModifiers.isShiftDown() ? 1 : 0); keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, true); } @@ -1370,7 +1389,7 @@ public: handleKeyPress (keyCode, unicodeChar); } - static bool isKeyReleasePartOfAutoRepeat (const XKeyEvent* const keyReleaseEvent) + static bool isKeyReleasePartOfAutoRepeat (const XKeyEvent& keyReleaseEvent) { if (XPending (display)) { @@ -1379,23 +1398,23 @@ public: // Look for a subsequent key-down event with the same timestamp and keycode return e.type == KeyPressEventType - && e.xkey.keycode == keyReleaseEvent->keycode - && e.xkey.time == keyReleaseEvent->time; + && e.xkey.keycode == keyReleaseEvent.keycode + && e.xkey.time == keyReleaseEvent.time; } return false; } - void handleKeyReleaseEvent (const XKeyEvent* const keyEvent) + void handleKeyReleaseEvent (const XKeyEvent& keyEvent) { if (! isKeyReleasePartOfAutoRepeat (keyEvent)) { - updateKeyStates (keyEvent->keycode, false); + updateKeyStates (keyEvent.keycode, false); KeySym sym; { ScopedXLock xlock; - sym = XkbKeycodeToKeysym (display, keyEvent->keycode, 0, 0); + sym = XkbKeycodeToKeysym (display, keyEvent.keycode, 0, 0); } const ModifierKeys oldMods (currentModifiers); @@ -1409,7 +1428,13 @@ public: } } - void handleWheelEvent (const XButtonPressedEvent* const buttonPressEvent, const float amount) + template + static Point getMousePos (const EventType& e) noexcept + { + return Point (e.x, e.y); + } + + void handleWheelEvent (const XButtonPressedEvent& buttonPressEvent, const float amount) { MouseWheelDetails wheel; wheel.deltaX = 0.0f; @@ -1417,23 +1442,21 @@ public: wheel.isReversed = false; wheel.isSmooth = false; - handleMouseWheel (0, Point (buttonPressEvent->x, buttonPressEvent->y), - getEventTime (buttonPressEvent->time), wheel); + handleMouseWheel (0, getMousePos (buttonPressEvent), getEventTime (buttonPressEvent), wheel); } - void handleButtonPressEvent (const XButtonPressedEvent* const buttonPressEvent, int buttonModifierFlag) + void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent, int buttonModifierFlag) { currentModifiers = currentModifiers.withFlags (buttonModifierFlag); toFront (true); - handleMouseEvent (0, Point (buttonPressEvent->x, buttonPressEvent->y), currentModifiers, - getEventTime (buttonPressEvent->time)); + handleMouseEvent (0, getMousePos (buttonPressEvent), currentModifiers, getEventTime (buttonPressEvent)); } - void handleButtonPressEvent (const XButtonPressedEvent* const buttonPressEvent) + void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent) { - updateKeyModifiers (buttonPressEvent->state); + updateKeyModifiers (buttonPressEvent.state); - switch (pointerMap [buttonPressEvent->button - Button1]) + switch (pointerMap [buttonPressEvent.button - Button1]) { case Keys::WheelUp: handleWheelEvent (buttonPressEvent, 50.0f / 256.0f); break; case Keys::WheelDown: handleWheelEvent (buttonPressEvent, -50.0f / 256.0f); break; @@ -1446,11 +1469,11 @@ public: clearLastMousePos(); } - void handleButtonReleaseEvent (const XButtonReleasedEvent* const buttonRelEvent) + void handleButtonReleaseEvent (const XButtonReleasedEvent& buttonRelEvent) { - updateKeyModifiers (buttonRelEvent->state); + updateKeyModifiers (buttonRelEvent.state); - switch (pointerMap [buttonRelEvent->button - Button1]) + switch (pointerMap [buttonRelEvent.button - Button1]) { case Keys::LeftButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); break; case Keys::RightButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); break; @@ -1458,16 +1481,15 @@ public: default: break; } - handleMouseEvent (0, Point (buttonRelEvent->x, buttonRelEvent->y), currentModifiers, - getEventTime (buttonRelEvent->time)); + handleMouseEvent (0, getMousePos (buttonRelEvent), currentModifiers, getEventTime (buttonRelEvent)); clearLastMousePos(); } - void handleMotionNotifyEvent (const XPointerMovedEvent* const movedEvent) + void handleMotionNotifyEvent (const XPointerMovedEvent& movedEvent) { - updateKeyModifiers (movedEvent->state); - const Point mousePos (movedEvent->x_root, movedEvent->y_root); + updateKeyModifiers (movedEvent.state); + const Point mousePos (movedEvent.x_root, movedEvent.y_root); if (lastMousePos != mousePos) { @@ -1497,31 +1519,31 @@ public: } } - handleMouseEvent (0, mousePos - getScreenPosition(), currentModifiers, getEventTime (movedEvent->time)); + handleMouseEvent (0, mousePos - getScreenPosition(), currentModifiers, getEventTime (movedEvent)); } } - void handleEnterNotifyEvent (const XEnterWindowEvent* const enterEvent) + void handleEnterNotifyEvent (const XEnterWindowEvent& enterEvent) { clearLastMousePos(); if (! currentModifiers.isAnyMouseButtonDown()) { - updateKeyModifiers (enterEvent->state); - handleMouseEvent (0, Point (enterEvent->x, enterEvent->y), currentModifiers, getEventTime (enterEvent->time)); + updateKeyModifiers (enterEvent.state); + handleMouseEvent (0, getMousePos (enterEvent), currentModifiers, getEventTime (enterEvent)); } } - void handleLeaveNotifyEvent (const XLeaveWindowEvent* const leaveEvent) + void handleLeaveNotifyEvent (const XLeaveWindowEvent& leaveEvent) { // Suppress the normal leave if we've got a pointer grab, or if // it's a bogus one caused by clicking a mouse button when running // in a Window manager - if (((! currentModifiers.isAnyMouseButtonDown()) && leaveEvent->mode == NotifyNormal) - || leaveEvent->mode == NotifyUngrab) + if (((! currentModifiers.isAnyMouseButtonDown()) && leaveEvent.mode == NotifyNormal) + || leaveEvent.mode == NotifyUngrab) { - updateKeyModifiers (leaveEvent->state); - handleMouseEvent (0, Point (leaveEvent->x, leaveEvent->y), currentModifiers, getEventTime (leaveEvent->time)); + updateKeyModifiers (leaveEvent.state); + handleMouseEvent (0, getMousePos (leaveEvent), currentModifiers, getEventTime (leaveEvent)); } } @@ -1539,37 +1561,37 @@ public: handleFocusLoss(); } - void handleExposeEvent (XExposeEvent* exposeEvent) + void handleExposeEvent (XExposeEvent& exposeEvent) { // Batch together all pending expose events XEvent nextEvent; ScopedXLock xlock; - if (exposeEvent->window != windowH) + if (exposeEvent.window != windowH) { Window child; - XTranslateCoordinates (display, exposeEvent->window, windowH, - exposeEvent->x, exposeEvent->y, &exposeEvent->x, &exposeEvent->y, + XTranslateCoordinates (display, exposeEvent.window, windowH, + exposeEvent.x, exposeEvent.y, &exposeEvent.x, &exposeEvent.y, &child); } - repaint (Rectangle (exposeEvent->x, exposeEvent->y, - exposeEvent->width, exposeEvent->height)); + repaint (Rectangle (exposeEvent.x, exposeEvent.y, + exposeEvent.width, exposeEvent.height)); while (XEventsQueued (display, QueuedAfterFlush) > 0) { XPeekEvent (display, &nextEvent); - if (nextEvent.type != Expose || nextEvent.xany.window != exposeEvent->window) + if (nextEvent.type != Expose || nextEvent.xany.window != exposeEvent.window) break; XNextEvent (display, &nextEvent); - XExposeEvent* nextExposeEvent = (XExposeEvent*) &nextEvent.xexpose; - repaint (Rectangle (nextExposeEvent->x, nextExposeEvent->y, - nextExposeEvent->width, nextExposeEvent->height)); + const XExposeEvent& nextExposeEvent = (const XExposeEvent&) nextEvent.xexpose; + repaint (Rectangle (nextExposeEvent.x, nextExposeEvent.y, + nextExposeEvent.width, nextExposeEvent.height)); } } - void handleConfigureNotifyEvent (XConfigureEvent* const confEvent) + void handleConfigureNotifyEvent (XConfigureEvent& confEvent) { updateBounds(); updateBorderSize(); @@ -1585,8 +1607,8 @@ public: currentModalComp->inputAttemptWhenModal(); } - if (confEvent->window == windowH - && confEvent->above != 0 + if (confEvent.window == windowH + && confEvent.above != 0 && isFrontWindow()) { handleBroughtToFront(); @@ -1618,32 +1640,32 @@ public: handleMovedOrResized(); } - void handleMappingNotify (XMappingEvent* const mappingEvent) + void handleMappingNotify (XMappingEvent& mappingEvent) { - if (mappingEvent->request != MappingPointer) + if (mappingEvent.request != MappingPointer) { // Deal with modifier/keyboard mapping ScopedXLock xlock; - XRefreshKeyboardMapping (mappingEvent); + XRefreshKeyboardMapping (&mappingEvent); updateModifierMappings(); } } - void handleClientMessageEvent (XClientMessageEvent* const clientMsg, XEvent* event) + void handleClientMessageEvent (XClientMessageEvent& clientMsg, XEvent& event) { const Atoms& atoms = Atoms::get(); - if (clientMsg->message_type == atoms.Protocols && clientMsg->format == 32) + if (clientMsg.message_type == atoms.Protocols && clientMsg.format == 32) { - const Atom atom = (Atom) clientMsg->data.l[0]; + const Atom atom = (Atom) clientMsg.data.l[0]; if (atom == atoms.ProtocolList [Atoms::PING]) { Window root = RootWindow (display, DefaultScreen (display)); - clientMsg->window = root; + clientMsg.window = root; - XSendEvent (display, root, False, NoEventMask, event); + XSendEvent (display, root, False, NoEventMask, &event); XFlush (display); } else if (atom == atoms.ProtocolList [Atoms::TAKE_FOCUS]) @@ -1653,11 +1675,11 @@ public: XWindowAttributes atts; ScopedXLock xlock; - if (clientMsg->window != 0 - && XGetWindowAttributes (display, clientMsg->window, &atts)) + if (clientMsg.window != 0 + && XGetWindowAttributes (display, clientMsg.window, &atts)) { if (atts.map_state == IsViewable) - XSetInputFocus (display, clientMsg->window, RevertToParent, clientMsg->data.l[1]); + XSetInputFocus (display, clientMsg.window, RevertToParent, clientMsg.data.l[1]); } } } @@ -1666,27 +1688,27 @@ public: handleUserClosingWindow(); } } - else if (clientMsg->message_type == atoms.XdndEnter) + else if (clientMsg.message_type == atoms.XdndEnter) { handleDragAndDropEnter (clientMsg); } - else if (clientMsg->message_type == atoms.XdndLeave) + else if (clientMsg.message_type == atoms.XdndLeave) { resetDragAndDrop(); } - else if (clientMsg->message_type == atoms.XdndPosition) + else if (clientMsg.message_type == atoms.XdndPosition) { handleDragAndDropPosition (clientMsg); } - else if (clientMsg->message_type == atoms.XdndDrop) + else if (clientMsg.message_type == atoms.XdndDrop) { handleDragAndDropDrop (clientMsg); } - else if (clientMsg->message_type == atoms.XdndStatus) + else if (clientMsg.message_type == atoms.XdndStatus) { handleDragAndDropStatus (clientMsg); } - else if (clientMsg->message_type == atoms.XdndFinished) + else if (clientMsg.message_type == atoms.XdndFinished) { resetDragAndDrop(); } @@ -1904,19 +1926,13 @@ private: switch (sym) { case XK_Shift_L: - case XK_Shift_R: - modifier = ModifierKeys::shiftModifier; - break; + case XK_Shift_R: modifier = ModifierKeys::shiftModifier; break; case XK_Control_L: - case XK_Control_R: - modifier = ModifierKeys::ctrlModifier; - break; + case XK_Control_R: modifier = ModifierKeys::ctrlModifier; break; case XK_Alt_L: - case XK_Alt_R: - modifier = ModifierKeys::altModifier; - break; + case XK_Alt_R: modifier = ModifierKeys::altModifier; break; case XK_Num_Lock: if (press) @@ -1955,9 +1971,7 @@ private: Keys::AltMask = 0; Keys::NumLockMask = 0; - XModifierKeymap* mapping = XGetModifierMapping (display); - - if (mapping) + if (XModifierKeymap* const mapping = XGetModifierMapping (display)) { for (int i = 0; i < 8; i++) { @@ -2213,6 +2227,12 @@ private: | ExposureMask | StructureNotifyMask | FocusChangeMask; } + template + static int64 getEventTime (const EventType& t) + { + return getEventTime (t.time); + } + static int64 getEventTime (::Time t) { static int64 eventTimeOffset = 0x12345678; @@ -2322,9 +2342,9 @@ private: sendDragAndDropMessage (msg); } - void handleDragAndDropStatus (const XClientMessageEvent* const clientMsg) + void handleDragAndDropStatus (const XClientMessageEvent& clientMsg) { - if ((clientMsg->data.l[1] & 1) == 0) + if ((clientMsg.data.l[1] & 1) == 0) { sendDragAndDropLeave(); @@ -2335,15 +2355,15 @@ private: } } - void handleDragAndDropPosition (const XClientMessageEvent* const clientMsg) + void handleDragAndDropPosition (const XClientMessageEvent& clientMsg) { if (dragAndDropSourceWindow == 0) return; - dragAndDropSourceWindow = clientMsg->data.l[0]; + dragAndDropSourceWindow = clientMsg.data.l[0]; - Point dropPos ((int) clientMsg->data.l[2] >> 16, - (int) clientMsg->data.l[2] & 0xffff); + Point dropPos ((int) clientMsg.data.l[2] >> 16, + (int) clientMsg.data.l[2] & 0xffff); dropPos -= getScreenPosition(); if (dragInfo.position != dropPos) @@ -2355,7 +2375,7 @@ private: for (int i = numElementsInArray (atoms.allowedActions); --i >= 0;) { - if ((Atom) clientMsg->data.l[4] == atoms.allowedActions[i]) + if ((Atom) clientMsg.data.l[4] == atoms.allowedActions[i]) { targetAction = atoms.allowedActions[i]; break; @@ -2372,7 +2392,7 @@ private: } } - void handleDragAndDropDrop (const XClientMessageEvent* const clientMsg) + void handleDragAndDropDrop (const XClientMessageEvent& clientMsg) { if (dragInfo.files.size() == 0) updateDraggedFileList (clientMsg); @@ -2386,13 +2406,13 @@ private: handleDragDrop (dragInfoCopy); } - void handleDragAndDropEnter (const XClientMessageEvent* const clientMsg) + void handleDragAndDropEnter (const XClientMessageEvent& clientMsg) { dragInfo.files.clear(); srcMimeTypeAtomList.clear(); dragAndDropCurrentMimeType = 0; - const unsigned long dndCurrentVersion = static_cast (clientMsg->data.l[1] & 0xff000000) >> 24; + const unsigned long dndCurrentVersion = static_cast (clientMsg.data.l[1] & 0xff000000) >> 24; if (dndCurrentVersion < 3 || dndCurrentVersion > Atoms::DndVersion) { @@ -2400,9 +2420,9 @@ private: return; } - dragAndDropSourceWindow = clientMsg->data.l[0]; + dragAndDropSourceWindow = clientMsg.data.l[0]; - if ((clientMsg->data.l[1] & 1) != 0) + if ((clientMsg.data.l[1] & 1) != 0) { ScopedXLock xlock; GetXProperty prop (dragAndDropSourceWindow, Atoms::get().XdndTypeList, 0, 0x8000000L, false, XA_ATOM); @@ -2423,8 +2443,8 @@ private: if (srcMimeTypeAtomList.size() == 0) { for (int i = 2; i < 5; ++i) - if (clientMsg->data.l[i] != None) - srcMimeTypeAtomList.add (clientMsg->data.l[i]); + if (clientMsg.data.l[i] != None) + srcMimeTypeAtomList.add (clientMsg.data.l[i]); if (srcMimeTypeAtomList.size() == 0) { @@ -2442,11 +2462,11 @@ private: handleDragAndDropPosition (clientMsg); } - void handleDragAndDropSelection (const XEvent* const evt) + void handleDragAndDropSelection (const XEvent& evt) { dragInfo.files.clear(); - if (evt->xselection.property != 0) + if (evt.xselection.property != 0) { StringArray lines; @@ -2455,7 +2475,7 @@ private: for (;;) { - GetXProperty prop (evt->xany.window, evt->xselection.property, + GetXProperty prop (evt.xany.window, evt.xselection.property, dropData.getSize() / 4, 65536, true, AnyPropertyType); if (! prop.success) @@ -2478,7 +2498,7 @@ private: } } - void updateDraggedFileList (const XClientMessageEvent* const clientMsg) + void updateDraggedFileList (const XClientMessageEvent& clientMsg) { dragInfo.files.clear(); @@ -2491,7 +2511,7 @@ private: dragAndDropCurrentMimeType, Atoms::getCreating ("JXSelectionWindowProperty"), windowH, - clientMsg->data.l[2]); + clientMsg.data.l[2]); } } @@ -2592,23 +2612,6 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindowToAtt return new LinuxComponentPeer (*this, styleFlags, (Window) nativeWindowToAttachTo); } - -//============================================================================== -// (this callback is hooked up in the messaging code) -void juce_windowMessageReceive (XEvent* event) -{ - if (event->xany.window != None) - { - if (LinuxComponentPeer* const peer = LinuxComponentPeer::getPeerFor (event->xany.window)) - peer->handleWindowMessage (event); - } - else if (event->xany.type == KeymapNotify) - { - const XKeymapEvent* const keymapEvent = (const XKeymapEvent*) &event->xkeymap; - memcpy (Keys::keyStates, keymapEvent->key_vector, 32); - } -} - //============================================================================== void Desktop::Displays::findDisplays() {