add juce, a very nice C++ application framework. the .bb is WIP
authorMichael Lauer <mickey@vanille-media.de>
Wed, 19 Apr 2006 17:15:59 +0000 (17:15 +0000)
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>
Wed, 19 Apr 2006 17:15:59 +0000 (17:15 +0000)
packages/juce/.mtn2git_empty [new file with mode: 0644]
packages/juce/files/.mtn2git_empty [new file with mode: 0644]
packages/juce/files/no-opengl.patch [new file with mode: 0644]
packages/juce/files/remove-x86isms.patch [new file with mode: 0644]
packages/juce/juce_1.29.bb [new file with mode: 0644]

diff --git a/packages/juce/.mtn2git_empty b/packages/juce/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/juce/files/.mtn2git_empty b/packages/juce/files/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/juce/files/no-opengl.patch b/packages/juce/files/no-opengl.patch
new file mode 100644 (file)
index 0000000..dd37934
--- /dev/null
@@ -0,0 +1,4477 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- juce/demo/build/linux/JuceDemo.make~no-opengl
++++ juce/demo/build/linux/JuceDemo.make
+@@ -13,7 +13,7 @@
+   CPPFLAGS := -MD -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include"
+   CFLAGS += $(CPPFLAGS) -g -D_DEBUG -ggdb
+   CXXFLAGS := $(CFLAGS)
+-  LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L "/usr/X11R6/lib/" -L "../../../bin" -lfreetype -lpthread -lX11 -lGL -lGLU -lXinerama -lasound -ljuce_debug
++  LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L "/usr/X11R6/lib/" -L "../../../bin" -lfreetype -lpthread -lX11 -lasound -ljuce_debug
+   LDDEPS :=
+   TARGET := jucedemo
+ endif
+@@ -26,7 +26,7 @@
+   CPPFLAGS := -MD -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include"
+   CFLAGS += $(CPPFLAGS) -O2
+   CXXFLAGS := $(CFLAGS)
+-  LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -s -L "/usr/X11R6/lib/" -L "../../../bin" -lfreetype -lpthread -lX11 -lGL -lGLU -lXinerama -lasound -ljuce
++  LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -s -L "/usr/X11R6/lib/" -L "../../../bin" -lfreetype -lpthread -lX11 -lasound -ljuce
+   LDDEPS :=
+   TARGET := jucedemo
+ endif
+@@ -39,7 +39,6 @@
+       $(OBJDIR)/DragAndDropDemo.o \
+       $(OBJDIR)/FontsAndTextDemo.o \
+       $(OBJDIR)/InterprocessCommsDemo.o \
+-      $(OBJDIR)/OpenGLDemo.o \
+       $(OBJDIR)/PathsAndTransformsDemo.o \
+       $(OBJDIR)/QuickTimeDemo.o \
+       $(OBJDIR)/ThreadingDemo.o \
+--- juce/platform_specific_code/juce_linux_Windowing.cpp
++++ /dev/null
+--- juce/linux/platform_specific_code/juce_linux_Windowing.cpp
++++ /dev/null
+--- juce/build/linux/platform_specific_code/juce_linux_Windowing.cpp~no-opengl
++++ juce/build/linux/platform_specific_code/juce_linux_Windowing.cpp
+@@ -1,2218 +1,2219 @@
+-/*\r
+-  ==============================================================================\r
+-\r
+-   This file is part of the JUCE library - "Jules' Utility Class Extensions"\r
+-   Copyright 2004-6 by Raw Material Software ltd.\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   JUCE can be redistributed and/or modified under the terms of the\r
+-   GNU General Public License, as published by the Free Software Foundation;\r
+-   either version 2 of the License, or (at your option) any later version.\r
+-\r
+-   JUCE is distributed in the hope that it will be useful,\r
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+-   GNU General Public License for more details.\r
+-\r
+-   You should have received a copy of the GNU General Public License\r
+-   along with JUCE; if not, visit www.gnu.org/licenses or write to the\r
+-   Free Software Foundation, Inc., 59 Temple Place, Suite 330, \r
+-   Boston, MA 02111-1307 USA\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   If you'd like to release a closed-source product which uses JUCE, commercial\r
+-   licenses are also available: visit www.rawmaterialsoftware.com/juce for\r
+-   more information.\r
+-\r
+-  ==============================================================================\r
+-*/\r
+-\r
+-#include "juce_Config.h"\r
+-#if JUCE_BUILD_GUI_CLASSES\r
+-\r
+-#include "linuxincludes.h"\r
+-#include <X11/Xlib.h>\r
+-#include <X11/Xutil.h>\r
+-#include <X11/Xatom.h>\r
+-#include <X11/Xmd.h>\r
+-#include <X11/keysym.h>\r
+-#include <X11/cursorfont.h>\r
+-\r
+-#include "../../../juce_Config.h"\r
+-\r
+-#if JUCE_USE_XINERAMA\r
+-#include <X11/extensions/Xinerama.h>\r
+-#endif\r
+-\r
+-#if JUCE_OPENGL\r
+-#include <X11/Xlib.h>\r
+-#include <GL/glx.h>\r
+-#endif\r
+-\r
+-#undef KeyPress\r
+-\r
+-#include "../../../src/juce_core/basics/juce_StandardHeader.h"\r
+-\r
+-BEGIN_JUCE_NAMESPACE\r
+-\r
+-#include "../../../src/juce_appframework/events/juce_Timer.h"\r
+-#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"\r
+-#include "../../../src/juce_appframework/gui/components/keyboard/juce_KeyPress.h"\r
+-#include "../../../src/juce_appframework/application/juce_SystemClipboard.h"\r
+-#include "../../../src/juce_appframework/gui/components/windows/juce_AlertWindow.h"\r
+-#include "../../../src/juce_appframework/gui/components/special/juce_OpenGLComponent.h"\r
+-#include "../../../src/juce_appframework/gui/components/juce_Desktop.h"\r
+-#include "../../../src/juce_appframework/events/juce_MessageManager.h"\r
+-#include "../../../src/juce_appframework/gui/components/juce_RepaintManager.h"\r
+-#include "../../../src/juce_appframework/gui/components/juce_ComponentDeletionWatcher.h"\r
+-#include "../../../src/juce_appframework/gui/graphics/geometry/juce_RectangleList.h"\r
+-#include "../../../src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.h"\r
+-#include "../../../src/juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h"\r
+-#include "../../../src/juce_core/basics/juce_Logger.h"\r
+-#include "../../../src/juce_core/threads/juce_Process.h"\r
+-#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"\r
+-\r
+-\r
+-//==============================================================================\r
+-static Atom wm_ChangeState = None;\r
+-static Atom wm_State = None;\r
+-static Atom wm_Protocols = None;\r
+-static Atom wm_ProtocolList [2] = { None, None };\r
+-static Atom wm_ActiveWin = None;\r
+-static Atom repaintId = None;\r
+-\r
+-#define TAKE_FOCUS 0\r
+-#define DELETE_WINDOW 1\r
+-\r
+-//==============================================================================\r
+-static bool isActiveApplication = false;\r
+-\r
+-bool Process::isForegroundProcess()\r
+-{\r
+-    return isActiveApplication;\r
+-}\r
+-\r
+-//==============================================================================\r
+-// These are defined in juce_linux_Messages.cpp\r
+-extern Display* display;\r
+-extern XContext improbableNumber;\r
+-\r
+-const int juce_windowIsSemiTransparentFlag = (1 << 31); // also in component.cpp\r
+-\r
+-static const int eventMask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask\r
+-                             | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask\r
+-                             | ExposureMask | StructureNotifyMask | FocusChangeMask;\r
+-\r
+-//==============================================================================\r
+-static int pointerMap[5];\r
+-static int lastMousePosX = 0, lastMousePosY = 0;\r
+-\r
+-enum MouseButtons\r
+-{\r
+-    NoButton = 0,\r
+-    LeftButton = 1,\r
+-    MiddleButton = 2,\r
+-    RightButton = 3,\r
+-    WheelUp = 4,\r
+-    WheelDown = 5\r
+-};\r
+-\r
+-static void getMousePos (int& x, int& y, int& mouseMods)\r
+-{\r
+-    Window root, child;\r
+-    int winx, winy;\r
+-    unsigned int mask;\r
+-\r
+-    mouseMods = 0;\r
+-\r
+-    if (XQueryPointer (display,\r
+-                       RootWindow (display, DefaultScreen (display)),\r
+-                       &root, &child,\r
+-                       &x, &y, &winx, &winy, &mask) == False)\r
+-    {\r
+-        // Pointer not on the default screen\r
+-        x = y = -1;\r
+-    }\r
+-    else\r
+-    {\r
+-        if ((mask & Button1Mask) != 0)\r
+-            mouseMods |= ModifierKeys::leftButtonModifier;\r
+-\r
+-        if ((mask & Button2Mask) != 0)\r
+-            mouseMods |= ModifierKeys::middleButtonModifier;\r
+-\r
+-        if ((mask & Button3Mask) != 0)\r
+-            mouseMods |= ModifierKeys::rightButtonModifier;\r
+-    }\r
+-}\r
+-\r
+-//==============================================================================\r
+-static int AltMask = 0;\r
+-static int NumLockMask = 0;\r
+-static bool numLock = 0;\r
+-static bool capsLock = 0;\r
+-static char keyStates [32];\r
+-\r
+-static void updateKeyStates (const int keycode, const bool press)\r
+-{\r
+-    const int keybyte = keycode >> 3;\r
+-    const int keybit = (1 << (keycode & 7));\r
+-\r
+-    if (press)\r
+-        keyStates [keybyte] |= keybit;\r
+-    else\r
+-        keyStates [keybyte] &= ~keybit;\r
+-}\r
+-\r
+-static bool keyDown (const int keycode)\r
+-{\r
+-    const int keybyte = keycode >> 3;\r
+-    const int keybit = (1 << (keycode & 7));\r
+-\r
+-    return (keyStates [keybyte] & keybit) != 0;\r
+-}\r
+-\r
+-static const int nonAsciiModifier = 0x10000;\r
+-\r
+-bool KeyPress::isKeyCurrentlyDown (int keyCode)\r
+-{\r
+-    int keysym;\r
+-\r
+-    if (keyCode & nonAsciiModifier)\r
+-    {\r
+-        keysym = 0xff00 | (keyCode & 0xff);\r
+-    }\r
+-    else\r
+-    {\r
+-        keysym = keyCode;\r
+-\r
+-        if (keysym == (XK_Tab & 0xff)\r
+-            || keysym == (XK_Return & 0xff)\r
+-            || keysym == (XK_Escape & 0xff)\r
+-            || keysym == (XK_BackSpace & 0xff))\r
+-        {\r
+-            keysym |= 0xff00;\r
+-        }\r
+-    }\r
+-\r
+-    return keyDown (XKeysymToKeycode (display, keysym));\r
+-}\r
+-\r
+-//==============================================================================\r
+-// Alt and Num lock are not defined by standard X\r
+-// modifier constants: check what they're mapped to\r
+-static void getModifierMapping()\r
+-{\r
+-    const int altLeftCode = XKeysymToKeycode (display, XK_Alt_L);\r
+-    const int numLockCode = XKeysymToKeycode (display, XK_Num_Lock);\r
+-\r
+-    AltMask = 0;\r
+-    NumLockMask = 0;\r
+-\r
+-    XModifierKeymap* mapping = XGetModifierMapping (display);\r
+-\r
+-    if (mapping)\r
+-    {\r
+-        for (int i = 0; i < 8; i++)\r
+-        {\r
+-            if (mapping->modifiermap [i << 1] == altLeftCode)\r
+-                AltMask = 1 << i;\r
+-            else if (mapping->modifiermap [i << 1] == numLockCode)\r
+-                NumLockMask = 1 << i;\r
+-        }\r
+-\r
+-        XFreeModifiermap (mapping);\r
+-    }\r
+-}\r
+-\r
+-static int currentModifiers = 0;\r
+-\r
+-void ModifierKeys::updateCurrentModifiers()\r
+-{\r
+-    currentModifierFlags = currentModifiers;\r
+-}\r
+-\r
+-const ModifierKeys ModifierKeys::getCurrentModifiersRealtime()\r
+-{\r
+-    int x, y, mouseMods;\r
+-    getMousePos (x, y, mouseMods);\r
+-\r
+-    currentModifiers &= ~ModifierKeys::allMouseButtonModifiers;\r
+-    currentModifiers |= mouseMods;\r
+-\r
+-    return ModifierKeys (currentModifiers);\r
+-}\r
+-\r
+-static void updateKeyModifiers (const int status)\r
+-{\r
+-    currentModifiers &= ~(ModifierKeys::shiftModifier\r
+-                           | ModifierKeys::ctrlModifier\r
+-                           | ModifierKeys::altModifier);\r
+-\r
+-    if (status & ShiftMask)\r
+-        currentModifiers |= ModifierKeys::shiftModifier;\r
+-\r
+-    if (status & ControlMask)\r
+-        currentModifiers |= ModifierKeys::ctrlModifier;\r
+-\r
+-    if (status & AltMask)\r
+-        currentModifiers |= ModifierKeys::altModifier;\r
+-\r
+-    numLock  = ((status & NumLockMask) != 0);\r
+-    capsLock = ((status & LockMask) != 0);\r
+-}\r
+-\r
+-static bool updateKeyModifiersFromSym (KeySym sym, const bool press)\r
+-{\r
+-    int modifier = 0;\r
+-    bool isModifier = true;\r
+-\r
+-    switch (sym)\r
+-    {\r
+-        case XK_Shift_L:\r
+-        case XK_Shift_R:\r
+-            modifier = ModifierKeys::shiftModifier;\r
+-            break;\r
+-\r
+-        case XK_Control_L:\r
+-        case XK_Control_R:\r
+-            modifier = ModifierKeys::ctrlModifier;\r
+-            break;\r
+-\r
+-        case XK_Alt_L:\r
+-        case XK_Alt_R:\r
+-            modifier = ModifierKeys::altModifier;\r
+-            break;\r
+-\r
+-        case XK_Num_Lock:\r
+-            if (press)\r
+-                numLock = ! numLock;\r
+-\r
+-            break;\r
+-\r
+-        case XK_Caps_Lock:\r
+-            if (press)\r
+-                capsLock = ! capsLock;\r
+-\r
+-            break;\r
+-\r
+-        case XK_Scroll_Lock:\r
+-            break;\r
+-\r
+-        default:\r
+-            isModifier = false;\r
+-            break;\r
+-    }\r
+-\r
+-    if (modifier != 0)\r
+-    {\r
+-        if (press)\r
+-            currentModifiers |= modifier;\r
+-        else\r
+-            currentModifiers &= ~modifier;\r
+-    }\r
+-\r
+-    return isModifier;\r
+-}\r
+-\r
+-\r
+-//==============================================================================\r
+-class XBitmapImage  : public Image\r
+-{\r
+-public:\r
+-    //==============================================================================\r
+-    XBitmapImage (const PixelFormat format_, const int w, const int h, const bool clearImage)\r
+-        : Image (format_, w, h)\r
+-    {\r
+-        jassert (format_ == RGB || format_ == ARGB);\r
+-\r
+-        pixelStride = (format_ == RGB) ? 3 : 4;\r
+-        lineStride = ((w * pixelStride + 3) & ~3);\r
+-        imageData = (uint8*) juce_malloc (lineStride * h);\r
+-\r
+-        if (format_ == ARGB && clearImage)\r
+-            zeromem (xImage->data, h * lineStride);\r
+-\r
+-        xImage = new XImage();\r
+-        xImage->width = w;\r
+-        xImage->height = h;\r
+-        xImage->xoffset = 0;\r
+-        xImage->format = ZPixmap;\r
+-        xImage->data = (char*) imageData;\r
+-        xImage->byte_order = ImageByteOrder (display);\r
+-        xImage->bitmap_unit = BitmapUnit (display);\r
+-        xImage->bitmap_bit_order = BitmapBitOrder (display);\r
+-        xImage->bitmap_pad = 32;\r
+-        xImage->depth = pixelStride * 8;\r
+-        xImage->bytes_per_line = lineStride;\r
+-        xImage->bits_per_pixel = pixelStride * 8;\r
+-        xImage->red_mask   = 0x00FF0000;\r
+-        xImage->green_mask = 0x0000FF00;\r
+-        xImage->blue_mask  = 0x000000FF;\r
+-\r
+-        if (! XInitImage (xImage))\r
+-        {\r
+-            jassertfalse\r
+-        }\r
+-    }\r
+-\r
+-    ~XBitmapImage()\r
+-    {\r
+-        juce_free (xImage->data);\r
+-        xImage->data = 0;\r
+-        XDestroyImage (xImage);\r
+-        imageData = 0; // to stop the base class freeing this\r
+-    }\r
+-\r
+-    void blitToWindow (Window window, int dx, int dy, int dw, int dh, int sx, int sy)\r
+-    {\r
+-        static GC gc = 0;\r
+-\r
+-        if (gc == 0)\r
+-            gc = DefaultGC (display, DefaultScreen (display));\r
+-\r
+-        // blit results to screen.\r
+-        XPutImage (display, (Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh);\r
+-    }\r
+-\r
+-    //==============================================================================\r
+-    juce_UseDebuggingNewOperator\r
+-\r
+-private:\r
+-    XImage* xImage;\r
+-};\r
+-\r
+-\r
+-//==============================================================================\r
+-class LinuxComponentPeer  : public ComponentPeer\r
+-{\r
+-public:\r
+-    //==============================================================================\r
+-    LinuxComponentPeer (Component* const component, const int windowStyleFlags)\r
+-        : ComponentPeer (component, windowStyleFlags),\r
+-          windowH (0),\r
+-          wx (0),\r
+-          wy (0),\r
+-          ww (0),\r
+-          wh (0),\r
+-          fullScreen (false),\r
+-          entered (false),\r
+-          mapped (false)\r
+-    {\r
+-        repainter = new LinuxRepaintManager (this, component, 3000);\r
+-\r
+-        MessageManager::getInstance()\r
+-           ->callFunctionOnMessageThread (&createWindowCallback, (void*) this);\r
+-\r
+-        setTitle (component->getName());\r
+-    }\r
+-\r
+-    ~LinuxComponentPeer()\r
+-    {\r
+-        MessageManager::getInstance()\r
+-            ->callFunctionOnMessageThread (&destroyWindowCallback, (void*) windowH);\r
+-\r
+-        windowH = 0;\r
+-        delete repainter;\r
+-    }\r
+-\r
+-    //==============================================================================\r
+-    void* getNativeHandle() const\r
+-    {\r
+-        return (void*) windowH;\r
+-    }\r
+-\r
+-    void setVisible (bool shouldBeVisible)\r
+-    {\r
+-        if (shouldBeVisible)\r
+-            XMapWindow (display, windowH);\r
+-        else\r
+-            XUnmapWindow (display, windowH);\r
+-    }\r
+-\r
+-    void setTitle (const String& title)\r
+-    {\r
+-        setWindowTitle (windowH, title);\r
+-    }\r
+-\r
+-    void setPosition (int x, int y)\r
+-    {\r
+-        setBounds (x, y, ww, wh, false);\r
+-    }\r
+-\r
+-    void setSize (int w, int h)\r
+-    {\r
+-        setBounds (wx, wy, w, h, false);\r
+-    }\r
+-\r
+-    void setBounds (int x, int y, int w, int h, const bool isNowFullScreen)\r
+-    {\r
+-        fullScreen = isNowFullScreen;\r
+-\r
+-        if (windowH != 0)\r
+-        {\r
+-            const ComponentDeletionWatcher deletionChecker (component);\r
+-\r
+-            wx = x;\r
+-            wy = y;\r
+-            ww = jmax (1, w);\r
+-            wh = jmax (1, h);\r
+-\r
+-            if (! mapped)\r
+-            {\r
+-                // Make sure the Window manager does what we want\r
+-                XSizeHints* hints = XAllocSizeHints();\r
+-                hints->flags = USSize | USPosition;\r
+-                hints->width = ww + windowBorder.getLeftAndRight();\r
+-                hints->height = wh + windowBorder.getTopAndBottom();\r
+-                hints->x = wx - windowBorder.getLeft();\r
+-                hints->y = wy - windowBorder.getTop();\r
+-                XSetWMNormalHints (display, windowH, hints);\r
+-                XFree (hints);\r
+-            }\r
+-\r
+-            XMoveResizeWindow (display, windowH,\r
+-                               wx - windowBorder.getLeft(),\r
+-                               wy - windowBorder.getTop(),\r
+-                               ww + windowBorder.getLeftAndRight(),\r
+-                               wh + windowBorder.getTopAndBottom());\r
+-\r
+-            if (! deletionChecker.hasBeenDeleted())\r
+-            {\r
+-                updateBorderSize();\r
+-                handleMovedOrResized();\r
+-            }\r
+-        }\r
+-    }\r
+-\r
+-    void getBounds (int& x, int& y, int& w, int& h) const\r
+-    {\r
+-        x = wx;\r
+-        y = wy;\r
+-        w = ww;\r
+-        h = wh;\r
+-    }\r
+-\r
+-    int getScreenX() const\r
+-    {\r
+-        return wx;\r
+-    }\r
+-\r
+-    int getScreenY() const\r
+-    {\r
+-        return wy;\r
+-    }\r
+-\r
+-    void setMinimised (bool shouldBeMinimised)\r
+-    {\r
+-        if (shouldBeMinimised)\r
+-        {\r
+-            Window root = RootWindow (display, DefaultScreen (display));\r
+-\r
+-            XClientMessageEvent clientMsg;\r
+-            clientMsg.display = display;\r
+-            clientMsg.window = windowH;\r
+-            clientMsg.type = ClientMessage;\r
+-            clientMsg.format = 32;\r
+-            clientMsg.message_type = wm_ChangeState;\r
+-            clientMsg.data.l[0] = IconicState;\r
+-\r
+-            XSendEvent (display, root, false,\r
+-                        SubstructureRedirectMask | SubstructureNotifyMask,\r
+-                        (XEvent*) &clientMsg);\r
+-        }\r
+-        else\r
+-        {\r
+-            setVisible (true);\r
+-        }\r
+-    }\r
+-\r
+-    bool isMinimised() const\r
+-    {\r
+-        bool minimised = false;\r
+-\r
+-        CARD32* stateProp;\r
+-        unsigned long nitems, bytesLeft;\r
+-        Atom actualType;\r
+-        int actualFormat;\r
+-\r
+-        if (XGetWindowProperty (display, windowH, wm_State, 0, 64, False,\r
+-                                wm_State, &actualType, &actualFormat, &nitems, &bytesLeft,\r
+-                                (unsigned char**) &stateProp) == Success\r
+-            && actualType == wm_State\r
+-            && actualFormat == 32\r
+-            && nitems > 0)\r
+-        {\r
+-            if (stateProp[0] == IconicState)\r
+-                minimised = true;\r
+-\r
+-            XFree (stateProp);\r
+-        }\r
+-\r
+-        return minimised;\r
+-    }\r
+-\r
+-    void setFullScreen (bool shouldBeFullScreen)\r
+-    {\r
+-        setMinimised (false);\r
+-\r
+-        if (fullScreen != shouldBeFullScreen)\r
+-        {\r
+-            Rectangle r (lastNonFullscreenBounds);\r
+-\r
+-            if (shouldBeFullScreen)\r
+-                r = Desktop::getInstance().getMainMonitorArea();\r
+-\r
+-            if (! r.isEmpty())\r
+-                setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);\r
+-\r
+-            getComponent()->repaint();\r
+-        }\r
+-    }\r
+-\r
+-    bool isFullScreen() const\r
+-    {\r
+-        return fullScreen;\r
+-    }\r
+-\r
+-    bool isChildWindowOf (Window possibleParent) const\r
+-    {\r
+-        Window* windowList = 0;\r
+-        uint32 windowListSize = 0;\r
+-        Window parent, root;\r
+-\r
+-        if (XQueryTree (display, windowH, &root, &parent, &windowList, &windowListSize) != 0)\r
+-        {\r
+-            if (windowList != 0)\r
+-                XFree (windowList);\r
+-\r
+-            return parent == possibleParent;\r
+-        }\r
+-\r
+-        return false;\r
+-    }\r
+-\r
+-    bool contains (int x, int y, bool trueIfInAChildWindow) const\r
+-    {\r
+-        jassert (x >= 0 && y >= 0 && x < ww && y < wh); // should only be called for points that are actually inside the bounds\r
+-\r
+-        x += wx;\r
+-        y += wy;\r
+-\r
+-        // the XQueryTree stuff later on is VERY slow, so if this call's just to check the mouse pos, it's\r
+-        // much more efficient to cheat..\r
+-        if (x == lastMousePosX && y == lastMousePosY)\r
+-        {\r
+-            Window root, child;\r
+-            int winx, winy;\r
+-            unsigned int mask;\r
+-\r
+-            if (XQueryPointer (display,\r
+-                               RootWindow (display, DefaultScreen (display)),\r
+-                               &root, &child,\r
+-                               &x, &y, &winx, &winy, &mask) != False)\r
+-            {\r
+-                return child == windowH\r
+-                        || (((styleFlags & windowHasTitleBar) != 0) && isChildWindowOf (child));\r
+-            }\r
+-        }\r
+-\r
+-        bool result = false;\r
+-\r
+-        Window* windowList = 0;\r
+-        uint32 windowListSize = 0;\r
+-\r
+-        Window parent, root = RootWindow (display, DefaultScreen (display));\r
+-\r
+-        if (XQueryTree (display, root, &root, &parent, &windowList, &windowListSize) != 0)\r
+-        {\r
+-            for (int i = windowListSize; --i >= 0;)\r
+-            {\r
+-                XWindowAttributes atts;\r
+-\r
+-                if (windowList[i] == windowH\r
+-                     || (((styleFlags & windowHasTitleBar) != 0) && isChildWindowOf (windowList[i])))\r
+-                {\r
+-                    result = true;\r
+-\r
+-                    if (! trueIfInAChildWindow)\r
+-                    {\r
+-                        Window child;\r
+-                        int tempX, tempY;\r
+-\r
+-                        result = XTranslateCoordinates (display, windowH, windowH,\r
+-                                                        x - wx - windowBorder.getLeft(),\r
+-                                                        y - wy - windowBorder.getTop(),\r
+-                                                        &tempX, &tempY,\r
+-                                                        &child)\r
+-                                    && (child == None);\r
+-                    }\r
+-\r
+-                    break;\r
+-                }\r
+-                else if (XGetWindowAttributes (display, windowList[i], &atts)\r
+-                          && atts.map_state == IsViewable\r
+-                          && x >= atts.x && y >= atts.y\r
+-                          && x < atts.x + atts.width\r
+-                          && y < atts.y + atts.height)\r
+-                {\r
+-                    break;\r
+-                }\r
+-            }\r
+-        }\r
+-\r
+-        if (windowList != 0)\r
+-            XFree (windowList);\r
+-\r
+-        return result;\r
+-    }\r
+-\r
+-    const BorderSize getFrameSize() const\r
+-    {\r
+-        return BorderSize();\r
+-    }\r
+-\r
+-    bool setAlwaysOnTop (bool alwaysOnTop)\r
+-    {\r
+-        if (windowH != 0)\r
+-        {\r
+-            XSetWindowAttributes swa;\r
+-            swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False;\r
+-\r
+-            XChangeWindowAttributes (display, windowH, CWOverrideRedirect, &swa);\r
+-        }\r
+-\r
+-        return true;\r
+-    }\r
+-\r
+-    void toFront (bool makeActive)\r
+-    {\r
+-        if (makeActive)\r
+-        {\r
+-            setVisible (true);\r
+-            grabFocus();\r
+-        }\r
+-\r
+-        XEvent ev;\r
+-        ev.xclient.type = ClientMessage;\r
+-        ev.xclient.serial = 0;\r
+-        ev.xclient.send_event = True;\r
+-        ev.xclient.message_type = wm_ActiveWin;\r
+-        ev.xclient.window = windowH;\r
+-        ev.xclient.format = 32;\r
+-        ev.xclient.data.l[0] = 2;\r
+-        ev.xclient.data.l[1] = CurrentTime;\r
+-        ev.xclient.data.l[2] = 0;\r
+-        ev.xclient.data.l[3] = 0;\r
+-        ev.xclient.data.l[4] = 0;\r
+-\r
+-        XSendEvent (display, RootWindow (display, DefaultScreen (display)),\r
+-                    False,\r
+-                    SubstructureRedirectMask | SubstructureNotifyMask,\r
+-                    &ev);\r
+-\r
+-        XSync (display, False);\r
+-    }\r
+-\r
+-    void toBehind (ComponentPeer* other)\r
+-    {\r
+-        LinuxComponentPeer* const otherPeer = dynamic_cast <LinuxComponentPeer*> (other);\r
+-        jassert (otherPeer != 0); // wrong type of window?\r
+-\r
+-        if (otherPeer != 0)\r
+-        {\r
+-            setMinimised (false);\r
+-\r
+-            Window newStack[] = { otherPeer->windowH, windowH };\r
+-\r
+-            XRestackWindows (display, newStack, 2);\r
+-        }\r
+-    }\r
+-\r
+-    bool isFocused() const\r
+-    {\r
+-        int revert;\r
+-        Window focus = 0;\r
+-        XGetInputFocus (display, &focus, &revert);\r
+-\r
+-        if (focus == 0 || focus == None || focus == PointerRoot)\r
+-            return 0;\r
+-\r
+-        ComponentPeer* focusedPeer = 0;\r
+-        if (XFindContext (display, (XID) focus, improbableNumber, (XPointer*) &focusedPeer) != 0)\r
+-            focusedPeer = 0;\r
+-\r
+-        return this == focusedPeer;\r
+-    }\r
+-\r
+-    void grabFocus()\r
+-    {\r
+-        XWindowAttributes atts;\r
+-\r
+-        if (windowH != 0\r
+-            && XGetWindowAttributes (display, windowH, &atts)\r
+-            && atts.map_state == IsViewable)\r
+-        {\r
+-            XSetInputFocus (display, windowH, RevertToParent, CurrentTime);\r
+-\r
+-            if (! isActiveApplication)\r
+-            {\r
+-                isActiveApplication = true;\r
+-                handleFocusGain();\r
+-            }\r
+-        }\r
+-    }\r
+-\r
+-    void repaint (int x, int y, int w, int h)\r
+-    {\r
+-        repainter->invalidateCache (x, y, w, h);\r
+-        repainter->repaint (x, y, w, h);\r
+-    }\r
+-\r
+-    void performPendingRepaints()\r
+-    {\r
+-        repainter->performPendingRepaints();\r
+-    }\r
+-\r
+-    //==============================================================================\r
+-    void handleWindowMessage (XEvent* event)\r
+-    {\r
+-        switch (event->xany.type)\r
+-        {\r
+-            case 2: // 'KeyPress'\r
+-            {\r
+-                XKeyEvent* keyEvent = (XKeyEvent*) &event->xkey;\r
+-                updateKeyStates (keyEvent->keycode, true);\r
+-\r
+-                int index = currentModifiers & ModifierKeys::shiftModifier ? 1 : 0;\r
+-                KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, index);\r
+-\r
+-                const int oldMods = currentModifiers;\r
+-                bool keyPressed = false;\r
+-\r
+-                const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false);\r
+-\r
+-                if ((sym & 0xff00) == 0xff00)\r
+-                {\r
+-                    // Translate keypad\r
+-                    if (sym == XK_KP_Divide)\r
+-                        sym = XK_slash;\r
+-                    else if (sym == XK_KP_Multiply)\r
+-                        sym = XK_asterisk;\r
+-                    else if (sym == XK_KP_Subtract)\r
+-                        sym = XK_hyphen;\r
+-                    else if (sym == XK_KP_Add)\r
+-                        sym = XK_plus;\r
+-                    else if (sym == XK_KP_Enter)\r
+-                        sym = XK_Return;\r
+-                    else if (sym == XK_KP_Decimal)\r
+-                        sym = numLock ? XK_period : XK_Delete;\r
+-                    else if (sym == XK_KP_0)\r
+-                        sym = numLock ? XK_0 : XK_Insert;\r
+-                    else if (sym == XK_KP_1)\r
+-                        sym = numLock ? XK_1 : XK_End;\r
+-                    else if (sym == XK_KP_2)\r
+-                        sym = numLock ? XK_2 : XK_Down;\r
+-                    else if (sym == XK_KP_3)\r
+-                        sym = numLock ? XK_3 : XK_Page_Down;\r
+-                    else if (sym == XK_KP_4)\r
+-                        sym = numLock ? XK_4 : XK_Left;\r
+-                    else if (sym == XK_KP_5)\r
+-                        sym = XK_5;\r
+-                    else if (sym == XK_KP_6)\r
+-                        sym = numLock ? XK_6 : XK_Right;\r
+-                    else if (sym == XK_KP_7)\r
+-                        sym = numLock ? XK_7 : XK_Home;\r
+-                    else if (sym == XK_KP_8)\r
+-                        sym = numLock ? XK_8 : XK_Up;\r
+-                    else if (sym == XK_KP_9)\r
+-                        sym = numLock ? XK_9 : XK_Page_Up;\r
+-\r
+-                    switch (sym)\r
+-                    {\r
+-                        case XK_Left:\r
+-                        case XK_Right:\r
+-                        case XK_Up:\r
+-                        case XK_Down:\r
+-                        case XK_Page_Up:\r
+-                        case XK_Page_Down:\r
+-                        case XK_End:\r
+-                        case XK_Home:\r
+-                        case XK_Delete:\r
+-                        case XK_Insert:\r
+-                            keyPressed = true;\r
+-                            sym = (sym & 0xff) | nonAsciiModifier;\r
+-                            break;\r
+-                        case XK_Tab:\r
+-                        case XK_Return:\r
+-                        case XK_Escape:\r
+-                        case XK_BackSpace:\r
+-                            keyPressed = true;\r
+-                            sym &= 0xff;\r
+-                            break;\r
+-                        default:\r
+-                        {\r
+-                            if (sym >= XK_F1 && sym <= XK_F12)\r
+-                            {\r
+-                                keyPressed = true;\r
+-                                sym = (sym & 0xff) | nonAsciiModifier;\r
+-                            }\r
+-                            break;\r
+-                        }\r
+-                    }\r
+-                }\r
+-\r
+-                if ((sym & 0xff00) == 0 && sym >= 8)\r
+-                    keyPressed = true;\r
+-\r
+-                if (capsLock && ((sym >= XK_A && sym <= XK_Z) || (sym >= XK_a && sym <= XK_z)))\r
+-                {\r
+-                    index ^= 1;\r
+-                    sym = XKeycodeToKeysym (display, keyEvent->keycode, index);\r
+-                }\r
+-\r
+-                if (oldMods != currentModifiers)\r
+-                    handleModifierKeysChange();\r
+-\r
+-                if (keyDownChange)\r
+-                    handleKeyUpOrDown();\r
+-\r
+-                if (keyPressed)\r
+-                    handleKeyPress (sym);\r
+-\r
+-                break;\r
+-            }\r
+-\r
+-            case KeyRelease:\r
+-            {\r
+-                XKeyEvent* keyEvent = (XKeyEvent*) &event->xkey;\r
+-                updateKeyStates (keyEvent->keycode, false);\r
+-\r
+-                KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, 0);\r
+-\r
+-                const int oldMods = currentModifiers;\r
+-                const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false);\r
+-\r
+-                if (oldMods != currentModifiers)\r
+-                    handleModifierKeysChange();\r
+-\r
+-                if (keyDownChange)\r
+-                    handleKeyUpOrDown();\r
+-\r
+-                break;\r
+-            }\r
+-\r
+-            case ButtonPress:\r
+-            {\r
+-                XButtonPressedEvent* buttonPressEvent = (XButtonPressedEvent*) &event->xbutton;\r
+-\r
+-                bool buttonMsg = false;\r
+-                bool wheelUpMsg = false;\r
+-                bool wheelDownMsg = false;\r
+-\r
+-                const int map = pointerMap [buttonPressEvent->button - Button1];\r
+-\r
+-                if (map == LeftButton)\r
+-                {\r
+-                    currentModifiers |= ModifierKeys::leftButtonModifier;\r
+-                    buttonMsg = true;\r
+-                }\r
+-                else if (map == RightButton)\r
+-                {\r
+-                    currentModifiers |= ModifierKeys::rightButtonModifier;\r
+-                    buttonMsg = true;\r
+-                }\r
+-                else if (map == MiddleButton)\r
+-                {\r
+-                    currentModifiers |= ModifierKeys::middleButtonModifier;\r
+-                    buttonMsg = true;\r
+-                }\r
+-                else if (map == WheelUp)\r
+-                {\r
+-                    wheelUpMsg = true;\r
+-                }\r
+-                else if (map == WheelDown)\r
+-                {\r
+-                    wheelDownMsg = true;\r
+-                }\r
+-\r
+-                updateKeyModifiers (buttonPressEvent->state);\r
+-\r
+-                if (buttonMsg)\r
+-                {\r
+-                    toFront (true);\r
+-                    handleMouseDown (buttonPressEvent->x, buttonPressEvent->y,\r
+-                                     getEventTime (buttonPressEvent->time));\r
+-                }\r
+-                else if (wheelUpMsg || wheelDownMsg)\r
+-                {\r
+-                    handleMouseWheel (wheelDownMsg ? -84 : 84,\r
+-                                      getEventTime (buttonPressEvent->time));\r
+-                }\r
+-\r
+-                lastMousePosX = lastMousePosY = 0x100000;\r
+-                break;\r
+-            }\r
+-\r
+-            case ButtonRelease:\r
+-            {\r
+-                XButtonReleasedEvent* buttonRelEvent = (XButtonReleasedEvent*) &event->xbutton;\r
+-\r
+-                const int oldModifiers = currentModifiers;\r
+-                const int map = pointerMap [buttonRelEvent->button - Button1];\r
+-\r
+-                if (map == LeftButton)\r
+-                    currentModifiers &= ~ModifierKeys::leftButtonModifier;\r
+-                else if (map == RightButton)\r
+-                    currentModifiers &= ~ModifierKeys::rightButtonModifier;\r
+-                else if (map == MiddleButton)\r
+-                    currentModifiers &= ~ModifierKeys::middleButtonModifier;\r
+-\r
+-                updateKeyModifiers (buttonRelEvent->state);\r
+-\r
+-                handleMouseUp (oldModifiers,\r
+-                               buttonRelEvent->x, buttonRelEvent->y,\r
+-                               getEventTime (buttonRelEvent->time));\r
+-\r
+-                lastMousePosX = lastMousePosY = 0x100000;\r
+-                break;\r
+-            }\r
+-\r
+-            case MotionNotify:\r
+-            {\r
+-                XPointerMovedEvent* movedEvent = (XPointerMovedEvent*) &event->xmotion;\r
+-\r
+-                updateKeyModifiers (movedEvent->state);\r
+-\r
+-                int x, y, mouseMods;\r
+-                getMousePos (x, y, mouseMods);\r
+-\r
+-                if (lastMousePosX != x || lastMousePosY != y)\r
+-                {\r
+-                    lastMousePosX = x;\r
+-                    lastMousePosY = y;\r
+-\r
+-                    x -= getScreenX();\r
+-                    y -= getScreenY();\r
+-\r
+-                    if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0)\r
+-                        handleMouseMove (x, y, getEventTime (movedEvent->time));\r
+-                    else\r
+-                        handleMouseDrag (x, y, getEventTime (movedEvent->time));\r
+-                }\r
+-\r
+-                break;\r
+-            }\r
+-\r
+-            case EnterNotify:\r
+-            {\r
+-                lastMousePosX = lastMousePosY = 0x100000;\r
+-                XEnterWindowEvent* enterEvent = (XEnterWindowEvent*) &event->xcrossing;\r
+-\r
+-                if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0\r
+-                     && ! entered)\r
+-                {\r
+-                    updateKeyModifiers (enterEvent->state);\r
+-\r
+-                    handleMouseEnter (enterEvent->x, enterEvent->y, getEventTime (enterEvent->time));\r
+-\r
+-                    entered = true;\r
+-                }\r
+-\r
+-                break;\r
+-            }\r
+-\r
+-            case LeaveNotify:\r
+-            {\r
+-                XLeaveWindowEvent* leaveEvent = (XLeaveWindowEvent*) &event->xcrossing;\r
+-\r
+-                // Suppress the normal leave if we've got a pointer grab, or if\r
+-                // it's a bogus one caused by clicking a mouse button when running\r
+-                // in a Window manager\r
+-                if (((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0\r
+-                     && leaveEvent->mode == NotifyNormal)\r
+-                    || leaveEvent->mode == NotifyUngrab)\r
+-                {\r
+-                    updateKeyModifiers (leaveEvent->state);\r
+-\r
+-                    handleMouseExit (leaveEvent->x, leaveEvent->y, getEventTime (leaveEvent->time));\r
+-\r
+-                    entered = false;\r
+-                }\r
+-\r
+-                break;\r
+-            }\r
+-\r
+-            case FocusIn:\r
+-            {\r
+-                isActiveApplication = true;\r
+-                handleFocusGain();\r
+-                break;\r
+-            }\r
+-\r
+-            case FocusOut:\r
+-            {\r
+-                isActiveApplication = false;\r
+-                handleFocusLoss();\r
+-                break;\r
+-            }\r
+-\r
+-            case Expose:\r
+-            {\r
+-                // Batch together all pending expose events\r
+-                XExposeEvent* exposeEvent = (XExposeEvent*) &event->xexpose;\r
+-                XEvent nextEvent;\r
+-\r
+-                repaint (exposeEvent->x, exposeEvent->y,\r
+-                         exposeEvent->width, exposeEvent->height);\r
+-\r
+-                while (XEventsQueued (display, QueuedAfterFlush) > 0)\r
+-                {\r
+-                    XPeekEvent (display, (XEvent*) &nextEvent);\r
+-                    if (nextEvent.type != Expose || nextEvent.xany.window != event->xany.window)\r
+-                        break;\r
+-\r
+-                    XNextEvent (display, (XEvent*)&nextEvent);\r
+-                    XExposeEvent* nextExposeEvent = (XExposeEvent*)(&nextEvent.xexpose);\r
+-                    repaint (nextExposeEvent->x, nextExposeEvent->y,\r
+-                             nextExposeEvent->width, nextExposeEvent->height);\r
+-                }\r
+-\r
+-                break;\r
+-            }\r
+-\r
+-            case CreateNotify:\r
+-            case DestroyNotify:\r
+-                // Think we can ignore these\r
+-                break;\r
+-\r
+-            case CirculateNotify:\r
+-                break;\r
+-\r
+-            case ConfigureNotify:\r
+-            case ReparentNotify:\r
+-            case GravityNotify:\r
+-                updateBounds();\r
+-                break;\r
+-\r
+-            case MapNotify:\r
+-                mapped = true;\r
+-                handleBroughtToFront();\r
+-                break;\r
+-\r
+-            case UnmapNotify:\r
+-                mapped = false;\r
+-                break;\r
+-\r
+-            case MappingNotify:\r
+-            {\r
+-                XMappingEvent* mappingEvent = (XMappingEvent*) &event->xmapping;\r
+-\r
+-                if (mappingEvent->request != MappingPointer)\r
+-                {\r
+-                    // Deal with modifier/keyboard mapping\r
+-                    XRefreshKeyboardMapping (mappingEvent);\r
+-                    getModifierMapping();\r
+-                }\r
+-\r
+-                break;\r
+-            }\r
+-\r
+-            case ClientMessage:\r
+-            {\r
+-                XClientMessageEvent* clientMsg = (XClientMessageEvent*) &event->xclient;\r
+-\r
+-                if (clientMsg->message_type == wm_Protocols && clientMsg->format == 32)\r
+-                {\r
+-                    const Atom atom = (Atom) clientMsg->data.l[0];\r
+-\r
+-                    if (atom == wm_ProtocolList [TAKE_FOCUS])\r
+-                    {\r
+-                        XWindowAttributes atts;\r
+-\r
+-                        if (clientMsg->window != 0\r
+-                             && XGetWindowAttributes (display, clientMsg->window, &atts))\r
+-                        {\r
+-                            if (atts.map_state == IsViewable)\r
+-                                XSetInputFocus (display, clientMsg->window, RevertToParent, clientMsg->data.l[1]);\r
+-                        }\r
+-                    }\r
+-                    else if (atom == wm_ProtocolList [DELETE_WINDOW])\r
+-                    {\r
+-                        handleUserClosingWindow();\r
+-                    }\r
+-                }\r
+-                else if (clientMsg->message_type == repaintId)\r
+-                {\r
+-                    // Get rid of all pending repaint events\r
+-                    XEvent nextEvent;\r
+-\r
+-                    while (XEventsQueued (display, QueuedAfterFlush) > 0)\r
+-                    {\r
+-                        XPeekEvent (display, &nextEvent);\r
+-                        if (nextEvent.xany.type != ClientMessage ||\r
+-                            nextEvent.xany.window != event->xany.window)\r
+-                            break;\r
+-\r
+-                        XClientMessageEvent* nextClientMsg = (XClientMessageEvent*) (&nextEvent.xclient);\r
+-                        if (nextClientMsg->message_type != repaintId)\r
+-                            break;\r
+-\r
+-                        XNextEvent (display, &nextEvent);\r
+-                    }\r
+-\r
+-                    static bool reentrancyCheck = false;\r
+-                    if (! reentrancyCheck)\r
+-                    {\r
+-                        reentrancyCheck = true;\r
+-\r
+-                        int ox, oy, ow, oh;\r
+-                        getBounds (ox, oy, ow, oh);\r
+-                        repaint (0, 0, ow, oh);\r
+-                        performPendingRepaints();\r
+-\r
+-                        reentrancyCheck = false;\r
+-                    }\r
+-                }\r
+-\r
+-                break;\r
+-            }\r
+-\r
+-            case SelectionClear:\r
+-            case SelectionNotify:\r
+-            case SelectionRequest:\r
+-                // We shouldn't get these on normal windows\r
+-                break;\r
+-\r
+-            default:\r
+-                break;\r
+-        }\r
+-    }\r
+-\r
+-    void showMouseCursor (Cursor cursor)\r
+-    {\r
+-        XDefineCursor (display, windowH, cursor);\r
+-    }\r
+-\r
+-    //==============================================================================\r
+-    juce_UseDebuggingNewOperator\r
+-\r
+-    bool dontRepaint;\r
+-\r
+-private:\r
+-    //==============================================================================\r
+-    class LinuxRepaintManager : public RepaintManager\r
+-    {\r
+-    public:\r
+-        LinuxRepaintManager (LinuxComponentPeer* const peer_,\r
+-                             Component* const component,\r
+-                             const int timeBeforeReleasingImage)\r
+-            : RepaintManager (component, timeBeforeReleasingImage),\r
+-              peer (peer_)\r
+-        {\r
+-        }\r
+-\r
+-        Image* createNewImage (int w, int h)\r
+-        {\r
+-            return new XBitmapImage (Image::RGB, w, h, false);\r
+-        }\r
+-\r
+-        void repaintNow (const RectangleList& areasToPaint)\r
+-        {\r
+-            peer->clearMaskedRegion();\r
+-\r
+-            renderCacheAreasNeedingRepaint();\r
+-\r
+-            int x, y;\r
+-            XBitmapImage* const paintingBuffer = (XBitmapImage*) getImage (x, y);\r
+-\r
+-            if (paintingBuffer != 0)\r
+-            {\r
+-                const RectangleList* repaintRegion = &areasToPaint;\r
+-                RectangleList temp;\r
+-\r
+-                if (! peer->maskedRegion.isEmpty())\r
+-                {\r
+-                    temp = areasToPaint;\r
+-                    temp.subtract (peer->maskedRegion);\r
+-                    repaintRegion = &temp;\r
+-                }\r
+-\r
+-                for (RectangleList::Iterator i (*repaintRegion); i.next();)\r
+-                {\r
+-                    const Rectangle& r = i.getRectangle();\r
+-\r
+-                    paintingBuffer->blitToWindow (peer->windowH,\r
+-                                                  r.getX(), r.getY(), r.getWidth(), r.getHeight(),\r
+-                                                  r.getX() - x, r.getY() - y);\r
+-                }\r
+-            }\r
+-        }\r
+-\r
+-    private:\r
+-        LinuxComponentPeer* const peer;\r
+-\r
+-        LinuxRepaintManager (const LinuxRepaintManager&);\r
+-        const LinuxRepaintManager& operator= (const LinuxRepaintManager&);\r
+-    };\r
+-\r
+-    LinuxRepaintManager* repainter;\r
+-\r
+-    friend class LinuxRepaintManager;\r
+-    Window windowH;\r
+-    int wx, wy, ww, wh;\r
+-    bool fullScreen, entered, mapped;\r
+-    BorderSize windowBorder;\r
+-\r
+-    //==============================================================================\r
+-    void removeWindowDecorations (Window wndH)\r
+-    {\r
+-        Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True);\r
+-\r
+-        if (hints != None)\r
+-        {\r
+-            typedef struct\r
+-            {\r
+-                CARD32 flags;\r
+-                CARD32 functions;\r
+-                CARD32 decorations;\r
+-                INT32 input_mode;\r
+-                CARD32 status;\r
+-            } MotifWmHints;\r
+-\r
+-            MotifWmHints motifHints;\r
+-            motifHints.flags = 2; /* MWM_HINTS_DECORATIONS */\r
+-            motifHints.decorations = 0;\r
+-\r
+-            XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,\r
+-                             (unsigned char*) &motifHints, 4);\r
+-        }\r
+-\r
+-        hints = XInternAtom (display, "_WIN_HINTS", True);\r
+-\r
+-        if (hints != None)\r
+-        {\r
+-            long gnomeHints = 0;\r
+-\r
+-            XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,\r
+-                             (unsigned char*) &gnomeHints, 1);\r
+-        }\r
+-\r
+-        hints = XInternAtom (display, "KWM_WIN_DECORATION", True);\r
+-\r
+-        if (hints != None)\r
+-        {\r
+-            long kwmHints = 2; /*KDE_tinyDecoration*/\r
+-\r
+-            XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,\r
+-                             (unsigned char*) &kwmHints, 1);\r
+-        }\r
+-\r
+-        hints = XInternAtom (display, "_NET_WM_WINDOW_TYPE", True);\r
+-\r
+-        if (hints != None)\r
+-        {\r
+-            Atom netHints [2];\r
+-            netHints[0] = XInternAtom (display, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", True);\r
+-\r
+-            if ((styleFlags & windowIsTemporary) != 0)\r
+-                netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_MENU", True);\r
+-            else\r
+-                netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_NORMAL", True);\r
+-\r
+-            XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace,\r
+-                             (unsigned char*) &netHints, 2);\r
+-        }\r
+-    }\r
+-\r
+-    void addWindowButtons (Window wndH)\r
+-    {\r
+-        Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True);\r
+-\r
+-        if (hints != None)\r
+-        {\r
+-            typedef struct\r
+-            {\r
+-                CARD32 flags;\r
+-                CARD32 functions;\r
+-                CARD32 decorations;\r
+-                INT32 input_mode;\r
+-                CARD32 status;\r
+-            } MotifWmHints;\r
+-\r
+-            MotifWmHints motifHints;\r
+-\r
+-            motifHints.flags = 1 | 2; /* MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS */\r
+-            motifHints.decorations = 2 /* MWM_DECOR_BORDER */ | 8 /* MWM_DECOR_TITLE */ | 16; /* MWM_DECOR_MENU */\r
+-\r
+-            motifHints.functions = 4 /* MWM_FUNC_MOVE */;\r
+-\r
+-            if ((styleFlags & windowHasCloseButton) != 0)\r
+-                motifHints.functions |= 32; /* MWM_FUNC_CLOSE */\r
+-\r
+-            if ((styleFlags & windowHasMinimiseButton) != 0)\r
+-            {\r
+-                motifHints.functions |= 8; /* MWM_FUNC_MINIMIZE */\r
+-                motifHints.decorations |= 0x20; /* MWM_DECOR_MINIMIZE */\r
+-            }\r
+-\r
+-            if ((styleFlags & windowHasMaximiseButton) != 0)\r
+-            {\r
+-                motifHints.functions |= 0x10; /* MWM_FUNC_MAXIMIZE */\r
+-                motifHints.decorations |= 0x40; /* MWM_DECOR_MAXIMIZE */\r
+-            }\r
+-\r
+-            if ((styleFlags & windowIsResizable) != 0)\r
+-            {\r
+-                motifHints.functions |= 2; /* MWM_FUNC_RESIZE */\r
+-                motifHints.decorations |= 0x4; /* MWM_DECOR_RESIZEH */\r
+-            }\r
+-\r
+-            XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,\r
+-                             (unsigned char*) &motifHints, 4);\r
+-        }\r
+-\r
+-        hints = XInternAtom (display, "_NET_WM_ALLOWED_ACTIONS", True);\r
+-\r
+-        if (hints != None)\r
+-        {\r
+-            Atom netHints [6];\r
+-            int num = 0;\r
+-\r
+-            netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_RESIZE", (styleFlags & windowIsResizable) ? True : False);\r
+-            netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_FULLSCREEN", (styleFlags & windowHasMaximiseButton) ? True : False);\r
+-            netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_MINIMIZE", (styleFlags & windowHasMinimiseButton) ? True : False);\r
+-            netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_CLOSE", (styleFlags & windowHasCloseButton) ? True : False);\r
+-\r
+-            XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace,\r
+-                             (unsigned char*) &netHints, num);\r
+-        }\r
+-    }\r
+-\r
+-    static void* createWindowCallback (void* userData)\r
+-    {\r
+-        ((LinuxComponentPeer*) userData)->createWindow();\r
+-        return 0;\r
+-    }\r
+-\r
+-    void createWindow()\r
+-    {\r
+-        static bool atomsInitialised = false;\r
+-\r
+-        if (! atomsInitialised)\r
+-        {\r
+-            atomsInitialised = true;\r
+-\r
+-            wm_Protocols                      = XInternAtom (display, "WM_PROTOCOLS", 1);\r
+-            wm_ProtocolList [TAKE_FOCUS]      = XInternAtom (display, "WM_TAKE_FOCUS", 1);\r
+-            wm_ProtocolList [DELETE_WINDOW]   = XInternAtom (display, "WM_DELETE_WINDOW", 1);\r
+-            wm_ChangeState                    = XInternAtom (display, "WM_CHANGE_STATE", 1);\r
+-            wm_State                          = XInternAtom (display, "WM_STATE", 1);\r
+-            wm_ActiveWin                      = XInternAtom (display, "_NET_ACTIVE_WINDOW", False);\r
+-            repaintId                         = XInternAtom (display, "JUCERepaintAtom", 1);\r
+-        }\r
+-\r
+-        // Get defaults for various properties\r
+-        const int screen = DefaultScreen (display);\r
+-        Window root = RootWindow (display, screen);\r
+-\r
+-        // Attempt to create a 24-bit window on the default screen.  If this is not\r
+-        // possible then exit\r
+-        XVisualInfo desiredVisual;\r
+-        desiredVisual.screen = screen;\r
+-        desiredVisual.depth = 24;\r
+-\r
+-        int numVisuals;\r
+-        XVisualInfo* visuals = XGetVisualInfo (display, VisualScreenMask | VisualDepthMask,\r
+-                                               &desiredVisual, &numVisuals);\r
+-\r
+-        if (numVisuals < 1 || visuals == 0)\r
+-        {\r
+-            Logger::outputDebugString ("ERROR: System doesn't support 24-bit RGB display.\n");\r
+-            Process::terminate();\r
+-        }\r
+-\r
+-        // Just choose the first one\r
+-        Visual* visual = visuals[0].visual;\r
+-        const int depth = visuals[0].depth;\r
+-        XFree (visuals);\r
+-\r
+-        // Set up the window attributes\r
+-        XSetWindowAttributes swa;\r
+-        swa.border_pixel = 0;\r
+-        swa.colormap = DefaultColormap (display, screen);\r
+-        swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False;\r
+-        swa.event_mask = eventMask;\r
+-\r
+-        Window wndH = XCreateWindow (display, root,\r
+-                                     0, 0, 1, 1, 0,\r
+-                                     depth, InputOutput, visual,\r
+-                                     CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,\r
+-                                     &swa);\r
+-\r
+-        XGrabButton (display, AnyButton, AnyModifier, wndH, False,\r
+-                     ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,\r
+-                     GrabModeAsync, GrabModeAsync, None, None);\r
+-\r
+-        // Set the window context to identify the window handle object\r
+-        if (XSaveContext (display, (XID) wndH, improbableNumber, (XPointer) this))\r
+-        {\r
+-            // Failed\r
+-            jassertfalse\r
+-            Logger::outputDebugString ("Failed to create context information for window.\n");\r
+-            XDestroyWindow (display, wndH);\r
+-            wndH = 0;\r
+-        }\r
+-\r
+-        // Set window manager hints\r
+-        XWMHints* wmHints = XAllocWMHints();\r
+-        wmHints->flags = InputHint | StateHint;\r
+-        wmHints->input = True;      // Locally active input model\r
+-        wmHints->initial_state = NormalState;\r
+-        XSetWMHints (display, wndH, wmHints);\r
+-        XFree (wmHints);\r
+-\r
+-        if ((styleFlags & juce_windowIsSemiTransparentFlag) != 0)\r
+-        {\r
+-            //xxx\r
+-            jassertfalse\r
+-        }\r
+-\r
+-        if ((styleFlags & windowAppearsOnTaskbar) != 0)\r
+-        {\r
+-            //xxx\r
+-        }\r
+-\r
+-        if ((styleFlags & windowHasTitleBar) == 0)\r
+-            removeWindowDecorations (wndH);\r
+-        else\r
+-            addWindowButtons (wndH);\r
+-\r
+-        XSetTransientForHint (display, wndH, RootWindow (display, DefaultScreen (display)));\r
+-\r
+-        // Set window manager protocols\r
+-        XChangeProperty (display, wndH, wm_Protocols, XA_ATOM, 32, PropModeReplace,\r
+-                         (unsigned char*) wm_ProtocolList, 2);\r
+-\r
+-        // Set window name\r
+-        setWindowTitle (wndH, getComponent()->getName());\r
+-\r
+-        // Initialise the pointer and keyboard mapping\r
+-        // This is not the same as the logical pointer mapping the X server uses:\r
+-        // we don't mess with this.\r
+-        static bool mappingInitialised = false;\r
+-\r
+-        if (! mappingInitialised)\r
+-        {\r
+-            mappingInitialised = true;\r
+-\r
+-            const int numButtons = XGetPointerMapping (display, 0, 0);\r
+-\r
+-            if (numButtons == 2)\r
+-            {\r
+-                pointerMap[0] = LeftButton;\r
+-                pointerMap[1] = RightButton;\r
+-                pointerMap[2] = pointerMap[3] = pointerMap[4] = NoButton;\r
+-            }\r
+-            else if (numButtons >= 3)\r
+-            {\r
+-                pointerMap[0] = LeftButton;\r
+-                pointerMap[1] = MiddleButton;\r
+-                pointerMap[2] = RightButton;\r
+-\r
+-                if (numButtons >= 5)\r
+-                {\r
+-                    pointerMap[3] = WheelUp;\r
+-                    pointerMap[4] = WheelDown;\r
+-                }\r
+-            }\r
+-\r
+-            getModifierMapping();\r
+-        }\r
+-\r
+-        windowH = wndH;\r
+-    }\r
+-\r
+-    static void* destroyWindowCallback (void* userData)\r
+-    {\r
+-        Window windowH = (Window) userData;\r
+-\r
+-        XPointer handlePointer;\r
+-        if (! XFindContext (display, (XID) windowH, improbableNumber, &handlePointer))\r
+-            XDeleteContext (display, (XID) windowH, improbableNumber);\r
+-\r
+-        XDestroyWindow (display, windowH);\r
+-\r
+-        // Wait for it to complete and then remove any events for this\r
+-        // window from the event queue.\r
+-        XSync (display, false);\r
+-\r
+-        XEvent event;\r
+-        while (XCheckWindowEvent (display, windowH, eventMask, &event) == True)\r
+-        {}\r
+-\r
+-        return 0;\r
+-    }\r
+-\r
+-    static int64 getEventTime (::Time t)\r
+-    {\r
+-        static int64 eventTimeOffset = 0x12345678;\r
+-        const int64 thisMessageTime = t;\r
+-\r
+-        if (eventTimeOffset == 0x12345678)\r
+-            eventTimeOffset = Time::currentTimeMillis() - thisMessageTime;\r
+-\r
+-        return eventTimeOffset + thisMessageTime;\r
+-    }\r
+-\r
+-    static void setWindowTitle (Window xwin, const char* const title)\r
+-    {\r
+-        XTextProperty nameProperty;\r
+-        char* strings[] = { (char*) title };\r
+-\r
+-        if (XStringListToTextProperty (strings, 1, &nameProperty))\r
+-        {\r
+-            XSetWMName (display, xwin, &nameProperty);\r
+-            XSetWMIconName (display, xwin, &nameProperty);\r
+-        }\r
+-    }\r
+-\r
+-    void updateBorderSize()\r
+-    {\r
+-        if ((styleFlags & windowHasTitleBar) == 0)\r
+-        {\r
+-            windowBorder = BorderSize (0);\r
+-        }\r
+-        else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0)\r
+-        {\r
+-            Atom hints = XInternAtom (display, "_NET_FRAME_EXTENTS", True);\r
+-\r
+-            if (hints != None)\r
+-            {\r
+-                CARD32* sizes = 0;\r
+-                unsigned long nitems, bytesLeft;\r
+-                Atom actualType;\r
+-                int actualFormat;\r
+-\r
+-                if (XGetWindowProperty (display, windowH, hints, 0, 4, False,\r
+-                                        XA_CARDINAL, &actualType, &actualFormat, &nitems, &bytesLeft,\r
+-                                        (unsigned char**) &sizes) == Success)\r
+-                {\r
+-                    if (actualFormat == 32)\r
+-                        windowBorder = BorderSize ((int) sizes[2], (int) sizes[0],\r
+-                                                   (int) sizes[3], (int) sizes[1]);\r
+-\r
+-                    XFree (sizes);\r
+-                }\r
+-            }\r
+-        }\r
+-    }\r
+-\r
+-    void updateBounds()\r
+-    {\r
+-        jassert (windowH != 0);\r
+-        if (windowH != 0)\r
+-        {\r
+-            Window root, child;\r
+-            unsigned int bw, depth;\r
+-\r
+-            if (! XGetGeometry (display, (Drawable) windowH, &root,\r
+-                                &wx, &wy, (unsigned int*) &ww, (unsigned int*) &wh,\r
+-                                &bw, &depth))\r
+-            {\r
+-                wx = wy = ww = wh = 0;\r
+-            }\r
+-            else if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child))\r
+-            {\r
+-                wx = wy = 0;\r
+-            }\r
+-\r
+-            updateBorderSize();\r
+-            handleMovedOrResized();\r
+-        }\r
+-    }\r
+-};\r
+-\r
+-//==============================================================================\r
+-ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/)\r
+-{\r
+-    return new LinuxComponentPeer (this, styleFlags);\r
+-}\r
+-\r
+-\r
+-//==============================================================================\r
+-// (this callback is hooked up in the messaging code)\r
+-void juce_windowMessageReceive (XEvent* event)\r
+-{\r
+-    if (event->xany.window != None)\r
+-    {\r
+-        // Check if the event is for one of our windows\r
+-        LinuxComponentPeer* peer = 0;\r
+-\r
+-        if (! XFindContext (display, (XID) event->xany.window, improbableNumber, (XPointer*) &peer))\r
+-        {\r
+-            if (peer != 0 && peer->isValidMessageListener())\r
+-                peer->handleWindowMessage (event);\r
+-        }\r
+-    }\r
+-    else\r
+-    {\r
+-        switch (event->xany.type)\r
+-        {\r
+-            case KeymapNotify:\r
+-            {\r
+-                const XKeymapEvent* const keymapEvent = (const XKeymapEvent*) &event->xkeymap;\r
+-                memcpy (keyStates, keymapEvent->key_vector, 32);\r
+-                break;\r
+-            }\r
+-\r
+-            default:\r
+-                break;\r
+-        }\r
+-    }\r
+-}\r
+-\r
+-//==============================================================================\r
+-void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool clipToWorkArea)\r
+-{\r
+-#if JUCE_USE_XINERAMA\r
+-    int major_opcode, first_event, first_error;\r
+-\r
+-    if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error)\r
+-         && XineramaIsActive (display))\r
+-    {\r
+-        int numMonitors = 0;\r
+-        XineramaScreenInfo* const screens = XineramaQueryScreens (display, &numMonitors);\r
+-\r
+-        if (screens != 0)\r
+-        {\r
+-            for (int i = numMonitors; --i >= 0;)\r
+-            {\r
+-                int index = screens[i].screen_number;\r
+-\r
+-                if (index >= 0)\r
+-                {\r
+-                    while (monitorCoords.size() < index)\r
+-                        monitorCoords.add (Rectangle (0, 0, 0, 0));\r
+-\r
+-                    monitorCoords.set (index, Rectangle (screens[i].x_org,\r
+-                                                         screens[i].y_org,\r
+-                                                         screens[i].width,\r
+-                                                         screens[i].height));\r
+-                }\r
+-            }\r
+-\r
+-            XFree (screens);\r
+-        }\r
+-    }\r
+-\r
+-    if (monitorCoords.size() == 0)\r
+-#endif\r
+-    {\r
+-        monitorCoords.add (Rectangle (0, 0,\r
+-                                      DisplayWidth (display, DefaultScreen (display)),\r
+-                                      DisplayHeight (display, DefaultScreen (display))));\r
+-    }\r
+-}\r
+-\r
+-//==============================================================================\r
+-bool Desktop::canUseSemiTransparentWindows()\r
+-{\r
+-    return false;\r
+-}\r
+-\r
+-void Desktop::getMousePosition (int& x, int& y)\r
+-{\r
+-    int mouseMods;\r
+-    getMousePos (x, y, mouseMods);\r
+-}\r
+-\r
+-void Desktop::setMousePosition (int x, int y)\r
+-{\r
+-    Window root = RootWindow (display, DefaultScreen (display));\r
+-    XWarpPointer (display, None, root, 0, 0, 0, 0, x, y);\r
+-}\r
+-\r
+-\r
+-//==============================================================================\r
+-void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY)\r
+-{\r
+-    Window root = RootWindow (display, DefaultScreen (display));\r
+-    const unsigned int imageW = image.getWidth();\r
+-    const unsigned int imageH = image.getHeight();\r
+-    unsigned int cursorW, cursorH;\r
+-\r
+-    if (! XQueryBestCursor (display, root, imageW, imageH, &cursorW, &cursorH))\r
+-        return 0;\r
+-\r
+-    Image im (Image::ARGB, cursorW, cursorH, true);\r
+-    Graphics g (im);\r
+-\r
+-    if (imageW > cursorW || imageH > cursorH)\r
+-    {\r
+-        hotspotX = (hotspotX * cursorW) / imageW;\r
+-        hotspotY = (hotspotY * cursorH) / imageH;\r
+-\r
+-        g.drawImageWithin (&image, 0, 0, imageW, imageH,\r
+-                           Justification::topLeft,\r
+-                           false, false);\r
+-    }\r
+-    else\r
+-    {\r
+-        g.drawImageAt (&image, 0, 0);\r
+-    }\r
+-\r
+-    const int stride = (cursorW + 7) >> 3;\r
+-    unsigned char* const maskPlane = (unsigned char*)juce_calloc (stride*cursorH);\r
+-    unsigned char* const sourcePlane = (unsigned char*)juce_calloc (stride*cursorH);\r
+-\r
+-    bool msbfirst = (BitmapBitOrder (display) == MSBFirst);\r
+-\r
+-    for (int y = cursorH; --y >= 0;)\r
+-    {\r
+-        for (int x = cursorW; --x >= 0;)\r
+-        {\r
+-            const unsigned char mask = (unsigned char)(1 << (msbfirst ? (7 - (x & 7)) : (x & 7)));\r
+-            const int offset = y * stride + (x >> 3);\r
+-\r
+-            const Colour c (im.getPixelAt (x, y));\r
+-\r
+-            if (c.getAlpha() >= 128)\r
+-                maskPlane[offset] |= mask;\r
+-\r
+-            if (c.getBrightness() >= 0.5f)\r
+-                sourcePlane[offset] |= mask;\r
+-        }\r
+-    }\r
+-\r
+-    Pixmap sourcePixmap = XCreatePixmapFromBitmapData (display, root, (char*)sourcePlane, cursorW, cursorH, 0xffff, 0, 1);\r
+-    Pixmap maskPixmap = XCreatePixmapFromBitmapData (display, root, (char*)maskPlane, cursorW, cursorH, 0xffff, 0, 1);\r
+-\r
+-    juce_free (maskPlane);\r
+-    juce_free (sourcePlane);\r
+-\r
+-    XColor white, black;\r
+-    black.red = black.green = black.blue = 0;\r
+-    white.red = white.green = white.blue = 0xffff;\r
+-\r
+-    void* result = (void*) XCreatePixmapCursor (display, sourcePixmap, maskPixmap, &white, &black, hotspotX, hotspotY);\r
+-\r
+-    XFreePixmap (display, sourcePixmap);\r
+-    XFreePixmap (display, maskPixmap);\r
+-\r
+-    return result;\r
+-}\r
+-\r
+-void juce_deleteMouseCursor (void* cursorHandle, bool)\r
+-{\r
+-    if (cursorHandle != None)\r
+-        XFreeCursor (display, (Cursor)cursorHandle);\r
+-}\r
+-\r
+-void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type)\r
+-{\r
+-    unsigned int shape;\r
+-\r
+-    switch (type)\r
+-    {\r
+-        case MouseCursor::NoCursor:\r
+-        {\r
+-            void* invisibleCursor;\r
+-\r
+-            Image im (Image::ARGB, 16, 16, true);\r
+-            invisibleCursor = juce_createMouseCursorFromImage (im, 0, 0);\r
+-\r
+-            return invisibleCursor;\r
+-        }\r
+-\r
+-        case MouseCursor::NormalCursor:\r
+-            return (void*) None; // Use parent cursor\r
+-\r
+-        case MouseCursor::DraggingHandCursor:\r
+-        {\r
+-            void* dragHandCursor;\r
+-            static unsigned char dragHandData[] = {71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,\r
+-              0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0,\r
+-              16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,\r
+-              132,117,151,116,132,146,248,60,209,138,98,22,203,114,34,236,37,52,77,217,\r
+-              247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };\r
+-            const int dragHandDataSize = 99;\r
+-\r
+-            Image* im = ImageFileFormat::loadFrom ((const char*) dragHandData, dragHandDataSize);\r
+-            dragHandCursor = juce_createMouseCursorFromImage (*im, 8, 7);\r
+-            delete im;\r
+-\r
+-            return dragHandCursor;\r
+-        }\r
+-\r
+-        case MouseCursor::CopyingCursor:\r
+-        {\r
+-            void* copyCursor;\r
+-\r
+-            static unsigned char copyCursorData[] = {71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0,\r
+-              128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0,\r
+-              21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111,\r
+-              78,133,218,215,137,31,82,154,100,200,86,91,202,142,12,108,212,87,235,174,\r
+-              15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112,\r
+-              252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 };\r
+-            const int copyCursorSize = 119;\r
+-\r
+-            Image* im = ImageFileFormat::loadFrom ((const char*)copyCursorData, copyCursorSize);\r
+-            copyCursor = juce_createMouseCursorFromImage (*im, 1, 3);\r
+-            delete im;\r
+-\r
+-            return copyCursor;\r
+-        }\r
+-\r
+-        case MouseCursor::WaitCursor:\r
+-            shape = XC_watch;\r
+-            break;\r
+-\r
+-        case MouseCursor::IBeamCursor:\r
+-            shape = XC_xterm;\r
+-            break;\r
+-\r
+-        case MouseCursor::PointingHandCursor:\r
+-            shape = XC_hand2;\r
+-            break;\r
+-\r
+-        case MouseCursor::LeftRightResizeCursor:\r
+-            shape = XC_sb_h_double_arrow;\r
+-            break;\r
+-\r
+-        case MouseCursor::UpDownResizeCursor:\r
+-            shape = XC_sb_v_double_arrow;\r
+-            break;\r
+-\r
+-        case MouseCursor::UpDownLeftRightResizeCursor:\r
+-            shape = XC_fleur;\r
+-            break;\r
+-\r
+-        case MouseCursor::TopEdgeResizeCursor:\r
+-            shape = XC_top_side;\r
+-            break;\r
+-\r
+-        case MouseCursor::BottomEdgeResizeCursor:\r
+-            shape = XC_bottom_side;\r
+-            break;\r
+-\r
+-        case MouseCursor::LeftEdgeResizeCursor:\r
+-            shape = XC_left_side;\r
+-            break;\r
+-\r
+-        case MouseCursor::RightEdgeResizeCursor:\r
+-            shape = XC_right_side;\r
+-            break;\r
+-\r
+-        case MouseCursor::TopLeftCornerResizeCursor:\r
+-            shape = XC_top_left_corner;\r
+-            break;\r
+-\r
+-        case MouseCursor::TopRightCornerResizeCursor:\r
+-            shape = XC_top_right_corner;\r
+-            break;\r
+-\r
+-        case MouseCursor::BottomLeftCornerResizeCursor:\r
+-            shape = XC_bottom_left_corner;\r
+-            break;\r
+-\r
+-        case MouseCursor::BottomRightCornerResizeCursor:\r
+-            shape = XC_bottom_right_corner;\r
+-            break;\r
+-\r
+-        case MouseCursor::CrosshairCursor:\r
+-            shape = XC_crosshair;\r
+-            break;\r
+-\r
+-        default:\r
+-            return (void*) None; // Use parent cursor\r
+-    }\r
+-\r
+-    return (void*) XCreateFontCursor (display, shape);\r
+-}\r
+-\r
+-void MouseCursor::showInWindow (ComponentPeer* peer) const\r
+-{\r
+-    LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (peer);\r
+-\r
+-    if (lp != 0)\r
+-        lp->showMouseCursor ((Cursor) getHandle());\r
+-}\r
+-\r
+-void MouseCursor::showInAllWindows() const\r
+-{\r
+-    for (int i = ComponentPeer::getNumPeers(); --i >= 0;)\r
+-        showInWindow (ComponentPeer::getPeer (i));\r
+-}\r
+-\r
+-//==============================================================================\r
+-Image* juce_createIconForFile (const File& file)\r
+-{\r
+-    return 0;\r
+-}\r
+-\r
+-\r
+-//==============================================================================\r
+-#if JUCE_OPENGL\r
+-\r
+-struct OpenGLContextInfo\r
+-{\r
+-    Window embeddedWindow;\r
+-    GLXContext renderContext;\r
+-};\r
+-\r
+-void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)\r
+-{\r
+-    XSync (display, False);\r
+-    jassert (component != 0);\r
+-\r
+-    if (component == 0)\r
+-        return 0;\r
+-\r
+-    LinuxComponentPeer* const peer\r
+-        = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());\r
+-\r
+-    if (peer == 0)\r
+-        return 0;\r
+-\r
+-    GLint attribList[] =\r
+-    {\r
+-        GLX_RGBA,\r
+-        GLX_DOUBLEBUFFER,\r
+-        GLX_RED_SIZE, 8,\r
+-        GLX_GREEN_SIZE, 8,\r
+-        GLX_BLUE_SIZE, 8,\r
+-        GLX_ALPHA_SIZE, 8,\r
+-        GLX_DEPTH_SIZE, 8,\r
+-        None\r
+-    };\r
+-\r
+-    XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribList);\r
+-\r
+-    if (bestVisual == 0)\r
+-        return 0;\r
+-\r
+-    OpenGLContextInfo* const oc = new OpenGLContextInfo();\r
+-\r
+-    oc->renderContext = glXCreateContext (display, bestVisual,\r
+-                                          (sharedContext != 0) ? ((OpenGLContextInfo*) sharedContext)->renderContext\r
+-                                                               : 0,\r
+-                                          GL_TRUE);\r
+-\r
+-    Window windowH = (Window) peer->getNativeHandle();\r
+-\r
+-    Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);\r
+-    XSetWindowAttributes swa;\r
+-    swa.colormap = colourMap;\r
+-    swa.border_pixel = 0;\r
+-    swa.event_mask = StructureNotifyMask;\r
+-\r
+-    oc->embeddedWindow = XCreateWindow (display, windowH,\r
+-                                        0, 0, 1, 1, 0,\r
+-                                        bestVisual->depth,\r
+-                                        InputOutput,\r
+-                                        bestVisual->visual,\r
+-                                        CWBorderPixel | CWColormap | CWEventMask,\r
+-                                        &swa);\r
+-\r
+-    XMapWindow (display, oc->embeddedWindow);\r
+-    XFreeColormap (display, colourMap);\r
+-\r
+-    XFree (bestVisual);\r
+-    XSync (display, False);\r
+-\r
+-    return oc;\r
+-}\r
+-\r
+-void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp)\r
+-{\r
+-    jassert (context != 0);\r
+-    OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;\r
+-\r
+-    XMoveResizeWindow (display, oc->embeddedWindow,\r
+-                       owner->getScreenX() - topComp->getScreenX(),\r
+-                       owner->getScreenY() - topComp->getScreenY(),\r
+-                       jmax (1, owner->getWidth()),\r
+-                       jmax (1, owner->getHeight()));\r
+-}\r
+-\r
+-void juce_deleteOpenGLContext (void* context)\r
+-{\r
+-    OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;\r
+-\r
+-    if (oc != 0)\r
+-    {\r
+-        glXDestroyContext (display, oc->renderContext);\r
+-\r
+-        XUnmapWindow (display, oc->embeddedWindow);\r
+-        XDestroyWindow (display, oc->embeddedWindow);\r
+-\r
+-        delete oc;\r
+-    }\r
+-}\r
+-\r
+-bool juce_makeOpenGLContextCurrent (void* context)\r
+-{\r
+-    OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;\r
+-\r
+-    if (oc != 0)\r
+-        return glXMakeCurrent (display, oc->embeddedWindow, oc->renderContext)\r
+-                && XSync (display, False);\r
+-    else\r
+-        return glXMakeCurrent (display, None, 0);\r
+-}\r
+-\r
+-void juce_swapOpenGLBuffers (void* context)\r
+-{\r
+-    OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;\r
+-\r
+-    if (oc != 0)\r
+-        glXSwapBuffers (display, oc->embeddedWindow);\r
+-}\r
+-\r
+-void juce_repaintOpenGLWindow (void* context)\r
+-{\r
+-}\r
+-\r
+-#endif\r
+-\r
+-\r
+-//==============================================================================\r
+-static void initClipboard (Window root, Atom* cutBuffers)\r
+-{\r
+-    static bool init = false;\r
+-\r
+-    if (! init)\r
+-    {\r
+-        init = true;\r
+-\r
+-        // Make sure all cut buffers exist before use\r
+-        for (int i = 0; i < 8; i++)\r
+-        {\r
+-            XChangeProperty (display, root, cutBuffers[i],\r
+-                             XA_STRING, 8, PropModeAppend, NULL, 0);\r
+-        }\r
+-    }\r
+-}\r
+-\r
+-// Clipboard implemented currently using cut buffers\r
+-// rather than the more powerful selection method\r
+-void SystemClipboard::copyTextToClipboard (const String& clipText)\r
+-{\r
+-    Window root = RootWindow (display, DefaultScreen (display));\r
+-    Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,\r
+-                           XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 };\r
+-\r
+-    initClipboard (root, cutBuffers);\r
+-\r
+-    XRotateWindowProperties (display, root, cutBuffers, 8, 1);\r
+-    XChangeProperty (display, root, cutBuffers[0],\r
+-                     XA_STRING, 8, PropModeReplace, (const unsigned char*)((const char*)clipText),\r
+-                     clipText.length());\r
+-}\r
+-\r
+-const String SystemClipboard::getTextFromClipboard()\r
+-{\r
+-    char* clipData;\r
+-    const int bufSize = 64;  // in words\r
+-    int actualFormat;\r
+-    int byteOffset = 0;\r
+-    unsigned long bytesLeft, nitems;\r
+-    Atom actualType;\r
+-    String returnData;\r
+-\r
+-    Window root = RootWindow (display, DefaultScreen (display));\r
+-\r
+-    Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,\r
+-                           XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 };\r
+-\r
+-    initClipboard (root, cutBuffers);\r
+-\r
+-    do\r
+-    {\r
+-        if (XGetWindowProperty (display, root, cutBuffers[0], byteOffset >> 2, bufSize,\r
+-                                False, XA_STRING, &actualType, &actualFormat, &nitems, &bytesLeft,\r
+-                                (unsigned char**) &clipData) != Success\r
+-            || actualType != XA_STRING\r
+-            || actualFormat != 8)\r
+-            return String();\r
+-\r
+-        byteOffset += nitems;\r
+-        returnData += String(clipData, nitems);\r
+-        XFree (clipData);\r
+-    }\r
+-    while (bytesLeft);\r
+-\r
+-    return returnData;\r
+-}\r
+-\r
+-//==============================================================================\r
+-bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles)\r
+-{\r
+-    jassertfalse    // not implemented!\r
+-    return false;\r
+-}\r
+-\r
+-bool DragAndDropContainer::performExternalDragDropOfText (const String& text)\r
+-{\r
+-    jassertfalse    // not implemented!\r
+-    return false;\r
+-}\r
+-\r
+-\r
+-//==============================================================================\r
+-void PlatformUtilities::beep()\r
+-{\r
+-    //xxx\r
+-}\r
+-\r
+-\r
+-//==============================================================================\r
+-bool AlertWindow::showNativeDialogBox (const String& title,\r
+-                                       const String& bodyText,\r
+-                                       bool isOkCancel)\r
+-{\r
+-    // xxx this is supposed to pop up an alert!\r
+-    Logger::outputDebugString (title + ": " + bodyText);\r
+-    return true;\r
+-}\r
+-\r
+-//==============================================================================\r
+-const int KeyPress::spaceKey            = XK_space & 0xff;\r
+-const int KeyPress::returnKey           = XK_Return & 0xff;\r
+-const int KeyPress::escapeKey           = XK_Escape & 0xff;\r
+-const int KeyPress::backspaceKey        = XK_BackSpace & 0xff;\r
+-const int KeyPress::leftKey             = (XK_Left & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::rightKey            = (XK_Right & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::upKey               = (XK_Up & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::downKey             = (XK_Down & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::pageUpKey           = (XK_Page_Up & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::pageDownKey         = (XK_Page_Down & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::endKey              = (XK_End & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::homeKey             = (XK_Home & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::insertKey           = (XK_Insert & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::deleteKey           = (XK_Delete & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::tabKey              = XK_Tab & 0xff;\r
+-const int KeyPress::F1Key               = (XK_F1 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F2Key               = (XK_F2 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F3Key               = (XK_F3 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F4Key               = (XK_F4 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F5Key               = (XK_F5 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F6Key               = (XK_F6 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F7Key               = (XK_F7 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F8Key               = (XK_F8 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F9Key               = (XK_F9 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F10Key              = (XK_F10 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F11Key              = (XK_F11 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::F12Key              = (XK_F12 & 0xff) | nonAsciiModifier;\r
+-const int KeyPress::playKey             = (0xffeeff00) | nonAsciiModifier;\r
+-const int KeyPress::stopKey             = (0xffeeff01) | nonAsciiModifier;\r
+-const int KeyPress::fastForwardKey      = (0xffeeff02) | nonAsciiModifier;\r
+-const int KeyPress::rewindKey           = (0xffeeff03) | nonAsciiModifier;\r
+-\r
+-\r
+-END_JUCE_NAMESPACE\r
+-\r
+-#endif\r
++/*
++  ==============================================================================
++
++   This file is part of the JUCE library - "Jules' Utility Class Extensions"
++   Copyright 2004-6 by Raw Material Software ltd.
++
++  ------------------------------------------------------------------------------
++
++   JUCE can be redistributed and/or modified under the terms of the
++   GNU General Public License, as published by the Free Software Foundation;
++   either version 2 of the License, or (at your option) any later version.
++
++   JUCE is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with JUCE; if not, visit www.gnu.org/licenses or write to the
++   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
++   Boston, MA 02111-1307 USA
++
++  ------------------------------------------------------------------------------
++
++   If you'd like to release a closed-source product which uses JUCE, commercial
++   licenses are also available: visit www.rawmaterialsoftware.com/juce for
++   more information.
++
++  ==============================================================================
++*/
++
++#include "juce_Config.h"
++#if JUCE_BUILD_GUI_CLASSES
++
++#include "linuxincludes.h"
++#include <X11/Xlib.h>
++#include <X11/Xutil.h>
++#include <X11/Xatom.h>
++#include <X11/Xmd.h>
++#include <X11/keysym.h>
++#include <X11/cursorfont.h>
++
++#include "../../../juce_Config.h"
++#undef JUCE_USE_XINERAMA
++#undef JUCE_OPENGL
++#if JUCE_USE_XINERAMA
++#include <X11/extensions/Xinerama.h>
++#endif
++
++#if JUCE_OPENGL
++#include <X11/Xlib.h>
++#include <GL/glx.h>
++#endif
++
++#undef KeyPress
++
++#include "../../../src/juce_core/basics/juce_StandardHeader.h"
++
++BEGIN_JUCE_NAMESPACE
++
++#include "../../../src/juce_appframework/events/juce_Timer.h"
++#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"
++#include "../../../src/juce_appframework/gui/components/keyboard/juce_KeyPress.h"
++#include "../../../src/juce_appframework/application/juce_SystemClipboard.h"
++#include "../../../src/juce_appframework/gui/components/windows/juce_AlertWindow.h"
++#include "../../../src/juce_appframework/gui/components/special/juce_OpenGLComponent.h"
++#include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
++#include "../../../src/juce_appframework/events/juce_MessageManager.h"
++#include "../../../src/juce_appframework/gui/components/juce_RepaintManager.h"
++#include "../../../src/juce_appframework/gui/components/juce_ComponentDeletionWatcher.h"
++#include "../../../src/juce_appframework/gui/graphics/geometry/juce_RectangleList.h"
++#include "../../../src/juce_appframework/gui/graphics/imaging/juce_ImageFileFormat.h"
++#include "../../../src/juce_appframework/gui/components/mouse/juce_DragAndDropContainer.h"
++#include "../../../src/juce_core/basics/juce_Logger.h"
++#include "../../../src/juce_core/threads/juce_Process.h"
++#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
++
++
++//==============================================================================
++static Atom wm_ChangeState = None;
++static Atom wm_State = None;
++static Atom wm_Protocols = None;
++static Atom wm_ProtocolList [2] = { None, None };
++static Atom wm_ActiveWin = None;
++static Atom repaintId = None;
++
++#define TAKE_FOCUS 0
++#define DELETE_WINDOW 1
++
++//==============================================================================
++static bool isActiveApplication = false;
++
++bool Process::isForegroundProcess()
++{
++    return isActiveApplication;
++}
++
++//==============================================================================
++// These are defined in juce_linux_Messages.cpp
++extern Display* display;
++extern XContext improbableNumber;
++
++const int juce_windowIsSemiTransparentFlag = (1 << 31); // also in component.cpp
++
++static const int eventMask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask
++                             | EnterWindowMask | LeaveWindowMask | PointerMotionMask | KeymapStateMask
++                             | ExposureMask | StructureNotifyMask | FocusChangeMask;
++
++//==============================================================================
++static int pointerMap[5];
++static int lastMousePosX = 0, lastMousePosY = 0;
++
++enum MouseButtons
++{
++    NoButton = 0,
++    LeftButton = 1,
++    MiddleButton = 2,
++    RightButton = 3,
++    WheelUp = 4,
++    WheelDown = 5
++};
++
++static void getMousePos (int& x, int& y, int& mouseMods)
++{
++    Window root, child;
++    int winx, winy;
++    unsigned int mask;
++
++    mouseMods = 0;
++
++    if (XQueryPointer (display,
++                       RootWindow (display, DefaultScreen (display)),
++                       &root, &child,
++                       &x, &y, &winx, &winy, &mask) == False)
++    {
++        // Pointer not on the default screen
++        x = y = -1;
++    }
++    else
++    {
++        if ((mask & Button1Mask) != 0)
++            mouseMods |= ModifierKeys::leftButtonModifier;
++
++        if ((mask & Button2Mask) != 0)
++            mouseMods |= ModifierKeys::middleButtonModifier;
++
++        if ((mask & Button3Mask) != 0)
++            mouseMods |= ModifierKeys::rightButtonModifier;
++    }
++}
++
++//==============================================================================
++static int AltMask = 0;
++static int NumLockMask = 0;
++static bool numLock = 0;
++static bool capsLock = 0;
++static char keyStates [32];
++
++static void updateKeyStates (const int keycode, const bool press)
++{
++    const int keybyte = keycode >> 3;
++    const int keybit = (1 << (keycode & 7));
++
++    if (press)
++        keyStates [keybyte] |= keybit;
++    else
++        keyStates [keybyte] &= ~keybit;
++}
++
++static bool keyDown (const int keycode)
++{
++    const int keybyte = keycode >> 3;
++    const int keybit = (1 << (keycode & 7));
++
++    return (keyStates [keybyte] & keybit) != 0;
++}
++
++static const int nonAsciiModifier = 0x10000;
++
++bool KeyPress::isKeyCurrentlyDown (int keyCode)
++{
++    int keysym;
++
++    if (keyCode & nonAsciiModifier)
++    {
++        keysym = 0xff00 | (keyCode & 0xff);
++    }
++    else
++    {
++        keysym = keyCode;
++
++        if (keysym == (XK_Tab & 0xff)
++            || keysym == (XK_Return & 0xff)
++            || keysym == (XK_Escape & 0xff)
++            || keysym == (XK_BackSpace & 0xff))
++        {
++            keysym |= 0xff00;
++        }
++    }
++
++    return keyDown (XKeysymToKeycode (display, keysym));
++}
++
++//==============================================================================
++// Alt and Num lock are not defined by standard X
++// modifier constants: check what they're mapped to
++static void getModifierMapping()
++{
++    const int altLeftCode = XKeysymToKeycode (display, XK_Alt_L);
++    const int numLockCode = XKeysymToKeycode (display, XK_Num_Lock);
++
++    AltMask = 0;
++    NumLockMask = 0;
++
++    XModifierKeymap* mapping = XGetModifierMapping (display);
++
++    if (mapping)
++    {
++        for (int i = 0; i < 8; i++)
++        {
++            if (mapping->modifiermap [i << 1] == altLeftCode)
++                AltMask = 1 << i;
++            else if (mapping->modifiermap [i << 1] == numLockCode)
++                NumLockMask = 1 << i;
++        }
++
++        XFreeModifiermap (mapping);
++    }
++}
++
++static int currentModifiers = 0;
++
++void ModifierKeys::updateCurrentModifiers()
++{
++    currentModifierFlags = currentModifiers;
++}
++
++const ModifierKeys ModifierKeys::getCurrentModifiersRealtime()
++{
++    int x, y, mouseMods;
++    getMousePos (x, y, mouseMods);
++
++    currentModifiers &= ~ModifierKeys::allMouseButtonModifiers;
++    currentModifiers |= mouseMods;
++
++    return ModifierKeys (currentModifiers);
++}
++
++static void updateKeyModifiers (const int status)
++{
++    currentModifiers &= ~(ModifierKeys::shiftModifier
++                           | ModifierKeys::ctrlModifier
++                           | ModifierKeys::altModifier);
++
++    if (status & ShiftMask)
++        currentModifiers |= ModifierKeys::shiftModifier;
++
++    if (status & ControlMask)
++        currentModifiers |= ModifierKeys::ctrlModifier;
++
++    if (status & AltMask)
++        currentModifiers |= ModifierKeys::altModifier;
++
++    numLock  = ((status & NumLockMask) != 0);
++    capsLock = ((status & LockMask) != 0);
++}
++
++static bool updateKeyModifiersFromSym (KeySym sym, const bool press)
++{
++    int modifier = 0;
++    bool isModifier = true;
++
++    switch (sym)
++    {
++        case XK_Shift_L:
++        case XK_Shift_R:
++            modifier = ModifierKeys::shiftModifier;
++            break;
++
++        case XK_Control_L:
++        case XK_Control_R:
++            modifier = ModifierKeys::ctrlModifier;
++            break;
++
++        case XK_Alt_L:
++        case XK_Alt_R:
++            modifier = ModifierKeys::altModifier;
++            break;
++
++        case XK_Num_Lock:
++            if (press)
++                numLock = ! numLock;
++
++            break;
++
++        case XK_Caps_Lock:
++            if (press)
++                capsLock = ! capsLock;
++
++            break;
++
++        case XK_Scroll_Lock:
++            break;
++
++        default:
++            isModifier = false;
++            break;
++    }
++
++    if (modifier != 0)
++    {
++        if (press)
++            currentModifiers |= modifier;
++        else
++            currentModifiers &= ~modifier;
++    }
++
++    return isModifier;
++}
++
++
++//==============================================================================
++class XBitmapImage  : public Image
++{
++public:
++    //==============================================================================
++    XBitmapImage (const PixelFormat format_, const int w, const int h, const bool clearImage)
++        : Image (format_, w, h)
++    {
++        jassert (format_ == RGB || format_ == ARGB);
++
++        pixelStride = (format_ == RGB) ? 3 : 4;
++        lineStride = ((w * pixelStride + 3) & ~3);
++        imageData = (uint8*) juce_malloc (lineStride * h);
++
++        if (format_ == ARGB && clearImage)
++            zeromem (xImage->data, h * lineStride);
++
++        xImage = new XImage();
++        xImage->width = w;
++        xImage->height = h;
++        xImage->xoffset = 0;
++        xImage->format = ZPixmap;
++        xImage->data = (char*) imageData;
++        xImage->byte_order = ImageByteOrder (display);
++        xImage->bitmap_unit = BitmapUnit (display);
++        xImage->bitmap_bit_order = BitmapBitOrder (display);
++        xImage->bitmap_pad = 32;
++        xImage->depth = pixelStride * 8;
++        xImage->bytes_per_line = lineStride;
++        xImage->bits_per_pixel = pixelStride * 8;
++        xImage->red_mask   = 0x00FF0000;
++        xImage->green_mask = 0x0000FF00;
++        xImage->blue_mask  = 0x000000FF;
++
++        if (! XInitImage (xImage))
++        {
++            jassertfalse
++        }
++    }
++
++    ~XBitmapImage()
++    {
++        juce_free (xImage->data);
++        xImage->data = 0;
++        XDestroyImage (xImage);
++        imageData = 0; // to stop the base class freeing this
++    }
++
++    void blitToWindow (Window window, int dx, int dy, int dw, int dh, int sx, int sy)
++    {
++        static GC gc = 0;
++
++        if (gc == 0)
++            gc = DefaultGC (display, DefaultScreen (display));
++
++        // blit results to screen.
++        XPutImage (display, (Drawable) window, gc, xImage, sx, sy, dx, dy, dw, dh);
++    }
++
++    //==============================================================================
++    juce_UseDebuggingNewOperator
++
++private:
++    XImage* xImage;
++};
++
++
++//==============================================================================
++class LinuxComponentPeer  : public ComponentPeer
++{
++public:
++    //==============================================================================
++    LinuxComponentPeer (Component* const component, const int windowStyleFlags)
++        : ComponentPeer (component, windowStyleFlags),
++          windowH (0),
++          wx (0),
++          wy (0),
++          ww (0),
++          wh (0),
++          fullScreen (false),
++          entered (false),
++          mapped (false)
++    {
++        repainter = new LinuxRepaintManager (this, component, 3000);
++
++        MessageManager::getInstance()
++           ->callFunctionOnMessageThread (&createWindowCallback, (void*) this);
++
++        setTitle (component->getName());
++    }
++
++    ~LinuxComponentPeer()
++    {
++        MessageManager::getInstance()
++            ->callFunctionOnMessageThread (&destroyWindowCallback, (void*) windowH);
++
++        windowH = 0;
++        delete repainter;
++    }
++
++    //==============================================================================
++    void* getNativeHandle() const
++    {
++        return (void*) windowH;
++    }
++
++    void setVisible (bool shouldBeVisible)
++    {
++        if (shouldBeVisible)
++            XMapWindow (display, windowH);
++        else
++            XUnmapWindow (display, windowH);
++    }
++
++    void setTitle (const String& title)
++    {
++        setWindowTitle (windowH, title);
++    }
++
++    void setPosition (int x, int y)
++    {
++        setBounds (x, y, ww, wh, false);
++    }
++
++    void setSize (int w, int h)
++    {
++        setBounds (wx, wy, w, h, false);
++    }
++
++    void setBounds (int x, int y, int w, int h, const bool isNowFullScreen)
++    {
++        fullScreen = isNowFullScreen;
++
++        if (windowH != 0)
++        {
++            const ComponentDeletionWatcher deletionChecker (component);
++
++            wx = x;
++            wy = y;
++            ww = jmax (1, w);
++            wh = jmax (1, h);
++
++            if (! mapped)
++            {
++                // Make sure the Window manager does what we want
++                XSizeHints* hints = XAllocSizeHints();
++                hints->flags = USSize | USPosition;
++                hints->width = ww + windowBorder.getLeftAndRight();
++                hints->height = wh + windowBorder.getTopAndBottom();
++                hints->x = wx - windowBorder.getLeft();
++                hints->y = wy - windowBorder.getTop();
++                XSetWMNormalHints (display, windowH, hints);
++                XFree (hints);
++            }
++
++            XMoveResizeWindow (display, windowH,
++                               wx - windowBorder.getLeft(),
++                               wy - windowBorder.getTop(),
++                               ww + windowBorder.getLeftAndRight(),
++                               wh + windowBorder.getTopAndBottom());
++
++            if (! deletionChecker.hasBeenDeleted())
++            {
++                updateBorderSize();
++                handleMovedOrResized();
++            }
++        }
++    }
++
++    void getBounds (int& x, int& y, int& w, int& h) const
++    {
++        x = wx;
++        y = wy;
++        w = ww;
++        h = wh;
++    }
++
++    int getScreenX() const
++    {
++        return wx;
++    }
++
++    int getScreenY() const
++    {
++        return wy;
++    }
++
++    void setMinimised (bool shouldBeMinimised)
++    {
++        if (shouldBeMinimised)
++        {
++            Window root = RootWindow (display, DefaultScreen (display));
++
++            XClientMessageEvent clientMsg;
++            clientMsg.display = display;
++            clientMsg.window = windowH;
++            clientMsg.type = ClientMessage;
++            clientMsg.format = 32;
++            clientMsg.message_type = wm_ChangeState;
++            clientMsg.data.l[0] = IconicState;
++
++            XSendEvent (display, root, false,
++                        SubstructureRedirectMask | SubstructureNotifyMask,
++                        (XEvent*) &clientMsg);
++        }
++        else
++        {
++            setVisible (true);
++        }
++    }
++
++    bool isMinimised() const
++    {
++        bool minimised = false;
++
++        CARD32* stateProp;
++        unsigned long nitems, bytesLeft;
++        Atom actualType;
++        int actualFormat;
++
++        if (XGetWindowProperty (display, windowH, wm_State, 0, 64, False,
++                                wm_State, &actualType, &actualFormat, &nitems, &bytesLeft,
++                                (unsigned char**) &stateProp) == Success
++            && actualType == wm_State
++            && actualFormat == 32
++            && nitems > 0)
++        {
++            if (stateProp[0] == IconicState)
++                minimised = true;
++
++            XFree (stateProp);
++        }
++
++        return minimised;
++    }
++
++    void setFullScreen (bool shouldBeFullScreen)
++    {
++        setMinimised (false);
++
++        if (fullScreen != shouldBeFullScreen)
++        {
++            Rectangle r (lastNonFullscreenBounds);
++
++            if (shouldBeFullScreen)
++                r = Desktop::getInstance().getMainMonitorArea();
++
++            if (! r.isEmpty())
++                setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
++
++            getComponent()->repaint();
++        }
++    }
++
++    bool isFullScreen() const
++    {
++        return fullScreen;
++    }
++
++    bool isChildWindowOf (Window possibleParent) const
++    {
++        Window* windowList = 0;
++        uint32 windowListSize = 0;
++        Window parent, root;
++
++        if (XQueryTree (display, windowH, &root, &parent, &windowList, &windowListSize) != 0)
++        {
++            if (windowList != 0)
++                XFree (windowList);
++
++            return parent == possibleParent;
++        }
++
++        return false;
++    }
++
++    bool contains (int x, int y, bool trueIfInAChildWindow) const
++    {
++        jassert (x >= 0 && y >= 0 && x < ww && y < wh); // should only be called for points that are actually inside the bounds
++
++        x += wx;
++        y += wy;
++
++        // the XQueryTree stuff later on is VERY slow, so if this call's just to check the mouse pos, it's
++        // much more efficient to cheat..
++        if (x == lastMousePosX && y == lastMousePosY)
++        {
++            Window root, child;
++            int winx, winy;
++            unsigned int mask;
++
++            if (XQueryPointer (display,
++                               RootWindow (display, DefaultScreen (display)),
++                               &root, &child,
++                               &x, &y, &winx, &winy, &mask) != False)
++            {
++                return child == windowH
++                        || (((styleFlags & windowHasTitleBar) != 0) && isChildWindowOf (child));
++            }
++        }
++
++        bool result = false;
++
++        Window* windowList = 0;
++        uint32 windowListSize = 0;
++
++        Window parent, root = RootWindow (display, DefaultScreen (display));
++
++        if (XQueryTree (display, root, &root, &parent, &windowList, &windowListSize) != 0)
++        {
++            for (int i = windowListSize; --i >= 0;)
++            {
++                XWindowAttributes atts;
++
++                if (windowList[i] == windowH
++                     || (((styleFlags & windowHasTitleBar) != 0) && isChildWindowOf (windowList[i])))
++                {
++                    result = true;
++
++                    if (! trueIfInAChildWindow)
++                    {
++                        Window child;
++                        int tempX, tempY;
++
++                        result = XTranslateCoordinates (display, windowH, windowH,
++                                                        x - wx - windowBorder.getLeft(),
++                                                        y - wy - windowBorder.getTop(),
++                                                        &tempX, &tempY,
++                                                        &child)
++                                    && (child == None);
++                    }
++
++                    break;
++                }
++                else if (XGetWindowAttributes (display, windowList[i], &atts)
++                          && atts.map_state == IsViewable
++                          && x >= atts.x && y >= atts.y
++                          && x < atts.x + atts.width
++                          && y < atts.y + atts.height)
++                {
++                    break;
++                }
++            }
++        }
++
++        if (windowList != 0)
++            XFree (windowList);
++
++        return result;
++    }
++
++    const BorderSize getFrameSize() const
++    {
++        return BorderSize();
++    }
++
++    bool setAlwaysOnTop (bool alwaysOnTop)
++    {
++        if (windowH != 0)
++        {
++            XSetWindowAttributes swa;
++            swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False;
++
++            XChangeWindowAttributes (display, windowH, CWOverrideRedirect, &swa);
++        }
++
++        return true;
++    }
++
++    void toFront (bool makeActive)
++    {
++        if (makeActive)
++        {
++            setVisible (true);
++            grabFocus();
++        }
++
++        XEvent ev;
++        ev.xclient.type = ClientMessage;
++        ev.xclient.serial = 0;
++        ev.xclient.send_event = True;
++        ev.xclient.message_type = wm_ActiveWin;
++        ev.xclient.window = windowH;
++        ev.xclient.format = 32;
++        ev.xclient.data.l[0] = 2;
++        ev.xclient.data.l[1] = CurrentTime;
++        ev.xclient.data.l[2] = 0;
++        ev.xclient.data.l[3] = 0;
++        ev.xclient.data.l[4] = 0;
++
++        XSendEvent (display, RootWindow (display, DefaultScreen (display)),
++                    False,
++                    SubstructureRedirectMask | SubstructureNotifyMask,
++                    &ev);
++
++        XSync (display, False);
++    }
++
++    void toBehind (ComponentPeer* other)
++    {
++        LinuxComponentPeer* const otherPeer = dynamic_cast <LinuxComponentPeer*> (other);
++        jassert (otherPeer != 0); // wrong type of window?
++
++        if (otherPeer != 0)
++        {
++            setMinimised (false);
++
++            Window newStack[] = { otherPeer->windowH, windowH };
++
++            XRestackWindows (display, newStack, 2);
++        }
++    }
++
++    bool isFocused() const
++    {
++        int revert;
++        Window focus = 0;
++        XGetInputFocus (display, &focus, &revert);
++
++        if (focus == 0 || focus == None || focus == PointerRoot)
++            return 0;
++
++        ComponentPeer* focusedPeer = 0;
++        if (XFindContext (display, (XID) focus, improbableNumber, (XPointer*) &focusedPeer) != 0)
++            focusedPeer = 0;
++
++        return this == focusedPeer;
++    }
++
++    void grabFocus()
++    {
++        XWindowAttributes atts;
++
++        if (windowH != 0
++            && XGetWindowAttributes (display, windowH, &atts)
++            && atts.map_state == IsViewable)
++        {
++            XSetInputFocus (display, windowH, RevertToParent, CurrentTime);
++
++            if (! isActiveApplication)
++            {
++                isActiveApplication = true;
++                handleFocusGain();
++            }
++        }
++    }
++
++    void repaint (int x, int y, int w, int h)
++    {
++        repainter->invalidateCache (x, y, w, h);
++        repainter->repaint (x, y, w, h);
++    }
++
++    void performPendingRepaints()
++    {
++        repainter->performPendingRepaints();
++    }
++
++    //==============================================================================
++    void handleWindowMessage (XEvent* event)
++    {
++        switch (event->xany.type)
++        {
++            case 2: // 'KeyPress'
++            {
++                XKeyEvent* keyEvent = (XKeyEvent*) &event->xkey;
++                updateKeyStates (keyEvent->keycode, true);
++
++                int index = currentModifiers & ModifierKeys::shiftModifier ? 1 : 0;
++                KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, index);
++
++                const int oldMods = currentModifiers;
++                bool keyPressed = false;
++
++                const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false);
++
++                if ((sym & 0xff00) == 0xff00)
++                {
++                    // Translate keypad
++                    if (sym == XK_KP_Divide)
++                        sym = XK_slash;
++                    else if (sym == XK_KP_Multiply)
++                        sym = XK_asterisk;
++                    else if (sym == XK_KP_Subtract)
++                        sym = XK_hyphen;
++                    else if (sym == XK_KP_Add)
++                        sym = XK_plus;
++                    else if (sym == XK_KP_Enter)
++                        sym = XK_Return;
++                    else if (sym == XK_KP_Decimal)
++                        sym = numLock ? XK_period : XK_Delete;
++                    else if (sym == XK_KP_0)
++                        sym = numLock ? XK_0 : XK_Insert;
++                    else if (sym == XK_KP_1)
++                        sym = numLock ? XK_1 : XK_End;
++                    else if (sym == XK_KP_2)
++                        sym = numLock ? XK_2 : XK_Down;
++                    else if (sym == XK_KP_3)
++                        sym = numLock ? XK_3 : XK_Page_Down;
++                    else if (sym == XK_KP_4)
++                        sym = numLock ? XK_4 : XK_Left;
++                    else if (sym == XK_KP_5)
++                        sym = XK_5;
++                    else if (sym == XK_KP_6)
++                        sym = numLock ? XK_6 : XK_Right;
++                    else if (sym == XK_KP_7)
++                        sym = numLock ? XK_7 : XK_Home;
++                    else if (sym == XK_KP_8)
++                        sym = numLock ? XK_8 : XK_Up;
++                    else if (sym == XK_KP_9)
++                        sym = numLock ? XK_9 : XK_Page_Up;
++
++                    switch (sym)
++                    {
++                        case XK_Left:
++                        case XK_Right:
++                        case XK_Up:
++                        case XK_Down:
++                        case XK_Page_Up:
++                        case XK_Page_Down:
++                        case XK_End:
++                        case XK_Home:
++                        case XK_Delete:
++                        case XK_Insert:
++                            keyPressed = true;
++                            sym = (sym & 0xff) | nonAsciiModifier;
++                            break;
++                        case XK_Tab:
++                        case XK_Return:
++                        case XK_Escape:
++                        case XK_BackSpace:
++                            keyPressed = true;
++                            sym &= 0xff;
++                            break;
++                        default:
++                        {
++                            if (sym >= XK_F1 && sym <= XK_F12)
++                            {
++                                keyPressed = true;
++                                sym = (sym & 0xff) | nonAsciiModifier;
++                            }
++                            break;
++                        }
++                    }
++                }
++
++                if ((sym & 0xff00) == 0 && sym >= 8)
++                    keyPressed = true;
++
++                if (capsLock && ((sym >= XK_A && sym <= XK_Z) || (sym >= XK_a && sym <= XK_z)))
++                {
++                    index ^= 1;
++                    sym = XKeycodeToKeysym (display, keyEvent->keycode, index);
++                }
++
++                if (oldMods != currentModifiers)
++                    handleModifierKeysChange();
++
++                if (keyDownChange)
++                    handleKeyUpOrDown();
++
++                if (keyPressed)
++                    handleKeyPress (sym);
++
++                break;
++            }
++
++            case KeyRelease:
++            {
++                XKeyEvent* keyEvent = (XKeyEvent*) &event->xkey;
++                updateKeyStates (keyEvent->keycode, false);
++
++                KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, 0);
++
++                const int oldMods = currentModifiers;
++                const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false);
++
++                if (oldMods != currentModifiers)
++                    handleModifierKeysChange();
++
++                if (keyDownChange)
++                    handleKeyUpOrDown();
++
++                break;
++            }
++
++            case ButtonPress:
++            {
++                XButtonPressedEvent* buttonPressEvent = (XButtonPressedEvent*) &event->xbutton;
++
++                bool buttonMsg = false;
++                bool wheelUpMsg = false;
++                bool wheelDownMsg = false;
++
++                const int map = pointerMap [buttonPressEvent->button - Button1];
++
++                if (map == LeftButton)
++                {
++                    currentModifiers |= ModifierKeys::leftButtonModifier;
++                    buttonMsg = true;
++                }
++                else if (map == RightButton)
++                {
++                    currentModifiers |= ModifierKeys::rightButtonModifier;
++                    buttonMsg = true;
++                }
++                else if (map == MiddleButton)
++                {
++                    currentModifiers |= ModifierKeys::middleButtonModifier;
++                    buttonMsg = true;
++                }
++                else if (map == WheelUp)
++                {
++                    wheelUpMsg = true;
++                }
++                else if (map == WheelDown)
++                {
++                    wheelDownMsg = true;
++                }
++
++                updateKeyModifiers (buttonPressEvent->state);
++
++                if (buttonMsg)
++                {
++                    toFront (true);
++                    handleMouseDown (buttonPressEvent->x, buttonPressEvent->y,
++                                     getEventTime (buttonPressEvent->time));
++                }
++                else if (wheelUpMsg || wheelDownMsg)
++                {
++                    handleMouseWheel (wheelDownMsg ? -84 : 84,
++                                      getEventTime (buttonPressEvent->time));
++                }
++
++                lastMousePosX = lastMousePosY = 0x100000;
++                break;
++            }
++
++            case ButtonRelease:
++            {
++                XButtonReleasedEvent* buttonRelEvent = (XButtonReleasedEvent*) &event->xbutton;
++
++                const int oldModifiers = currentModifiers;
++                const int map = pointerMap [buttonRelEvent->button - Button1];
++
++                if (map == LeftButton)
++                    currentModifiers &= ~ModifierKeys::leftButtonModifier;
++                else if (map == RightButton)
++                    currentModifiers &= ~ModifierKeys::rightButtonModifier;
++                else if (map == MiddleButton)
++                    currentModifiers &= ~ModifierKeys::middleButtonModifier;
++
++                updateKeyModifiers (buttonRelEvent->state);
++
++                handleMouseUp (oldModifiers,
++                               buttonRelEvent->x, buttonRelEvent->y,
++                               getEventTime (buttonRelEvent->time));
++
++                lastMousePosX = lastMousePosY = 0x100000;
++                break;
++            }
++
++            case MotionNotify:
++            {
++                XPointerMovedEvent* movedEvent = (XPointerMovedEvent*) &event->xmotion;
++
++                updateKeyModifiers (movedEvent->state);
++
++                int x, y, mouseMods;
++                getMousePos (x, y, mouseMods);
++
++                if (lastMousePosX != x || lastMousePosY != y)
++                {
++                    lastMousePosX = x;
++                    lastMousePosY = y;
++
++                    x -= getScreenX();
++                    y -= getScreenY();
++
++                    if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0)
++                        handleMouseMove (x, y, getEventTime (movedEvent->time));
++                    else
++                        handleMouseDrag (x, y, getEventTime (movedEvent->time));
++                }
++
++                break;
++            }
++
++            case EnterNotify:
++            {
++                lastMousePosX = lastMousePosY = 0x100000;
++                XEnterWindowEvent* enterEvent = (XEnterWindowEvent*) &event->xcrossing;
++
++                if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0
++                     && ! entered)
++                {
++                    updateKeyModifiers (enterEvent->state);
++
++                    handleMouseEnter (enterEvent->x, enterEvent->y, getEventTime (enterEvent->time));
++
++                    entered = true;
++                }
++
++                break;
++            }
++
++            case LeaveNotify:
++            {
++                XLeaveWindowEvent* leaveEvent = (XLeaveWindowEvent*) &event->xcrossing;
++
++                // 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 & ModifierKeys::allMouseButtonModifiers) == 0
++                     && leaveEvent->mode == NotifyNormal)
++                    || leaveEvent->mode == NotifyUngrab)
++                {
++                    updateKeyModifiers (leaveEvent->state);
++
++                    handleMouseExit (leaveEvent->x, leaveEvent->y, getEventTime (leaveEvent->time));
++
++                    entered = false;
++                }
++
++                break;
++            }
++
++            case FocusIn:
++            {
++                isActiveApplication = true;
++                handleFocusGain();
++                break;
++            }
++
++            case FocusOut:
++            {
++                isActiveApplication = false;
++                handleFocusLoss();
++                break;
++            }
++
++            case Expose:
++            {
++                // Batch together all pending expose events
++                XExposeEvent* exposeEvent = (XExposeEvent*) &event->xexpose;
++                XEvent nextEvent;
++
++                repaint (exposeEvent->x, exposeEvent->y,
++                         exposeEvent->width, exposeEvent->height);
++
++                while (XEventsQueued (display, QueuedAfterFlush) > 0)
++                {
++                    XPeekEvent (display, (XEvent*) &nextEvent);
++                    if (nextEvent.type != Expose || nextEvent.xany.window != event->xany.window)
++                        break;
++
++                    XNextEvent (display, (XEvent*)&nextEvent);
++                    XExposeEvent* nextExposeEvent = (XExposeEvent*)(&nextEvent.xexpose);
++                    repaint (nextExposeEvent->x, nextExposeEvent->y,
++                             nextExposeEvent->width, nextExposeEvent->height);
++                }
++
++                break;
++            }
++
++            case CreateNotify:
++            case DestroyNotify:
++                // Think we can ignore these
++                break;
++
++            case CirculateNotify:
++                break;
++
++            case ConfigureNotify:
++            case ReparentNotify:
++            case GravityNotify:
++                updateBounds();
++                break;
++
++            case MapNotify:
++                mapped = true;
++                handleBroughtToFront();
++                break;
++
++            case UnmapNotify:
++                mapped = false;
++                break;
++
++            case MappingNotify:
++            {
++                XMappingEvent* mappingEvent = (XMappingEvent*) &event->xmapping;
++
++                if (mappingEvent->request != MappingPointer)
++                {
++                    // Deal with modifier/keyboard mapping
++                    XRefreshKeyboardMapping (mappingEvent);
++                    getModifierMapping();
++                }
++
++                break;
++            }
++
++            case ClientMessage:
++            {
++                XClientMessageEvent* clientMsg = (XClientMessageEvent*) &event->xclient;
++
++                if (clientMsg->message_type == wm_Protocols && clientMsg->format == 32)
++                {
++                    const Atom atom = (Atom) clientMsg->data.l[0];
++
++                    if (atom == wm_ProtocolList [TAKE_FOCUS])
++                    {
++                        XWindowAttributes atts;
++
++                        if (clientMsg->window != 0
++                             && XGetWindowAttributes (display, clientMsg->window, &atts))
++                        {
++                            if (atts.map_state == IsViewable)
++                                XSetInputFocus (display, clientMsg->window, RevertToParent, clientMsg->data.l[1]);
++                        }
++                    }
++                    else if (atom == wm_ProtocolList [DELETE_WINDOW])
++                    {
++                        handleUserClosingWindow();
++                    }
++                }
++                else if (clientMsg->message_type == repaintId)
++                {
++                    // Get rid of all pending repaint events
++                    XEvent nextEvent;
++
++                    while (XEventsQueued (display, QueuedAfterFlush) > 0)
++                    {
++                        XPeekEvent (display, &nextEvent);
++                        if (nextEvent.xany.type != ClientMessage ||
++                            nextEvent.xany.window != event->xany.window)
++                            break;
++
++                        XClientMessageEvent* nextClientMsg = (XClientMessageEvent*) (&nextEvent.xclient);
++                        if (nextClientMsg->message_type != repaintId)
++                            break;
++
++                        XNextEvent (display, &nextEvent);
++                    }
++
++                    static bool reentrancyCheck = false;
++                    if (! reentrancyCheck)
++                    {
++                        reentrancyCheck = true;
++
++                        int ox, oy, ow, oh;
++                        getBounds (ox, oy, ow, oh);
++                        repaint (0, 0, ow, oh);
++                        performPendingRepaints();
++
++                        reentrancyCheck = false;
++                    }
++                }
++
++                break;
++            }
++
++            case SelectionClear:
++            case SelectionNotify:
++            case SelectionRequest:
++                // We shouldn't get these on normal windows
++                break;
++
++            default:
++                break;
++        }
++    }
++
++    void showMouseCursor (Cursor cursor)
++    {
++        XDefineCursor (display, windowH, cursor);
++    }
++
++    //==============================================================================
++    juce_UseDebuggingNewOperator
++
++    bool dontRepaint;
++
++private:
++    //==============================================================================
++    class LinuxRepaintManager : public RepaintManager
++    {
++    public:
++        LinuxRepaintManager (LinuxComponentPeer* const peer_,
++                             Component* const component,
++                             const int timeBeforeReleasingImage)
++            : RepaintManager (component, timeBeforeReleasingImage),
++              peer (peer_)
++        {
++        }
++
++        Image* createNewImage (int w, int h)
++        {
++            return new XBitmapImage (Image::RGB, w, h, false);
++        }
++
++        void repaintNow (const RectangleList& areasToPaint)
++        {
++            peer->clearMaskedRegion();
++
++            renderCacheAreasNeedingRepaint();
++
++            int x, y;
++            XBitmapImage* const paintingBuffer = (XBitmapImage*) getImage (x, y);
++
++            if (paintingBuffer != 0)
++            {
++                const RectangleList* repaintRegion = &areasToPaint;
++                RectangleList temp;
++
++                if (! peer->maskedRegion.isEmpty())
++                {
++                    temp = areasToPaint;
++                    temp.subtract (peer->maskedRegion);
++                    repaintRegion = &temp;
++                }
++
++                for (RectangleList::Iterator i (*repaintRegion); i.next();)
++                {
++                    const Rectangle& r = i.getRectangle();
++
++                    paintingBuffer->blitToWindow (peer->windowH,
++                                                  r.getX(), r.getY(), r.getWidth(), r.getHeight(),
++                                                  r.getX() - x, r.getY() - y);
++                }
++            }
++        }
++
++    private:
++        LinuxComponentPeer* const peer;
++
++        LinuxRepaintManager (const LinuxRepaintManager&);
++        const LinuxRepaintManager& operator= (const LinuxRepaintManager&);
++    };
++
++    LinuxRepaintManager* repainter;
++
++    friend class LinuxRepaintManager;
++    Window windowH;
++    int wx, wy, ww, wh;
++    bool fullScreen, entered, mapped;
++    BorderSize windowBorder;
++
++    //==============================================================================
++    void removeWindowDecorations (Window wndH)
++    {
++        Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True);
++
++        if (hints != None)
++        {
++            typedef struct
++            {
++                CARD32 flags;
++                CARD32 functions;
++                CARD32 decorations;
++                INT32 input_mode;
++                CARD32 status;
++            } MotifWmHints;
++
++            MotifWmHints motifHints;
++            motifHints.flags = 2; /* MWM_HINTS_DECORATIONS */
++            motifHints.decorations = 0;
++
++            XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
++                             (unsigned char*) &motifHints, 4);
++        }
++
++        hints = XInternAtom (display, "_WIN_HINTS", True);
++
++        if (hints != None)
++        {
++            long gnomeHints = 0;
++
++            XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
++                             (unsigned char*) &gnomeHints, 1);
++        }
++
++        hints = XInternAtom (display, "KWM_WIN_DECORATION", True);
++
++        if (hints != None)
++        {
++            long kwmHints = 2; /*KDE_tinyDecoration*/
++
++            XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
++                             (unsigned char*) &kwmHints, 1);
++        }
++
++        hints = XInternAtom (display, "_NET_WM_WINDOW_TYPE", True);
++
++        if (hints != None)
++        {
++            Atom netHints [2];
++            netHints[0] = XInternAtom (display, "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", True);
++
++            if ((styleFlags & windowIsTemporary) != 0)
++                netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_MENU", True);
++            else
++                netHints[1] = XInternAtom (display, "_NET_WM_WINDOW_TYPE_NORMAL", True);
++
++            XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace,
++                             (unsigned char*) &netHints, 2);
++        }
++    }
++
++    void addWindowButtons (Window wndH)
++    {
++        Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True);
++
++        if (hints != None)
++        {
++            typedef struct
++            {
++                CARD32 flags;
++                CARD32 functions;
++                CARD32 decorations;
++                INT32 input_mode;
++                CARD32 status;
++            } MotifWmHints;
++
++            MotifWmHints motifHints;
++
++            motifHints.flags = 1 | 2; /* MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS */
++            motifHints.decorations = 2 /* MWM_DECOR_BORDER */ | 8 /* MWM_DECOR_TITLE */ | 16; /* MWM_DECOR_MENU */
++
++            motifHints.functions = 4 /* MWM_FUNC_MOVE */;
++
++            if ((styleFlags & windowHasCloseButton) != 0)
++                motifHints.functions |= 32; /* MWM_FUNC_CLOSE */
++
++            if ((styleFlags & windowHasMinimiseButton) != 0)
++            {
++                motifHints.functions |= 8; /* MWM_FUNC_MINIMIZE */
++                motifHints.decorations |= 0x20; /* MWM_DECOR_MINIMIZE */
++            }
++
++            if ((styleFlags & windowHasMaximiseButton) != 0)
++            {
++                motifHints.functions |= 0x10; /* MWM_FUNC_MAXIMIZE */
++                motifHints.decorations |= 0x40; /* MWM_DECOR_MAXIMIZE */
++            }
++
++            if ((styleFlags & windowIsResizable) != 0)
++            {
++                motifHints.functions |= 2; /* MWM_FUNC_RESIZE */
++                motifHints.decorations |= 0x4; /* MWM_DECOR_RESIZEH */
++            }
++
++            XChangeProperty (display, wndH, hints, hints, 32, PropModeReplace,
++                             (unsigned char*) &motifHints, 4);
++        }
++
++        hints = XInternAtom (display, "_NET_WM_ALLOWED_ACTIONS", True);
++
++        if (hints != None)
++        {
++            Atom netHints [6];
++            int num = 0;
++
++            netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_RESIZE", (styleFlags & windowIsResizable) ? True : False);
++            netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_FULLSCREEN", (styleFlags & windowHasMaximiseButton) ? True : False);
++            netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_MINIMIZE", (styleFlags & windowHasMinimiseButton) ? True : False);
++            netHints [num++] = XInternAtom (display, "_NET_WM_ACTION_CLOSE", (styleFlags & windowHasCloseButton) ? True : False);
++
++            XChangeProperty (display, wndH, hints, XA_ATOM, 32, PropModeReplace,
++                             (unsigned char*) &netHints, num);
++        }
++    }
++
++    static void* createWindowCallback (void* userData)
++    {
++        ((LinuxComponentPeer*) userData)->createWindow();
++        return 0;
++    }
++
++    void createWindow()
++    {
++        static bool atomsInitialised = false;
++
++        if (! atomsInitialised)
++        {
++            atomsInitialised = true;
++
++            wm_Protocols                      = XInternAtom (display, "WM_PROTOCOLS", 1);
++            wm_ProtocolList [TAKE_FOCUS]      = XInternAtom (display, "WM_TAKE_FOCUS", 1);
++            wm_ProtocolList [DELETE_WINDOW]   = XInternAtom (display, "WM_DELETE_WINDOW", 1);
++            wm_ChangeState                    = XInternAtom (display, "WM_CHANGE_STATE", 1);
++            wm_State                          = XInternAtom (display, "WM_STATE", 1);
++            wm_ActiveWin                      = XInternAtom (display, "_NET_ACTIVE_WINDOW", False);
++            repaintId                         = XInternAtom (display, "JUCERepaintAtom", 1);
++        }
++
++        // Get defaults for various properties
++        const int screen = DefaultScreen (display);
++        Window root = RootWindow (display, screen);
++
++        // Attempt to create a 24-bit window on the default screen.  If this is not
++        // possible then exit
++        XVisualInfo desiredVisual;
++        desiredVisual.screen = screen;
++        desiredVisual.depth = 24;
++
++        int numVisuals;
++        XVisualInfo* visuals = XGetVisualInfo (display, VisualScreenMask | VisualDepthMask,
++                                               &desiredVisual, &numVisuals);
++
++        if (numVisuals < 1 || visuals == 0)
++        {
++            Logger::outputDebugString ("ERROR: System doesn't support 24-bit RGB display.\n");
++            Process::terminate();
++        }
++
++        // Just choose the first one
++        Visual* visual = visuals[0].visual;
++        const int depth = visuals[0].depth;
++        XFree (visuals);
++
++        // Set up the window attributes
++        XSetWindowAttributes swa;
++        swa.border_pixel = 0;
++        swa.colormap = DefaultColormap (display, screen);
++        swa.override_redirect = getComponent()->isAlwaysOnTop() ? True : False;
++        swa.event_mask = eventMask;
++
++        Window wndH = XCreateWindow (display, root,
++                                     0, 0, 1, 1, 0,
++                                     depth, InputOutput, visual,
++                                     CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
++                                     &swa);
++
++        XGrabButton (display, AnyButton, AnyModifier, wndH, False,
++                     ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
++                     GrabModeAsync, GrabModeAsync, None, None);
++
++        // Set the window context to identify the window handle object
++        if (XSaveContext (display, (XID) wndH, improbableNumber, (XPointer) this))
++        {
++            // Failed
++            jassertfalse
++            Logger::outputDebugString ("Failed to create context information for window.\n");
++            XDestroyWindow (display, wndH);
++            wndH = 0;
++        }
++
++        // Set window manager hints
++        XWMHints* wmHints = XAllocWMHints();
++        wmHints->flags = InputHint | StateHint;
++        wmHints->input = True;      // Locally active input model
++        wmHints->initial_state = NormalState;
++        XSetWMHints (display, wndH, wmHints);
++        XFree (wmHints);
++
++        if ((styleFlags & juce_windowIsSemiTransparentFlag) != 0)
++        {
++            //xxx
++            jassertfalse
++        }
++
++        if ((styleFlags & windowAppearsOnTaskbar) != 0)
++        {
++            //xxx
++        }
++
++        if ((styleFlags & windowHasTitleBar) == 0)
++            removeWindowDecorations (wndH);
++        else
++            addWindowButtons (wndH);
++
++        XSetTransientForHint (display, wndH, RootWindow (display, DefaultScreen (display)));
++
++        // Set window manager protocols
++        XChangeProperty (display, wndH, wm_Protocols, XA_ATOM, 32, PropModeReplace,
++                         (unsigned char*) wm_ProtocolList, 2);
++
++        // Set window name
++        setWindowTitle (wndH, getComponent()->getName());
++
++        // Initialise the pointer and keyboard mapping
++        // This is not the same as the logical pointer mapping the X server uses:
++        // we don't mess with this.
++        static bool mappingInitialised = false;
++
++        if (! mappingInitialised)
++        {
++            mappingInitialised = true;
++
++            const int numButtons = XGetPointerMapping (display, 0, 0);
++
++            if (numButtons == 2)
++            {
++                pointerMap[0] = LeftButton;
++                pointerMap[1] = RightButton;
++                pointerMap[2] = pointerMap[3] = pointerMap[4] = NoButton;
++            }
++            else if (numButtons >= 3)
++            {
++                pointerMap[0] = LeftButton;
++                pointerMap[1] = MiddleButton;
++                pointerMap[2] = RightButton;
++
++                if (numButtons >= 5)
++                {
++                    pointerMap[3] = WheelUp;
++                    pointerMap[4] = WheelDown;
++                }
++            }
++
++            getModifierMapping();
++        }
++
++        windowH = wndH;
++    }
++
++    static void* destroyWindowCallback (void* userData)
++    {
++        Window windowH = (Window) userData;
++
++        XPointer handlePointer;
++        if (! XFindContext (display, (XID) windowH, improbableNumber, &handlePointer))
++            XDeleteContext (display, (XID) windowH, improbableNumber);
++
++        XDestroyWindow (display, windowH);
++
++        // Wait for it to complete and then remove any events for this
++        // window from the event queue.
++        XSync (display, false);
++
++        XEvent event;
++        while (XCheckWindowEvent (display, windowH, eventMask, &event) == True)
++        {}
++
++        return 0;
++    }
++
++    static int64 getEventTime (::Time t)
++    {
++        static int64 eventTimeOffset = 0x12345678;
++        const int64 thisMessageTime = t;
++
++        if (eventTimeOffset == 0x12345678)
++            eventTimeOffset = Time::currentTimeMillis() - thisMessageTime;
++
++        return eventTimeOffset + thisMessageTime;
++    }
++
++    static void setWindowTitle (Window xwin, const char* const title)
++    {
++        XTextProperty nameProperty;
++        char* strings[] = { (char*) title };
++
++        if (XStringListToTextProperty (strings, 1, &nameProperty))
++        {
++            XSetWMName (display, xwin, &nameProperty);
++            XSetWMIconName (display, xwin, &nameProperty);
++        }
++    }
++
++    void updateBorderSize()
++    {
++        if ((styleFlags & windowHasTitleBar) == 0)
++        {
++            windowBorder = BorderSize (0);
++        }
++        else if (windowBorder.getTopAndBottom() == 0 && windowBorder.getLeftAndRight() == 0)
++        {
++            Atom hints = XInternAtom (display, "_NET_FRAME_EXTENTS", True);
++
++            if (hints != None)
++            {
++                CARD32* sizes = 0;
++                unsigned long nitems, bytesLeft;
++                Atom actualType;
++                int actualFormat;
++
++                if (XGetWindowProperty (display, windowH, hints, 0, 4, False,
++                                        XA_CARDINAL, &actualType, &actualFormat, &nitems, &bytesLeft,
++                                        (unsigned char**) &sizes) == Success)
++                {
++                    if (actualFormat == 32)
++                        windowBorder = BorderSize ((int) sizes[2], (int) sizes[0],
++                                                   (int) sizes[3], (int) sizes[1]);
++
++                    XFree (sizes);
++                }
++            }
++        }
++    }
++
++    void updateBounds()
++    {
++        jassert (windowH != 0);
++        if (windowH != 0)
++        {
++            Window root, child;
++            unsigned int bw, depth;
++
++            if (! XGetGeometry (display, (Drawable) windowH, &root,
++                                &wx, &wy, (unsigned int*) &ww, (unsigned int*) &wh,
++                                &bw, &depth))
++            {
++                wx = wy = ww = wh = 0;
++            }
++            else if (! XTranslateCoordinates (display, windowH, root, 0, 0, &wx, &wy, &child))
++            {
++                wx = wy = 0;
++            }
++
++            updateBorderSize();
++            handleMovedOrResized();
++        }
++    }
++};
++
++//==============================================================================
++ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/)
++{
++    return new LinuxComponentPeer (this, styleFlags);
++}
++
++
++//==============================================================================
++// (this callback is hooked up in the messaging code)
++void juce_windowMessageReceive (XEvent* event)
++{
++    if (event->xany.window != None)
++    {
++        // Check if the event is for one of our windows
++        LinuxComponentPeer* peer = 0;
++
++        if (! XFindContext (display, (XID) event->xany.window, improbableNumber, (XPointer*) &peer))
++        {
++            if (peer != 0 && peer->isValidMessageListener())
++                peer->handleWindowMessage (event);
++        }
++    }
++    else
++    {
++        switch (event->xany.type)
++        {
++            case KeymapNotify:
++            {
++                const XKeymapEvent* const keymapEvent = (const XKeymapEvent*) &event->xkeymap;
++                memcpy (keyStates, keymapEvent->key_vector, 32);
++                break;
++            }
++
++            default:
++                break;
++        }
++    }
++}
++
++//==============================================================================
++void juce_updateMultiMonitorInfo (Array <Rectangle>& monitorCoords, const bool clipToWorkArea)
++{
++#if JUCE_USE_XINERAMA
++    int major_opcode, first_event, first_error;
++
++    if (XQueryExtension (display, "XINERAMA", &major_opcode, &first_event, &first_error)
++         && XineramaIsActive (display))
++    {
++        int numMonitors = 0;
++        XineramaScreenInfo* const screens = XineramaQueryScreens (display, &numMonitors);
++
++        if (screens != 0)
++        {
++            for (int i = numMonitors; --i >= 0;)
++            {
++                int index = screens[i].screen_number;
++
++                if (index >= 0)
++                {
++                    while (monitorCoords.size() < index)
++                        monitorCoords.add (Rectangle (0, 0, 0, 0));
++
++                    monitorCoords.set (index, Rectangle (screens[i].x_org,
++                                                         screens[i].y_org,
++                                                         screens[i].width,
++                                                         screens[i].height));
++                }
++            }
++
++            XFree (screens);
++        }
++    }
++
++    if (monitorCoords.size() == 0)
++#endif
++    {
++        monitorCoords.add (Rectangle (0, 0,
++                                      DisplayWidth (display, DefaultScreen (display)),
++                                      DisplayHeight (display, DefaultScreen (display))));
++    }
++}
++
++//==============================================================================
++bool Desktop::canUseSemiTransparentWindows()
++{
++    return false;
++}
++
++void Desktop::getMousePosition (int& x, int& y)
++{
++    int mouseMods;
++    getMousePos (x, y, mouseMods);
++}
++
++void Desktop::setMousePosition (int x, int y)
++{
++    Window root = RootWindow (display, DefaultScreen (display));
++    XWarpPointer (display, None, root, 0, 0, 0, 0, x, y);
++}
++
++
++//==============================================================================
++void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY)
++{
++    Window root = RootWindow (display, DefaultScreen (display));
++    const unsigned int imageW = image.getWidth();
++    const unsigned int imageH = image.getHeight();
++    unsigned int cursorW, cursorH;
++
++    if (! XQueryBestCursor (display, root, imageW, imageH, &cursorW, &cursorH))
++        return 0;
++
++    Image im (Image::ARGB, cursorW, cursorH, true);
++    Graphics g (im);
++
++    if (imageW > cursorW || imageH > cursorH)
++    {
++        hotspotX = (hotspotX * cursorW) / imageW;
++        hotspotY = (hotspotY * cursorH) / imageH;
++
++        g.drawImageWithin (&image, 0, 0, imageW, imageH,
++                           Justification::topLeft,
++                           false, false);
++    }
++    else
++    {
++        g.drawImageAt (&image, 0, 0);
++    }
++
++    const int stride = (cursorW + 7) >> 3;
++    unsigned char* const maskPlane = (unsigned char*)juce_calloc (stride*cursorH);
++    unsigned char* const sourcePlane = (unsigned char*)juce_calloc (stride*cursorH);
++
++    bool msbfirst = (BitmapBitOrder (display) == MSBFirst);
++
++    for (int y = cursorH; --y >= 0;)
++    {
++        for (int x = cursorW; --x >= 0;)
++        {
++            const unsigned char mask = (unsigned char)(1 << (msbfirst ? (7 - (x & 7)) : (x & 7)));
++            const int offset = y * stride + (x >> 3);
++
++            const Colour c (im.getPixelAt (x, y));
++
++            if (c.getAlpha() >= 128)
++                maskPlane[offset] |= mask;
++
++            if (c.getBrightness() >= 0.5f)
++                sourcePlane[offset] |= mask;
++        }
++    }
++
++    Pixmap sourcePixmap = XCreatePixmapFromBitmapData (display, root, (char*)sourcePlane, cursorW, cursorH, 0xffff, 0, 1);
++    Pixmap maskPixmap = XCreatePixmapFromBitmapData (display, root, (char*)maskPlane, cursorW, cursorH, 0xffff, 0, 1);
++
++    juce_free (maskPlane);
++    juce_free (sourcePlane);
++
++    XColor white, black;
++    black.red = black.green = black.blue = 0;
++    white.red = white.green = white.blue = 0xffff;
++
++    void* result = (void*) XCreatePixmapCursor (display, sourcePixmap, maskPixmap, &white, &black, hotspotX, hotspotY);
++
++    XFreePixmap (display, sourcePixmap);
++    XFreePixmap (display, maskPixmap);
++
++    return result;
++}
++
++void juce_deleteMouseCursor (void* cursorHandle, bool)
++{
++    if (cursorHandle != None)
++        XFreeCursor (display, (Cursor)cursorHandle);
++}
++
++void* juce_createStandardMouseCursor (MouseCursor::StandardCursorType type)
++{
++    unsigned int shape;
++
++    switch (type)
++    {
++        case MouseCursor::NoCursor:
++        {
++            void* invisibleCursor;
++
++            Image im (Image::ARGB, 16, 16, true);
++            invisibleCursor = juce_createMouseCursorFromImage (im, 0, 0);
++
++            return invisibleCursor;
++        }
++
++        case MouseCursor::NormalCursor:
++            return (void*) None; // Use parent cursor
++
++        case MouseCursor::DraggingHandCursor:
++        {
++            void* dragHandCursor;
++            static unsigned char dragHandData[] = {71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,
++              0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0,
++              16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,
++              132,117,151,116,132,146,248,60,209,138,98,22,203,114,34,236,37,52,77,217,
++              247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };
++            const int dragHandDataSize = 99;
++
++            Image* im = ImageFileFormat::loadFrom ((const char*) dragHandData, dragHandDataSize);
++            dragHandCursor = juce_createMouseCursorFromImage (*im, 8, 7);
++            delete im;
++
++            return dragHandCursor;
++        }
++
++        case MouseCursor::CopyingCursor:
++        {
++            void* copyCursor;
++
++            static unsigned char copyCursorData[] = {71,73,70,56,57,97,21,0,21,0,145,0,0,0,0,0,255,255,255,0,
++              128,128,255,255,255,33,249,4,1,0,0,3,0,44,0,0,0,0,21,0,
++              21,0,0,2,72,4,134,169,171,16,199,98,11,79,90,71,161,93,56,111,
++              78,133,218,215,137,31,82,154,100,200,86,91,202,142,12,108,212,87,235,174,
++              15,54,214,126,237,226,37,96,59,141,16,37,18,201,142,157,230,204,51,112,
++              252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 };
++            const int copyCursorSize = 119;
++
++            Image* im = ImageFileFormat::loadFrom ((const char*)copyCursorData, copyCursorSize);
++            copyCursor = juce_createMouseCursorFromImage (*im, 1, 3);
++            delete im;
++
++            return copyCursor;
++        }
++
++        case MouseCursor::WaitCursor:
++            shape = XC_watch;
++            break;
++
++        case MouseCursor::IBeamCursor:
++            shape = XC_xterm;
++            break;
++
++        case MouseCursor::PointingHandCursor:
++            shape = XC_hand2;
++            break;
++
++        case MouseCursor::LeftRightResizeCursor:
++            shape = XC_sb_h_double_arrow;
++            break;
++
++        case MouseCursor::UpDownResizeCursor:
++            shape = XC_sb_v_double_arrow;
++            break;
++
++        case MouseCursor::UpDownLeftRightResizeCursor:
++            shape = XC_fleur;
++            break;
++
++        case MouseCursor::TopEdgeResizeCursor:
++            shape = XC_top_side;
++            break;
++
++        case MouseCursor::BottomEdgeResizeCursor:
++            shape = XC_bottom_side;
++            break;
++
++        case MouseCursor::LeftEdgeResizeCursor:
++            shape = XC_left_side;
++            break;
++
++        case MouseCursor::RightEdgeResizeCursor:
++            shape = XC_right_side;
++            break;
++
++        case MouseCursor::TopLeftCornerResizeCursor:
++            shape = XC_top_left_corner;
++            break;
++
++        case MouseCursor::TopRightCornerResizeCursor:
++            shape = XC_top_right_corner;
++            break;
++
++        case MouseCursor::BottomLeftCornerResizeCursor:
++            shape = XC_bottom_left_corner;
++            break;
++
++        case MouseCursor::BottomRightCornerResizeCursor:
++            shape = XC_bottom_right_corner;
++            break;
++
++        case MouseCursor::CrosshairCursor:
++            shape = XC_crosshair;
++            break;
++
++        default:
++            return (void*) None; // Use parent cursor
++    }
++
++    return (void*) XCreateFontCursor (display, shape);
++}
++
++void MouseCursor::showInWindow (ComponentPeer* peer) const
++{
++    LinuxComponentPeer* const lp = dynamic_cast <LinuxComponentPeer*> (peer);
++
++    if (lp != 0)
++        lp->showMouseCursor ((Cursor) getHandle());
++}
++
++void MouseCursor::showInAllWindows() const
++{
++    for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
++        showInWindow (ComponentPeer::getPeer (i));
++}
++
++//==============================================================================
++Image* juce_createIconForFile (const File& file)
++{
++    return 0;
++}
++
++
++//==============================================================================
++#if JUCE_OPENGL
++
++struct OpenGLContextInfo
++{
++    Window embeddedWindow;
++    GLXContext renderContext;
++};
++
++void* juce_createOpenGLContext (OpenGLComponent* component, void* sharedContext)
++{
++    XSync (display, False);
++    jassert (component != 0);
++
++    if (component == 0)
++        return 0;
++
++    LinuxComponentPeer* const peer
++        = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer());
++
++    if (peer == 0)
++        return 0;
++
++    GLint attribList[] =
++    {
++        GLX_RGBA,
++        GLX_DOUBLEBUFFER,
++        GLX_RED_SIZE, 8,
++        GLX_GREEN_SIZE, 8,
++        GLX_BLUE_SIZE, 8,
++        GLX_ALPHA_SIZE, 8,
++        GLX_DEPTH_SIZE, 8,
++        None
++    };
++
++    XVisualInfo* const bestVisual = glXChooseVisual (display, DefaultScreen (display), attribList);
++
++    if (bestVisual == 0)
++        return 0;
++
++    OpenGLContextInfo* const oc = new OpenGLContextInfo();
++
++    oc->renderContext = glXCreateContext (display, bestVisual,
++                                          (sharedContext != 0) ? ((OpenGLContextInfo*) sharedContext)->renderContext
++                                                               : 0,
++                                          GL_TRUE);
++
++    Window windowH = (Window) peer->getNativeHandle();
++
++    Colormap colourMap = XCreateColormap (display, windowH, bestVisual->visual, AllocNone);
++    XSetWindowAttributes swa;
++    swa.colormap = colourMap;
++    swa.border_pixel = 0;
++    swa.event_mask = StructureNotifyMask;
++
++    oc->embeddedWindow = XCreateWindow (display, windowH,
++                                        0, 0, 1, 1, 0,
++                                        bestVisual->depth,
++                                        InputOutput,
++                                        bestVisual->visual,
++                                        CWBorderPixel | CWColormap | CWEventMask,
++                                        &swa);
++
++    XMapWindow (display, oc->embeddedWindow);
++    XFreeColormap (display, colourMap);
++
++    XFree (bestVisual);
++    XSync (display, False);
++
++    return oc;
++}
++
++void juce_updateOpenGLWindowPos (void* context, Component* owner, Component* topComp)
++{
++    jassert (context != 0);
++    OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
++
++    XMoveResizeWindow (display, oc->embeddedWindow,
++                       owner->getScreenX() - topComp->getScreenX(),
++                       owner->getScreenY() - topComp->getScreenY(),
++                       jmax (1, owner->getWidth()),
++                       jmax (1, owner->getHeight()));
++}
++
++void juce_deleteOpenGLContext (void* context)
++{
++    OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
++
++    if (oc != 0)
++    {
++        glXDestroyContext (display, oc->renderContext);
++
++        XUnmapWindow (display, oc->embeddedWindow);
++        XDestroyWindow (display, oc->embeddedWindow);
++
++        delete oc;
++    }
++}
++
++bool juce_makeOpenGLContextCurrent (void* context)
++{
++    OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
++
++    if (oc != 0)
++        return glXMakeCurrent (display, oc->embeddedWindow, oc->renderContext)
++                && XSync (display, False);
++    else
++        return glXMakeCurrent (display, None, 0);
++}
++
++void juce_swapOpenGLBuffers (void* context)
++{
++    OpenGLContextInfo* const oc = (OpenGLContextInfo*) context;
++
++    if (oc != 0)
++        glXSwapBuffers (display, oc->embeddedWindow);
++}
++
++void juce_repaintOpenGLWindow (void* context)
++{
++}
++
++#endif
++
++
++//==============================================================================
++static void initClipboard (Window root, Atom* cutBuffers)
++{
++    static bool init = false;
++
++    if (! init)
++    {
++        init = true;
++
++        // Make sure all cut buffers exist before use
++        for (int i = 0; i < 8; i++)
++        {
++            XChangeProperty (display, root, cutBuffers[i],
++                             XA_STRING, 8, PropModeAppend, NULL, 0);
++        }
++    }
++}
++
++// Clipboard implemented currently using cut buffers
++// rather than the more powerful selection method
++void SystemClipboard::copyTextToClipboard (const String& clipText)
++{
++    Window root = RootWindow (display, DefaultScreen (display));
++    Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,
++                           XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 };
++
++    initClipboard (root, cutBuffers);
++
++    XRotateWindowProperties (display, root, cutBuffers, 8, 1);
++    XChangeProperty (display, root, cutBuffers[0],
++                     XA_STRING, 8, PropModeReplace, (const unsigned char*)((const char*)clipText),
++                     clipText.length());
++}
++
++const String SystemClipboard::getTextFromClipboard()
++{
++    char* clipData;
++    const int bufSize = 64;  // in words
++    int actualFormat;
++    int byteOffset = 0;
++    unsigned long bytesLeft, nitems;
++    Atom actualType;
++    String returnData;
++
++    Window root = RootWindow (display, DefaultScreen (display));
++
++    Atom cutBuffers[8] = { XA_CUT_BUFFER0, XA_CUT_BUFFER1, XA_CUT_BUFFER2, XA_CUT_BUFFER3,
++                           XA_CUT_BUFFER4, XA_CUT_BUFFER5, XA_CUT_BUFFER6, XA_CUT_BUFFER7 };
++
++    initClipboard (root, cutBuffers);
++
++    do
++    {
++        if (XGetWindowProperty (display, root, cutBuffers[0], byteOffset >> 2, bufSize,
++                                False, XA_STRING, &actualType, &actualFormat, &nitems, &bytesLeft,
++                                (unsigned char**) &clipData) != Success
++            || actualType != XA_STRING
++            || actualFormat != 8)
++            return String();
++
++        byteOffset += nitems;
++        returnData += String(clipData, nitems);
++        XFree (clipData);
++    }
++    while (bytesLeft);
++
++    return returnData;
++}
++
++//==============================================================================
++bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles)
++{
++    jassertfalse    // not implemented!
++    return false;
++}
++
++bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
++{
++    jassertfalse    // not implemented!
++    return false;
++}
++
++
++//==============================================================================
++void PlatformUtilities::beep()
++{
++    //xxx
++}
++
++
++//==============================================================================
++bool AlertWindow::showNativeDialogBox (const String& title,
++                                       const String& bodyText,
++                                       bool isOkCancel)
++{
++    // xxx this is supposed to pop up an alert!
++    Logger::outputDebugString (title + ": " + bodyText);
++    return true;
++}
++
++//==============================================================================
++const int KeyPress::spaceKey            = XK_space & 0xff;
++const int KeyPress::returnKey           = XK_Return & 0xff;
++const int KeyPress::escapeKey           = XK_Escape & 0xff;
++const int KeyPress::backspaceKey        = XK_BackSpace & 0xff;
++const int KeyPress::leftKey             = (XK_Left & 0xff) | nonAsciiModifier;
++const int KeyPress::rightKey            = (XK_Right & 0xff) | nonAsciiModifier;
++const int KeyPress::upKey               = (XK_Up & 0xff) | nonAsciiModifier;
++const int KeyPress::downKey             = (XK_Down & 0xff) | nonAsciiModifier;
++const int KeyPress::pageUpKey           = (XK_Page_Up & 0xff) | nonAsciiModifier;
++const int KeyPress::pageDownKey         = (XK_Page_Down & 0xff) | nonAsciiModifier;
++const int KeyPress::endKey              = (XK_End & 0xff) | nonAsciiModifier;
++const int KeyPress::homeKey             = (XK_Home & 0xff) | nonAsciiModifier;
++const int KeyPress::insertKey           = (XK_Insert & 0xff) | nonAsciiModifier;
++const int KeyPress::deleteKey           = (XK_Delete & 0xff) | nonAsciiModifier;
++const int KeyPress::tabKey              = XK_Tab & 0xff;
++const int KeyPress::F1Key               = (XK_F1 & 0xff) | nonAsciiModifier;
++const int KeyPress::F2Key               = (XK_F2 & 0xff) | nonAsciiModifier;
++const int KeyPress::F3Key               = (XK_F3 & 0xff) | nonAsciiModifier;
++const int KeyPress::F4Key               = (XK_F4 & 0xff) | nonAsciiModifier;
++const int KeyPress::F5Key               = (XK_F5 & 0xff) | nonAsciiModifier;
++const int KeyPress::F6Key               = (XK_F6 & 0xff) | nonAsciiModifier;
++const int KeyPress::F7Key               = (XK_F7 & 0xff) | nonAsciiModifier;
++const int KeyPress::F8Key               = (XK_F8 & 0xff) | nonAsciiModifier;
++const int KeyPress::F9Key               = (XK_F9 & 0xff) | nonAsciiModifier;
++const int KeyPress::F10Key              = (XK_F10 & 0xff) | nonAsciiModifier;
++const int KeyPress::F11Key              = (XK_F11 & 0xff) | nonAsciiModifier;
++const int KeyPress::F12Key              = (XK_F12 & 0xff) | nonAsciiModifier;
++const int KeyPress::playKey             = (0xffeeff00) | nonAsciiModifier;
++const int KeyPress::stopKey             = (0xffeeff01) | nonAsciiModifier;
++const int KeyPress::fastForwardKey      = (0xffeeff02) | nonAsciiModifier;
++const int KeyPress::rewindKey           = (0xffeeff03) | nonAsciiModifier;
++
++
++END_JUCE_NAMESPACE
++
++#endif
diff --git a/packages/juce/files/remove-x86isms.patch b/packages/juce/files/remove-x86isms.patch
new file mode 100644 (file)
index 0000000..83016f7
--- /dev/null
@@ -0,0 +1,2353 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- juce/src/juce_core/basics/juce_Atomic.h~remove-x86isms.patch
++++ juce/src/juce_core/basics/juce_Atomic.h
+@@ -1,188 +1,200 @@
+-/*\r
+-  ==============================================================================\r
+-\r
+-   This file is part of the JUCE library - "Jules' Utility Class Extensions"\r
+-   Copyright 2004-6 by Raw Material Software ltd.\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   JUCE can be redistributed and/or modified under the terms of the\r
+-   GNU General Public License, as published by the Free Software Foundation;\r
+-   either version 2 of the License, or (at your option) any later version.\r
+-\r
+-   JUCE is distributed in the hope that it will be useful,\r
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+-   GNU General Public License for more details.\r
+-\r
+-   You should have received a copy of the GNU General Public License\r
+-   along with JUCE; if not, visit www.gnu.org/licenses or write to the\r
+-   Free Software Foundation, Inc., 59 Temple Place, Suite 330, \r
+-   Boston, MA 02111-1307 USA\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   If you'd like to release a closed-source product which uses JUCE, commercial\r
+-   licenses are also available: visit www.rawmaterialsoftware.com/juce for\r
+-   more information.\r
+-\r
+-  ==============================================================================\r
+-*/\r
+-\r
+-#ifndef __JUCE_ATOMIC_JUCEHEADER__\r
+-#define __JUCE_ATOMIC_JUCEHEADER__\r
+-\r
+-// Atomic increment/decrement operations..\r
+-\r
+-//==============================================================================\r
+-#if JUCE_MAC && ! DOXYGEN\r
+-  #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)\r
+-    #include <libkern/OSAtomic.h>\r
+-\r
+-    forcedinline void atomicIncrement (int& variable) throw()\r
+-    {\r
+-        OSAtomicIncrement32 ((int32_t*) &variable);\r
+-    }\r
+-\r
+-    forcedinline int atomicIncrementAndReturn (int& variable) throw()\r
+-    {\r
+-        return OSAtomicIncrement32 ((int32_t*) &variable);\r
+-    }\r
+-\r
+-    forcedinline void atomicDecrement (int& variable) throw()\r
+-    {\r
+-        OSAtomicDecrement32 ((int32_t*) &variable);\r
+-    }\r
+-\r
+-    forcedinline int atomicDecrementAndReturn (int& variable) throw()\r
+-    {\r
+-       return OSAtomicDecrement32 ((int32_t*) &variable);\r
+-    }\r
+-\r
+-  #else\r
+-    forcedinline void atomicIncrement (int& variable) throw()\r
+-    {\r
+-       OTAtomicAdd32 (1, (SInt32*) &variable);\r
+-    }\r
+-\r
+-    forcedinline int atomicIncrementAndReturn (int& variable) throw()\r
+-    {\r
+-       return OTAtomicAdd32 (1, (SInt32*) &variable);\r
+-    }\r
+-\r
+-    forcedinline void atomicDecrement (int& variable) throw()\r
+-    {\r
+-       OTAtomicAdd32 (-1, (SInt32*) &variable);\r
+-    }\r
+-\r
+-    forcedinline int atomicDecrementAndReturn (int& variable) throw()\r
+-    {\r
+-       return OTAtomicAdd32 (-1, (SInt32*) &variable);\r
+-    }\r
+-  #endif\r
+-#else\r
+-#ifdef __GNUC__\r
+-\r
+-    /** Increments an integer in a thread-safe way. */\r
+-    forcedinline void atomicIncrement (int& variable) throw()\r
+-    {\r
+-        __asm__ __volatile (\r
+-            "lock incl (%%ecx)"\r
+-            :\r
+-            : "c" (&variable));\r
+-    }\r
+-\r
+-    /** Increments an integer in a thread-safe way and returns the incremented value. */\r
+-    forcedinline int atomicIncrementAndReturn (int& variable) throw()\r
+-    {\r
+-        int result;\r
+-\r
+-        __asm__ __volatile (\r
+-            "lock xaddl %%eax, (%%ebx)  \n\\r
+-             incl %%eax"\r
+-            : "=a" (result)\r
+-            : "b" (&variable), "a" (1)\r
+-            : "cc", "memory");\r
+-\r
+-        return result;\r
+-    }\r
+-\r
+-    /** Decrememts an integer in a thread-safe way. */\r
+-    forcedinline void atomicDecrement (int& variable) throw()\r
+-    {\r
+-        __asm__ __volatile (\r
+-            "lock decl (%%ecx)"\r
+-            :\r
+-            : "c" (&variable));\r
+-    }\r
+-\r
+-    /** Decrememts an integer in a thread-safe way and returns the incremented value. */\r
+-    forcedinline int atomicDecrementAndReturn (int& variable) throw()\r
+-    {\r
+-        int result;\r
+-\r
+-        __asm__ __volatile (\r
+-            "lock xaddl %%eax, (%%ebx)  \n\\r
+-             decl %%eax"\r
+-            : "=a" (result)\r
+-            : "b" (&variable), "a" (-1)\r
+-            : "cc", "memory");\r
+-\r
+-        return result;\r
+-    }\r
+-\r
+-#else\r
+-\r
+-    /** Increments an integer in a thread-safe way. */\r
+-    inline_assembly void __fastcall atomicIncrement (int& variable) throw()\r
+-    {\r
+-        __asm {\r
+-            mov ecx, dword ptr [variable]\r
+-            lock inc dword ptr [ecx]\r
+-        }\r
+-    }\r
+-\r
+-    /** Increments an integer in a thread-safe way and returns the incremented value. */\r
+-    inline_assembly int __fastcall atomicIncrementAndReturn (int& variable) throw()\r
+-    {\r
+-        int result;\r
+-\r
+-        __asm {\r
+-            mov ecx, dword ptr [variable]\r
+-            mov eax, 1\r
+-            lock xadd dword ptr [ecx], eax\r
+-            inc eax\r
+-            mov result, eax\r
+-        }\r
+-\r
+-        return result;\r
+-    }\r
+-\r
+-    /** Decrememts an integer in a thread-safe way. */\r
+-    inline_assembly void __fastcall atomicDecrement (int& variable) throw()\r
+-    {\r
+-        __asm {\r
+-            mov ecx, dword ptr [variable]\r
+-            lock dec dword ptr [ecx]\r
+-        }\r
+-    }\r
+-\r
+-    /** Decrememts an integer in a thread-safe way and returns the incremented value. */\r
+-    inline_assembly int __fastcall atomicDecrementAndReturn (int& variable) throw()\r
+-    {\r
+-        int result;\r
+-\r
+-        __asm {\r
+-            mov ecx, dword ptr [variable]\r
+-            mov eax, -1\r
+-            lock xadd dword ptr [ecx], eax\r
+-            dec eax\r
+-            mov result, eax\r
+-        }\r
+-\r
+-        return result;\r
+-    }\r
+-#endif\r
+-#endif\r
+-\r
+-#endif   // __JUCE_ATOMIC_JUCEHEADER__\r
++/*
++  ==============================================================================
++
++   This file is part of the JUCE library - "Jules' Utility Class Extensions"
++   Copyright 2004-6 by Raw Material Software ltd.
++
++  ------------------------------------------------------------------------------
++
++   JUCE can be redistributed and/or modified under the terms of the
++   GNU General Public License, as published by the Free Software Foundation;
++   either version 2 of the License, or (at your option) any later version.
++
++   JUCE is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with JUCE; if not, visit www.gnu.org/licenses or write to the
++   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
++   Boston, MA 02111-1307 USA
++
++  ------------------------------------------------------------------------------
++
++   If you'd like to release a closed-source product which uses JUCE, commercial
++   licenses are also available: visit www.rawmaterialsoftware.com/juce for
++   more information.
++
++  ==============================================================================
++*/
++
++#ifndef __JUCE_ATOMIC_JUCEHEADER__
++#define __JUCE_ATOMIC_JUCEHEADER__
++
++// Atomic increment/decrement operations..
++
++//==============================================================================
++#if JUCE_MAC && ! DOXYGEN
++  #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
++    #include <libkern/OSAtomic.h>
++
++    forcedinline void atomicIncrement (int& variable) throw()
++    {
++        OSAtomicIncrement32 ((int32_t*) &variable);
++    }
++
++    forcedinline int atomicIncrementAndReturn (int& variable) throw()
++    {
++        return OSAtomicIncrement32 ((int32_t*) &variable);
++    }
++
++    forcedinline void atomicDecrement (int& variable) throw()
++    {
++        OSAtomicDecrement32 ((int32_t*) &variable);
++    }
++
++    forcedinline int atomicDecrementAndReturn (int& variable) throw()
++    {
++       return OSAtomicDecrement32 ((int32_t*) &variable);
++    }
++
++  #else
++    forcedinline void atomicIncrement (int& variable) throw()
++    {
++       OTAtomicAdd32 (1, (SInt32*) &variable);
++    }
++
++    forcedinline int atomicIncrementAndReturn (int& variable) throw()
++    {
++       return OTAtomicAdd32 (1, (SInt32*) &variable);
++    }
++
++    forcedinline void atomicDecrement (int& variable) throw()
++    {
++       OTAtomicAdd32 (-1, (SInt32*) &variable);
++    }
++
++    forcedinline int atomicDecrementAndReturn (int& variable) throw()
++    {
++       return OTAtomicAdd32 (-1, (SInt32*) &variable);
++    }
++  #endif
++#else
++#ifdef __GNUC__
++
++    /** Increments an integer in a thread-safe way. */
++    forcedinline void atomicIncrement (int& variable) throw()
++    {
++#ifndef __x86__
++        variable++;
++#else
++        __asm__ __volatile (
++            "lock incl (%%ecx)"
++            :
++            : "c" (&variable));
++#endif
++    }
++
++    /** Increments an integer in a thread-safe way and returns the incremented value. */
++    forcedinline int atomicIncrementAndReturn (int& variable) throw()
++    {
++        int result;
++#ifndef __x86__
++        result = ++variable;
++#else
++        __asm__ __volatile (
++            "lock xaddl %%eax, (%%ebx)  \n\
++             incl %%eax"
++            : "=a" (result)
++            : "b" (&variable), "a" (1)
++            : "cc", "memory");
++#endif
++        return result;
++    }
++
++    /** Decrememts an integer in a thread-safe way. */
++    forcedinline void atomicDecrement (int& variable) throw()
++    {
++#ifndef __x86__
++        variable--;
++#else
++        __asm__ __volatile (
++            "lock decl (%%ecx)"
++            :
++            : "c" (&variable));
++#endif
++    }
++
++    /** Decrememts an integer in a thread-safe way and returns the incremented value. */
++    forcedinline int atomicDecrementAndReturn (int& variable) throw()
++    {
++        int result;
++#ifndef __x86__
++        result = --variable;
++#else
++        __asm__ __volatile (
++            "lock xaddl %%eax, (%%ebx)  \n\
++             decl %%eax"
++            : "=a" (result)
++            : "b" (&variable), "a" (-1)
++            : "cc", "memory");
++#endif
++        return result;
++    }
++
++#else
++
++    /** Increments an integer in a thread-safe way. */
++    inline_assembly void __fastcall atomicIncrement (int& variable) throw()
++    {
++        __asm {
++            mov ecx, dword ptr [variable]
++            lock inc dword ptr [ecx]
++        }
++    }
++
++    /** Increments an integer in a thread-safe way and returns the incremented value. */
++    inline_assembly int __fastcall atomicIncrementAndReturn (int& variable) throw()
++    {
++        int result;
++
++        __asm {
++            mov ecx, dword ptr [variable]
++            mov eax, 1
++            lock xadd dword ptr [ecx], eax
++            inc eax
++            mov result, eax
++        }
++
++        return result;
++    }
++
++    /** Decrememts an integer in a thread-safe way. */
++    inline_assembly void __fastcall atomicDecrement (int& variable) throw()
++    {
++        __asm {
++            mov ecx, dword ptr [variable]
++            lock dec dword ptr [ecx]
++        }
++    }
++
++    /** Decrememts an integer in a thread-safe way and returns the incremented value. */
++    inline_assembly int __fastcall atomicDecrementAndReturn (int& variable) throw()
++    {
++        int result;
++
++        __asm {
++            mov ecx, dword ptr [variable]
++            mov eax, -1
++            lock xadd dword ptr [ecx], eax
++            dec eax
++            mov result, eax
++        }
++
++        return result;
++    }
++#endif
++#endif
++
++#endif   // __JUCE_ATOMIC_JUCEHEADER__
+--- juce/src/juce_core/basics/juce_PlatformDefs.h~remove-x86isms.patch
++++ juce/src/juce_core/basics/juce_PlatformDefs.h
+@@ -1,326 +1,330 @@
+-/*\r
+-  ==============================================================================\r
+-\r
+-   This file is part of the JUCE library - "Jules' Utility Class Extensions"\r
+-   Copyright 2004-6 by Raw Material Software ltd.\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   JUCE can be redistributed and/or modified under the terms of the\r
+-   GNU General Public License, as published by the Free Software Foundation;\r
+-   either version 2 of the License, or (at your option) any later version.\r
+-\r
+-   JUCE is distributed in the hope that it will be useful,\r
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+-   GNU General Public License for more details.\r
+-\r
+-   You should have received a copy of the GNU General Public License\r
+-   along with JUCE; if not, visit www.gnu.org/licenses or write to the\r
+-   Free Software Foundation, Inc., 59 Temple Place, Suite 330, \r
+-   Boston, MA 02111-1307 USA\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   If you'd like to release a closed-source product which uses JUCE, commercial\r
+-   licenses are also available: visit www.rawmaterialsoftware.com/juce for\r
+-   more information.\r
+-\r
+-  ==============================================================================\r
+-*/\r
+-\r
+-#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__\r
+-#define __JUCE_PLATFORMDEFS_JUCEHEADER__\r
+-\r
+-\r
+-//==============================================================================\r
+-// set up platform definitions..\r
+-#ifdef _WIN32\r
+-  #define       JUCE_WIN32 1\r
+-  #define       JUCE_WINDOWS 1\r
+-#else\r
+-  #ifdef LINUX\r
+-    #define     JUCE_LINUX 1\r
+-  #else\r
+-    #define     JUCE_MAC 1\r
+-  #endif\r
+-#endif\r
+-\r
+-//==============================================================================\r
+-#ifdef JUCE_WINDOWS\r
+-  #ifdef _MSC_VER\r
+-    #ifdef _WIN64\r
+-      #define JUCE_64BIT 1\r
+-    #else\r
+-      #define JUCE_32BIT 1\r
+-    #endif\r
+-  #endif\r
+-\r
+-  #ifdef _DEBUG\r
+-    #define JUCE_DEBUG 1\r
+-  #endif\r
+-\r
+-  /** If defined, this indicates that the processor is little-endian. */\r
+-  #define JUCE_LITTLE_ENDIAN 1\r
+-\r
+-  #define JUCE_INTEL 1\r
+-#endif\r
+-\r
+-//==============================================================================\r
+-#ifdef JUCE_MAC\r
+-\r
+-  #include <CoreServices/CoreServices.h>\r
+-  #include <wchar.h>\r
+-\r
+-  #ifndef NDEBUG\r
+-    #define JUCE_DEBUG 1\r
+-  #endif\r
+-\r
+-  #ifdef __LITTLE_ENDIAN__\r
+-    #define JUCE_LITTLE_ENDIAN 1\r
+-  #else\r
+-    #define JUCE_BIG_ENDIAN 1\r
+-  #endif\r
+-\r
+-  #if defined (__ppc__) || defined (__ppc64__)\r
+-    #define JUCE_PPC 1\r
+-  #else\r
+-    #define JUCE_INTEL 1\r
+-  #endif\r
+-\r
+-  #ifdef __LP64__\r
+-    #define JUCE_64BIT 1\r
+-  #else\r
+-    #define JUCE_32BIT 1\r
+-  #endif\r
+-#endif\r
+-\r
+-//==============================================================================\r
+-#ifdef JUCE_LINUX\r
+-\r
+-  #ifdef _DEBUG\r
+-    #define JUCE_DEBUG 1\r
+-  #endif\r
+-\r
+-  #include <wchar.h>\r
+-\r
+-  // Allow override for big-endian Linux platforms\r
+-  #ifndef JUCE_BIG_ENDIAN\r
+-    #define JUCE_LITTLE_ENDIAN 1\r
+-  #endif\r
+-\r
+-  #if defined (__LP64__) || defined (_LP64)\r
+-    #define JUCE_64BIT 1\r
+-  #else\r
+-    #define JUCE_32BIT 1\r
+-  #endif\r
+-\r
+-  #define JUCE_INTEL 1\r
+-#endif\r
+-\r
+-//==============================================================================\r
+-#if defined (__GNUC__) || defined (__MWERKS__)\r
+-    /** A platform-independent 64-bit integer type. */\r
+-    typedef long long           int64;\r
+-    /** A platform-independent 64-bit unsigned integer type. */\r
+-    typedef unsigned long long  uint64;\r
+-    /** A platform-independent unicode character type. */\r
+-    typedef wchar_t             juce_wchar;\r
+-\r
+-    /** A platform-independent way of forcing an inline function.\r
+-\r
+-      Use the syntax: @code\r
+-        forcedinline void myfunction (int x)\r
+-      @endcode\r
+-    */\r
+-    #ifndef JUCE_DEBUG\r
+-      #define forcedinline  inline __attribute__((always_inline))\r
+-    #else\r
+-      #define forcedinline  inline\r
+-    #endif\r
+-\r
+-    /** A platform-independent way of stopping the compiler inlining a function.\r
+-\r
+-      Use the syntax: @code\r
+-        juce_noinline void myfunction (int x)\r
+-      @endcode\r
+-    */\r
+-    #define juce_noinline __attribute__((noinline))\r
+-\r
+-#else\r
+-    //==============================================================================\r
+-    /** A platform-independent 64-bit integer type. */\r
+-    typedef __int64             int64;\r
+-    /** A platform-independent 64-bit unsigned integer type. */\r
+-    typedef unsigned __int64    uint64;\r
+-\r
+-    /** A platform-independent unicode character type. */\r
+-    typedef wchar_t             juce_wchar;\r
+-\r
+-    /** A platform-independent way of forcing an inline function.\r
+-\r
+-      Use the syntax: @code\r
+-        forcedinline void myfunction (int x)\r
+-      @endcode\r
+-    */\r
+-    #ifdef _MSC_VER\r
+-      #define forcedinline  __forceinline\r
+-    #else\r
+-      #define forcedinline  inline\r
+-    #endif\r
+-\r
+-    /** A platform-independent way of stopping the compiler inlining a function.\r
+-\r
+-      Use the syntax: @code\r
+-        juce_noinline void myfunction (int x)\r
+-      @endcode\r
+-    */\r
+-    #define juce_noinline\r
+-\r
+-#endif\r
+-\r
+-#if JUCE_64BIT\r
+-   typedef int64                   pointer_sized_int;\r
+-   typedef uint64                  pointer_sized_uint;\r
+-#else\r
+-  #if _MSC_VER >= 1300\r
+-     typedef _W64 int              pointer_sized_int;\r
+-     typedef _W64 unsigned int     pointer_sized_uint;\r
+-  #else\r
+-     typedef int                   pointer_sized_int;\r
+-     typedef unsigned int          pointer_sized_uint;\r
+-  #endif\r
+-#endif\r
+-\r
+-\r
+-// borland can't handle inline functions containing asm code, so define a\r
+-// special type of inline modifier for this kind of function. Sigh..\r
+-#ifdef __BORLANDC__\r
+-  #define inline_assembly\r
+-#else\r
+-  #define inline_assembly forcedinline\r
+-#endif\r
+-\r
+-//==============================================================================\r
+-typedef signed char     int8;\r
+-typedef unsigned char   uint8;\r
+-typedef signed short    int16;\r
+-typedef unsigned short  uint16;\r
+-typedef signed int      int32;\r
+-typedef unsigned int    uint32;\r
+-\r
+-\r
+-//==============================================================================\r
+-// Debugging macros\r
+-//\r
+-\r
+-#ifdef JUCE_DEBUG\r
+-  //==============================================================================\r
+-  // If debugging is enabled..\r
+-\r
+-  /** Writes a string to the standard error stream.\r
+-\r
+-    This is only compiled in a debug build.\r
+-\r
+-    @see Logger::outputDebugString\r
+-  */\r
+-  #define DBG(dbgtext)              Logger::outputDebugString (dbgtext);\r
+-\r
+-  /** Printf's a string to the standard error stream.\r
+-\r
+-    This is only compiled in a debug build.\r
+-\r
+-    @see Logger::outputDebugString\r
+-  */\r
+-  #define DBG_PRINTF(dbgprintf)     Logger::outputDebugPrintf dbgprintf;\r
+-\r
+-  // Assertions..\r
+-  #if defined (_MSC_VER) || DOXYGEN\r
+-    /** This will always cause an assertion failure.\r
+-\r
+-        This is only compiled in a debug build.\r
+-\r
+-        @see jassert()\r
+-    */\r
+-    #ifdef __BORLANDC__\r
+-      extern void juce_StopInDebugger();\r
+-      #define jassertfalse          { juce_StopInDebugger(); }\r
+-    #else\r
+-      #define jassertfalse          { __asm int 3 }\r
+-    #endif\r
+-  #elif defined (JUCE_MAC)\r
+-    #define jassertfalse            { Debugger(); }\r
+-  #elif defined (__GNUC__) || defined (JUCE_LINUX)\r
+-    #define jassertfalse            { asm("int $3"); }\r
+-  #endif\r
+-\r
+-  //==============================================================================\r
+-  /** Platform-independent assertion macro.\r
+-\r
+-    This gets optimised out when not being built with debugging turned on.\r
+-\r
+-    Be careful not to call any functions within its arguments that are vital to\r
+-    the behaviour of the program, because these won't get called in the release\r
+-    build.\r
+-\r
+-    @see jassertfalse\r
+-  */\r
+-  #define jassert(a)                { if (! (a)) jassertfalse }\r
+-\r
+-#else\r
+-  //==============================================================================\r
+-  // If debugging is disabled, disable all the assertions and debugging stuff..\r
+-\r
+-  #define DBG(dbgtext)\r
+-  #define DBG_PRINTF(dbgprintf)\r
+-\r
+-  #define jassert(a)        {}\r
+-  #define jassertfalse      {}\r
+-\r
+-#endif\r
+-\r
+-//==============================================================================\r
+-#ifndef DOXYGEN\r
+- template <bool b> struct JuceStaticAssert;\r
+- template <> struct JuceStaticAssert <true> { static void dummy() {} };\r
+-#endif\r
+-\r
+-/** A compile-time assertion macro.\r
+-\r
+-    If the expression parameter is false, the macro will cause a compile error.\r
+-*/\r
+-#define static_jassert(expression)      JuceStaticAssert<expression>::dummy();\r
+-\r
+-\r
+-//==============================================================================\r
+-#if JUCE_CATCH_UNHANDLED_EXCEPTIONS\r
+-\r
+-  #define JUCE_TRY try\r
+-\r
+-  /** Used in try-catch blocks, this macro will send exceptions to the JUCEApplication\r
+-      object so they can be logged by the application if it wants to.\r
+-  */\r
+-  #define JUCE_CATCH_EXCEPTION \\r
+-    catch (const std::exception& e)  \\r
+-    { \\r
+-        JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); \\r
+-    } \\r
+-    catch (...) \\r
+-    { \\r
+-        JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__); \\r
+-    }\r
+-\r
+-  #define JUCE_CATCH_ALL            catch (...) {}\r
+-  #define JUCE_CATCH_ALL_ASSERT     catch (...) { jassertfalse }\r
+-\r
+-#else\r
+-\r
+-  #define JUCE_TRY\r
+-  #define JUCE_CATCH_EXCEPTION\r
+-  #define JUCE_CATCH_ALL\r
+-  #define JUCE_CATCH_ALL_ASSERT\r
+-\r
+-#endif\r
+-\r
+-\r
+-#endif   // __JUCE_PLATFORMDEFS_JUCEHEADER__\r
++/*
++  ==============================================================================
++
++   This file is part of the JUCE library - "Jules' Utility Class Extensions"
++   Copyright 2004-6 by Raw Material Software ltd.
++
++  ------------------------------------------------------------------------------
++
++   JUCE can be redistributed and/or modified under the terms of the
++   GNU General Public License, as published by the Free Software Foundation;
++   either version 2 of the License, or (at your option) any later version.
++
++   JUCE is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with JUCE; if not, visit www.gnu.org/licenses or write to the
++   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
++   Boston, MA 02111-1307 USA
++
++  ------------------------------------------------------------------------------
++
++   If you'd like to release a closed-source product which uses JUCE, commercial
++   licenses are also available: visit www.rawmaterialsoftware.com/juce for
++   more information.
++
++  ==============================================================================
++*/
++
++#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__
++#define __JUCE_PLATFORMDEFS_JUCEHEADER__
++
++
++//==============================================================================
++// set up platform definitions..
++#ifdef _WIN32
++  #define       JUCE_WIN32 1
++  #define       JUCE_WINDOWS 1
++#else
++  #ifdef LINUX
++    #define     JUCE_LINUX 1
++  #else
++    #define     JUCE_MAC 1
++  #endif
++#endif
++
++//==============================================================================
++#ifdef JUCE_WINDOWS
++  #ifdef _MSC_VER
++    #ifdef _WIN64
++      #define JUCE_64BIT 1
++    #else
++      #define JUCE_32BIT 1
++    #endif
++  #endif
++
++  #ifdef _DEBUG
++    #define JUCE_DEBUG 1
++  #endif
++
++  /** If defined, this indicates that the processor is little-endian. */
++  #define JUCE_LITTLE_ENDIAN 1
++
++  #define JUCE_INTEL 1
++#endif
++
++//==============================================================================
++#ifdef JUCE_MAC
++
++  #include <CoreServices/CoreServices.h>
++  #include <wchar.h>
++
++  #ifndef NDEBUG
++    #define JUCE_DEBUG 1
++  #endif
++
++  #ifdef __LITTLE_ENDIAN__
++    #define JUCE_LITTLE_ENDIAN 1
++  #else
++    #define JUCE_BIG_ENDIAN 1
++  #endif
++
++  #if defined (__ppc__) || defined (__ppc64__)
++    #define JUCE_PPC 1
++  #else
++    #define JUCE_INTEL 1
++  #endif
++
++  #ifdef __LP64__
++    #define JUCE_64BIT 1
++  #else
++    #define JUCE_32BIT 1
++  #endif
++#endif
++
++//==============================================================================
++#ifdef JUCE_LINUX
++
++  #ifdef _DEBUG
++    #define JUCE_DEBUG 1
++  #endif
++
++  #include <wchar.h>
++
++  // Allow override for big-endian Linux platforms
++  #ifndef JUCE_BIG_ENDIAN
++    #define JUCE_LITTLE_ENDIAN 1
++  #endif
++
++  #if defined (__LP64__) || defined (_LP64)
++    #define JUCE_64BIT 1
++  #else
++    #define JUCE_32BIT 1
++  #endif
++
++  #define JUCE_INTEL 1
++#endif
++
++//==============================================================================
++#if defined (__GNUC__) || defined (__MWERKS__)
++    /** A platform-independent 64-bit integer type. */
++    typedef long long           int64;
++    /** A platform-independent 64-bit unsigned integer type. */
++    typedef unsigned long long  uint64;
++    /** A platform-independent unicode character type. */
++    typedef wchar_t             juce_wchar;
++
++    /** A platform-independent way of forcing an inline function.
++
++      Use the syntax: @code
++        forcedinline void myfunction (int x)
++      @endcode
++    */
++    #ifndef JUCE_DEBUG
++      #define forcedinline  inline __attribute__((always_inline))
++    #else
++      #define forcedinline  inline
++    #endif
++
++    /** A platform-independent way of stopping the compiler inlining a function.
++
++      Use the syntax: @code
++        juce_noinline void myfunction (int x)
++      @endcode
++    */
++    #define juce_noinline __attribute__((noinline))
++
++#else
++    //==============================================================================
++    /** A platform-independent 64-bit integer type. */
++    typedef __int64             int64;
++    /** A platform-independent 64-bit unsigned integer type. */
++    typedef unsigned __int64    uint64;
++
++    /** A platform-independent unicode character type. */
++    typedef wchar_t             juce_wchar;
++
++    /** A platform-independent way of forcing an inline function.
++
++      Use the syntax: @code
++        forcedinline void myfunction (int x)
++      @endcode
++    */
++    #ifdef _MSC_VER
++      #define forcedinline  __forceinline
++    #else
++      #define forcedinline  inline
++    #endif
++
++    /** A platform-independent way of stopping the compiler inlining a function.
++
++      Use the syntax: @code
++        juce_noinline void myfunction (int x)
++      @endcode
++    */
++    #define juce_noinline
++
++#endif
++
++#if JUCE_64BIT
++   typedef int64                   pointer_sized_int;
++   typedef uint64                  pointer_sized_uint;
++#else
++  #if _MSC_VER >= 1300
++     typedef _W64 int              pointer_sized_int;
++     typedef _W64 unsigned int     pointer_sized_uint;
++  #else
++     typedef int                   pointer_sized_int;
++     typedef unsigned int          pointer_sized_uint;
++  #endif
++#endif
++
++
++// borland can't handle inline functions containing asm code, so define a
++// special type of inline modifier for this kind of function. Sigh..
++#ifdef __BORLANDC__
++  #define inline_assembly
++#else
++  #define inline_assembly forcedinline
++#endif
++
++//==============================================================================
++typedef signed char     int8;
++typedef unsigned char   uint8;
++typedef signed short    int16;
++typedef unsigned short  uint16;
++typedef signed int      int32;
++typedef unsigned int    uint32;
++
++
++//==============================================================================
++// Debugging macros
++//
++
++#ifdef JUCE_DEBUG
++  //==============================================================================
++  // If debugging is enabled..
++
++  /** Writes a string to the standard error stream.
++
++    This is only compiled in a debug build.
++
++    @see Logger::outputDebugString
++  */
++  #define DBG(dbgtext)              Logger::outputDebugString (dbgtext);
++
++  /** Printf's a string to the standard error stream.
++
++    This is only compiled in a debug build.
++
++    @see Logger::outputDebugString
++  */
++  #define DBG_PRINTF(dbgprintf)     Logger::outputDebugPrintf dbgprintf;
++
++  // Assertions..
++  #if defined (_MSC_VER) || DOXYGEN
++    /** This will always cause an assertion failure.
++
++        This is only compiled in a debug build.
++
++        @see jassert()
++    */
++    #ifdef __BORLANDC__
++      extern void juce_StopInDebugger();
++      #define jassertfalse          { juce_StopInDebugger(); }
++    #else
++      #define jassertfalse          { __asm int 3 }
++    #endif
++  #elif defined (JUCE_MAC)
++    #define jassertfalse            { Debugger(); }
++  #elif defined (__GNUC__) || defined (JUCE_LINUX)
++    #ifndef __x86__
++      #define jassertfalse          { 1/0; }
++    #else
++      #define jassertfalse            { asm("int $3"); }
++    #endif
++  #endif
++
++  //==============================================================================
++  /** Platform-independent assertion macro.
++
++    This gets optimised out when not being built with debugging turned on.
++
++    Be careful not to call any functions within its arguments that are vital to
++    the behaviour of the program, because these won't get called in the release
++    build.
++
++    @see jassertfalse
++  */
++  #define jassert(a)                { if (! (a)) jassertfalse }
++
++#else
++  //==============================================================================
++  // If debugging is disabled, disable all the assertions and debugging stuff..
++
++  #define DBG(dbgtext)
++  #define DBG_PRINTF(dbgprintf)
++
++  #define jassert(a)        {}
++  #define jassertfalse      {}
++
++#endif
++
++//==============================================================================
++#ifndef DOXYGEN
++ template <bool b> struct JuceStaticAssert;
++ template <> struct JuceStaticAssert <true> { static void dummy() {} };
++#endif
++
++/** A compile-time assertion macro.
++
++    If the expression parameter is false, the macro will cause a compile error.
++*/
++#define static_jassert(expression)      JuceStaticAssert<expression>::dummy();
++
++
++//==============================================================================
++#if JUCE_CATCH_UNHANDLED_EXCEPTIONS
++
++  #define JUCE_TRY try
++
++  /** Used in try-catch blocks, this macro will send exceptions to the JUCEApplication
++      object so they can be logged by the application if it wants to.
++  */
++  #define JUCE_CATCH_EXCEPTION \
++    catch (const std::exception& e)  \
++    { \
++        JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); \
++    } \
++    catch (...) \
++    { \
++        JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__); \
++    }
++
++  #define JUCE_CATCH_ALL            catch (...) {}
++  #define JUCE_CATCH_ALL_ASSERT     catch (...) { jassertfalse }
++
++#else
++
++  #define JUCE_TRY
++  #define JUCE_CATCH_EXCEPTION
++  #define JUCE_CATCH_ALL
++  #define JUCE_CATCH_ALL_ASSERT
++
++#endif
++
++
++#endif   // __JUCE_PLATFORMDEFS_JUCEHEADER__
+--- juce/src/juce_core/basics/juce_DataConversions.h~remove-x86isms.patch
++++ juce/src/juce_core/basics/juce_DataConversions.h
+@@ -1,172 +1,176 @@
+-/*\r
+-  ==============================================================================\r
+-\r
+-   This file is part of the JUCE library - "Jules' Utility Class Extensions"\r
+-   Copyright 2004-6 by Raw Material Software ltd.\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   JUCE can be redistributed and/or modified under the terms of the\r
+-   GNU General Public License, as published by the Free Software Foundation;\r
+-   either version 2 of the License, or (at your option) any later version.\r
+-\r
+-   JUCE is distributed in the hope that it will be useful,\r
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+-   GNU General Public License for more details.\r
+-\r
+-   You should have received a copy of the GNU General Public License\r
+-   along with JUCE; if not, visit www.gnu.org/licenses or write to the\r
+-   Free Software Foundation, Inc., 59 Temple Place, Suite 330, \r
+-   Boston, MA 02111-1307 USA\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   If you'd like to release a closed-source product which uses JUCE, commercial\r
+-   licenses are also available: visit www.rawmaterialsoftware.com/juce for\r
+-   more information.\r
+-\r
+-  ==============================================================================\r
+-*/\r
+-\r
+-#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__\r
+-#define __JUCE_DATACONVERSIONS_JUCEHEADER__\r
+-\r
+-#include "juce_PlatformDefs.h"\r
+-\r
+-//==============================================================================\r
+-// Endianness conversions..\r
+-\r
+-/** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */\r
+-inline_assembly uint32 swapByteOrder (uint32 n) throw()\r
+-{\r
+-#ifdef JUCE_MAC\r
+-    return CFSwapInt32 (n);\r
+-#else\r
+-  #ifdef __GNUC__\r
+-    // Inpenetrable GCC version..\r
+-    asm("bswap %%eax" : "=a"(n) : "a"(n));\r
+-    return n;\r
+-  #else\r
+-    // Win32 version..\r
+-    __asm {\r
+-        mov eax, n\r
+-        bswap eax\r
+-        mov n, eax\r
+-    }\r
+-    return n;\r
+-  #endif\r
+-#endif\r
+-}\r
+-\r
+-/** Swaps the byte-order of a 16-bit short. */\r
+-inline uint16 swapByteOrder (const uint16 n) throw()\r
+-{\r
+-    return (uint16) ((n << 8) | (n >> 8));\r
+-}\r
+-\r
+-inline uint64 swapByteOrder (const uint64 value) throw()\r
+-{\r
+-#ifdef JUCE_MAC\r
+-    return CFSwapInt64 (value);\r
+-#else\r
+-    return (((int64) swapByteOrder ((uint32) value)) << 32)\r
+-            | swapByteOrder ((uint32) (value >> 32));\r
+-#endif\r
+-}\r
+-\r
+-#ifdef JUCE_LITTLE_ENDIAN\r
+-  /** Swaps the byte order of a 16-bit int if the CPU is big-endian */\r
+-  inline uint16     swapIfBigEndian (const uint16 v) throw()             { return v; }\r
+-  /** Swaps the byte order of a 32-bit int if the CPU is big-endian */\r
+-  inline uint32     swapIfBigEndian (const uint32 v) throw()             { return v; }\r
+-  /** Swaps the byte order of a 16-bit int if the CPU is little-endian */\r
+-  inline uint16     swapIfLittleEndian (const uint16 v) throw()          { return swapByteOrder (v); }\r
+-  /** Swaps the byte order of a 32-bit int if the CPU is little-endian */\r
+-  inline uint32     swapIfLittleEndian (const uint32 v) throw()          { return swapByteOrder (v); }\r
+-\r
+-  /** Turns 4 bytes into a little-endian integer. */\r
+-  inline uint32     littleEndianInt (const char* const bytes) throw()    { return *(uint32*) bytes; }\r
+-\r
+-  /** Turns 2 bytes into a little-endian integer. */\r
+-  inline uint16     littleEndianShort (const char* const bytes) throw()  { return *(uint16*) bytes; }\r
+-\r
+-  /** Turns 4 bytes into a big-endian integer. */\r
+-  inline uint32     bigEndianInt (const char* const bytes) throw()       { return swapByteOrder (*(uint32*) bytes); }\r
+-\r
+-  /** Turns 2 bytes into a big-endian integer. */\r
+-  inline uint16     bigEndianShort (const char* const bytes) throw()     { return swapByteOrder (*(uint16*) bytes); }\r
+-\r
+-#else\r
+-  /** Swaps the byte order of a 16-bit int if the CPU is big-endian */\r
+-  inline uint16     swapIfBigEndian (const uint16 v) throw()             { return swapByteOrder (v); }\r
+-  /** Swaps the byte order of a 32-bit int if the CPU is big-endian */\r
+-  inline uint32     swapIfBigEndian (const uint32 v) throw()             { return swapByteOrder (v); }\r
+-  /** Swaps the byte order of a 16-bit int if the CPU is little-endian */\r
+-  inline uint16     swapIfLittleEndian (const uint16 v) throw()          { return v; }\r
+-  /** Swaps the byte order of a 32-bit int if the CPU is little-endian */\r
+-  inline uint32     swapIfLittleEndian (const uint32 v) throw()          { return v; }\r
+-\r
+-  /** Turns 4 bytes into a little-endian integer. */\r
+-  inline uint32     littleEndianInt (const char* const bytes) throw()    { return swapByteOrder (*(uint32*) bytes); }\r
+-\r
+-  /** Turns 2 bytes into a little-endian integer. */\r
+-  inline uint16     littleEndianShort (const char* const bytes) throw()  { return swapByteOrder (*(uint16*) bytes); }\r
+-\r
+-  /** Turns 4 bytes into a big-endian integer. */\r
+-  inline uint32     bigEndianInt (const char* const bytes) throw()       { return *(uint32*) bytes; }\r
+-\r
+-  /** Turns 2 bytes into a big-endian integer. */\r
+-  inline uint16     bigEndianShort (const char* const bytes) throw()     { return *(uint16*) bytes; }\r
+-#endif\r
+-\r
+-/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */\r
+-inline int littleEndian24Bit (const char* const bytes) throw()                          { return (((int) bytes[2]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[0]); }\r
+-/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */\r
+-inline int bigEndian24Bit (const char* const bytes) throw()                             { return (((int) bytes[0]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[2]); }\r
+-\r
+-/** Copies a 24-bit number to 3 little-endian bytes. */\r
+-inline void littleEndian24BitToChars (const int value, char* const destBytes) throw()   { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); }\r
+-/** Copies a 24-bit number to 3 big-endian bytes. */\r
+-inline void bigEndian24BitToChars (const int value, char* const destBytes) throw()      { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); }\r
+-\r
+-\r
+-//==============================================================================\r
+-/** Fast floating-point-to-integer conversion.\r
+-\r
+-    This is faster than using the normal c++ cast to convert a double to an int, and\r
+-    it will round the value to the nearest integer, rather than rounding it down\r
+-    like the normal cast does.\r
+-*/\r
+-inline int roundDoubleToInt (const double value) throw()\r
+-{\r
+-    union { int asInt[2]; double asDouble; } n;\r
+-    n.asDouble = value + 6755399441055744.0;\r
+-\r
+-#if JUCE_BIG_ENDIAN\r
+-    return n.asInt [1];\r
+-#else\r
+-    return n.asInt [0];\r
+-#endif\r
+-}\r
+-\r
+-/** Fast floating-point-to-integer conversion.\r
+-\r
+-    This is faster than using the normal c++ cast to convert a float to an int, and\r
+-    it will round the value to the nearest integer, rather than rounding it down\r
+-    like the normal cast does.\r
+-*/\r
+-inline int roundFloatToInt (const float value) throw()\r
+-{\r
+-    union { int asInt[2]; double asDouble; } n;\r
+-    n.asDouble = value + 6755399441055744.0;\r
+-\r
+-#if JUCE_BIG_ENDIAN\r
+-    return n.asInt [1];\r
+-#else\r
+-    return n.asInt [0];\r
+-#endif\r
+-}\r
+-\r
+-\r
+-#endif   // __JUCE_DATACONVERSIONS_JUCEHEADER__\r
++/*
++  ==============================================================================
++
++   This file is part of the JUCE library - "Jules' Utility Class Extensions"
++   Copyright 2004-6 by Raw Material Software ltd.
++
++  ------------------------------------------------------------------------------
++
++   JUCE can be redistributed and/or modified under the terms of the
++   GNU General Public License, as published by the Free Software Foundation;
++   either version 2 of the License, or (at your option) any later version.
++
++   JUCE is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with JUCE; if not, visit www.gnu.org/licenses or write to the
++   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
++   Boston, MA 02111-1307 USA
++
++  ------------------------------------------------------------------------------
++
++   If you'd like to release a closed-source product which uses JUCE, commercial
++   licenses are also available: visit www.rawmaterialsoftware.com/juce for
++   more information.
++
++  ==============================================================================
++*/
++
++#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__
++#define __JUCE_DATACONVERSIONS_JUCEHEADER__
++
++#include "juce_PlatformDefs.h"
++
++//==============================================================================
++// Endianness conversions..
++
++/** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */
++inline_assembly uint32 swapByteOrder (uint32 n) throw()
++{
++#ifdef JUCE_MAC
++    return CFSwapInt32 (n);
++#else
++  #ifdef __GNUC__
++    #ifndef __x86__
++    return ( ((n)&0xff)<<24) | (((n)&0xff00)<<8) | (((n)>>8)&0xff00) | (((n)>>24)&0xff);
++    #else
++      // Inpenetrable GCC version..
++      asm("bswap %%eax" : "=a"(n) : "a"(n));
++      return n;
++    #endif
++  #else
++    // Win32 version..
++    __asm {
++        mov eax, n
++        bswap eax
++        mov n, eax
++    }
++    return n;
++  #endif
++#endif
++}
++
++/** Swaps the byte-order of a 16-bit short. */
++inline uint16 swapByteOrder (const uint16 n) throw()
++{
++    return (uint16) ((n << 8) | (n >> 8));
++}
++
++inline uint64 swapByteOrder (const uint64 value) throw()
++{
++#ifdef JUCE_MAC
++    return CFSwapInt64 (value);
++#else
++    return (((int64) swapByteOrder ((uint32) value)) << 32)
++            | swapByteOrder ((uint32) (value >> 32));
++#endif
++}
++
++#ifdef JUCE_LITTLE_ENDIAN
++  /** Swaps the byte order of a 16-bit int if the CPU is big-endian */
++  inline uint16     swapIfBigEndian (const uint16 v) throw()             { return v; }
++  /** Swaps the byte order of a 32-bit int if the CPU is big-endian */
++  inline uint32     swapIfBigEndian (const uint32 v) throw()             { return v; }
++  /** Swaps the byte order of a 16-bit int if the CPU is little-endian */
++  inline uint16     swapIfLittleEndian (const uint16 v) throw()          { return swapByteOrder (v); }
++  /** Swaps the byte order of a 32-bit int if the CPU is little-endian */
++  inline uint32     swapIfLittleEndian (const uint32 v) throw()          { return swapByteOrder (v); }
++
++  /** Turns 4 bytes into a little-endian integer. */
++  inline uint32     littleEndianInt (const char* const bytes) throw()    { return *(uint32*) bytes; }
++
++  /** Turns 2 bytes into a little-endian integer. */
++  inline uint16     littleEndianShort (const char* const bytes) throw()  { return *(uint16*) bytes; }
++
++  /** Turns 4 bytes into a big-endian integer. */
++  inline uint32     bigEndianInt (const char* const bytes) throw()       { return swapByteOrder (*(uint32*) bytes); }
++
++  /** Turns 2 bytes into a big-endian integer. */
++  inline uint16     bigEndianShort (const char* const bytes) throw()     { return swapByteOrder (*(uint16*) bytes); }
++
++#else
++  /** Swaps the byte order of a 16-bit int if the CPU is big-endian */
++  inline uint16     swapIfBigEndian (const uint16 v) throw()             { return swapByteOrder (v); }
++  /** Swaps the byte order of a 32-bit int if the CPU is big-endian */
++  inline uint32     swapIfBigEndian (const uint32 v) throw()             { return swapByteOrder (v); }
++  /** Swaps the byte order of a 16-bit int if the CPU is little-endian */
++  inline uint16     swapIfLittleEndian (const uint16 v) throw()          { return v; }
++  /** Swaps the byte order of a 32-bit int if the CPU is little-endian */
++  inline uint32     swapIfLittleEndian (const uint32 v) throw()          { return v; }
++
++  /** Turns 4 bytes into a little-endian integer. */
++  inline uint32     littleEndianInt (const char* const bytes) throw()    { return swapByteOrder (*(uint32*) bytes); }
++
++  /** Turns 2 bytes into a little-endian integer. */
++  inline uint16     littleEndianShort (const char* const bytes) throw()  { return swapByteOrder (*(uint16*) bytes); }
++
++  /** Turns 4 bytes into a big-endian integer. */
++  inline uint32     bigEndianInt (const char* const bytes) throw()       { return *(uint32*) bytes; }
++
++  /** Turns 2 bytes into a big-endian integer. */
++  inline uint16     bigEndianShort (const char* const bytes) throw()     { return *(uint16*) bytes; }
++#endif
++
++/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
++inline int littleEndian24Bit (const char* const bytes) throw()                          { return (((int) bytes[2]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[0]); }
++/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
++inline int bigEndian24Bit (const char* const bytes) throw()                             { return (((int) bytes[0]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[2]); }
++
++/** Copies a 24-bit number to 3 little-endian bytes. */
++inline void littleEndian24BitToChars (const int value, char* const destBytes) throw()   { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); }
++/** Copies a 24-bit number to 3 big-endian bytes. */
++inline void bigEndian24BitToChars (const int value, char* const destBytes) throw()      { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); }
++
++
++//==============================================================================
++/** Fast floating-point-to-integer conversion.
++
++    This is faster than using the normal c++ cast to convert a double to an int, and
++    it will round the value to the nearest integer, rather than rounding it down
++    like the normal cast does.
++*/
++inline int roundDoubleToInt (const double value) throw()
++{
++    union { int asInt[2]; double asDouble; } n;
++    n.asDouble = value + 6755399441055744.0;
++
++#if JUCE_BIG_ENDIAN
++    return n.asInt [1];
++#else
++    return n.asInt [0];
++#endif
++}
++
++/** Fast floating-point-to-integer conversion.
++
++    This is faster than using the normal c++ cast to convert a float to an int, and
++    it will round the value to the nearest integer, rather than rounding it down
++    like the normal cast does.
++*/
++inline int roundFloatToInt (const float value) throw()
++{
++    union { int asInt[2]; double asDouble; } n;
++    n.asDouble = value + 6755399441055744.0;
++
++#if JUCE_BIG_ENDIAN
++    return n.asInt [1];
++#else
++    return n.asInt [0];
++#endif
++}
++
++
++#endif   // __JUCE_DATACONVERSIONS_JUCEHEADER__
+--- juce/build/linux/platform_specific_code/juce_linux_SystemStats.cpp~remove-x86isms.patch
++++ juce/build/linux/platform_specific_code/juce_linux_SystemStats.cpp
+@@ -1,472 +1,472 @@
+-/*\r
+-  ==============================================================================\r
+-\r
+-   This file is part of the JUCE library - "Jules' Utility Class Extensions"\r
+-   Copyright 2004-6 by Raw Material Software ltd.\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   JUCE can be redistributed and/or modified under the terms of the\r
+-   GNU General Public License, as published by the Free Software Foundation;\r
+-   either version 2 of the License, or (at your option) any later version.\r
+-\r
+-   JUCE is distributed in the hope that it will be useful,\r
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+-   GNU General Public License for more details.\r
+-\r
+-   You should have received a copy of the GNU General Public License\r
+-   along with JUCE; if not, visit www.gnu.org/licenses or write to the\r
+-   Free Software Foundation, Inc., 59 Temple Place, Suite 330, \r
+-   Boston, MA 02111-1307 USA\r
+-\r
+-  ------------------------------------------------------------------------------\r
+-\r
+-   If you'd like to release a closed-source product which uses JUCE, commercial\r
+-   licenses are also available: visit www.rawmaterialsoftware.com/juce for\r
+-   more information.\r
+-\r
+-  ==============================================================================\r
+-*/\r
+-\r
+-#include "linuxincludes.h"\r
+-#include "../../../src/juce_core/basics/juce_StandardHeader.h"\r
+-\r
+-#ifdef __CYGWIN__\r
+-  #include <apr_uuid.h>\r
+-  #include <malloc.h>\r
+-#else\r
+-  #include <sys/sysinfo.h>\r
+-  #include <dlfcn.h>\r
+-#endif\r
+-\r
+-#ifdef JUCE_UUID\r
+-  #include <uuid/uuid.h>\r
+-#endif\r
+-\r
+-#ifndef CPU_ISSET\r
+-  #undef SUPPORT_AFFINITIES\r
+-#endif\r
+-\r
+-BEGIN_JUCE_NAMESPACE\r
+-\r
+-#include "../../../src/juce_core/io/files/juce_File.h"\r
+-#include "../../../src/juce_core/basics/juce_SystemStats.h"\r
+-#include "../../../src/juce_core/basics/juce_Logger.h"\r
+-#include "../../../src/juce_core/misc/juce_Uuid.h"\r
+-#include "../../../src/juce_core/threads/juce_Process.h"\r
+-#include "../../../src/juce_appframework/events/juce_Timer.h"\r
+-#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"\r
+-\r
+-static struct _LogicalCpuInfo\r
+-{\r
+-    bool htSupported;\r
+-    bool htAvailable;\r
+-    int numPackages;\r
+-    int numLogicalPerPackage;\r
+-    uint32 physicalAffinityMask;\r
+-} logicalCpuInfo;\r
+-\r
+-//==============================================================================\r
+-static unsigned int getCPUIDWord (int* familyModel = 0, int* extFeatures = 0) __attribute__ ((noinline));\r
+-\r
+-static unsigned int getCPUIDWord (int* familyModel, int* extFeatures)\r
+-{\r
+-    unsigned int cpu = 0;\r
+-    unsigned int ext = 0;\r
+-    unsigned int family = 0;\r
+-\r
+-    __asm__ __volatile__ (\r
+-"        pushf                            \n"\r
+-#if JUCE_64BIT\r
+-"        pop    %%rax                     \n"\r
+-#else\r
+-"        pop    %%eax                     \n"\r
+-#endif\r
+-"        movl   %%eax, %%ecx              \n"\r
+-"        xorl   $0x200000, %%eax          \n"\r
+-#if JUCE_64BIT\r
+-"        push   %%rax                     \n"\r
+-#else\r
+-"        push   %%eax                     \n"\r
+-#endif\r
+-"        popf                             \n"\r
+-"        pushf                            \n"\r
+-#if JUCE_64BIT\r
+-"        pop    %%rax                     \n"\r
+-#else\r
+-"        pop    %%eax                     \n"\r
+-#endif\r
+-"        andl   $0x200000, %%eax          \n"\r
+-"        andl   $0x200000, %%ecx          \n"\r
+-"        cmpl   %%eax, %%ecx              \n"\r
+-"        movl   $0, %%edx                 \n"\r
+-"        je     noCpuId                   \n"\r
+-"        movl   $1, %%eax                 \n"\r
+-"        cpuid                            \n"\r
+-"noCpuId:                                 \n"\r
+-       : "=a"(family),                                 /* Output in eax */\r
+-         "=d"(cpu),                                    /* Output in ebx */\r
+-         "=b"(ext)                                     /* Output in edx */\r
+-       :                                               /* No inputs */\r
+-       : "cc", "ecx"                                   /* Clobber list */\r
+-    );\r
+-\r
+-    if (familyModel)\r
+-        *familyModel = family;\r
+-    if (extFeatures)\r
+-        *extFeatures = ext;\r
+-\r
+-    return cpu;\r
+-}\r
+-\r
+-void juce_initLogicalCpuInfo()\r
+-{\r
+-    int familyModelWord, extFeaturesWord;\r
+-    int featuresWord = getCPUIDWord (&familyModelWord, &extFeaturesWord);\r
+-\r
+-    logicalCpuInfo.htSupported = false;\r
+-    logicalCpuInfo.htAvailable = false;\r
+-    logicalCpuInfo.numLogicalPerPackage = 1;\r
+-    logicalCpuInfo.numPackages = 0;\r
+-    logicalCpuInfo.physicalAffinityMask = 0;\r
+-\r
+-#if SUPPORT_AFFINITIES\r
+-    cpu_set_t processAffinity;\r
+-\r
+-    /*\r
+-       N.B. If this line causes a compile error, then you've probably not got the latest\r
+-       version of glibc installed.\r
+-\r
+-       If you don't want to update your copy of glibc and don't care about cpu affinities,\r
+-       then you can just disable all this stuff by removing the SUPPORT_AFFINITIES macro\r
+-       from the linuxincludes.h file.\r
+-    */\r
+-    if (sched_getaffinity (getpid(),\r
+-                           sizeof (cpu_set_t),\r
+-                           &processAffinity) != sizeof (cpu_set_t))\r
+-    {\r
+-        return;\r
+-    }\r
+-\r
+-    // Checks: CPUID supported, model >= Pentium 4, Hyperthreading bit set, logical CPUs per package > 1\r
+-    if (featuresWord == 0\r
+-        || ((familyModelWord >> 8) & 0xf) < 15\r
+-        || (featuresWord & (1 << 28)) == 0\r
+-        || ((extFeaturesWord >> 16) & 0xff) < 2)\r
+-    {\r
+-        for (int i = 0; i < 64; ++i)\r
+-            if (CPU_ISSET (i, &processAffinity))\r
+-                logicalCpuInfo.physicalAffinityMask |= (1 << i);\r
+-\r
+-        return;\r
+-    }\r
+-\r
+-    logicalCpuInfo.htSupported = true;\r
+-    logicalCpuInfo.numLogicalPerPackage = (extFeaturesWord >> 16) & 0xff;\r
+-\r
+-    cpu_set_t affinityMask;\r
+-    cpu_set_t physAff;\r
+-    CPU_ZERO (&physAff);\r
+-\r
+-    unsigned char i = 1;\r
+-    unsigned char physIdMask = 0xFF;\r
+-    unsigned char physIdShift = 0;\r
+-\r
+-    //unsigned char apicId, logId, physId;\r
+-\r
+-    while (i < logicalCpuInfo.numLogicalPerPackage)\r
+-    {\r
+-        i *= 2;\r
+-        physIdMask <<= 1;\r
+-        physIdShift++;\r
+-    }\r
+-\r
+-    CPU_SET (0, &affinityMask);\r
+-    logicalCpuInfo.numPackages = 0;\r
+-\r
+-//xxx revisit this at some point..\r
+-/*    while ((affinityMask != 0) && (affinityMask <= processAffinity))\r
+-    {\r
+-        int ret;\r
+-        if (! sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinityMask))\r
+-        {\r
+-            sched_yield(); // schedule onto correct CPU\r
+-\r
+-            featuresWord = getCPUIDWord(&familyModelWord, &extFeaturesWord);\r
+-            apicId = (unsigned char)(extFeaturesWord >> 24);\r
+-            logId = (unsigned char)(apicId & ~physIdMask);\r
+-            physId = (unsigned char)(apicId >> physIdShift);\r
+-\r
+-            if (logId != 0)\r
+-                logicalCpuInfo.htAvailable = true;\r
+-\r
+-            if ((((int)logId) % logicalCpuInfo.numLogicalPerPackage) == 0)\r
+-            {\r
+-                // This is a physical CPU\r
+-                physAff |= affinityMask;\r
+-                logicalCpuInfo.numPackages++;\r
+-            }\r
+-        }\r
+-\r
+-        affinityMask = affinityMask << 1;\r
+-    }\r
+-\r
+-    sched_setaffinity (getpid(), sizeof(unsigned long), &processAffinity);\r
+-*/\r
+-\r
+-    logicalCpuInfo.physicalAffinityMask = 0;\r
+-\r
+-    for (int i = 0; i < 64; ++i)\r
+-        if (CPU_ISSET (i, &physAff))\r
+-            logicalCpuInfo.physicalAffinityMask |= (1 << i);\r
+-\r
+-#endif\r
+-}\r
+-\r
+-//==============================================================================\r
+-void Logger::outputDebugString (const String& text)\r
+-{\r
+-    fprintf (stdout, (const char*) (text + T("\n")));\r
+-}\r
+-\r
+-void Logger::outputDebugPrintf (const tchar* format, ...)\r
+-{\r
+-    String text;\r
+-    va_list args;\r
+-    va_start (args, format);\r
+-    text.vprintf(format, args);\r
+-    outputDebugString(text);\r
+-}\r
+-\r
+-const String SystemStats::getOSType()\r
+-{\r
+-    return SystemStats::Linux;\r
+-}\r
+-\r
+-static const String getCpuInfo (const char* key, bool lastOne = false)\r
+-{\r
+-    String info;\r
+-    char buf [256];\r
+-\r
+-    FILE* f = fopen ("/proc/cpuinfo", "r");\r
+-\r
+-    while (f != 0 && fgets (buf, sizeof(buf), f))\r
+-    {\r
+-        if (strncmp (buf, key, strlen (key)) == 0)\r
+-        {\r
+-            char* p = buf;\r
+-\r
+-            while (*p && *p != '\n')\r
+-                ++p;\r
+-\r
+-            if (*p != 0)\r
+-                *p = 0;\r
+-\r
+-            p = buf;\r
+-\r
+-            while (*p != 0 && *p != ':')\r
+-                ++p;\r
+-\r
+-            if (*p != 0 && *(p + 1) != 0)\r
+-                info = p + 2;\r
+-\r
+-            if (! lastOne)\r
+-                break;\r
+-        }\r
+-    }\r
+-\r
+-    fclose (f);\r
+-    return info;\r
+-}\r
+-\r
+-bool SystemStats::hasMMX()\r
+-{\r
+-    return getCpuInfo ("flags").contains (T("mmx"));\r
+-}\r
+-\r
+-bool SystemStats::hasSSE()\r
+-{\r
+-    return getCpuInfo ("flags").contains (T("sse"));\r
+-}\r
+-\r
+-bool SystemStats::hasSSE2()\r
+-{\r
+-    return getCpuInfo ("flags").contains (T("sse2"));\r
+-}\r
+-\r
+-bool SystemStats::has3DNow()\r
+-{\r
+-    return getCpuInfo ("flags").contains (T("3dnow"));\r
+-}\r
+-\r
+-const String SystemStats::getCpuVendor()\r
+-{\r
+-    return getCpuInfo ("vendor_id");\r
+-}\r
+-\r
+-int SystemStats::getCpuSpeedInMegaherz()\r
+-{\r
+-    const String speed (getCpuInfo ("cpu MHz"));\r
+-\r
+-    return (int) (speed.getFloatValue() + 0.5f);\r
+-}\r
+-\r
+-bool SystemStats::hasHyperThreading()\r
+-{\r
+-    return logicalCpuInfo.htAvailable;\r
+-}\r
+-\r
+-int SystemStats::getMemorySizeInMegabytes()\r
+-{\r
+-#ifndef __CYGWIN__\r
+-    struct sysinfo sysi;\r
+-\r
+-    if (sysinfo (&sysi) == 0)\r
+-        return (sysi.totalram * sysi.mem_unit / (1024 * 1024));\r
+-\r
+-    return 0;\r
+-\r
+-#else\r
+-    jassertfalse\r
+-    return 256;\r
+-#endif\r
+-}\r
+-\r
+-unsigned int juce_millisecondsSinceStartup()\r
+-{\r
+-    static unsigned int calibrate = 0;\r
+-    static bool calibrated = false;\r
+-    timeval t;\r
+-    unsigned int ret = 0;\r
+-\r
+-    if (! gettimeofday (&t, 0))\r
+-    {\r
+-        if (! calibrated)\r
+-        {\r
+-#ifndef __CYGWIN__\r
+-            struct sysinfo sysi;\r
+-\r
+-            if (sysinfo (&sysi) == 0)\r
+-                // Safe to assume system was not brought up earlier than 1970!\r
+-                calibrate = t.tv_sec - sysi.uptime;\r
+-#else\r
+-            // bit of a hack, but things should all still work, as we're not often\r
+-            // really interested in how long the machine's been turned on, and just\r
+-            // use this call for relative times..\r
+-            calibrate = t.tv_sec;\r
+-#endif\r
+-\r
+-            calibrated = true;\r
+-        }\r
+-\r
+-        ret = 1000 * (t.tv_sec - calibrate) + (t.tv_usec / 1000);\r
+-    }\r
+-\r
+-    return ret;\r
+-}\r
+-\r
+-double juce_millisecondsSinceStartupHiRes()\r
+-{\r
+-    return Time::getHighResolutionTicks() * (1.0 / 1000000.0);\r
+-}\r
+-\r
+-int64 Time::getHighResolutionTicks()\r
+-{\r
+-    timeval t;\r
+-    if (gettimeofday(&t,NULL))\r
+-        return 0;\r
+-\r
+-    return ((int64) t.tv_sec * (int64) 1000000) + (int64) t.tv_usec;\r
+-}\r
+-\r
+-int64 Time::getHighResolutionTicksPerSecond()\r
+-{\r
+-    // Microseconds\r
+-    return 1000000;\r
+-}\r
+-\r
+-bool Time::setSystemTimeToThisTime() const\r
+-{\r
+-    timeval t;\r
+-    t.tv_sec = millisSinceEpoch % 1000000;\r
+-    t.tv_usec = millisSinceEpoch - t.tv_sec;\r
+-\r
+-    return settimeofday (&t, NULL) ? false : true;\r
+-}\r
+-\r
+-const String Uuid::generateUuid()\r
+-{\r
+-#ifdef JUCE_UUID\r
+-    uuid_t uuid;\r
+-    char *s = new char[37];\r
+-    String uuidStr;\r
+-\r
+-    uuid_generate (uuid);\r
+-    uuid_unparse (uuid, s);\r
+-\r
+-    uuidStr = s;\r
+-    delete[] s;\r
+-\r
+-    return uuidStr;\r
+-#else\r
+-    jassertfalse\r
+-    return String::empty;\r
+-#endif\r
+-}\r
+-\r
+-int SystemStats::getPageSize()\r
+-{\r
+-    static int systemPageSize = 0;\r
+-\r
+-    if (systemPageSize == 0)\r
+-        systemPageSize = sysconf (_SC_PAGESIZE);\r
+-\r
+-    return systemPageSize;\r
+-}\r
+-\r
+-int SystemStats::getNumPhysicalCpus()\r
+-{\r
+-    if (logicalCpuInfo.numPackages)\r
+-        return logicalCpuInfo.numPackages;\r
+-\r
+-    return getNumLogicalCpus();\r
+-}\r
+-\r
+-int SystemStats::getNumLogicalCpus()\r
+-{\r
+-    const int lastCpu = getCpuInfo ("processor", true).getIntValue();\r
+-\r
+-    return lastCpu + 1;\r
+-}\r
+-\r
+-uint32 SystemStats::getPhysicalAffinityMask()\r
+-{\r
+-#if SUPPORT_AFFINITIES\r
+-    return logicalCpuInfo.physicalAffinityMask;\r
+-#else\r
+-    /* affinities aren't supported because either the appropriate header files weren't found,\r
+-       or the SUPPORT_AFFINITIES macro was turned off in linuxheaders.h\r
+-    */\r
+-    jassertfalse\r
+-    return 0;\r
+-#endif\r
+-\r
+-}\r
+-\r
+-//==============================================================================\r
+-void SystemStats::initialiseStats()\r
+-{\r
+-    // Process starts off as root when running suid\r
+-    Process::lowerPrivilege();\r
+-\r
+-    String s (SystemStats::getJUCEVersion());\r
+-\r
+-    juce_initLogicalCpuInfo();\r
+-}\r
+-\r
+-void PlatformUtilities::fpuReset()\r
+-{\r
+-}\r
+-\r
+-END_JUCE_NAMESPACE\r
++/*
++  ==============================================================================
++
++   This file is part of the JUCE library - "Jules' Utility Class Extensions"
++   Copyright 2004-6 by Raw Material Software ltd.
++
++  ------------------------------------------------------------------------------
++
++   JUCE can be redistributed and/or modified under the terms of the
++   GNU General Public License, as published by the Free Software Foundation;
++   either version 2 of the License, or (at your option) any later version.
++
++   JUCE is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with JUCE; if not, visit www.gnu.org/licenses or write to the
++   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
++   Boston, MA 02111-1307 USA
++
++  ------------------------------------------------------------------------------
++
++   If you'd like to release a closed-source product which uses JUCE, commercial
++   licenses are also available: visit www.rawmaterialsoftware.com/juce for
++   more information.
++
++  ==============================================================================
++*/
++
++#include "linuxincludes.h"
++#include "../../../src/juce_core/basics/juce_StandardHeader.h"
++
++#ifdef __CYGWIN__
++  #include <apr_uuid.h>
++  #include <malloc.h>
++#else
++  #include <sys/sysinfo.h>
++  #include <dlfcn.h>
++#endif
++
++#ifdef JUCE_UUID
++  #include <uuid/uuid.h>
++#endif
++
++#ifndef CPU_ISSET
++  #undef SUPPORT_AFFINITIES
++#endif
++
++BEGIN_JUCE_NAMESPACE
++
++#include "../../../src/juce_core/io/files/juce_File.h"
++#include "../../../src/juce_core/basics/juce_SystemStats.h"
++#include "../../../src/juce_core/basics/juce_Logger.h"
++#include "../../../src/juce_core/misc/juce_Uuid.h"
++#include "../../../src/juce_core/threads/juce_Process.h"
++#include "../../../src/juce_appframework/events/juce_Timer.h"
++#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
++
++static struct _LogicalCpuInfo
++{
++    bool htSupported;
++    bool htAvailable;
++    int numPackages;
++    int numLogicalPerPackage;
++    uint32 physicalAffinityMask;
++} logicalCpuInfo;
++
++//==============================================================================
++static unsigned int getCPUIDWord (int* familyModel = 0, int* extFeatures = 0) __attribute__ ((noinline));
++
++static unsigned int getCPUIDWord (int* familyModel, int* extFeatures)
++{
++    unsigned int cpu = 0;
++    unsigned int ext = 0;
++    unsigned int family = 0;
++#ifdef __x86__
++    __asm__ __volatile__ (
++"        pushf                            \n"
++#if JUCE_64BIT
++"        pop    %%rax                     \n"
++#else
++"        pop    %%eax                     \n"
++#endif
++"        movl   %%eax, %%ecx              \n"
++"        xorl   $0x200000, %%eax          \n"
++#if JUCE_64BIT
++"        push   %%rax                     \n"
++#else
++"        push   %%eax                     \n"
++#endif
++"        popf                             \n"
++"        pushf                            \n"
++#if JUCE_64BIT
++"        pop    %%rax                     \n"
++#else
++"        pop    %%eax                     \n"
++#endif
++"        andl   $0x200000, %%eax          \n"
++"        andl   $0x200000, %%ecx          \n"
++"        cmpl   %%eax, %%ecx              \n"
++"        movl   $0, %%edx                 \n"
++"        je     noCpuId                   \n"
++"        movl   $1, %%eax                 \n"
++"        cpuid                            \n"
++"noCpuId:                                 \n"
++       : "=a"(family),                                 /* Output in eax */
++         "=d"(cpu),                                    /* Output in ebx */
++         "=b"(ext)                                     /* Output in edx */
++       :                                               /* No inputs */
++       : "cc", "ecx"                                   /* Clobber list */
++    );
++#endif
++    if (familyModel)
++        *familyModel = family;
++    if (extFeatures)
++        *extFeatures = ext;
++
++    return cpu;
++}
++
++void juce_initLogicalCpuInfo()
++{
++    int familyModelWord, extFeaturesWord;
++    int featuresWord = getCPUIDWord (&familyModelWord, &extFeaturesWord);
++
++    logicalCpuInfo.htSupported = false;
++    logicalCpuInfo.htAvailable = false;
++    logicalCpuInfo.numLogicalPerPackage = 1;
++    logicalCpuInfo.numPackages = 0;
++    logicalCpuInfo.physicalAffinityMask = 0;
++
++#if SUPPORT_AFFINITIES
++    cpu_set_t processAffinity;
++
++    /*
++       N.B. If this line causes a compile error, then you've probably not got the latest
++       version of glibc installed.
++
++       If you don't want to update your copy of glibc and don't care about cpu affinities,
++       then you can just disable all this stuff by removing the SUPPORT_AFFINITIES macro
++       from the linuxincludes.h file.
++    */
++    if (sched_getaffinity (getpid(),
++                           sizeof (cpu_set_t),
++                           &processAffinity) != sizeof (cpu_set_t))
++    {
++        return;
++    }
++
++    // Checks: CPUID supported, model >= Pentium 4, Hyperthreading bit set, logical CPUs per package > 1
++    if (featuresWord == 0
++        || ((familyModelWord >> 8) & 0xf) < 15
++        || (featuresWord & (1 << 28)) == 0
++        || ((extFeaturesWord >> 16) & 0xff) < 2)
++    {
++        for (int i = 0; i < 64; ++i)
++            if (CPU_ISSET (i, &processAffinity))
++                logicalCpuInfo.physicalAffinityMask |= (1 << i);
++
++        return;
++    }
++
++    logicalCpuInfo.htSupported = true;
++    logicalCpuInfo.numLogicalPerPackage = (extFeaturesWord >> 16) & 0xff;
++
++    cpu_set_t affinityMask;
++    cpu_set_t physAff;
++    CPU_ZERO (&physAff);
++
++    unsigned char i = 1;
++    unsigned char physIdMask = 0xFF;
++    unsigned char physIdShift = 0;
++
++    //unsigned char apicId, logId, physId;
++
++    while (i < logicalCpuInfo.numLogicalPerPackage)
++    {
++        i *= 2;
++        physIdMask <<= 1;
++        physIdShift++;
++    }
++
++    CPU_SET (0, &affinityMask);
++    logicalCpuInfo.numPackages = 0;
++
++//xxx revisit this at some point..
++/*    while ((affinityMask != 0) && (affinityMask <= processAffinity))
++    {
++        int ret;
++        if (! sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinityMask))
++        {
++            sched_yield(); // schedule onto correct CPU
++
++            featuresWord = getCPUIDWord(&familyModelWord, &extFeaturesWord);
++            apicId = (unsigned char)(extFeaturesWord >> 24);
++            logId = (unsigned char)(apicId & ~physIdMask);
++            physId = (unsigned char)(apicId >> physIdShift);
++
++            if (logId != 0)
++                logicalCpuInfo.htAvailable = true;
++
++            if ((((int)logId) % logicalCpuInfo.numLogicalPerPackage) == 0)
++            {
++                // This is a physical CPU
++                physAff |= affinityMask;
++                logicalCpuInfo.numPackages++;
++            }
++        }
++
++        affinityMask = affinityMask << 1;
++    }
++
++    sched_setaffinity (getpid(), sizeof(unsigned long), &processAffinity);
++*/
++
++    logicalCpuInfo.physicalAffinityMask = 0;
++
++    for (int i = 0; i < 64; ++i)
++        if (CPU_ISSET (i, &physAff))
++            logicalCpuInfo.physicalAffinityMask |= (1 << i);
++
++#endif
++}
++
++//==============================================================================
++void Logger::outputDebugString (const String& text)
++{
++    fprintf (stdout, (const char*) (text + T("\n")));
++}
++
++void Logger::outputDebugPrintf (const tchar* format, ...)
++{
++    String text;
++    va_list args;
++    va_start (args, format);
++    text.vprintf(format, args);
++    outputDebugString(text);
++}
++
++const String SystemStats::getOSType()
++{
++    return SystemStats::Linux;
++}
++
++static const String getCpuInfo (const char* key, bool lastOne = false)
++{
++    String info;
++    char buf [256];
++
++    FILE* f = fopen ("/proc/cpuinfo", "r");
++
++    while (f != 0 && fgets (buf, sizeof(buf), f))
++    {
++        if (strncmp (buf, key, strlen (key)) == 0)
++        {
++            char* p = buf;
++
++            while (*p && *p != '\n')
++                ++p;
++
++            if (*p != 0)
++                *p = 0;
++
++            p = buf;
++
++            while (*p != 0 && *p != ':')
++                ++p;
++
++            if (*p != 0 && *(p + 1) != 0)
++                info = p + 2;
++
++            if (! lastOne)
++                break;
++        }
++    }
++
++    fclose (f);
++    return info;
++}
++
++bool SystemStats::hasMMX()
++{
++    return getCpuInfo ("flags").contains (T("mmx"));
++}
++
++bool SystemStats::hasSSE()
++{
++    return getCpuInfo ("flags").contains (T("sse"));
++}
++
++bool SystemStats::hasSSE2()
++{
++    return getCpuInfo ("flags").contains (T("sse2"));
++}
++
++bool SystemStats::has3DNow()
++{
++    return getCpuInfo ("flags").contains (T("3dnow"));
++}
++
++const String SystemStats::getCpuVendor()
++{
++    return getCpuInfo ("vendor_id");
++}
++
++int SystemStats::getCpuSpeedInMegaherz()
++{
++    const String speed (getCpuInfo ("cpu MHz"));
++
++    return (int) (speed.getFloatValue() + 0.5f);
++}
++
++bool SystemStats::hasHyperThreading()
++{
++    return logicalCpuInfo.htAvailable;
++}
++
++int SystemStats::getMemorySizeInMegabytes()
++{
++#ifndef __CYGWIN__
++    struct sysinfo sysi;
++
++    if (sysinfo (&sysi) == 0)
++        return (sysi.totalram * sysi.mem_unit / (1024 * 1024));
++
++    return 0;
++
++#else
++    jassertfalse
++    return 256;
++#endif
++}
++
++unsigned int juce_millisecondsSinceStartup()
++{
++    static unsigned int calibrate = 0;
++    static bool calibrated = false;
++    timeval t;
++    unsigned int ret = 0;
++
++    if (! gettimeofday (&t, 0))
++    {
++        if (! calibrated)
++        {
++#ifndef __CYGWIN__
++            struct sysinfo sysi;
++
++            if (sysinfo (&sysi) == 0)
++                // Safe to assume system was not brought up earlier than 1970!
++                calibrate = t.tv_sec - sysi.uptime;
++#else
++            // bit of a hack, but things should all still work, as we're not often
++            // really interested in how long the machine's been turned on, and just
++            // use this call for relative times..
++            calibrate = t.tv_sec;
++#endif
++
++            calibrated = true;
++        }
++
++        ret = 1000 * (t.tv_sec - calibrate) + (t.tv_usec / 1000);
++    }
++
++    return ret;
++}
++
++double juce_millisecondsSinceStartupHiRes()
++{
++    return Time::getHighResolutionTicks() * (1.0 / 1000000.0);
++}
++
++int64 Time::getHighResolutionTicks()
++{
++    timeval t;
++    if (gettimeofday(&t,NULL))
++        return 0;
++
++    return ((int64) t.tv_sec * (int64) 1000000) + (int64) t.tv_usec;
++}
++
++int64 Time::getHighResolutionTicksPerSecond()
++{
++    // Microseconds
++    return 1000000;
++}
++
++bool Time::setSystemTimeToThisTime() const
++{
++    timeval t;
++    t.tv_sec = millisSinceEpoch % 1000000;
++    t.tv_usec = millisSinceEpoch - t.tv_sec;
++
++    return settimeofday (&t, NULL) ? false : true;
++}
++
++const String Uuid::generateUuid()
++{
++#ifdef JUCE_UUID
++    uuid_t uuid;
++    char *s = new char[37];
++    String uuidStr;
++
++    uuid_generate (uuid);
++    uuid_unparse (uuid, s);
++
++    uuidStr = s;
++    delete[] s;
++
++    return uuidStr;
++#else
++    jassertfalse
++    return String::empty;
++#endif
++}
++
++int SystemStats::getPageSize()
++{
++    static int systemPageSize = 0;
++
++    if (systemPageSize == 0)
++        systemPageSize = sysconf (_SC_PAGESIZE);
++
++    return systemPageSize;
++}
++
++int SystemStats::getNumPhysicalCpus()
++{
++    if (logicalCpuInfo.numPackages)
++        return logicalCpuInfo.numPackages;
++
++    return getNumLogicalCpus();
++}
++
++int SystemStats::getNumLogicalCpus()
++{
++    const int lastCpu = getCpuInfo ("processor", true).getIntValue();
++
++    return lastCpu + 1;
++}
++
++uint32 SystemStats::getPhysicalAffinityMask()
++{
++#if SUPPORT_AFFINITIES
++    return logicalCpuInfo.physicalAffinityMask;
++#else
++    /* affinities aren't supported because either the appropriate header files weren't found,
++       or the SUPPORT_AFFINITIES macro was turned off in linuxheaders.h
++    */
++    jassertfalse
++    return 0;
++#endif
++
++}
++
++//==============================================================================
++void SystemStats::initialiseStats()
++{
++    // Process starts off as root when running suid
++    Process::lowerPrivilege();
++
++    String s (SystemStats::getJUCEVersion());
++
++    juce_initLogicalCpuInfo();
++}
++
++void PlatformUtilities::fpuReset()
++{
++}
++
++END_JUCE_NAMESPACE
diff --git a/packages/juce/juce_1.29.bb b/packages/juce/juce_1.29.bb
new file mode 100644 (file)
index 0000000..0127a35
--- /dev/null
@@ -0,0 +1,34 @@
+DESCRIPTION = "JUCE is a cross-platform application framework"
+HOMEPAGE = "http://www.rawmaterialsoftware.com/juce"
+AUTHOR = "Julian Stoerer"
+MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>"
+LICENSE = "GPL"
+DEPENDS = "alsa-lib freetype x11"
+PR = "r0"
+
+#FIXME the patches are a) HACKS and b) something's wrong with lineend conversion
+SRC_URI = "http://www.rawmaterialsoftware.com/juce/downloads/juce_1_29.zip \
+           file://remove-x86isms.patch;patch=1 \
+           file://no-opengl.patch;patch=1"
+S = "${WORKDIR}/juce"
+
+LIB = "libjuce_debug"
+
+do_compile() {
+       cd ${S}/build/linux && oe_runmake
+       cd ${S}/demo/build/linux && oe_runmake
+}
+
+do_stage() {
+       oe_libinstall -a -C bin ${LIB} ${STAGING_LIBDIR}
+       #FIXME add includes
+}
+
+do_install() {
+       install -d ${D}${bindir}
+       install -m 0655 demo/build/linux/build/jucedemo ${D}${bindir}
+}
+
+PACKAGES = "jucedemo"
+FILES_jucedemo = "${bindir}"
+