mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-31 03:00:05 +00:00
Simplified some linux X11 code involving atoms
This commit is contained in:
parent
0784f399f3
commit
50af60fa81
1 changed files with 74 additions and 110 deletions
|
|
@ -44,7 +44,6 @@ struct Atoms
|
|||
pid = getCreating ("_NET_WM_PID");
|
||||
windowType = getIfExists ("_NET_WM_WINDOW_TYPE");
|
||||
windowState = getIfExists ("_NET_WM_STATE");
|
||||
compositingManager = getCreating ("_NET_WM_CM_S0");
|
||||
|
||||
XdndAware = getCreating ("XdndAware");
|
||||
XdndEnter = getCreating ("XdndEnter");
|
||||
|
|
@ -66,9 +65,6 @@ struct Atoms
|
|||
allowedMimeTypes[2] = getCreating ("text/plain");
|
||||
allowedMimeTypes[3] = getCreating ("text/uri-list");
|
||||
|
||||
externalAllowedFileMimeTypes[0] = getCreating ("text/uri-list");
|
||||
externalAllowedTextMimeTypes[0] = getCreating ("text/plain");
|
||||
|
||||
allowedActions[0] = getCreating ("XdndActionMove");
|
||||
allowedActions[1] = XdndActionCopy;
|
||||
allowedActions[2] = getCreating ("XdndActionLink");
|
||||
|
|
@ -76,12 +72,6 @@ struct Atoms
|
|||
allowedActions[4] = XdndActionPrivate;
|
||||
}
|
||||
|
||||
static const Atoms& get()
|
||||
{
|
||||
static Atoms atoms;
|
||||
return atoms;
|
||||
}
|
||||
|
||||
enum ProtocolItems
|
||||
{
|
||||
TAKE_FOCUS = 0,
|
||||
|
|
@ -90,14 +80,12 @@ struct Atoms
|
|||
};
|
||||
|
||||
Atom protocols, protocolList[3], changeState, state, userTime,
|
||||
activeWin, pid, windowType, windowState, compositingManager,
|
||||
activeWin, pid, windowType, windowState,
|
||||
XdndAware, XdndEnter, XdndLeave, XdndPosition, XdndStatus,
|
||||
XdndDrop, XdndFinished, XdndSelection, XdndTypeList, XdndActionList,
|
||||
XdndActionDescription, XdndActionCopy, XdndActionPrivate,
|
||||
allowedActions[5],
|
||||
allowedMimeTypes[4],
|
||||
externalAllowedFileMimeTypes[1],
|
||||
externalAllowedTextMimeTypes[1];
|
||||
allowedMimeTypes[4];
|
||||
|
||||
static const unsigned long DndVersion;
|
||||
|
||||
|
|
@ -231,41 +219,42 @@ namespace XSHMHelpers
|
|||
XShmSegmentInfo segmentInfo;
|
||||
zerostruct (segmentInfo);
|
||||
|
||||
XImage* xImage = XShmCreateImage (display, DefaultVisual (display, DefaultScreen (display)),
|
||||
24, ZPixmap, 0, &segmentInfo, 50, 50);
|
||||
|
||||
if ((segmentInfo.shmid = shmget (IPC_PRIVATE,
|
||||
(size_t) (xImage->bytes_per_line * xImage->height),
|
||||
IPC_CREAT | 0777)) >= 0)
|
||||
if (XImage* xImage = XShmCreateImage (display, DefaultVisual (display, DefaultScreen (display)),
|
||||
24, ZPixmap, 0, &segmentInfo, 50, 50))
|
||||
{
|
||||
segmentInfo.shmaddr = (char*) shmat (segmentInfo.shmid, 0, 0);
|
||||
|
||||
if (segmentInfo.shmaddr != (void*) -1)
|
||||
if ((segmentInfo.shmid = shmget (IPC_PRIVATE,
|
||||
(size_t) (xImage->bytes_per_line * xImage->height),
|
||||
IPC_CREAT | 0777)) >= 0)
|
||||
{
|
||||
segmentInfo.readOnly = False;
|
||||
xImage->data = segmentInfo.shmaddr;
|
||||
XSync (display, False);
|
||||
segmentInfo.shmaddr = (char*) shmat (segmentInfo.shmid, 0, 0);
|
||||
|
||||
if (XShmAttach (display, &segmentInfo) != 0)
|
||||
if (segmentInfo.shmaddr != (void*) -1)
|
||||
{
|
||||
segmentInfo.readOnly = False;
|
||||
xImage->data = segmentInfo.shmaddr;
|
||||
XSync (display, False);
|
||||
XShmDetach (display, &segmentInfo);
|
||||
|
||||
isAvailable = true;
|
||||
if (XShmAttach (display, &segmentInfo) != 0)
|
||||
{
|
||||
XSync (display, False);
|
||||
XShmDetach (display, &segmentInfo);
|
||||
|
||||
isAvailable = true;
|
||||
}
|
||||
}
|
||||
|
||||
XFlush (display);
|
||||
XDestroyImage (xImage);
|
||||
|
||||
shmdt (segmentInfo.shmaddr);
|
||||
}
|
||||
|
||||
XFlush (display);
|
||||
XDestroyImage (xImage);
|
||||
shmctl (segmentInfo.shmid, IPC_RMID, 0);
|
||||
|
||||
shmdt (segmentInfo.shmaddr);
|
||||
XSetErrorHandler (oldHandler);
|
||||
if (trappedErrorCode != 0)
|
||||
isAvailable = false;
|
||||
}
|
||||
|
||||
shmctl (segmentInfo.shmid, IPC_RMID, 0);
|
||||
|
||||
XSetErrorHandler (oldHandler);
|
||||
if (trappedErrorCode != 0)
|
||||
isAvailable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -326,9 +315,10 @@ namespace XRender
|
|||
return xRenderQueryVersion != nullptr;
|
||||
}
|
||||
|
||||
static bool hasCompositingWindowManager()
|
||||
static bool hasCompositingWindowManager() noexcept
|
||||
{
|
||||
return display != nullptr && XGetSelectionOwner (display, Atoms::get().compositingManager) != 0;
|
||||
return display != nullptr
|
||||
&& XGetSelectionOwner (display, Atoms::getCreating ("_NET_WM_CM_S0")) != 0;
|
||||
}
|
||||
|
||||
static XRenderPictFormat* findPictureFormat()
|
||||
|
|
@ -404,12 +394,10 @@ namespace Visuals
|
|||
desiredMask |= VisualBitsPerRGBMask;
|
||||
}
|
||||
|
||||
XVisualInfo* xvinfos = XGetVisualInfo (display,
|
||||
desiredMask,
|
||||
&desiredVisual,
|
||||
&numVisuals);
|
||||
|
||||
if (xvinfos != nullptr)
|
||||
if (XVisualInfo* xvinfos = XGetVisualInfo (display,
|
||||
desiredMask,
|
||||
&desiredVisual,
|
||||
&numVisuals))
|
||||
{
|
||||
for (int i = 0; i < numVisuals; i++)
|
||||
{
|
||||
|
|
@ -438,9 +426,7 @@ namespace Visuals
|
|||
#if JUCE_USE_XRENDER
|
||||
if (XRender::isAvailable())
|
||||
{
|
||||
XRenderPictFormat* pictFormat = XRender::findPictureFormat();
|
||||
|
||||
if (pictFormat != 0)
|
||||
if (XRenderPictFormat* pictFormat = XRender::findPictureFormat())
|
||||
{
|
||||
int numVisuals = 0;
|
||||
XVisualInfo desiredVisual;
|
||||
|
|
@ -448,10 +434,9 @@ namespace Visuals
|
|||
desiredVisual.depth = 32;
|
||||
desiredVisual.bits_per_rgb = 8;
|
||||
|
||||
XVisualInfo* xvinfos = XGetVisualInfo (display,
|
||||
VisualScreenMask | VisualDepthMask | VisualBitsPerRGBMask,
|
||||
&desiredVisual, &numVisuals);
|
||||
if (xvinfos != nullptr)
|
||||
if (XVisualInfo* xvinfos = XGetVisualInfo (display,
|
||||
VisualScreenMask | VisualDepthMask | VisualBitsPerRGBMask,
|
||||
&desiredVisual, &numVisuals))
|
||||
{
|
||||
for (int i = 0; i < numVisuals; ++i)
|
||||
{
|
||||
|
|
@ -1611,7 +1596,7 @@ public:
|
|||
clientMsg.window = windowH;
|
||||
clientMsg.type = ClientMessage;
|
||||
clientMsg.format = 32;
|
||||
clientMsg.message_type = Atoms::get().windowState;
|
||||
clientMsg.message_type = atoms.windowState;
|
||||
clientMsg.data.l[0] = 0; // Remove
|
||||
clientMsg.data.l[1] = (long) fs;
|
||||
clientMsg.data.l[2] = 0;
|
||||
|
|
@ -1703,7 +1688,7 @@ public:
|
|||
clientMsg.window = windowH;
|
||||
clientMsg.type = ClientMessage;
|
||||
clientMsg.format = 32;
|
||||
clientMsg.message_type = Atoms::get().changeState;
|
||||
clientMsg.message_type = atoms.changeState;
|
||||
clientMsg.data.l[0] = IconicState;
|
||||
|
||||
ScopedXLock xlock;
|
||||
|
|
@ -1718,7 +1703,6 @@ public:
|
|||
bool isMinimised() const override
|
||||
{
|
||||
ScopedXLock xlock;
|
||||
const Atoms& atoms = Atoms::get();
|
||||
GetXProperty prop (windowH, atoms.state, 0, 64, false, atoms.state);
|
||||
|
||||
return prop.success
|
||||
|
|
@ -1853,7 +1837,7 @@ public:
|
|||
ev.xclient.type = ClientMessage;
|
||||
ev.xclient.serial = 0;
|
||||
ev.xclient.send_event = True;
|
||||
ev.xclient.message_type = Atoms::get().activeWin;
|
||||
ev.xclient.message_type = atoms.activeWin;
|
||||
ev.xclient.window = windowH;
|
||||
ev.xclient.format = 32;
|
||||
ev.xclient.data.l[0] = 2;
|
||||
|
|
@ -2412,8 +2396,6 @@ public:
|
|||
|
||||
void handleClientMessageEvent (XClientMessageEvent& clientMsg, XEvent& event)
|
||||
{
|
||||
const Atoms& atoms = Atoms::get();
|
||||
|
||||
if (clientMsg.message_type == atoms.protocols && clientMsg.format == 32)
|
||||
{
|
||||
const Atom atom = (Atom) clientMsg.data.l[0];
|
||||
|
|
@ -2684,6 +2666,7 @@ private:
|
|||
JUCE_DECLARE_NON_COPYABLE (LinuxRepaintManager)
|
||||
};
|
||||
|
||||
const Atoms atoms;
|
||||
ScopedPointer<LinuxRepaintManager> repainter;
|
||||
|
||||
friend class LinuxRepaintManager;
|
||||
|
|
@ -2917,7 +2900,7 @@ private:
|
|||
|
||||
netHints[1] = Atoms::getIfExists ("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE");
|
||||
|
||||
xchangeProperty (windowH, Atoms::get().windowType, XA_ATOM, 32, &netHints, 2);
|
||||
xchangeProperty (windowH, atoms.windowType, XA_ATOM, 32, &netHints, 2);
|
||||
|
||||
int numHints = 0;
|
||||
|
||||
|
|
@ -2928,7 +2911,7 @@ private:
|
|||
netHints [numHints++] = Atoms::getIfExists ("_NET_WM_STATE_ABOVE");
|
||||
|
||||
if (numHints > 0)
|
||||
xchangeProperty (windowH, Atoms::get().windowState, XA_ATOM, 32, &netHints, numHints);
|
||||
xchangeProperty (windowH, atoms.windowState, XA_ATOM, 32, &netHints, numHints);
|
||||
}
|
||||
|
||||
void createWindow (Window parentToAddTo)
|
||||
|
|
@ -3007,8 +2990,6 @@ private:
|
|||
|
||||
setTitle (component.getName());
|
||||
|
||||
const Atoms& atoms = Atoms::get();
|
||||
|
||||
// Associate the PID, allowing to be shut down when something goes wrong
|
||||
unsigned long pid = (unsigned long) getpid();
|
||||
xchangeProperty (windowH, atoms.pid, XA_CARDINAL, 32, &pid, 1);
|
||||
|
|
@ -3072,7 +3053,7 @@ private:
|
|||
|
||||
long getUserTime() const
|
||||
{
|
||||
GetXProperty prop (windowH, Atoms::get().userTime, 0, 65536, false, XA_CARDINAL);
|
||||
GetXProperty prop (windowH, atoms.userTime, 0, 65536, false, XA_CARDINAL);
|
||||
return prop.success ? *(long*) prop.data : 0;
|
||||
}
|
||||
|
||||
|
|
@ -3129,10 +3110,14 @@ private:
|
|||
//==============================================================================
|
||||
struct DragState
|
||||
{
|
||||
DragState() noexcept
|
||||
DragState()
|
||||
: isText (false), dragging (false), expectingStatus (false),
|
||||
canDrop (false), targetWindow (None), xdndVersion (-1)
|
||||
{
|
||||
if (isText)
|
||||
allowedTypes.add (Atoms::getCreating ("text/plain"));
|
||||
else
|
||||
allowedTypes.add (Atoms::getCreating ("text/uri-list"));
|
||||
}
|
||||
|
||||
bool isText;
|
||||
|
|
@ -3143,21 +3128,7 @@ private:
|
|||
int xdndVersion; // negotiated version with target
|
||||
Rectangle<int> silentRect;
|
||||
String textOrFiles;
|
||||
|
||||
const Atom* getMimeTypes() const noexcept { return isText ? Atoms::get().externalAllowedTextMimeTypes
|
||||
: Atoms::get().externalAllowedFileMimeTypes; }
|
||||
|
||||
int getNumMimeTypes() const noexcept { return isText ? numElementsInArray (Atoms::get().externalAllowedTextMimeTypes)
|
||||
: numElementsInArray (Atoms::get().externalAllowedFileMimeTypes); }
|
||||
|
||||
bool matchesTarget (Atom targetType) const
|
||||
{
|
||||
for (int i = getNumMimeTypes(); --i >= 0;)
|
||||
if (getMimeTypes()[i] == targetType)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
Array<Atom> allowedTypes;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -3205,7 +3176,7 @@ private:
|
|||
XClientMessageEvent msg;
|
||||
zerostruct (msg);
|
||||
|
||||
msg.message_type = Atoms::get().XdndDrop;
|
||||
msg.message_type = atoms.XdndDrop;
|
||||
msg.data.l[2] = CurrentTime;
|
||||
|
||||
sendExternalDragAndDropMessage (msg, targetWindow);
|
||||
|
|
@ -3216,15 +3187,11 @@ private:
|
|||
XClientMessageEvent msg;
|
||||
zerostruct (msg);
|
||||
|
||||
msg.message_type = Atoms::get().XdndEnter;
|
||||
msg.message_type = atoms.XdndEnter;
|
||||
msg.data.l[1] = (dragState.xdndVersion << 24);
|
||||
|
||||
const Atom* mimeTypes = dragState.getMimeTypes();
|
||||
const int numMimeTypes = dragState.getNumMimeTypes();
|
||||
|
||||
msg.data.l[1] = (dragState.xdndVersion << 24) | (numMimeTypes > 3);
|
||||
msg.data.l[2] = numMimeTypes > 0 ? (long) mimeTypes[0] : 0;
|
||||
msg.data.l[3] = numMimeTypes > 1 ? (long) mimeTypes[1] : 0;
|
||||
msg.data.l[4] = numMimeTypes > 2 ? (long) mimeTypes[2] : 0;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
msg.data.l[i + 2] = (long) dragState.allowedTypes[i];
|
||||
|
||||
sendExternalDragAndDropMessage (msg, targetWindow);
|
||||
}
|
||||
|
|
@ -3234,7 +3201,7 @@ private:
|
|||
XClientMessageEvent msg;
|
||||
zerostruct (msg);
|
||||
|
||||
msg.message_type = Atoms::get().XdndPosition;
|
||||
msg.message_type = atoms.XdndPosition;
|
||||
|
||||
Point<int> mousePos (Desktop::getInstance().getMousePosition());
|
||||
|
||||
|
|
@ -3245,7 +3212,7 @@ private:
|
|||
msg.data.l[1] = 0;
|
||||
msg.data.l[2] = (mousePos.x << 16) | mousePos.y;
|
||||
msg.data.l[3] = CurrentTime;
|
||||
msg.data.l[4] = (long) Atoms::get().XdndActionCopy; // this is all JUCE currently supports
|
||||
msg.data.l[4] = (long) atoms.XdndActionCopy; // this is all JUCE currently supports
|
||||
|
||||
dragState.expectingStatus = sendExternalDragAndDropMessage (msg, targetWindow);
|
||||
}
|
||||
|
|
@ -3255,7 +3222,7 @@ private:
|
|||
XClientMessageEvent msg;
|
||||
zerostruct (msg);
|
||||
|
||||
msg.message_type = Atoms::get().XdndStatus;
|
||||
msg.message_type = atoms.XdndStatus;
|
||||
msg.data.l[1] = (acceptDrop ? 1 : 0) | 2; // 2 indicates that we want to receive position messages
|
||||
msg.data.l[4] = (long) dropAction;
|
||||
|
||||
|
|
@ -3267,7 +3234,7 @@ private:
|
|||
XClientMessageEvent msg;
|
||||
zerostruct (msg);
|
||||
|
||||
msg.message_type = Atoms::get().XdndLeave;
|
||||
msg.message_type = atoms.XdndLeave;
|
||||
sendExternalDragAndDropMessage (msg, targetWindow);
|
||||
}
|
||||
|
||||
|
|
@ -3276,7 +3243,7 @@ private:
|
|||
XClientMessageEvent msg;
|
||||
zerostruct (msg);
|
||||
|
||||
msg.message_type = Atoms::get().XdndFinished;
|
||||
msg.message_type = atoms.XdndFinished;
|
||||
sendDragAndDropMessage (msg);
|
||||
}
|
||||
|
||||
|
|
@ -3298,7 +3265,7 @@ private:
|
|||
s.xselection.property = None;
|
||||
s.xselection.time = evt.xselectionrequest.time;
|
||||
|
||||
if (dragState.matchesTarget (targetType))
|
||||
if (dragState.allowedTypes.contains (targetType))
|
||||
{
|
||||
s.xselection.property = evt.xselectionrequest.property;
|
||||
|
||||
|
|
@ -3321,8 +3288,8 @@ private:
|
|||
dragState.silentRect = Rectangle<int>();
|
||||
|
||||
if ((clientMsg.data.l[1] & 1) != 0
|
||||
&& ((Atom) clientMsg.data.l[4] == Atoms::get().XdndActionCopy
|
||||
|| (Atom) clientMsg.data.l[4] == Atoms::get().XdndActionPrivate))
|
||||
&& ((Atom) clientMsg.data.l[4] == atoms.XdndActionCopy
|
||||
|| (Atom) clientMsg.data.l[4] == atoms.XdndActionPrivate))
|
||||
{
|
||||
if ((clientMsg.data.l[1] & 2) == 0) // target requests silent rectangle
|
||||
dragState.silentRect.setBounds ((int) clientMsg.data.l[2] >> 16,
|
||||
|
|
@ -3366,7 +3333,7 @@ private:
|
|||
if (targetWindow == None)
|
||||
return;
|
||||
|
||||
GetXProperty prop (targetWindow, Atoms::get().XdndAware,
|
||||
GetXProperty prop (targetWindow, atoms.XdndAware,
|
||||
0, 2, false, AnyPropertyType);
|
||||
|
||||
if (prop.success
|
||||
|
|
@ -3401,7 +3368,6 @@ private:
|
|||
(int) clientMsg.data.l[2] & 0xffff);
|
||||
dropPos -= bounds.getPosition();
|
||||
|
||||
const Atoms& atoms = Atoms::get();
|
||||
Atom targetAction = atoms.XdndActionCopy;
|
||||
|
||||
for (int i = numElementsInArray (atoms.allowedActions); --i >= 0;)
|
||||
|
|
@ -3471,7 +3437,7 @@ private:
|
|||
if ((clientMsg.data.l[1] & 1) != 0)
|
||||
{
|
||||
ScopedXLock xlock;
|
||||
GetXProperty prop (dragAndDropSourceWindow, Atoms::get().XdndTypeList, 0, 0x8000000L, false, XA_ATOM);
|
||||
GetXProperty prop (dragAndDropSourceWindow, atoms.XdndTypeList, 0, 0x8000000L, false, XA_ATOM);
|
||||
|
||||
if (prop.success
|
||||
&& prop.actualType == XA_ATOM
|
||||
|
|
@ -3499,7 +3465,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
const Atoms& atoms = Atoms::get();
|
||||
for (int i = 0; i < srcMimeTypeAtomList.size() && dragAndDropCurrentMimeType == 0; ++i)
|
||||
for (int j = 0; j < numElementsInArray (atoms.allowedMimeTypes); ++j)
|
||||
if (srcMimeTypeAtomList[i] == atoms.allowedMimeTypes[j])
|
||||
|
|
@ -3563,7 +3528,7 @@ private:
|
|||
{
|
||||
ScopedXLock xlock;
|
||||
XConvertSelection (display,
|
||||
Atoms::get().XdndSelection,
|
||||
atoms.XdndSelection,
|
||||
dragAndDropCurrentMimeType,
|
||||
Atoms::getCreating ("JXSelectionWindowProperty"),
|
||||
windowH,
|
||||
|
|
@ -3571,18 +3536,18 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
static bool isWindowDnDAware (Window w)
|
||||
bool isWindowDnDAware (Window w) const
|
||||
{
|
||||
int numProperties = 0;
|
||||
Atom* const atoms = XListProperties (display, w, &numProperties);
|
||||
Atom* const properties = XListProperties (display, w, &numProperties);
|
||||
|
||||
bool dndAwarePropFound = false;
|
||||
for (int i = 0; i < numProperties; ++i)
|
||||
if (atoms[i] == Atoms::get().XdndAware)
|
||||
if (properties[i] == atoms.XdndAware)
|
||||
dndAwarePropFound = true;
|
||||
|
||||
if (atoms != nullptr)
|
||||
XFree (atoms);
|
||||
if (properties != nullptr)
|
||||
XFree (properties);
|
||||
|
||||
return dndAwarePropFound;
|
||||
}
|
||||
|
|
@ -3622,13 +3587,12 @@ private:
|
|||
// No other method of changing the pointer seems to work, this call is needed from this very context
|
||||
XChangeActivePointerGrab (display, pointerGrabMask, (Cursor) createDraggingHandCursor(), CurrentTime);
|
||||
|
||||
const Atoms& atoms = Atoms::get();
|
||||
XSetSelectionOwner (display, atoms.XdndSelection, windowH, CurrentTime);
|
||||
|
||||
// save the available types to XdndTypeList
|
||||
xchangeProperty (windowH, atoms.XdndTypeList, XA_ATOM, 32,
|
||||
dragState.getMimeTypes(),
|
||||
dragState.getNumMimeTypes());
|
||||
dragState.allowedTypes.getRawDataPointer(),
|
||||
dragState.allowedTypes.size());
|
||||
|
||||
dragState.dragging = true;
|
||||
handleExternalDragMotionNotify();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue