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
#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>
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 d->rect = rect;
00102
if (d->selection != None)
00103
00104
return false;
00105
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 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
00178
00179
00180
00181
QPoint origin(0, 0);
00182
if( d->rect.topLeft().x() < 0 || d->rect.topLeft().y() < 0 ) {
00183
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