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