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 <[EMAIL PROTECTED]> + +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 <[EMAIL PROTECTED]> + + 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 <[EMAIL PROTECTED]> + +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>> _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
