00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "config.h"
00015
00016 #include <tqrect.h>
00017 #include <tqsize.h>
00018 #include <tqstring.h>
00019 #include <tqpixmap.h>
00020 #include <tqwindowdefs.h>
00021 #include <tqwidget.h>
00022
00023 #ifdef Q_WS_X11
00024
00025 #include <tdeapplication.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 TDESharedPixmapPrivate
00056 {
00057 public:
00058 Atom pixmap;
00059 Atom target;
00060 Atom selection;
00061 TQRect rect;
00062 };
00063
00064 TDESharedPixmap::TDESharedPixmap()
00065 : TQWidget(0L, "shpixmap comm window")
00066 {
00067 d = new TDESharedPixmapPrivate;
00068 init();
00069 }
00070
00071
00072 TDESharedPixmap::~TDESharedPixmap()
00073 {
00074 delete d;
00075 }
00076
00077
00078 void TDESharedPixmap::init()
00079 {
00080 d->pixmap = XInternAtom(tqt_xdisplay(), "PIXMAP", false);
00081 TQCString atom;
00082 atom.sprintf("target prop for window %lx", static_cast<unsigned long int>(winId()));
00083 d->target = XInternAtom(tqt_xdisplay(), atom.data(), false);
00084 d->selection = None;
00085 }
00086
00087
00088 bool TDESharedPixmap::isAvailable(const TQString & name) const
00089 {
00090 TQString str = TQString("KDESHPIXMAP:%1").arg(name);
00091 Atom sel = XInternAtom(tqt_xdisplay(), str.latin1(), true);
00092 if (sel == None)
00093 return false;
00094 return XGetSelectionOwner(tqt_xdisplay(), sel) != None;
00095 }
00096
00097
00098 bool TDESharedPixmap::loadFromShared(const TQString & name, const TQRect & rect)
00099 {
00100 d->rect = rect;
00101 if (d->selection != None)
00102
00103 return false;
00104
00105 TQPixmap::resize(0, 0);
00106
00107 TQString str = TQString("KDESHPIXMAP:%1").arg(name);
00108 d->selection = XInternAtom(tqt_xdisplay(), str.latin1(), true);
00109 if (d->selection == None)
00110 return false;
00111 if (XGetSelectionOwner(tqt_xdisplay(), d->selection) == None)
00112 {
00113 d->selection = None;
00114 return false;
00115 }
00116
00117 XConvertSelection(tqt_xdisplay(), d->selection, d->pixmap, d->target,
00118 winId(), CurrentTime);
00119 return true;
00120 }
00121
00122
00123 bool TDESharedPixmap::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 unsigned char *pixmap_id = 0;
00145 Atom type;
00146
00147 XGetWindowProperty(tqt_xdisplay(), winId(), ev->property, 0, 1, false,
00148 d->pixmap, &type, &format, &nitems, &ldummy,
00149 &pixmap_id);
00150
00151 if (nitems != 1 || !pixmap_id)
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 void *drawable_id = (void *) pixmap_id;
00161 Drawable pixmap = *(Drawable*) drawable_id;
00162
00163 if (!XGetGeometry(tqt_xdisplay(), pixmap, &root, &dummy, &dummy, &width, &height, &udummy, &udummy)) {
00164 return false;
00165 }
00166
00167 if (d->rect.isEmpty())
00168 {
00169 TQPixmap::resize(width, height);
00170 XCopyArea(tqt_xdisplay(), pixmap, ((KPixmap*)this)->handle(), tqt_xget_temp_gc(tqt_xscreen(), false),
00171 0, 0, width, height, 0, 0);
00172
00173 XFree(pixmap_id);
00174 XDeleteProperty(tqt_xdisplay(), winId(), ev->property);
00175 d->selection = None;
00176 emit done(true);
00177 return true;
00178 }
00179
00180
00181
00182
00183
00184 TQPoint origin(0, 0);
00185 if( d->rect.topLeft().x() < 0 || d->rect.topLeft().y() < 0 ) {
00186
00187 TQPoint tl = d->rect.topLeft();
00188 TQPoint br = d->rect.bottomRight();
00189 if( tl.x() < 0 ) {
00190 origin.setX( abs( tl.x() ) );
00191 tl.setX( 0 );
00192 }
00193 if( tl.y() < 0 ) {
00194 origin.setY( abs( tl.y() ) );
00195 tl.setY( 0 );
00196 }
00197 TQRect adjustedRect( tl, br );
00198 d->rect = adjustedRect;
00199 }
00200
00201 unsigned w = d->rect.width(), h = d->rect.height();
00202 unsigned tw = TQMIN(width, w), th = TQMIN(height, h);
00203 unsigned xa = d->rect.x() % width, ya = d->rect.y() % height;
00204 unsigned t1w = TQMIN(width-xa,tw), t1h = TQMIN(height-ya,th);
00205
00206 TQPixmap::resize( tw+origin.x(), th+origin.y() );
00207
00208 XCopyArea(tqt_xdisplay(), pixmap, (static_cast<KPixmap*>(this))->handle(), tqt_xget_temp_gc(tqt_xscreen(), false),
00209 xa, ya, t1w+origin.x(), t1h+origin.y(), origin.x(), origin.y() );
00210 XCopyArea(tqt_xdisplay(), pixmap, (static_cast<KPixmap*>(this))->handle(), tqt_xget_temp_gc(tqt_xscreen(), false),
00211 0, ya, tw-t1w, t1h, t1w, 0);
00212 XCopyArea(tqt_xdisplay(), pixmap, (static_cast<KPixmap*>(this))->handle(), tqt_xget_temp_gc(tqt_xscreen(), false),
00213 xa, 0, t1w, th-t1h, 0, t1h);
00214 XCopyArea(tqt_xdisplay(), pixmap, (static_cast<KPixmap*>(this))->handle(), tqt_xget_temp_gc(tqt_xscreen(), false),
00215 0, 0, tw-t1w, th-t1h, t1w, t1h);
00216
00217 XFree(pixmap_id);
00218
00219 d->selection = None;
00220 XDeleteProperty(tqt_xdisplay(), winId(), ev->property);
00221 emit done(true);
00222 return true;
00223 }
00224
00225
00226 #include "ksharedpixmap.moc"
00227 #endif