SOURCES: 0001-dnd_optimization.patch (NEW), 0002-dnd_active_window...
arekm
arekm at pld-linux.org
Mon Feb 5 18:34:45 CET 2007
Author: arekm Date: Mon Feb 5 17:34:45 2007 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- put qt copy patches here; 5 new patches
---- Files affected:
SOURCES:
0001-dnd_optimization.patch (NONE -> 1.1) (NEW), 0002-dnd_active_window_fix.patch (NONE -> 1.1) (NEW), 0005-qpixmap_mitshm.patch (NONE -> 1.1) (NEW), 0007-qpixmap_constants.patch (NONE -> 1.1) (NEW), 0015-qiconview-finditem.patch (NONE -> 1.1) (NEW), 0016-qiconview-rebuildcontainer.patch (NONE -> 1.1) (NEW), 0017-qiconview-ctrl_rubber.patch (NONE -> 1.1) (NEW), 0020-designer-deletetabs.patch (NONE -> 1.1) (NEW), 0032-fix_rotated_randr.diff (NONE -> 1.1) (NEW), 0035-qvaluelist-streaming-operator.patch (NONE -> 1.1) (NEW), 0036-qprogressbar-optimization.patch (NONE -> 1.1) (NEW), 0038-dragobject-dont-prefer-unknown.patch (NONE -> 1.1) (NEW), 0044-qscrollview-windowactivate-fix.diff (NONE -> 1.1) (NEW), 0046-qiconview-no-useless-scrollbar.diff (NONE -> 1.1) (NEW), 0047-fix-kmenu-width.diff (NONE -> 1.1) (NEW), 0048-qclipboard_hack_80072.patch (NONE -> 1.1) (NEW), 0049-qiconview-rubber_on_move.diff (NONE -> 1.1) (NEW), 0056-khotkeys_input_84434.patch (NONE ->
1.1) (NEW), 0059-qpopup_has_mouse.patch (NONE -> 1.1) (NEW), 0060-qpopup_ignore_mousepos.patch (NONE -> 1.1) (NEW), 0061-qscrollview-propagate-horizontal-wheelevent.patch (NONE -> 1.1) (NEW), 0069-fix-minsize.patch (NONE -> 1.1) (NEW), 0070-fix-broken-fonts.patch (NONE -> 1.1) (NEW), 0071-fix-qtextedit-performance.patch (NONE -> 1.1) (NEW), 0073-xinerama-aware-qpopup.patch (NONE -> 1.1) (NEW), 0074-indic-script-fix.patch (NONE -> 1.1) (NEW), 0075-fix-array-underrun.diff (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/0001-dnd_optimization.patch
diff -u /dev/null SOURCES/0001-dnd_optimization.patch:1.1
--- /dev/null Mon Feb 5 18:34:45 2007
+++ SOURCES/0001-dnd_optimization.patch Mon Feb 5 18:34:40 2007
@@ -0,0 +1,187 @@
+qt-bugs@ issue : 16115
+applied: no
+author: Lubos Lunak <l.lunak at kde.org>
+
+See http://lists.kde.org/?t=104388858900001&r=1&w=2
+
+
+--- src/kernel/qdnd_x11.cpp.sav 2003-02-05 16:09:45.000000000 +0100
++++ src/kernel/qdnd_x11.cpp 2003-02-07 16:14:49.000000000 +0100
+@@ -49,13 +49,15 @@
+ #include "qdragobject.h"
+ #include "qobjectlist.h"
+ #include "qcursor.h"
++#include "qbitmap.h"
++#include "qpainter.h"
+
+ #include "qt_x11_p.h"
+
+ // conflict resolution
+
+-// unused, may be used again later: const int XKeyPress = KeyPress;
+-// unused, may be used again later: const int XKeyRelease = KeyRelease;
++const int XKeyPress = KeyPress;
++const int XKeyRelease = KeyRelease;
+ #undef KeyPress
+ #undef KeyRelease
+
+@@ -249,20 +251,47 @@ class QShapedPixmapWidget : public QWidg
+ public:
+ QShapedPixmapWidget(int screen = -1) :
+ QWidget(QApplication::desktop()->screen( screen ),
+- 0, WStyle_Customize | WStyle_Tool | WStyle_NoBorder | WX11BypassWM )
++ 0, WStyle_Customize | WStyle_Tool | WStyle_NoBorder | WX11BypassWM ), oldpmser( 0 ), oldbmser( 0 )
+ {
+ }
+
+- void setPixmap(QPixmap pm)
++ void setPixmap(QPixmap pm, QPoint hot)
+ {
+- if ( pm.mask() ) {
++ int bmser = pm.mask() ? pm.mask()->serialNumber() : 0;
++ if( oldpmser == pm.serialNumber() && oldbmser == bmser
++ && oldhot == hot )
++ return;
++ oldpmser = pm.serialNumber();
++ oldbmser = bmser;
++ oldhot = hot;
++ bool hotspot_in = !(hot.x() < 0 || hot.y() < 0 || hot.x() >= pm.width() || hot.y() >= pm.height());
++// if the pixmap has hotspot in its area, make a "hole" in it at that position
++// this will allow XTranslateCoordinates() to find directly the window below the cursor instead
++// of finding this pixmap, and therefore there won't be needed any (slow) search for the window
++// using findRealWindow()
++ if( hotspot_in ) {
++ QBitmap mask = pm.mask() ? *pm.mask() : QBitmap( pm.width(), pm.height());
++ if( !pm.mask())
++ mask.fill( Qt::color1 );
++ QPainter p( &mask );
++ p.setPen( Qt::color0 );
++ p.drawPoint( hot.x(), hot.y());
++ p.end();
++ pm.setMask( mask );
++ setMask( mask );
++ } else if ( pm.mask() ) {
+ setMask( *pm.mask() );
+ } else {
+ clearMask();
+ }
+ resize(pm.width(),pm.height());
+ setErasePixmap(pm);
++ erase();
+ }
++private:
++ int oldpmser;
++ int oldbmser;
++ QPoint oldhot;
+ };
+
+ QShapedPixmapWidget * qt_xdnd_deco = 0;
+@@ -859,6 +888,45 @@ void QDragManager::timerEvent( QTimerEve
+ move( QCursor::pos() );
+ }
+
++static bool qt_xdnd_was_move = false;
++static bool qt_xdnd_found = false;
++// check whole incoming X queue for move events
++// checking whole queue is done by always returning False in the predicate
++// if there's another move event in the queue, and there's not a mouse button
++// or keyboard or ClientMessage event before it, the current move event
++// may be safely discarded
++// this helps avoiding being overloaded by being flooded from many events
++// from the XServer
++static
++Bool qt_xdnd_predicate( Display*, XEvent* ev, XPointer )
++{
++ if( qt_xdnd_found )
++ return False;
++ if( ev->type == MotionNotify )
++ {
++ qt_xdnd_was_move = true;
++ qt_xdnd_found = true;
++ }
++ if( ev->type == ButtonPress || ev->type == ButtonRelease
++ || ev->type == XKeyPress || ev->type == XKeyRelease
++ || ev->type == ClientMessage )
++ {
++ qt_xdnd_was_move = false;
++ qt_xdnd_found = true;
++ }
++ return False;
++}
++
++static
++bool qt_xdnd_another_movement()
++{
++ qt_xdnd_was_move = false;
++ qt_xdnd_found = false;
++ XEvent dummy;
++ XCheckIfEvent( qt_xdisplay(), &dummy, qt_xdnd_predicate, NULL );
++ return qt_xdnd_was_move;
++}
++
+ bool QDragManager::eventFilter( QObject * o, QEvent * e)
+ {
+ if ( beingCancelled ) {
+@@ -881,8 +949,10 @@ bool QDragManager::eventFilter( QObject
+
+ if ( e->type() == QEvent::MouseMove ) {
+ QMouseEvent* me = (QMouseEvent *)e;
+- updateMode(me->stateAfter());
+- move( me->globalPos() );
++ if( !qt_xdnd_another_movement()) {
++ updateMode(me->stateAfter());
++ move( me->globalPos() );
++ }
+ return TRUE;
+ } else if ( e->type() == QEvent::MouseButtonRelease ) {
+ qApp->removeEventFilter( this );
+@@ -1106,7 +1176,7 @@ void QDragManager::move( const QPoint &
+ delete qt_xdnd_deco;
+ qt_xdnd_deco = new QShapedPixmapWidget( screen );
+ }
+- updatePixmap();
++ updatePixmap( globalPos );
+
+ if ( qt_xdnd_source_sameanswer.contains( globalPos ) &&
+ qt_xdnd_source_sameanswer.isValid() ) {
+@@ -1679,7 +1749,7 @@ bool QDragManager::drag( QDragObject * o
+ // qt_xdnd_source_object persists until we get an xdnd_finish message
+ }
+
+-void QDragManager::updatePixmap()
++void QDragManager::updatePixmap( const QPoint& cursorPos )
+ {
+ if ( qt_xdnd_deco ) {
+ QPixmap pm;
+@@ -1694,9 +1764,8 @@ void QDragManager::updatePixmap()
+ defaultPm = new QPixmap(default_pm);
+ pm = *defaultPm;
+ }
+- qt_xdnd_deco->setPixmap(pm);
+- qt_xdnd_deco->move(QCursor::pos()-pm_hot);
+- qt_xdnd_deco->repaint(FALSE);
++ qt_xdnd_deco->setPixmap(pm, pm_hot);
++ qt_xdnd_deco->move(cursorPos-pm_hot);
+ //if ( willDrop ) {
+ qt_xdnd_deco->show();
+ //} else {
+@@ -1705,4 +1774,9 @@ void QDragManager::updatePixmap()
+ }
+ }
+
++void QDragManager::updatePixmap()
++{
++ updatePixmap( QCursor::pos());
++}
++
+ #endif // QT_NO_DRAGANDDROP
+--- src/kernel/qdragobject.h.sav 2002-11-01 19:25:07.000000000 +0100
++++ src/kernel/qdragobject.h 2001-01-01 01:01:00.000000000 +0100
+@@ -245,6 +245,7 @@ private:
+ void move( const QPoint & );
+ void drop();
+ void updatePixmap();
++ void updatePixmap( const QPoint& cursorPos );
+
+ private:
+ QDragObject * object;
================================================================
Index: SOURCES/0002-dnd_active_window_fix.patch
diff -u /dev/null SOURCES/0002-dnd_active_window_fix.patch:1.1
--- /dev/null Mon Feb 5 18:34:45 2007
+++ SOURCES/0002-dnd_active_window_fix.patch Mon Feb 5 18:34:40 2007
@@ -0,0 +1,189 @@
+qt-bugs@ issue : 25122
+applied: no
+author: Lubos Lunak <l.lunak at kde.org>
+
+ Hello,
+
+ for example: Open Konqueror window, showing some files. Start dragging one
+ desktop icon. If you press/release Ctrl, there'll be a '+' attached to the
+ icon, showing the DND operation. Now, while still doing DND, make the
+ Konqueror window active (Alt+Tab with KDE-3.1.2+, hover over its taskbar
+ entry, Ctrl+Fn to switch to a different virtual desktop, etc.). As soon as
+ the app performing DND is not the active application, and the mouse is not
+ moving, pressing/releasing Ctrl doesn't do anything, the state only updates
+ when the mouse is moved.
+
+ This is caused by the fact that Qt has only pointer grab when doing DND, but
+ doesn't have keyboard grab. I actually consider this a good thing, because
+ the only keys important for DND are modifiers, and they come together with
+ pointer events, and not having keyboard grab allows using keyboard shortcuts
+ like Alt+Tab while DND. However, when the mouse is not moved, and only a
+ modifier key is pressed/released, the app won't get any mouse event, and
+ won't also get the keyboard event.
+
+ The attached patch changes Qt to explicitly check the modifiers state using
+ XQueryPointer() if there's wasn't recently any mouse/keyboard event, which
+ ensures the state is updated even in the situation described above.
+
+--- src/kernel/qapplication_x11.cpp.sav 2003-06-21 12:31:35.000000000 +0200
++++ src/kernel/qapplication_x11.cpp 2003-06-21 12:35:44.000000000 +0200
+@@ -4053,7 +4053,7 @@ void QApplication::closePopup( QWidget *
+ // Keyboard event translation
+ //
+
+-static int translateButtonState( int s )
++int qt_x11_translateButtonState( int s )
+ {
+ int bst = 0;
+ if ( s & Button1Mask )
+@@ -4119,7 +4119,7 @@ bool QETWidget::translateMouseEvent( con
+ pos.ry() = lastMotion.y;
+ globalPos.rx() = lastMotion.x_root;
+ globalPos.ry() = lastMotion.y_root;
+- state = translateButtonState( lastMotion.state );
++ state = qt_x11_translateButtonState( lastMotion.state );
+ if ( qt_button_down && (state & (LeftButton |
+ MidButton |
+ RightButton ) ) == 0 )
+@@ -4143,7 +4143,7 @@ bool QETWidget::translateMouseEvent( con
+ pos.ry() = xevent->xcrossing.y;
+ globalPos.rx() = xevent->xcrossing.x_root;
+ globalPos.ry() = xevent->xcrossing.y_root;
+- state = translateButtonState( xevent->xcrossing.state );
++ state = qt_x11_translateButtonState( xevent->xcrossing.state );
+ if ( qt_button_down && (state & (LeftButton |
+ MidButton |
+ RightButton ) ) == 0 )
+@@ -4155,7 +4155,7 @@ bool QETWidget::translateMouseEvent( con
+ pos.ry() = event->xbutton.y;
+ globalPos.rx() = event->xbutton.x_root;
+ globalPos.ry() = event->xbutton.y_root;
+- state = translateButtonState( event->xbutton.state );
++ state = qt_x11_translateButtonState( event->xbutton.state );
+ switch ( event->xbutton.button ) {
+ case Button1: button = LeftButton; break;
+ case Button2: button = MidButton; break;
+@@ -4950,7 +4950,7 @@ bool QETWidget::translateKeyEventInterna
+ XKeyEvent xkeyevent = event->xkey;
+
+ // save the modifier state, we will use the keystate uint later by passing
+- // it to translateButtonState
++ // it to qt_x11_translateButtonState
+ uint keystate = event->xkey.state;
+ // remove the modifiers where mode_switch exists... HPUX machines seem
+ // to have alt *AND* mode_switch both in Mod1Mask, which causes
+@@ -5064,7 +5064,7 @@ bool QETWidget::translateKeyEventInterna
+ }
+ #endif // !QT_NO_XIM
+
+- state = translateButtonState( keystate );
++ state = qt_x11_translateButtonState( keystate );
+
+ static int directionKeyEvent = 0;
+ if ( qt_use_rtl_extensions && type == QEvent::KeyRelease ) {
+--- src/kernel/qdnd_x11.cpp.sav 2003-06-30 15:26:42.000000000 +0200
++++ src/kernel/qdnd_x11.cpp 2003-06-30 15:32:23.000000000 +0200
+@@ -114,6 +114,8 @@ Atom qt_xdnd_finished;
+ Atom qt_xdnd_type_list;
+ const int qt_xdnd_version = 4;
+
++extern int qt_x11_translateButtonState( int s );
++
+ // Actions
+ //
+ // The Xdnd spec allows for user-defined actions. This could be implemented
+@@ -198,6 +200,8 @@ static Atom qt_xdnd_source_current_time;
+ static int qt_xdnd_current_screen = -1;
+ // state of dragging... true if dragging, false if not
+ bool qt_xdnd_dragging = FALSE;
++// need to check state of keyboard modifiers
++static bool need_modifiers_check = FALSE;
+
+ // dict of payload data, sorted by type atom
+ static QIntDict<QByteArray> * qt_xdnd_target_data = 0;
+@@ -879,8 +883,20 @@ void qt_handle_xdnd_finished( QWidget *,
+
+ void QDragManager::timerEvent( QTimerEvent* e )
+ {
+- if ( e->timerId() == heartbeat && qt_xdnd_source_sameanswer.isNull() )
+- move( QCursor::pos() );
++ if ( e->timerId() == heartbeat ) {
++ if( need_modifiers_check ) {
++ Window root, child;
++ int root_x, root_y, win_x, win_y;
++ unsigned int mask;
++ XQueryPointer( qt_xdisplay(), qt_xrootwin( qt_xdnd_current_screen ),
++ &root, &child, &root_x, &root_y, &win_x, &win_y, &mask );
++ if( updateMode( (ButtonState)qt_x11_translateButtonState( mask )))
++ qt_xdnd_source_sameanswer = QRect(); // force move
++ }
++ need_modifiers_check = TRUE;
++ if( qt_xdnd_source_sameanswer.isNull() )
++ move( QCursor::pos() );
++ }
+ }
+
+ static bool qt_xdnd_was_move = false;
+@@ -948,6 +964,7 @@ bool QDragManager::eventFilter( QObject
+ updateMode(me->stateAfter());
+ move( me->globalPos() );
+ }
++ need_modifiers_check = FALSE;
+ return TRUE;
+ } else if ( e->type() == QEvent::MouseButtonRelease ) {
+ qApp->removeEventFilter( this );
+@@ -986,9 +1003,11 @@ bool QDragManager::eventFilter( QObject
+ beingCancelled = FALSE;
+ qApp->exit_loop();
+ } else {
+- updateMode(ke->stateAfter());
+- qt_xdnd_source_sameanswer = QRect(); // force move
+- move( QCursor::pos() );
++ if( updateMode(ke->stateAfter())) {
++ qt_xdnd_source_sameanswer = QRect(); // force move
++ move( QCursor::pos() );
++ }
++ need_modifiers_check = FALSE;
+ }
+ return TRUE; // Eat all key events
+ }
+@@ -1014,10 +1033,10 @@ bool QDragManager::eventFilter( QObject
+
+
+ static Qt::ButtonState oldstate;
+-void QDragManager::updateMode( ButtonState newstate )
++bool QDragManager::updateMode( ButtonState newstate )
+ {
+ if ( newstate == oldstate )
+- return;
++ return false;
+ const int both = ShiftButton|ControlButton;
+ if ( (newstate & both) == both ) {
+ global_requested_action = QDropEvent::Link;
+@@ -1041,6 +1060,7 @@ void QDragManager::updateMode( ButtonSta
+ }
+ }
+ oldstate = newstate;
++ return true;
+ }
+
+
+@@ -1707,6 +1727,7 @@ bool QDragManager::drag( QDragObject * o
+ qt_xdnd_source_sameanswer = QRect();
+ move(QCursor::pos());
+ heartbeat = startTimer(200);
++ need_modifiers_check = FALSE;
+
+ #ifndef QT_NO_CURSOR
+ qApp->setOverrideCursor( arrowCursor );
+--- src/kernel/qdragobject.h.sav 2003-05-19 22:34:43.000000000 +0200
++++ src/kernel/qdragobject.h 2001-01-01 01:01:00.000000000 +0100
+@@ -248,7 +248,7 @@ private:
+
+ private:
+ QDragObject * object;
+- void updateMode( ButtonState newstate );
++ bool updateMode( ButtonState newstate );
+ void updateCursor();
+
+ QWidget * dragSource;
================================================================
Index: SOURCES/0005-qpixmap_mitshm.patch
diff -u /dev/null SOURCES/0005-qpixmap_mitshm.patch:1.1
--- /dev/null Mon Feb 5 18:34:45 2007
+++ SOURCES/0005-qpixmap_mitshm.patch Mon Feb 5 18:34:40 2007
@@ -0,0 +1,583 @@
+qt-bugs@ issue : 11790 (part of)
+applied: no
+author: Lubos Lunak <l.lunak at kde.org>
+
+NOTE: Needs #define QT_MITSHM in the matching qplatformdefs.h file. This
+ patch does so only for linux-g++ and linux-g++-distcc platforms.
+
+MITSHM extension support for QPixmap<->QImage conversions.
+
+Hello,
+
+ the review and apply the attached patches that improve performance of
+QImage->QPixmap conversions. They should be applied in order
+'mitshm','more_local' and 'fast', but they're independent from each other
+(well, besides merging problems).
+
+ Mitshm patch adds MITSHM extension support for both
+QPixmap::convertFromImage() and QPixmap::convertToImage(). I've noticed there
+was some MITSHM support already, turned off by default, but it was used only
+for QPixmap::xForm() , and it used shared pixmaps (and I'd bet nobody uses
+it). My patch adds shared ximages support for faster pixmap<->image
+conversions. Since I don't understand the xForm() code much, and I didn't
+want to do anything with it, I added three #define's:
+ - QT_MITSHM generally enabling MITSHM support, which should be set in
+qplatformsdefs.h (or wherever you setup platform specific stuff), it can be
+enabled at least on Linux
+ - QT_MITSHM_CONVERSIONS - this is for my new code
+ - QT_MITSHM_XFORM - this is for the xForm() code
+ There's one more #define, QT_MITSHM_RMID_IGNORES_REFCOUNT. Glibc
+documentation of shmctl( ... IPC_RMID ) quite clearly says that the memory
+segment is freed only after the refcount increased by shmat() and decreased
+by shmdt() is 0. However, at least according to
+http://bugs.kde.org/show_bug.cgi?id=27517 , this doesn't happen on other
+platforms for some strange reason. Such platforms should have this #define if
+you ever consider supporting MITSHM on them.
+
+ The lower limit for using MITSHM for the image is about 8KiB
+(width*height*depth > 100*100*32 ). Also, BestOptim in such case doesn't keep
+the ximage, as the shared ximage is always freed before the function returns
+(I don't know if it's worth copying it).
+
+ The second patch ('more_local'), in short, does nothing. Besides improving
+performance by about 10% by making variables more "local", making few of them
+const, and also making some of them unsigned (this help gcc for some reason).
+
+ The last one, 'fast', moves some if's out of the loops, and handles some most
+common case specially (15bpp, 16bpp and 32bpp ximage depths). 32bpp case, if
+the endianess matches, is simply uses memcpy(), for the 15/16bpp depth,
+variables are replaced directly by matching values, statements are a bit
+reordered and merged when suitable, and again, in case endianess matches,
+pixels are written simply as Q_INT16. Most probably it would also help to
+process two pixels at once and write them as Q_INT32, but I didn't want to
+complicate the code too much (later >;) ).
+
+ The last snippet of 'fast' handles case when xi->bytes_per_line is not equal
+to width for 8bpp ximage. I'm not actually sure if that can ever happen, but
+since I've already written it *shrug*.
+
+ The 'more_local' and 'fast' patches change only convertFromImage(), as I
+don't think convertToImage() is that performance critical (but it's as
+unoptimized as convertFromImage() was).
+
+ Maybe some numbers. The difference is of course mainly visible with larger
+pixmaps. The two optimizations alone reduce the time to 50% for 32bpp, to 70%
+for 16bpp. The MITSHM support, when other patches are already applied too,
+for 32bpp images saves about 33%. Together, the total time is reduced to
+about 40% for 32bpp. Imlib probably still beats that, but at least this
+obsoletes KPixmapIO.
+
+--- src/kernel/qpixmap_x11.cpp.sav 2003-06-30 15:14:46.000000000 +0200
++++ src/kernel/qpixmap_x11.cpp 2003-06-30 15:51:37.000000000 +0200
+@@ -37,7 +37,19 @@
+
+ // NOT REVISED
+
++#include "qplatformdefs.h"
++
++#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
++#undef QT_MITSHM
++#endif
++
++#ifdef QT_MITSHM
++
++// Use the MIT Shared Memory extension for pixmap<->image conversions
++#define QT_MITSHM_CONVERSIONS
++
+ // Uncomment the next line to enable the MIT Shared Memory extension
++// for QPixmap::xForm()
+ //
+ // WARNING: This has some problems:
+ //
+@@ -45,14 +57,13 @@
+ // 2. Qt does not handle the ShmCompletion message, so you will
+ // get strange effects if you xForm() repeatedly.
+ //
+-// #define QT_MITSHM
++// #define QT_MITSHM_XFORM
+
+-#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
+-#undef QT_MITSHM
++#else
++#undef QT_MITSHM_CONVERSIONS
++#undef QT_MITSHM_XFORM
+ #endif
+
+-#include "qplatformdefs.h"
+-
+ #include "qbitmap.h"
+ #include "qpaintdevicemetrics.h"
+ #include "qimage.h"
+@@ -91,7 +102,7 @@ inline static void qSafeXDestroyImage( X
+ MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
+ *****************************************************************************/
+
+-#if defined(QT_MITSHM)
++#if defined(QT_MITSHM_XFORM)
+
+ static bool xshminit = FALSE;
+ static XShmSegmentInfo xshminfo;
+@@ -173,8 +184,100 @@ static bool qt_create_mitshm_buffer( con
+ // return FALSE;
+ // }
+
+-#endif // QT_MITSHM
++#endif // QT_MITSHM_XFORM
+
++#ifdef QT_MITSHM_CONVERSIONS
++
++static bool qt_mitshm_error = false;
++static int qt_mitshm_errorhandler( Display*, XErrorEvent* )
++{
++ qt_mitshm_error = true;
++ return 0;
++}
++
++static XImage* qt_XShmCreateImage( Display* dpy, Visual* visual, unsigned int depth,
++ int format, int /*offset*/, char* /*data*/, unsigned int width, unsigned int height,
++ int /*bitmap_pad*/, int /*bytes_per_line*/, XShmSegmentInfo* shminfo )
++{
++ if( width * height * depth < 100*100*32 )
++ return NULL;
++ static int shm_inited = -1;
++ if( shm_inited == -1 ) {
++ if( XShmQueryExtension( dpy ))
++ shm_inited = 1;
++ else
++ shm_inited = 0;
++ }
++ if( shm_inited == 0 )
++ return NULL;
++ XImage* xi = XShmCreateImage( dpy, visual, depth, format, NULL, shminfo, width,
++ height );
++ if( xi == NULL )
++ return NULL;
++ shminfo->shmid = shmget( IPC_PRIVATE, xi->bytes_per_line * xi->height,
++ IPC_CREAT|0600);
++ if( shminfo->shmid < 0 ) {
++ XDestroyImage( xi );
++ return NULL;
++ }
++ shminfo->readOnly = False;
++ shminfo->shmaddr = (char*)shmat( shminfo->shmid, 0, 0 );
++ if( shminfo->shmaddr == (char*)-1 ) {
++ XDestroyImage( xi );
++ shmctl( shminfo->shmid, IPC_RMID, 0 );
++ return NULL;
++ }
++ xi->data = shminfo->shmaddr;
++#ifndef QT_MITSHM_RMID_IGNORES_REFCOUNT
++ // mark as deleted to automatically free the memory in case
++ // of a crash (but this doesn't work e.g. on Solaris)
++ shmctl( shminfo->shmid, IPC_RMID, 0 );
++#endif
++ if( shm_inited == 1 ) { // first time
++ XErrorHandler old_h = XSetErrorHandler( qt_mitshm_errorhandler );
++ XShmAttach( dpy, shminfo );
++ shm_inited = 2;
++ XSync( dpy, False );
++ XSetErrorHandler( old_h );
++ if( qt_mitshm_error ) { // oops ... perhaps we are remote?
++ shm_inited = 0;
++ XDestroyImage( xi );
++ shmdt( shminfo->shmaddr );
++#ifdef QT_MITSHM_RMID_IGNORES_REFCOUNT
++ shmctl( shminfo->shmid, IPC_RMID, 0 );
++#endif
++ return NULL;
++ }
++ } else
++ XShmAttach( dpy, shminfo );
++ return xi;
++}
++
++static void qt_XShmDestroyImage( XImage* xi, XShmSegmentInfo* shminfo )
++{
++ XShmDetach( QPaintDevice::x11AppDisplay(), shminfo );
++ XDestroyImage( xi );
++ shmdt( shminfo->shmaddr );
++#ifdef QT_MITSHM_RMID_IGNORES_REFCOUNT
++ shmctl( shminfo->shmid, IPC_RMID, 0 );
++#endif
++}
++
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list