00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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>
00031
00032 #include <X11/Xlib.h>
00033
00034
00035
00036 #include <X11/Xutil.h>
00037 #ifdef HAVE_MITSHM
00038 #include <X11/extensions/XShm.h>
00039 #endif
00040
00041 #include <netwm.h>
00042
00043
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
00103 return false;
00104
00105 d->rect = rect;
00106 QPixmap::resize(0, 0);
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
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
00182
00183
00184
00185 QPoint origin(0, 0);
00186 if( d->rect.topLeft().x() < 0 || d->rect.topLeft().y() < 0 ) {
00187
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