Changeset 56


Ignore:
Timestamp:
Jan 19, 2006, 10:09:05 PM (20 years ago)
Author:
dmik
Message:

Added the OS/2 specific (i.e. not portable) internal public method to create OS/2 icons/pointers from QPixmap objects.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/qpixmap.h

    r8 r56  
    162162    int         allocCell();
    163163    void        freeCell( bool = FALSE );
     164#elif defined(Q_WS_PM)
     165    static HPOINTER createIcon( bool pointer, int hotX, int hotY,
     166                                const QPixmap *normal, const QPixmap *mini );
    164167#endif
    165168
     
    252255#elif defined(Q_WS_PM)
    253256    void prepareForMasking( bool prepare );
     257    HPOINTER createIcon( bool pointer, int hotX, int hotY, bool mini );
    254258    void attachHandle( HBITMAP hbm );
    255259    HBITMAP detachHandle();
  • trunk/src/kernel/qpixmap_pm.cpp

    r8 r56  
    186186{
    187187    if ( data && data->deref() ) {              // last reference lost
     188        if ( hps )
     189            GpiSetBitmap( hps, 0 );
    188190        if ( data->mask ) {
    189191            delete data->mask;
     
    194196        }
    195197        if ( data->hbm ) {
    196             if ( hps )
    197                 GpiSetBitmap( hps, 0 );
    198198            GpiDeleteBitmap( data->hbm );
    199199            data->hbm = 0;
     
    11291129
    11301130// Prepares for painting the masked pixmap: precomposes and selects the
    1131 // masked pixmap into this pixmap's hps. If prepare = FALSE, it does the
    1132 // cleanup. Currently used from ::bitBlt().
     1131// masked pixmap (with transparent pixels made black) into this pixmap's hps.
     1132// If prepare = FALSE, it does the cleanup. Currently used in ::bitBlt()
     1133// and in QPixmap::createIcon().
    11331134void QPixmap::prepareForMasking( bool prepare )
    11341135{
     
    11851186}
    11861187
     1188HPOINTER QPixmap::createIcon( bool pointer, int hotX, int hotY, bool mini )
     1189{
     1190    HPOINTER icon = NULLHANDLE;
     1191
     1192    if ( !isNull() ) {
     1193        int w = WinQuerySysValue( HWND_DESKTOP, pointer ? SV_CXPOINTER : SV_CXICON );
     1194        int h = WinQuerySysValue( HWND_DESKTOP, pointer ? SV_CYPOINTER : SV_CYICON );
     1195        if ( mini ) {
     1196            w /= 2;
     1197            h /= 2;
     1198        }
     1199       
     1200        QPixmap pm = *this;
     1201        if ( data->w != w || data->h != h ) {
     1202#if !defined(QT_NO_IMAGE_SMOOTHSCALE)
     1203            // do smooth resize until icon is two or more times bigger
     1204            // than the pixmap
     1205            if ( data->w * 2 > w || data->h * 2 > h ) {
     1206                QImage i = convertToImage();
     1207                pm = QPixmap( i.smoothScale( w, h ) );
     1208            } else
     1209#endif
     1210            {
     1211                pm = QPixmap( w, h );
     1212                POINTL ptls[] = {
     1213                    { 0, 0 }, { w, h },
     1214                    { 0, 0 }, { data->w, data->h },
     1215                };
     1216                GpiBitBlt( pm.hps, hps, 4, ptls, ROP_SRCCOPY, BBO_IGNORE );
     1217            }
     1218        }
     1219       
     1220        QBitmap msk( w, h * 2, TRUE );
     1221        if ( pm.data->mask ) {
     1222            // create AND mask (XOR mask is left zeroed -- it's ok) 
     1223            POINTL ptls[] = {
     1224                { 0, h }, { w, h * 2 },
     1225                { 0, 0 }, { w, h },
     1226            };
     1227            GpiBitBlt( msk.hps, pm.data->mask->hps, 4, ptls, ROP_NOTSRCCOPY, BBO_IGNORE );
     1228            pm.prepareForMasking( TRUE );
     1229        }
     1230       
     1231        // unselect bitmap handles from hps
     1232        GpiSetBitmap( pm.hps, 0 );       
     1233        GpiSetBitmap( msk.hps, 0 );
     1234       
     1235        POINTERINFO info;
     1236        info.fPointer = pointer;
     1237        info.xHotspot = hotX;
     1238        info.yHotspot = hotY;
     1239        info.hbmPointer = msk.data->hbm;
     1240        info.hbmColor = pm.data->mask ? pm.data->maskedHbm : pm.data->hbm;
     1241        info.hbmMiniPointer = 0;
     1242        info.hbmMiniColor = 0;
     1243        icon = WinCreatePointerIndirect( HWND_DESKTOP, &info );
     1244
     1245        if ( pm.mask() )
     1246            pm.prepareForMasking( FALSE );
     1247       
     1248        GpiSetBitmap( msk.hps, msk.data->hbm );       
     1249        GpiSetBitmap( pm.hps, pm.data->hbm );       
     1250    }
     1251   
     1252    return icon;
     1253}
     1254
    11871255void QPixmap::attachHandle( HBITMAP hbm )
    11881256{
     
    12251293
    12261294    return hbm;
     1295}
     1296
     1297/*!
     1298    \internal
     1299
     1300    Creates an OS/2 icon or pointer from two given pixmaps.
     1301   
     1302    \param pointer true to create a pointer, false to create an icon
     1303    \param hotX X coordinate of the action point within the pointer/icon
     1304    \param hotY Y coordinate of the action point within the pointer/icon
     1305    \param normal pixmap for a normal-sized pointer/icon
     1306    \param mini pixmap for a mini-sized pointer/icon
     1307   
     1308    \note Due to a bug in WinCreatePointerIndirect, you can specify either
     1309    \a normal pixmap or \a mini pixmap, but not both (if both are specified,
     1310    \a normal will be used). This may be fixed later.
     1311*/
     1312// static
     1313HPOINTER QPixmap::createIcon( bool pointer, int hotX, int hotY,
     1314                              const QPixmap *normal, const QPixmap *mini )
     1315{
     1316    // Due to a bug in WinCreatePointerIndirect (it always ignores
     1317    // hbmMiniPointer and hbmMiniColor fields), we can specify either a normal
     1318    // icon (and get a mini icon autocreated by PM) or a mini icon (with a
     1319    // normal icon autocreated by PM), but not both. This methods still accepts
     1320    // pixmaps for both icon sizes (assuming that we will find a workaround one
     1321    // day) but uses only one of them.
     1322   
     1323    if ( normal && !normal->isNull() ) {
     1324#ifdef QT_CHECK_RANGE
     1325        if ( mini && !mini->isNull() )
     1326            qWarning( "QPixmap::createIcon(): due to a bug in WinCreatePointerIndirect "
     1327                      "either a normal or a mini pixmap should be specified, "
     1328                      "but not both. Will use a normal pixmap." );
     1329#endif   
     1330        return const_cast <QPixmap *> (normal)->createIcon( pointer, hotX, hotY, false );
     1331    }
     1332   
     1333    if ( mini && !mini->isNull() )
     1334        return const_cast <QPixmap *> (mini)->createIcon( pointer, hotX, hotY, true );
     1335   
     1336    return 0;
    12271337}
    12281338
Note: See TracChangeset for help on using the changeset viewer.