Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

x11_dragdrop.cpp

00001 /*****************************************************************************
00002  * x11_dragdrop.cpp
00003  *****************************************************************************
00004  * Copyright (C) 2003 the VideoLAN team
00005  * $Id: x11_dragdrop.cpp 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Cyril Deguet     <[email protected]>
00008  *          Olivier Teulière <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 #ifdef X11_SKINS
00026 
00027 #include <X11/Xlib.h>
00028 #include <X11/Xatom.h>
00029 
00030 #include "x11_dragdrop.hpp"
00031 #include "x11_display.hpp"
00032 #include "x11_factory.hpp"
00033 #include "../commands/cmd_add_item.hpp"
00034 
00035 #include <string>
00036 #include <list>
00037 
00038 
00039 X11DragDrop::X11DragDrop( intf_thread_t *pIntf, X11Display &rDisplay,
00040                           Window win, bool playOnDrop ):
00041     SkinObject( pIntf ), m_rDisplay( rDisplay ), m_wnd( win ),
00042     m_playOnDrop( playOnDrop )
00043 {
00044 }
00045 
00046 
00047 void X11DragDrop::dndEnter( ldata_t data )
00048 {
00049     Window src = data[0];
00050 
00051     // Retrieve available data types
00052     list<string> dataTypes;
00053     if( data[1] & 1 )   // More than 3 data types ?
00054     {
00055         Atom type;
00056         int format;
00057         unsigned long nitems, nbytes;
00058         Atom *dataList;
00059         Atom typeListAtom = XInternAtom( XDISPLAY, "XdndTypeList", 0 );
00060         XGetWindowProperty( XDISPLAY, src, typeListAtom, 0, 65536, False,
00061                             XA_ATOM, &type, &format, &nitems, &nbytes,
00062                             (unsigned char**)&dataList );
00063         for( unsigned long i=0; i<nitems; i++ )
00064         {
00065             string dataType = XGetAtomName( XDISPLAY, dataList[i] );
00066             dataTypes.push_back( dataType );
00067         }
00068         XFree( (void*)dataList );
00069     }
00070     else
00071     {
00072         for( int i = 2; i < 5; i++ )
00073         {
00074             if( data[i] != None )
00075             {
00076                 string dataType = XGetAtomName( XDISPLAY, data[i] );
00077                 dataTypes.push_back( dataType );
00078             }
00079         }
00080     }
00081 
00082     // Find the right target
00083     m_target = None;
00084     list<string>::iterator it;
00085     for( it = dataTypes.begin(); it != dataTypes.end(); it++ )
00086     {
00087         if( *it == "text/plain" || *it == "STRING" )
00088         {
00089             m_target = XInternAtom( XDISPLAY, (*it).c_str(), 0 );
00090             break;
00091         }
00092     }
00093 }
00094 
00095 
00096 void X11DragDrop::dndPosition( ldata_t data )
00097 {
00098     Window src = data[0];
00099     Time time = data[2];
00100 
00101     Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 );
00102     Atom targetAtom = XInternAtom( XDISPLAY, "text/plain", 0 );
00103     Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 );
00104 
00105     Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
00106     Atom typeAtom = XInternAtom( XDISPLAY, "XdndFinished", 0 );
00107 
00108     // Convert the selection into the given target
00109     // NEEDED or it doesn't work!
00110     XConvertSelection( XDISPLAY, selectionAtom, targetAtom, propAtom, src,
00111                        time );
00112 
00113     actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
00114     typeAtom = XInternAtom( XDISPLAY, "XdndStatus", 0 );
00115 
00116     XEvent event;
00117     event.type = ClientMessage;
00118     event.xclient.window = src;
00119     event.xclient.display = XDISPLAY;
00120     event.xclient.message_type = typeAtom;
00121     event.xclient.format = 32;
00122     event.xclient.data.l[0] = m_wnd;
00123     if( m_target != None )
00124     {
00125         // Accept the drop
00126         event.xclient.data.l[1] = 1;
00127     }
00128     else
00129     {
00130         // Do not accept the drop
00131         event.xclient.data.l[1] = 0;
00132     }
00133     int w = X11Factory::instance( getIntf() )->getScreenWidth();
00134     int h = X11Factory::instance( getIntf() )->getScreenHeight();
00135     event.xclient.data.l[2] = 0;
00136     event.xclient.data.l[3] = (w << 16) | h;
00137     event.xclient.data.l[4] = actionAtom;
00138 
00139     // Tell the source whether we accept the drop
00140     XSendEvent( XDISPLAY, src, False, 0, &event );
00141 }
00142 
00143 
00144 void X11DragDrop::dndLeave( ldata_t data )
00145 {
00146 }
00147 
00148 
00149 void X11DragDrop::dndDrop( ldata_t data )
00150 {
00151     Window src = data[0];
00152     Time time = data[2];
00153 
00154     Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 );
00155     Atom targetAtom = XInternAtom( XDISPLAY, "text/plain", 0 );
00156     Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 );
00157 
00158     Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 );
00159     Atom typeAtom = XInternAtom( XDISPLAY, "XdndFinished", 0 );
00160 
00161     // Convert the selection into the given target
00162     XConvertSelection( XDISPLAY, selectionAtom, targetAtom, propAtom, src,
00163                        time );
00164 
00165     // Read the selection
00166     Atom type;
00167     int format;
00168     unsigned long nitems, nbytes;
00169     char *buffer;
00170     XGetWindowProperty( XDISPLAY, src, propAtom, 0, 1024, False,
00171                         AnyPropertyType, &type, &format, &nitems, &nbytes,
00172                         (unsigned char**)&buffer );
00173     string selection = "";
00174     if( buffer != NULL )
00175     {
00176         selection = buffer;
00177     }
00178     XFree( buffer );
00179 
00180     if( selection != "" )
00181     {
00182         // TODO: multiple files handling
00183         string::size_type end = selection.find( "\n", 0 );
00184         selection = selection.substr( 0, end - 1 );
00185         end = selection.find( "\r", 0 );
00186         selection = selection.substr( 0, end - 1 );
00187 
00188         // Find the protocol, if any
00189         string::size_type pos = selection.find( ":", 0 );
00190         if( selection.find( "
00191         {
00192             selection.erase( pos + 1, 2 );
00193         }
00194 
00195         char *psz_fileName = new char[selection.size() + 1];
00196         strncpy( psz_fileName, selection.c_str(), selection.size() + 1 );
00197 
00198         // Add the file
00199         CmdAddItem cmd( getIntf(), psz_fileName, m_playOnDrop );
00200         cmd.execute();
00201 
00202         delete[] psz_fileName;
00203     }
00204 
00205     // Tell the source we accepted the drop
00206     XEvent event;
00207     event.type = ClientMessage;
00208     event.xclient.window = src;
00209     event.xclient.display = XDISPLAY;
00210     event.xclient.message_type = typeAtom;
00211     event.xclient.format = 32;
00212     event.xclient.data.l[0] = m_wnd;
00213     event.xclient.data.l[1] = 1;            // drop accepted
00214     event.xclient.data.l[2] = actionAtom;
00215     XSendEvent( XDISPLAY, src, False, 0, &event );
00216 }
00217 
00218 #endif

Generated on Tue Dec 20 10:14:44 2005 for vlc-0.8.4a by  doxygen 1.4.2