mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-16 00:34:19 +00:00
Linux: fixed dependency between juce_gui_basics and juce_events.
This commit is contained in:
parent
6b1654e1d2
commit
a7a16116d0
3 changed files with 217 additions and 196 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <char> 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<Atom*> (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<const unsigned char*> (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 <char> 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<Atom*> (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<const unsigned char*> (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)
|
||||
|
|
|
|||
|
|
@ -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 <typename EventType>
|
||||
static Point<int> getMousePos (const EventType& e) noexcept
|
||||
{
|
||||
return Point<int> (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<int> (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<int> (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<int> (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<int> mousePos (movedEvent->x_root, movedEvent->y_root);
|
||||
updateKeyModifiers (movedEvent.state);
|
||||
const Point<int> 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<int> (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<int> (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<int> (exposeEvent->x, exposeEvent->y,
|
||||
exposeEvent->width, exposeEvent->height));
|
||||
repaint (Rectangle<int> (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<int> (nextExposeEvent->x, nextExposeEvent->y,
|
||||
nextExposeEvent->width, nextExposeEvent->height));
|
||||
const XExposeEvent& nextExposeEvent = (const XExposeEvent&) nextEvent.xexpose;
|
||||
repaint (Rectangle<int> (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 <typename EventType>
|
||||
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<int> dropPos ((int) clientMsg->data.l[2] >> 16,
|
||||
(int) clientMsg->data.l[2] & 0xffff);
|
||||
Point<int> 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 <unsigned long> (clientMsg->data.l[1] & 0xff000000) >> 24;
|
||||
const unsigned long dndCurrentVersion = static_cast <unsigned long> (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()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue