~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to Gui/wm/wsxdnd.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Took WindowMaker implementation and adopted for MPlayer */
 
2
 
 
3
 
 
4
#include <X11/Xlib.h>
 
5
#include "ws.h"
 
6
#include "wsxdnd.h"
 
7
 
 
8
#include <stdio.h>
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
 
 
12
#include <X11/Xatom.h>
 
13
 
 
14
#include "../mp_msg.h"
 
15
#include "../help_mp.h"
 
16
 
 
17
#define XDND_VERSION 3L
 
18
 
 
19
Atom _XA_XdndAware;
 
20
Atom _XA_XdndEnter;
 
21
Atom _XA_XdndLeave;
 
22
Atom _XA_XdndDrop;
 
23
Atom _XA_XdndPosition;
 
24
Atom _XA_XdndStatus;
 
25
Atom _XA_XdndActionCopy;
 
26
Atom _XA_XdndSelection;
 
27
Atom _XA_XdndFinished;
 
28
Atom _XA_XdndTypeList;
 
29
 
 
30
Atom atom_support;
 
31
 
 
32
void wsXDNDInitialize()
 
33
{
 
34
 
 
35
    _XA_XdndAware = XInternAtom(wsDisplay, "XdndAware", False);
 
36
    _XA_XdndEnter = XInternAtom(wsDisplay, "XdndEnter", False);
 
37
    _XA_XdndLeave = XInternAtom(wsDisplay, "XdndLeave", False);
 
38
    _XA_XdndDrop = XInternAtom(wsDisplay, "XdndDrop", False);
 
39
    _XA_XdndPosition = XInternAtom(wsDisplay, "XdndPosition", False);
 
40
    _XA_XdndStatus = XInternAtom(wsDisplay, "XdndStatus", False);
 
41
    _XA_XdndActionCopy = XInternAtom(wsDisplay, "XdndActionCopy", False);
 
42
    _XA_XdndSelection = XInternAtom(wsDisplay, "XdndSelection", False);
 
43
    _XA_XdndFinished = XInternAtom(wsDisplay, "XdndFinished", False);
 
44
    _XA_XdndTypeList = XInternAtom(wsDisplay, "XdndTypeList", False);
 
45
}
 
46
 
 
47
void wsXDNDMakeAwareness(wsTWindow* window) {
 
48
    long int xdnd_version = XDND_VERSION;
 
49
    XChangeProperty (wsDisplay, window->WindowID, _XA_XdndAware, XA_ATOM,
 
50
            32, PropModeAppend, (char *)&xdnd_version, 1);
 
51
}
 
52
 
 
53
void wsXDNDClearAwareness(wsTWindow* window) {
 
54
    XDeleteProperty (wsDisplay, window->WindowID, _XA_XdndAware);
 
55
}
 
56
 
 
57
#define MAX_DND_FILES 64
 
58
Bool
 
59
wsXDNDProcessSelection(wsTWindow* wnd, XEvent *event)
 
60
{
 
61
    Atom ret_type;
 
62
    int ret_format;
 
63
    unsigned long ret_items;
 
64
    unsigned long remain_byte;
 
65
    char * delme;
 
66
    XEvent xevent;
 
67
 
 
68
    Window selowner = XGetSelectionOwner(wsDisplay,_XA_XdndSelection);
 
69
 
 
70
    XGetWindowProperty(wsDisplay, event->xselection.requestor,
 
71
            event->xselection.property,
 
72
            0, 65536, True, atom_support, &ret_type, &ret_format,
 
73
            &ret_items, &remain_byte, (unsigned char **)&delme);
 
74
 
 
75
    /*send finished*/
 
76
    memset (&xevent, 0, sizeof(xevent));
 
77
    xevent.xany.type = ClientMessage;
 
78
    xevent.xany.display = wsDisplay;
 
79
    xevent.xclient.window = selowner;
 
80
    xevent.xclient.message_type = _XA_XdndFinished;
 
81
    xevent.xclient.format = 32;
 
82
    XDND_FINISHED_TARGET_WIN(&xevent) = wnd->WindowID;
 
83
    XSendEvent(wsDisplay, selowner, 0, 0, &xevent);
 
84
 
 
85
    if (!delme){
 
86
      mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_WS_DDNothing );
 
87
      return False;
 
88
    }
 
89
 
 
90
    {
 
91
      /* Handle dropped files */
 
92
      char * retain = delme;
 
93
      char * files[MAX_DND_FILES];
 
94
      int num = 0;
 
95
 
 
96
      while(retain < delme + ret_items) {
 
97
        if (!strncmp(retain,"file:",5)) {
 
98
          /* add more 2 chars while removing 5 is harmless */
 
99
          retain+=5;
 
100
        }
 
101
 
 
102
        /* add the "retain" to the list */
 
103
        files[num++]=retain;
 
104
 
 
105
 
 
106
        /* now check for special characters */
 
107
        {
 
108
          int newone = 0;
 
109
          while(retain < (delme + ret_items)){
 
110
            if(*retain == '\r' || *retain == '\n'){
 
111
              *retain=0;
 
112
              newone = 1;
 
113
            } else {
 
114
              if (newone)
 
115
                break;
 
116
            }
 
117
            retain++;
 
118
          }
 
119
        }
 
120
 
 
121
        if (num >= MAX_DND_FILES)
 
122
          break;
 
123
      }
 
124
        
 
125
      /* Handle the files */
 
126
      if(wnd->DandDHandler){
 
127
        wnd->DandDHandler(num-1,files);
 
128
      }
 
129
    }
 
130
 
 
131
    free(delme);
 
132
    return True;
 
133
}
 
134
 
 
135
Bool
 
136
wsXDNDProcessClientMessage(wsTWindow* wnd, XClientMessageEvent *event)
 
137
{
 
138
  /* test */
 
139
  /*{
 
140
    char * name = XGetAtomName(wsDisplay, event->message_type);
 
141
    printf("Got %s\n",name);
 
142
    XFree(name);
 
143
    }*/
 
144
 
 
145
  if (event->message_type == _XA_XdndEnter) {
 
146
    Atom ok = XInternAtom(wsDisplay, "text/uri-list", False);
 
147
    atom_support = None;
 
148
    if ((event->data.l[1] & 1) == 0){
 
149
      int index;
 
150
      for(index = 0; index <= 2 ; index++){
 
151
        if (event->data.l[2+index] == ok) {
 
152
          atom_support = ok;
 
153
        }
 
154
      }
 
155
      if (atom_support == None) {
 
156
        mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_WS_NotAFile );
 
157
      }
 
158
    } else {
 
159
      /* need to check the whole list here */
 
160
      unsigned long ret_left = 1;
 
161
      int offset = 0;
 
162
      Atom* ret_buff;
 
163
      Atom ret_type;
 
164
      int ret_format;
 
165
      unsigned long ret_items;
 
166
 
 
167
      /* while there is data left...*/
 
168
      while(ret_left && atom_support == None){
 
169
        XGetWindowProperty(wsDisplay,event->data.l[0],_XA_XdndTypeList,
 
170
                           offset,256,False,XA_ATOM,&ret_type,
 
171
                           &ret_format,&ret_items,&ret_left,
 
172
                           (unsigned char**)&ret_buff);
 
173
        
 
174
        /* sanity checks...*/
 
175
        if(ret_buff == NULL || ret_type != XA_ATOM || ret_format != 8*sizeof(Atom)){
 
176
          XFree(ret_buff);
 
177
          break;
 
178
        }
 
179
        /* now chek what we've got */
 
180
        {
 
181
          int i;
 
182
          for(i=0; i<ret_items; i++){
 
183
            if(ret_buff[i] == ok){
 
184
              atom_support = ok;
 
185
              break;
 
186
            }
 
187
          }
 
188
        }
 
189
        /* maybe next time ... */
 
190
        XFree(ret_buff);
 
191
        offset += 256;
 
192
      }
 
193
    }
 
194
    return True;
 
195
  }
 
196
  
 
197
  if (event->message_type == _XA_XdndLeave) {
 
198
    return True;
 
199
  }
 
200
  
 
201
  if (event->message_type == _XA_XdndDrop) {
 
202
    if (event->data.l[0] != XGetSelectionOwner(wsDisplay, _XA_XdndSelection)){
 
203
      puts("Wierd selection owner... QT?");
 
204
    }
 
205
    if (atom_support != None) {
 
206
      XConvertSelection(wsDisplay, _XA_XdndSelection, atom_support,
 
207
                        _XA_XdndSelection, event->window,
 
208
                        CurrentTime);
 
209
    }
 
210
    return True;
 
211
  }
 
212
  
 
213
  if (event->message_type == _XA_XdndPosition) {
 
214
    Window srcwin = event->data.l[0];
 
215
    if (atom_support == None){
 
216
      return True;
 
217
    }
 
218
 
 
219
    /* send response */
 
220
    {
 
221
      XEvent xevent;
 
222
      memset (&xevent, 0, sizeof(xevent));
 
223
      xevent.xany.type = ClientMessage;
 
224
      xevent.xany.display = wsDisplay;
 
225
      xevent.xclient.window = srcwin;
 
226
      xevent.xclient.message_type = _XA_XdndStatus;
 
227
      xevent.xclient.format = 32; 
 
228
      
 
229
      XDND_STATUS_TARGET_WIN (&xevent) = event->window;
 
230
      XDND_STATUS_WILL_ACCEPT_SET (&xevent, True);
 
231
      XDND_STATUS_WANT_POSITION_SET(&xevent, True);
 
232
      /* actually need smth real here */
 
233
      XDND_STATUS_RECT_SET(&xevent, 0, 0, 1024,768);
 
234
      XDND_STATUS_ACTION(&xevent) = _XA_XdndActionCopy;
 
235
      
 
236
      XSendEvent(wsDisplay, srcwin, 0, 0, &xevent);
 
237
    }
 
238
    return True;
 
239
  }
 
240
  
 
241
  return False;
 
242
}