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