• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kdeui

ksharedpixmap.cpp

Go to the documentation of this file.
00001 /* vi: ts=8 sts=4 sw=4
00002  *
00003  *
00004  * This file is part of the KDE libraries.
00005  * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Library General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * Shared pixmap client for KDE.
00013  */
00014 #include "config.h"
00015 
00016 #include <qrect.h>
00017 #include <qsize.h>
00018 #include <qstring.h>
00019 #include <qpixmap.h>
00020 #include <qwindowdefs.h>
00021 #include <qwidget.h>
00022 
00023 #ifdef Q_WS_X11
00024 
00025 #include <kapplication.h>
00026 #include <krootprop.h>
00027 #include <ksharedpixmap.h>
00028 #include <kdebug.h>
00029 #include <stdlib.h> // for abs
00030 
00031 #include <X11/Xlib.h> 
00032 
00033 // Make sure to include all this X-based shit before we clean up the mess.
00034 // Needed for --enable-final. Not needed by this file itself!
00035 #include <X11/Xutil.h> 
00036 #ifdef HAVE_MITSHM
00037 #include <X11/extensions/XShm.h> 
00038 #endif
00039 
00040 #include <netwm.h> 
00041 
00042 // Clean up the mess
00043 
00044 #undef Bool
00045 #undef Above
00046 #undef Below
00047 #undef KeyPress
00048 #undef KeyRelease
00049 #undef FocusOut
00050 
00055 class KSharedPixmapPrivate
00056 {
00057 public:
00058   Atom pixmap;
00059   Atom target;
00060   Atom selection;
00061   QRect rect;
00062 };
00063 
00064 KSharedPixmap::KSharedPixmap()
00065     : QWidget(0L, "shpixmap comm window")
00066 {
00067     d = new KSharedPixmapPrivate;
00068     init();
00069 }
00070 
00071 
00072 KSharedPixmap::~KSharedPixmap()
00073 {
00074     delete d;
00075 }
00076 
00077 
00078 void KSharedPixmap::init()
00079 {
00080     d->pixmap = XInternAtom(qt_xdisplay(), "PIXMAP", false);
00081     QCString atom;
00082     atom.sprintf("target prop for window %lx", static_cast<unsigned long int>(winId()));
00083     d->target = XInternAtom(qt_xdisplay(), atom.data(), false);
00084     d->selection = None;
00085 }
00086 
00087 
00088 bool KSharedPixmap::isAvailable(const QString & name) const
00089 {
00090     QString str = QString("KDESHPIXMAP:%1").arg(name);
00091     Atom sel = XInternAtom(qt_xdisplay(), str.latin1(), true);
00092     if (sel == None)
00093     return false;
00094     return XGetSelectionOwner(qt_xdisplay(), sel) != None;
00095 }
00096 
00097 
00098 bool KSharedPixmap::loadFromShared(const QString & name, const QRect & rect)
00099 {
00100     d->rect = rect;
00101     if (d->selection != None)
00102     // already active
00103     return false;
00104 
00105     QPixmap::resize(0, 0); // invalidate
00106 
00107     QString str = QString("KDESHPIXMAP:%1").arg(name);
00108     d->selection = XInternAtom(qt_xdisplay(), str.latin1(), true);
00109     if (d->selection == None)
00110     return false;
00111     if (XGetSelectionOwner(qt_xdisplay(), d->selection) == None)
00112     {
00113     d->selection = None;
00114     return false;
00115     }
00116 
00117     XConvertSelection(qt_xdisplay(), d->selection, d->pixmap, d->target,
00118         winId(), CurrentTime);
00119     return true;
00120 }
00121 
00122 
00123 bool KSharedPixmap::x11Event(XEvent *event)
00124 {
00125     if (event->type != SelectionNotify)
00126     return false;
00127 
00128     XSelectionEvent *ev = &event->xselection;
00129     if (ev->selection != d->selection)
00130     return false;
00131 
00132     if ((ev->target != d->pixmap) || (ev->property == None))
00133     {
00134     kdWarning(270) << k_funcinfo << "illegal selection notify event.\n";
00135     d->selection = None;
00136     emit done(false);
00137     return true;
00138     }
00139 
00140     // Read pixmap handle from ev->property
00141 
00142     int dummy, format;
00143     unsigned long nitems, ldummy;
00144     unsigned char *pixmap_id = 0;
00145     Atom type;
00146 
00147     XGetWindowProperty(qt_xdisplay(), winId(), ev->property, 0, 1, false,
00148         d->pixmap, &type, &format, &nitems, &ldummy,
00149         &pixmap_id);
00150 
00151     if (nitems != 1 || !pixmap_id)
00152     {
00153     kdWarning(270) << k_funcinfo << "could not read property, nitems = " << nitems << "\n";
00154     emit done(false);
00155     return true;
00156     }
00157 
00158     Window root;
00159     unsigned int width, height, udummy;
00160     void *drawable_id = (void *) pixmap_id;
00161     Drawable pixmap = *(Drawable*) drawable_id;
00162 
00163     Status status = XGetGeometry(qt_xdisplay(), pixmap, &root, &dummy, &dummy, &width, &height, &udummy, &udummy);
00164 
00165     if (status == BadDrawable)
00166         return false;
00167 
00168     if (d->rect.isEmpty())
00169     {
00170     QPixmap::resize(width, height);
00171     XCopyArea(qt_xdisplay(), pixmap, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
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     XCopyArea(qt_xdisplay(), pixmap, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
00210             xa, ya, t1w+origin.x(), t1h+origin.y(), origin.x(), origin.y() );
00211     XCopyArea(qt_xdisplay(), pixmap, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
00212         0, ya, tw-t1w, t1h, t1w, 0);
00213     XCopyArea(qt_xdisplay(), pixmap, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
00214         xa, 0, t1w, th-t1h, 0, t1h);
00215     XCopyArea(qt_xdisplay(), pixmap, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false),
00216         0, 0, tw-t1w, th-t1h, t1w, t1h);
00217 
00218     XFree(pixmap_id);
00219 
00220     d->selection = None;
00221     XDeleteProperty(qt_xdisplay(), winId(), ev->property);
00222     emit done(true);
00223     return true;
00224 }
00225 
00226 
00227 #include "ksharedpixmap.moc"
00228 #endif

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal