⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drag.cpp

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 CPP
字号:
/* This file is part of the KDE libraries    Copyright (C) 1997 Torben Weis (weis@kde.org)    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public License    along with this library; see the file COPYING.LIB.  If not, write to    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,    Boston, MA 02111-1307, USA.*//* * $Id: drag.cpp,v 1.1 2003/09/08 19:42:03 jasonk Exp $ *  * $Log: drag.cpp,v $ * Revision 1.1  2003/09/08 19:42:03  jasonk * Addition of packages directory and associated files. * * Revision 1.1.1.1  2003/08/07 21:18:32  jasonk * Initial import of PIXIL into new cvs repository. * * Revision 1.1.1.1  2003/06/23 22:04:23  jasonk * * * Revision 1.1.1.1  2000/07/07 16:10:58  jasonk * Initial import of ViewML * * Revision 1.24  1999/01/18 10:56:11  kulow * .moc files are back in kdelibs. Built fine here using automake 1.3 * * Revision 1.23  1999/01/15 09:30:29  kulow * it's official - kdelibs builds with srcdir != builddir. For this I * automocifized it, the generated rules are easier to maintain than * selfwritten rules. I have to fight with some bugs of this tool, but * generally it's better than keeping them updated by hand. * * Revision 1.22  1998/08/22 20:02:32  kulow * make kdecore have nicer output, when compiled with -Weffc++ :) * * Revision 1.21  1998/06/19 18:18:04  kalle * Cleaned up debugging messages * * This was my last change before KDE 1.0. * * Revision 1.20  1998/06/16 06:03:12  kalle * Implemented copy constructors and assignment operators or disabled them * * Revision 1.19  1998/03/09 20:21:52  kulow * just remove the dragZone from the dragZoneList, if kapp is still exist. * If this happens in the end of the application, big problems accour (the * reason, for many segfaults of applications at exit) * * Revision 1.18  1998/01/18 14:38:28  kulow * reverted the changes, Jacek commited. * Only the RCS comments were affected, but to keep them consistent, I * thought, it's better to revert them. * I checked twice, that only comments are affected ;) * * Revision 1.16  1997/11/04 11:00:30  kulow * fixed some free mismatch errors * * Revision 1.15  1997/10/21 20:44:40  kulow * removed all NULLs and replaced it with 0L or "". * There are some left in mediatool, but this is not C++ * * Revision 1.14  1997/10/16 11:14:26  torben * Kalle: Copyright headers * kdoctoolbar removed * * Revision 1.13  1997/10/12 11:05:32  kulow * don't export debugWin. kmenuedit used the same name * * Revision 1.12  1997/10/04 14:51:31  kulow * added some prototypes in case the shape.h is not found. I'm not sure, * if this works, but it helps for compiling * * Revision 1.11  1997/09/18 12:47:15  kulow * uups. The error message is not valid for the cpp file * * Revision 1.10  1997/09/18 12:16:03  kulow * corrected some header dependencies. Removed most of them in drag.h and put * them in drag.cpp. Now it should compile even under SunOS 4.4.1 ;) * * Revision 1.9  1997/08/31 08:03:47  kdecvs * Heureka: Fritz fixed the dragging of icons on the root window (Kalle) * * Revision 1.8  1997/07/31 19:52:31  kalle * Root-drop bug hopefully fixed (courtesy of Fritz Elfert of ISDN4Linux fame) * * Revision 1.7  1997/05/09 15:10:10  kulow * Coolo: patched ltconfig for FreeBSD * removed some stupid warnings * * Revision 1.6  1997/05/09 08:23:40  kulow * Coolo: included X11 headers again in drag.cpp (my fault) * * Revision 1.5  1997/05/08 22:53:15  kalle * Kalle: * KPixmap gone for good * Eliminated static objects from KApplication and HTML-Widget * * Revision 1.4  1997/05/08 21:09:44  kulow * Coolo: I forgot to include Torben's changes * * Revision 1.4  1997/03/10 19:59:12  kalle * Merged changes from 0.6.3 * * Revision 1.3  1997/01/15 20:01:58  kalle * merged changes from 0.52 * * Revision 1.2  1996/12/07 22:21:18  kalle * RCS header, include kapp.h * * * Drag 'n Drop implementation, taken from kfm * * Author: Torben Weis */#include "drag.h"#include <stdio.h>#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#ifdef STDC_HEADERS#include <stdlib.h>#endif#include <qlist.h>#include <qcursor.h>#include <qbitmap.h>#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# if HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif    #include "kapp.h"#include <X11/Xlib.h>#include <X11/Xatom.h>#include <X11/Xutil.h>#include <X11/Xos.h>#ifdef HAVE_X11_EXTENSTIONS_SHAPE_H#include <X11/extensions/shape.h>#elseextern "C" {void XShapeCombineMask(Display*, Window, int, int, int, Pixmap, int);#define ShapeBounding                   0 #define ShapeSet                        0 }#endifstatic Window debugWin = 0;KDNDDropZone::KDNDDropZone( QWidget* _parent, int _accept ) : QObject(){  widget = _parent;  acceptType = _accept;    kapp->addDropZone( this );}QWidget* KDNDDropZone::getWidget(){  return widget;}QStrList & KDNDDropZone::getURLList(){    return urlList;}void KDNDDropZone::parseURLList(){    urlList.clear();    if ( dndType != DndURL )	return;    QString s = dndData;    s.detach();    int i;        while ( ( i = s.find( "\n" ) ) != -1 )    {	QString t = s.left( i );	urlList.append( t.data() );	s = s.mid( i + 1, s.length() );    }        urlList.append( s.data() );}void KDNDDropZone::drop( char *_data, int _size, int _type, int _x, int _y ){  dndSize = _size;  dndType = _type;  dndData = _data;    dndX = _x;  dndY = _y;    parseURLList();  emit dropAction( this );}void KDNDDropZone::enter( char *_data, int _size, int _type, int _x, int _y ){  dndSize = _size;  dndType = _type;  dndData = _data;    dndX = _x;  dndY = _y;    parseURLList();  emit dropEnter( this );}void KDNDDropZone::leave(){  emit dropLeave( this );}KDNDDropZone::~KDNDDropZone(){  if (kapp)     kapp->removeDropZone( this );}void KDNDWidget::startDrag( KDNDIcon *_icon, char *_data, int _size, int _type, int _dx, int _dy ){  if ( dndData != 0 )     delete [] dndData ;    drag = true;      dndData = new char[ _size + 1 ];  memcpy( dndData, _data, _size );  dndData[ _size ] = 0;    dndSize = _size + 1;  dndType = _type;  dndIcon = _icon;  dndOffsetX = _dx;  dndOffsetY = _dy;    dndIcon->raise();    dndLastWindow = (Window)0;    Window root = DefaultRootWindow( kapp->getDisplay() );  XChangeProperty( kapp->getDisplay(), root, kapp->getDndSelectionAtom(), 				   XA_STRING, 8,				   PropModeReplace, (const unsigned char*)dndData, dndSize);    /* I commented this out, like mentioned by Paul Kendal (coolo)  // Commenting this out will only work with click on focus window managers  // grabMouse();  XGrabPointer(kapp->getDisplay(),root,False,			   ButtonMotionMask|ButtonPressMask|ButtonReleaseMask,			   GrabModeSync,GrabModeAsync,root,			   None,			   CurrentTime);*/  // KDNDApplication::setOverrideCursor( waitCursor );}Window KDNDWidget::findRootWindow( QPoint & p ){    int x,y;    Window root = DefaultRootWindow( kapp->getDisplay() );    Window win;    XTranslateCoordinates( kapp->getDisplay(), root, root, p.x(), p.y(), &x, &y, &win );    /*  Window root;  Window parent;  Window *children;  unsigned int cchildren;    int win = -1;  int win_x,win_y,win_h,win_w;    root = DefaultRootWindow( kapp->getDisplay() );    XQueryTree( kapp->getDisplay(), root, &root, &parent, 			  &children, &cchildren );    XWindowAttributes *attribs = new XWindowAttributes;    for ( int i = 0; i < cchildren; i++ )    {	  int x,y;	  unsigned int w,h,b,d;	  	  XGetGeometry( kapp->getDisplay(), children[i], &root, 					&x, &y, &w, &h, &b, &d );	  QRect r( x,y,w,h );	  	  if ( r.contains( p ) && children[i] != dndIcon->winId() )		{   		  XGetWindowAttributes( kapp->getDisplay(), children[i], attribs );		  		  if ( attribs->map_state != 0 )			{			  win = children[i];			  win_x = x;			  win_y = y;			  win_h = h;			  win_w = w;			}		}    }         delete attribs;  */  return win;}/** * @oldErrorHandler stores the original error handler. */staticint (* oldErrorHandler)(Display *, XErrorEvent *) = 0L;/** * Errorhandler to be used during DND */staticint myErrorHandler(Display *d, XErrorEvent *e){	char msg[80];	XGetErrorText(d, e->error_code, msg, 80);	//	fprintf(stderr, "Ignored Error: %s\n", msg);	//	fprintf(stderr, "Request: Maj=%d Min=%di, Serial=%08lx\n",	//		e->request_code, e->minor_code, e->serial);	return 0;}void KDNDWidget::mouseReleaseEvent( QMouseEvent * _mouse ){  if ( !drag )    {	  dndMouseReleaseEvent( _mouse );	  return;    }      // KDNDApplication::restoreOverrideCursor();  dndIcon->move( -200, -200 );  //   printf("************************************************************\n");//   printf("*** id = %i ****\n", dndIcon->winId());//   printf("************************************************************\n");  debugWin = dndIcon->winId();    QPoint p = mapToGlobal( _mouse->pos() );    Window root;  root = DefaultRootWindow( kapp->getDisplay() );    Window win = findRootWindow( p );//   printf("************************************************************\n");//   printf("*** win = %ld **** dndLastWindow = %ld ****\n", win, dndLastWindow );//   printf("************************************************************\n");    drag = false;/* I commented this out, since it works without (coolo)  // Commenting this out will only work with click on focus window managers  // releaseMouse();  XUngrabPointer(kapp->getDisplay(),CurrentTime);*///   printf("Ungarbbed\n");    // If we found a destination for the drop   if ( win != 0 )  // if ( dndLastWindow != 0 )    {	          XWindowAttributes Wattr;          XGetWindowAttributes(kapp->getDisplay(), win, &Wattr);          if (Wattr.map_state != IsUnmapped)          { // 	printf("Sending event\n");		      XEvent Event;	  	      Event.xclient.type              = ClientMessage;	      Event.xclient.display           = kapp->getDisplay();	      Event.xclient.message_type      = kapp->getDndProtocolAtom();	      Event.xclient.format            = 32;	      Event.xclient.window            = dndLastWindow;	      Event.xclient.data.l[0]         = dndType;	      Event.xclient.data.l[1]         = 0;	      Event.xclient.data.l[2]         = 0;	      Event.xclient.data.l[3]         = p.x();	      Event.xclient.data.l[4]         = p.y();              // Switch to "friendly" error handler.              if (oldErrorHandler == 0L)	          oldErrorHandler = XSetErrorHandler(myErrorHandler);// 	      printf("1\n");	      XSendEvent( kapp->getDisplay(), dndLastWindow, True, NoEventMask, &Event );	// 	      printf("2\n");	      XSync( kapp->getDisplay(), FALSE );	// 	      printf("3\n");	      (void) XSetErrorHandler(oldErrorHandler);              oldErrorHandler = 0L;          }	  delete [] dndData;	  dndData = 0L;    }   else   {//        printf("Root Drop Event\n");       rootDropEvent( p.x(), p.y() );   }  delete dndIcon;  dndIcon = 0L;     dragEndEvent();}void KDNDWidget::mouseMoveEvent( QMouseEvent * _mouse ){  if ( !drag )    {	  dndMouseMoveEvent( _mouse );	  return;    }      // dndIcon->hide();    // QPoint p = mapToGlobal( _mouse->pos() );  QPoint p = QCursor::pos();  /* Window root;  root = DefaultRootWindow( kapp->getDisplay() );    Window win = findRootWindow( p );  printf("Window = '%x'  %i %i\n",win,dndOffsetX,dndOffsetY);  printf("x=%i y=%i\n",p.x(),p.y()); */  QPoint p2( p.x(), p.y() );  p2.setX( p2.x() + dndOffsetX );  p2.setY( p2.y() + dndOffsetY );  dndIcon->move( p2 );  // dndIcon->show();}void KDNDWidget::rootDropEvent( int _x, int _y ){  Window root;  Window parent;  Window *children;  unsigned int cchildren;    //   printf("Root Window\n");  root = DefaultRootWindow( kapp->getDisplay() );//   printf("Query root tree\n");  // Switch to "friendly" error handler.  if (oldErrorHandler == 0L)      oldErrorHandler = XSetErrorHandler(myErrorHandler);  XQueryTree( kapp->getDisplay(), root, &root, &parent, &children, &cchildren );      for ( uint i = 0; i < cchildren; i++ )  {	if ( children[i] == debugWin ) {}// 	  printf("******************** root id = %ld *********************\n",children[i] );      else      {	  XEvent Event;      	  XWindowAttributes Wattr;	  XGetWindowAttributes(kapp->getDisplay(), children[i], &Wattr);	  if (Wattr.map_state == IsUnmapped)		continue; 	  Event.xclient.type              = ClientMessage;	  Event.xclient.display           = kapp->getDisplay();	  Event.xclient.message_type      = kapp->getDndRootProtocolAtom();	  Event.xclient.format            = 32;	  Event.xclient.window            = children[ i ];	  Event.xclient.data.l[0]         = dndType;	  Event.xclient.data.l[1]         = (long) time( 0L );	  Event.xclient.data.l[2]         = 0;	  Event.xclient.data.l[3]         = _x;	  Event.xclient.data.l[4]         = _y;	  XSendEvent( kapp->getDisplay(), children[ i ], True, NoEventMask, &Event);	  XSync( kapp->getDisplay(), FALSE );	      }  }      (void)XSetErrorHandler(oldErrorHandler);  oldErrorHandler = 0L;//   printf("Done\n");    // Clean up.  rootDropEvent();}void KDNDWidget::rootDropEvent(){  if ( dndIcon != 0L )	delete dndIcon;  dndIcon = 0L;    if ( dndData != 0L )	delete [] dndData;  dndData = 0L;}KDNDWidget::~KDNDWidget(){  if ( dndData != 0L )     delete [] dndData;}KDNDIcon::KDNDIcon( QPixmap &_pixmap, int _x, int _y ) :  QWidget( 0L, 0L, WStyle_Customize | WStyle_Tool | WStyle_NoBorder ){  pixmap = _pixmap;    setGeometry( _x, _y, _pixmap.width(), _pixmap.height() );  show();}KDNDIcon::KDNDIcon( const KDNDIcon& icon ) : QWidget(){  pixmap = icon.pixmap; // implicitly ref-counted}KDNDIcon& KDNDIcon::operator= ( const KDNDIcon& icon ){  if( this != &icon )	pixmap = icon.pixmap;  return *this;}void KDNDIcon::paintEvent( QPaintEvent * ) {  bitBlt( this, 0,0, &pixmap );}void KDNDIcon::resizeEvent( QResizeEvent * ){  if ( pixmap.mask() != 0L )	XShapeCombineMask( x11Display(), winId(), ShapeBounding, 0, 0, 					   pixmap.mask()->handle(), ShapeSet );}KDNDIcon::~KDNDIcon(){}#include "drag.moc"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -