kdeui Library API Documentation

ksharedpixmap.cpp

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 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 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 Drawable *pixmap_id; 00145 Atom type; 00146 00147 XGetWindowProperty(qt_xdisplay(), winId(), ev->property, 0, 1, false, 00148 d->pixmap, &type, &format, &nitems, &ldummy, 00149 (unsigned char **) &pixmap_id); 00150 00151 if (nitems != 1) 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 XGetGeometry(qt_xdisplay(), *pixmap_id, &root, &dummy, &dummy, &width, 00161 &height, &udummy, &udummy); 00162 00163 if (d->rect.isEmpty()) 00164 { 00165 QPixmap::resize(width, height); 00166 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00167 0, 0, width, height, 0, 0); 00168 00169 XFree(pixmap_id); 00170 XDeleteProperty(qt_xdisplay(), winId(), ev->property); 00171 d->selection = None; 00172 emit done(true); 00173 return true; 00174 } 00175 00176 // Do some more processing here: Generate a tile that can be used as a 00177 // background tile for the rectangle "rect". 00178 00179 //Check for origin off screen 00180 QPoint origin(0, 0); 00181 if( d->rect.topLeft().x() < 0 || d->rect.topLeft().y() < 0 ) { 00182 //Save the offset and relocate the rect corners 00183 QPoint tl = d->rect.topLeft(); 00184 QPoint br = d->rect.bottomRight(); 00185 if( tl.x() < 0 ) { 00186 origin.setX( abs( tl.x() ) ); 00187 tl.setX( 0 ); 00188 } 00189 if( tl.y() < 0 ) { 00190 origin.setY( abs( tl.y() ) ); 00191 tl.setY( 0 ); 00192 } 00193 QRect adjustedRect( tl, br ); 00194 d->rect = adjustedRect; 00195 } 00196 00197 unsigned w = d->rect.width(), h = d->rect.height(); 00198 unsigned tw = QMIN(width, w), th = QMIN(height, h); 00199 unsigned xa = d->rect.x() % width, ya = d->rect.y() % height; 00200 unsigned t1w = QMIN(width-xa,tw), t1h = QMIN(height-ya,th); 00201 00202 QPixmap::resize( tw+origin.x(), th+origin.y() ); 00203 00204 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00205 xa, ya, t1w+origin.x(), t1h+origin.y(), origin.x(), origin.y() ); 00206 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00207 0, ya, tw-t1w, t1h, t1w, 0); 00208 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00209 xa, 0, t1w, th-t1h, 0, t1h); 00210 XCopyArea(qt_xdisplay(), *pixmap_id, ((KPixmap*)this)->handle(), qt_xget_temp_gc(qt_xscreen(), false), 00211 0, 0, tw-t1w, th-t1h, t1w, t1h); 00212 00213 XFree(pixmap_id); 00214 00215 d->selection = None; 00216 XDeleteProperty(qt_xdisplay(), winId(), ev->property); 00217 emit done(true); 00218 return true; 00219 } 00220 00221 00222 #include "ksharedpixmap.moc" 00223 #endif
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:40:34 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003