Browse Source

Simplified some linux X11 code involving atoms

tags/2021-05-28
jules 9 years ago
parent
commit
50af60fa81
1 changed files with 74 additions and 110 deletions
  1. +74
    -110
      modules/juce_gui_basics/native/juce_linux_Windowing.cpp

+ 74
- 110
modules/juce_gui_basics/native/juce_linux_Windowing.cpp View File

@@ -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);
XFlush (display);
XDestroyImage (xImage);
shmdt (segmentInfo.shmaddr);
}
shmdt (segmentInfo.shmaddr);
}
shmctl (segmentInfo.shmid, IPC_RMID, 0);
shmctl (segmentInfo.shmid, IPC_RMID, 0);
XSetErrorHandler (oldHandler);
if (trappedErrorCode != 0)
isAvailable = false;
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;
const Atom* mimeTypes = dragState.getMimeTypes();
const int numMimeTypes = dragState.getNumMimeTypes();
msg.message_type = atoms.XdndEnter;
msg.data.l[1] = (dragState.xdndVersion << 24);
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…
Cancel
Save