| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# ksharedpixmap.cpp

    00001 /* vi: ts=8 sts=4 sw=4
    00002  *
    00003  * $Id: ksharedpixmap.cpp,v 1.15 2002/08/13 17:10:12 coolo Exp $
    00004  *
    00005  * This file is part of the KDE libraries.
    00006  * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
    00007  *
    00008  * This library is free software; you can redistribute it and/or
    00009  * modify it under the terms of the GNU Library General Public
    00010  * License as published by the Free Software Foundation; either
    00011  * version 2 of the License, or (at your option) any later version.
    00012  *
    00013  * Shared pixmap client for KDE.
    00014  */
    00015 #include "config.h"
    00016
    00017 #include <qrect.h>
    00018 #include <qsize.h>
    00019 #include <qstring.h>
    00020 #include <qpixmap.h>
    00021 #include <qwindowdefs.h>
    00022 #include <qwidget.h>
    00023
    00024 #ifndef Q_WS_QWS
    00025
    00026 #include <kapplication.h>
    00027 #include <krootprop.h>
    00028 #include <ksharedpixmap.h>
    00029 #include <kdebug.h>
    00030 #include <stdlib.h> // for abs
    00031
    00032 #include <X11/Xlib.h>
    00033
    00034 // Make sure to include all this X-based shit before we clean up the mess.
    00035 // Needed for --enable-final. Not needed by this file itself!
    00036 #include <X11/Xutil.h>
    00037 #ifdef HAVE_MITSHM
    00038 #include <X11/extensions/XShm.h>
    00039 #endif
    00040
    00041 #include <netwm.h>
    00042
    00043 // Clean up the mess
    00044
    00045 #undef Bool
    00046 #undef Above
    00047 #undef Below
    00048 #undef KeyPress
    00049 #undef KeyRelease
    00050 #undef FocusOut
    00051
    00056 class KSharedPixmapPrivate
    00057 {
    00058 public:
    00059   Atom pixmap;
    00060   Atom target;
    00061   Atom selection;
    00062   QRect rect;
    00063 };
    00064
    00065 KSharedPixmap::KSharedPixmap()
    00066     : QWidget(0L, "shpixmap comm window")
    00067 {
    00068     d = new KSharedPixmapPrivate;
    00069     init();
    00070 }
    00071
    00072
    00073 KSharedPixmap::~KSharedPixmap()
    00074 {
    00075     delete d;
    00076 }
    00077
    00078
    00079 void KSharedPixmap::init()
    00080 {
    00081     d->pixmap = XInternAtom(qt_xdisplay(), "PIXMAP", false);
    00082     QCString atom;
    00083     atom.sprintf("target prop for window %lx", static_cast<unsigned long int>(winId()));
    00084     d->target = XInternAtom(qt_xdisplay(), atom.data(), false);
    00085     d->selection = None;
    00086 }
    00087
    00088
    00089 bool KSharedPixmap::isAvailable(const QString & name) const
    00090 {
    00091     QString str = QString("KDESHPIXMAP:%1").arg(name);
    00092     Atom sel = XInternAtom(qt_xdisplay(), str.latin1(), true);
    00093     if (sel == None)
    00094         return false;
    00095     return XGetSelectionOwner(qt_xdisplay(), sel) != None;
    00096 }
    00097
    00098
    00099 bool KSharedPixmap::loadFromShared(const QString & name, const QRect & rect)
    00100 {
    00101     if (d->selection != None)
    00102         // already active
    00103         return false;
    00104
    00105     d->rect = rect;
    00106     QPixmap::resize(0, 0); // invalidate
    00107
    00108     QString str = QString("KDESHPIXMAP:%1").arg(name);
    00109     d->selection = XInternAtom(qt_xdisplay(), str.latin1(), true);
    00110     if (d->selection == None)
    00111         return false;
    00112     if (XGetSelectionOwner(qt_xdisplay(), d->selection) == None)
    00113     {
    00114         d->selection = None;
    00115         return false;
    00116     }
    00117
    00118     XConvertSelection(qt_xdisplay(), d->selection, d->pixmap, d->target,
    00119             winId(), CurrentTime);
    00120     return true;
    00121 }
    00122
    00123
    00124 bool KSharedPixmap::x11Event(XEvent *event)
    00125 {
    00126     if (event->type != SelectionNotify)
    00127         return false;
    00128
    00129     XSelectionEvent *ev = &event->xselection;
    00130     if (ev->selection != d->selection)
    00131         return false;
    00132
    00133     if ((ev->target != d->pixmap) || (ev->property == None))
    00134     {
    00135         kdWarning(270) << k_funcinfo << "illegal selection notify event.\n";
    00136         d->selection = None;
    00137         emit done(false);
    00138         return true;
    00139     }
    00140
    00141     // Read pixmap handle from ev->property
    00142
    00143     int dummy, format;
    00144     unsigned long nitems, ldummy;
    00145     Drawable *pixmap_id;
    00146     Atom type;
    00147
    00148     XGetWindowProperty(qt_xdisplay(), winId(), ev->property, 0, 1, false,
    00149             d->pixmap, &type, &format, &nitems, &ldummy,
    00150             (unsigned char **) &pixmap_id);
    00151
    00152     if (nitems != 1)
    00153     {
    00154         kdWarning(270) << k_funcinfo << "could not read property, nitems = " << nitems << "\n";
    00155         emit done(false);
    00156         return true;
    00157     }
    00158
    00159     Window root;
    00160     unsigned int width, height, udummy;
    00161     XGetGeometry(qt_xdisplay(), *pixmap_id, &root, &dummy, &dummy, &width,
    00162             &height, &udummy, &udummy);
    00163
    00164     if (d->rect.isEmpty())
    00165     {
    00166         QPixmap::resize(width, height);
    00167 #if QT_VERSION < 300
    00168         XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(),
    00169 #else
    00170         XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
    00171 #endif
    00172                 0, 0, width, height, 0, 0);
    00173
    00174         XFree(pixmap_id);
    00175         XDeleteProperty(qt_xdisplay(), winId(), ev->property);
    00176         d->selection = None;
    00177         emit done(true);
    00178         return true;
    00179     }
    00180
    00181     // Do some more processing here: Generate a tile that can be used as a
    00182     // background tile for the rectangle "rect".
    00183
    00184     //Check for origin off screen
    00185     QPoint origin(0, 0);
    00186     if(  d->rect.topLeft().x() < 0 ||  d->rect.topLeft().y() < 0 ) {
    00187         //Save the offset and relocate the rect corners
    00188         QPoint tl = d->rect.topLeft();
    00189         QPoint br = d->rect.bottomRight();
    00190         if( tl.x() < 0 ) {
    00191             origin.setX( abs( tl.x() ) );
    00192             tl.setX( 0 );
    00193         }
    00194         if( tl.y() < 0 ) {
    00195             origin.setY( abs( tl.y() ) );
    00196             tl.setY( 0 );
    00197         }
    00198         QRect adjustedRect( tl, br );
    00199         d->rect = adjustedRect;
    00200     }
    00201
    00202     unsigned w = d->rect.width(), h = d->rect.height();
    00203     unsigned tw = QMIN(width, w), th = QMIN(height, h);
    00204     unsigned xa = d->rect.x() % width, ya = d->rect.y() % height;
    00205     unsigned t1w = QMIN(width-xa,tw), t1h = QMIN(height-ya,th);
    00206
    00207     QPixmap::resize( tw+origin.x(), th+origin.y() );
    00208
    00209 #if QT_VERSION < 300
    00210     XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(),
    00211             xa, ya, t1w+origin.x(), t1h+origin.y(), origin.x(), origin.y() );
    00212     XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(),
    00213             0, ya, tw-t1w, t1h, t1w, 0);
    00214     XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(),
    00215             xa, 0, t1w, th-t1h, 0, t1h);
    00216     XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(),
    00217             0, 0, tw-t1w, th-t1h, t1w, t1h);
    00218 #else
    00219     XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
    00220             xa, ya, t1w+origin.x(), t1h+origin.y(), origin.x(), origin.y() );
    00221     XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
    00222             0, ya, tw-t1w, t1h, t1w, 0);
    00223     XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
    00224             xa, 0, t1w, th-t1h, 0, t1h);
    00225     XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
    00226             0, 0, tw-t1w, th-t1h, t1w, t1h);
    00227 #endif
    00228
    00229     XFree(pixmap_id);
    00230
    00231     d->selection = None;
    00232     XDeleteProperty(qt_xdisplay(), winId(), ev->property);
    00233     emit done(true);
    00234     return true;
    00235 }
    00236
    00237
    00238 #include "ksharedpixmap.moc"
    00239 #endif

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:57:40 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001