kdeui Library API Documentation

ksharedpixmap.cpp

00001 /* vi: ts=8 sts=4 sw=4 00002 * 00003 * $Id: ksharedpixmap.cpp,v 1.17.2.1 2004/05/24 10:30:12 waba 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 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 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> // schroder 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> // schroder 00037 #ifdef HAVE_MITSHM 00038 #include <X11/extensions/XShm.h> // schroder 00039 #endif 00040 00041 #include <netwm.h> // schroder 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 d->rect = rect; 00102 if (d->selection != None) 00103 // already active 00104 return false; 00105 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 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00168 0, 0, width, height, 0, 0); 00169 00170 XFree(pixmap_id); 00171 XDeleteProperty(qt_xdisplay(), winId(), ev->property); 00172 d->selection = None; 00173 emit done(true); 00174 return true; 00175 } 00176 00177 // Do some more processing here: Generate a tile that can be used as a 00178 // background tile for the rectangle "rect". 00179 00180 //Check for origin off screen 00181 QPoint origin(0, 0); 00182 if( d->rect.topLeft().x() < 0 || d->rect.topLeft().y() < 0 ) { 00183 //Save the offset and relocate the rect corners 00184 QPoint tl = d->rect.topLeft(); 00185 QPoint br = d->rect.bottomRight(); 00186 if( tl.x() < 0 ) { 00187 origin.setX( abs( tl.x() ) ); 00188 tl.setX( 0 ); 00189 } 00190 if( tl.y() < 0 ) { 00191 origin.setY( abs( tl.y() ) ); 00192 tl.setY( 0 ); 00193 } 00194 QRect adjustedRect( tl, br ); 00195 d->rect = adjustedRect; 00196 } 00197 00198 unsigned w = d->rect.width(), h = d->rect.height(); 00199 unsigned tw = QMIN(width, w), th = QMIN(height, h); 00200 unsigned xa = d->rect.x() % width, ya = d->rect.y() % height; 00201 unsigned t1w = QMIN(width-xa,tw), t1h = QMIN(height-ya,th); 00202 00203 QPixmap::resize( tw+origin.x(), th+origin.y() ); 00204 00205 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00206 xa, ya, t1w+origin.x(), t1h+origin.y(), origin.x(), origin.y() ); 00207 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00208 0, ya, tw-t1w, t1h, t1w, 0); 00209 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00210 xa, 0, t1w, th-t1h, 0, t1h); 00211 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00212 0, 0, tw-t1w, th-t1h, t1w, t1h); 00213 00214 XFree(pixmap_id); 00215 00216 d->selection = None; 00217 XDeleteProperty(qt_xdisplay(), winId(), ev->property); 00218 emit done(true); 00219 return true; 00220 } 00221 00222 00223 #include "ksharedpixmap.moc" 00224 #endif
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 8 11:14:28 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003