00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00052 list<string> dataTypes;
00053 if( data[1] & 1 )
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
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
00109
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
00126 event.xclient.data.l[1] = 1;
00127 }
00128 else
00129 {
00130
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
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
00162 XConvertSelection( XDISPLAY, selectionAtom, targetAtom, propAtom, src,
00163 time );
00164
00165
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
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
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