Quantcast
Channel: Active questions tagged ubuntu - Stack Overflow
Viewing all articles
Browse latest Browse all 5962

How can I capture XDND information while dragging files between different directories in unbuntu

$
0
0

I wrote a demo to capture XDND type messages for dragging files between folders in UBUNTU22.04. But I found that even though I set the mask for all message types, I still couldn't catch messages from the Client Message type when I was dragging files from one directory to another.

Here is my code, which can be compiled directly from Downloads folder(It`s Important as I implied based on the folder , see it in my code :D ) to others on uruntu22-64bits

#include <limits.h>#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <pthread.h>#include <X11/Xlib.h>#include <X11/Xresource.h>#include <X11/Xutil.h>#include <X11/Xatom.h>#include <X11/X.h>//-----------------------------------------------------------------------------typedef unsigned int ATOM;#define Bool int#define Status int#define True 1#define False 0#define TRUE 1#define FALE 0static  Atom      XdndVersion= (Atom)3;static  Atom      XdndAware;static  Atom      XdndSelection;static  Atom      XdndEnter;static  Atom      XdndLeave;static  Atom      XdndPosition;static  Atom      XdndDrop;static  Atom      XdndFinished;static  Atom      XdndStatus;static  Atom      XdndActionCopy;static  Atom      XdndActionMove;static  Atom      XdndActionLink;static  Atom      XdndActionAsk;static  Atom      XdndActionPrivate;static  Atom      XdndTypeList;static  Atom      XdndTextUriList;static  Atom      XdndSelectionAtom;static  Window    xdndSourceWindow= 0;static  Atom     *xdndTypeList= 0;static  int   xdndWillAccept= 0;#define xdndEnter_sourceWindow(evt)     ( (evt)->data.l[0])#define xdndEnter_version(evt)          ( (evt)->data.l[1] >> 24)#define xdndEnter_hasThreeTypes(evt)        (((evt)->data.l[1] & 0x1UL) == 0)#define xdndEnter_typeAt(evt, idx)      ( (evt)->data.l[2 + (idx)])#define xdndPosition_sourceWindow(evt)      ((Window)((evt)->data.l[0]))#define xdndPosition_rootX(evt)         ((evt)->data.l[2] >> 16)#define xdndPosition_rootY(evt)         ((evt)->data.l[2] & 0xffffUL)#define xdndPosition_action(evt)        ((Atom)((evt)->data.l[4]))#define xdndStatus_targetWindow(evt)        ((evt)->data.l[0])#define xdndStatus_setWillAccept(evt, b)    ((evt)->data.l[1]= (((evt)->data.l[1] & ~1UL) | ((b) ? 1 : 0)))#define xdndStatus_setWantPosition(evt, b)  ((evt)->data.l[1]= (((evt)->data.l[1] & ~2UL) | ((b) ? 2 : 0)))#define xdndStatus_action(evt)          ((evt)->data.l[4])#define xdndDrop_sourceWindow(evt)      ((Window)((evt)->data.l[0]))#define xdndDrop_time(evt)          ((evt)->data.l[2])#define xdndFinished_targetWindow(evt)      ((evt)->data.l[0])enum XdndState {  XdndStateIdle,  XdndStateEntered,  XdndStateTracking};static enum XdndState xdndState= XdndStateIdle;struct xdndatom {  Atom  atom;  char *name;}; struct FullLinuxWindowAttributes{    unsigned int sizeof_FullLinuxWindowAttributes;    char windowName[512];    int root_x_return;    int root_y_return;    int win_x_return;    int win_y_return;    char typeof_currentX11Window[32];    char* currentX11Window;    unsigned int sizeof_CurrentX11Window;    char typeof_xWindowAttributes[32];    char* xWindowAttributes;    unsigned int sizeof_xWindowAttributes;    char attributes[2048][32];    char reservedData[512]; };static struct xdndatom xdndatoms[] = {  { 0, "XdndAware"                },  { 0, "XdndSelection"            },  { 0, "XdndEnter"                },  { 0, "XdndLeave"                },  { 0, "XdndPosition"             },  { 0, "XdndDrop"                 },  { 0, "XdndFinished"             },  { 0, "XdndStatus"               },  { 0, "XdndActionCopy"           },  { 0, "XdndActionMove"           },  { 0, "XdndActionLink"           },  { 0, "XdndActionAsk"            },  { 0, "XdndActionPrivate"        },  { 0, "XdndTypeList"             },  { 0, "XdndActionList"           },  { 0, "XdndActionDescription"    },  { 0, "text/uri-list"            },  { 0, "UTF8_STRING"              },  { 0, "COMPOUND_TEXT"            },  { 0, "TEXT"                     },  { 0, "STRING"                   },  { 0, "text/plain;charset=utf-8" },  { 0, "text/plain"               }};char** uxDropFileNames;static  Atom      XdndTypeList;static  Atom      XdndTextUriList;  Display* stDisplay ;   Window stParent;void dndInitialise(void){  XdndAware=         XInternAtom(stDisplay, "XdndAware", False);  XdndSelection=     XInternAtom(stDisplay, "XdndSelection", False);  XdndEnter=         XInternAtom(stDisplay, "XdndEnter", False);  XdndLeave=         XInternAtom(stDisplay, "XdndLeave", False);  XdndPosition=      XInternAtom(stDisplay, "XdndPosition", False);  XdndDrop=      XInternAtom(stDisplay, "XdndDrop", False);  XdndFinished=      XInternAtom(stDisplay, "XdndFinished", False);  XdndStatus=        XInternAtom(stDisplay, "XdndStatus", False);  XdndActionCopy=    XInternAtom(stDisplay, "XdndActionCopy", False);  XdndActionMove=    XInternAtom(stDisplay, "XdndActionMove", False);  XdndActionLink=    XInternAtom(stDisplay, "XdndActionLink", False);  XdndActionAsk=     XInternAtom(stDisplay, "XdndActionAsk", False);  XdndActionPrivate=     XInternAtom(stDisplay, "XdndActionPrivate", False);  XdndTypeList=      XInternAtom(stDisplay, "XdndTypeList", False);  XdndTextUriList=   XInternAtom(stDisplay, "text/uri-list", False);  XdndSelectionAtom=     XInternAtom(stDisplay, "XdndSqueakSelection", False);  XChangeProperty(stDisplay, stParent, XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char *)&XdndVersion, 1);}static const char *xdnd_get_atom_name(Atom atom){  int i;  char *name = "Unregistered Xdnd Atom";  for(i = 0; i < sizeof(xdndatoms) / sizeof(struct xdndatom); i++)  {    if(xdndatoms[i].atom == atom)    {      name = xdndatoms[i].name;      break;    }  }  return name;}static void *xcalloc(size_t nmemb, size_t size){  void *ptr= calloc(nmemb, size);  if (!ptr)    {      fprintf(stderr, "out of memory\n");      exit(1);    }  return ptr;}static void dndGetTypeList(XClientMessageEvent *evt){    if(!stDisplay)        return ;    if (xdndTypeList)    {        free(xdndTypeList);        xdndTypeList= 0;    }  xdndWillAccept= 0;    if (xdndEnter_hasThreeTypes(evt))    {        int i;        printf("  3 types\n");        xdndTypeList= (Atom *)xcalloc(3 + 1, sizeof(Atom));        for (i= 0;  i <  3;  ++i)            xdndTypeList[i]= xdndEnter_typeAt(evt, i);        xdndTypeList[3]= 0;    }    else    {        Atom type, *atoms;        int format;        unsigned long i, count, remaining;        unsigned char *data= 0;        XGetWindowProperty(stDisplay, xdndSourceWindow, XdndTypeList, 0, 0x8000000L, False, XA_ATOM,&type, &format, &count, &remaining, &data);        if ((type != XA_ATOM) || (format != 32) || (count == 0) || !data)        {        if (data) XFree(data);        fprintf(stderr, "XGetWindowProperty failed in xdndGetTypeList\n");        return;        }        xdndTypeList= (Atom *)xcalloc(count + 1, sizeof(Atom));        atoms= (Atom *)data;        for (i= 0;  i < count;  ++i)            xdndTypeList[i]= atoms[i];        xdndTypeList[count]= 0;        XFree(data);        printf("  %ld types\n", count);    }  /* We only accept filenames (MIME type "text/uri-list"). */    {        int i;        for (i= 0;  xdndTypeList[i];  ++i)        {            printf("  type %d == %ld %s\n", i, xdndTypeList[i], XGetAtomName(stDisplay, xdndTypeList[i]));            if (XdndTextUriList == xdndTypeList[i])                xdndWillAccept= 1;        }    }}static void dndEnter(XClientMessageEvent *evt){  printf( "dndEnter\n");  if (xdndEnter_version(evt) < 3)    {      fprintf(stderr, "xdnd: protocol version %ld not supported\n", xdndEnter_version(evt));      return;    }  Window xdndSourceWindow= xdndEnter_sourceWindow(evt);  dndGetTypeList(evt);  xdndState= XdndStateEntered;}static void dndSendFinished(Window target){    XClientMessageEvent evt;    memset (&evt, 0, sizeof(evt));    evt.type         = ClientMessage;    evt.display      = stDisplay;    evt.window       = xdndSourceWindow;    evt.message_type = XdndFinished;    evt.format       = 32;    xdndFinished_targetWindow(&evt)= target;    XSendEvent(stDisplay, xdndSourceWindow, 0, 0, (XEvent *)&evt);    printf( "sent finished to %ld\n", xdndSourceWindow);}static void dndLeave(XClientMessageEvent *evt){    printf("dndLeave\n");    //recordDragEvent(DragLeave, 1);    xdndState= XdndStateIdle;}static void dndGetSelection(Window owner, Atom property){    unsigned long remaining;    unsigned char *data= 0;    Atom actual;    int format;    unsigned long count;    if (Success != XGetWindowProperty(stDisplay, owner, property, 0, 65536, 1, AnyPropertyType,&actual, &format, &count, &remaining, &data))        fprintf(stderr, "dndGetSelection: XGetWindowProperty failed\n");    else if (remaining)        /* a little violent perhaps */        fprintf(stderr, "dndGetSelection: XGetWindowProperty has more than 64K (why?)\n");    else    {        char *tokens= data;        char *item= 0;        while ((item= strtok(tokens, "\n\r")))        {            printf("got URI <%s>\n", item);            if (!strncmp(item, "file:", 5))     /*** xxx BOGUS -- just while image is broken ***/            {            /* if (uxDropFileCount)                uxDropFileNames= (char **)xrealloc(uxDropFileNames, (uxDropFileCount + 1) * sizeof(char *));            else                uxDropFileNames= (char **)xcalloc(1, sizeof(char *));                uxDropFileNames[uxDropFileCount++]= uri2string(item);*/            }        tokens= 0;        }        //if (uxDropFileCount)                //recordDragEvent(DragDrop, uxDropFileCount);        //printf("+++ DROP %d\n", uxDropFileCount);    }    XFree(data);}int dndHandleSelectionNotify(XSelectionEvent *evt){  if (evt->property == XdndSelectionAtom)    {      dndGetSelection(evt->requestor, evt->property);      dndSendFinished(evt->requestor);      dndLeave((XClientMessageEvent *)evt);      return 1;    }  return 0;}int dndHandleClientMessage(XClientMessageEvent *evt){    int handled= 1;    Atom type= evt->message_type;    printf("dndHandleClientMessage\n");    if(type == XdndEnter)    dndEnter(evt);    /*else if (type == XdndPosition) dndPosition(evt);    else if (type == XdndDrop)   dndDrop(evt);    else if (type == XdndLeave)  dndLeave(evt);*/    else     handled= 0;    return handled;}static void run(Window checkWindow){    while (1)    {        XEvent evt;        long event_mask= ButtonPressMask | ButtonReleaseMask                        | KeyPressMask | KeyReleaseMask                        | PointerMotionMask                        | EnterWindowMask | LeaveWindowMask | ExposureMask;        event_mask = 0x00ffffff;        XSelectInput(stDisplay,checkWindow,event_mask);        XWindowEvent (stDisplay,checkWindow, event_mask,&evt);        printf ("evt.type: %d\n",evt.type);        switch (evt.type)        {            case MotionNotify:  printf("MotionNotify\n");           break;            case EnterNotify:   printf("EnterNotify\n");            break;            case LeaveNotify:   printf("LeaveNotify\n");            break;            case ButtonPress:   printf("ButtonPress\n");            break;            case ButtonRelease: printf("ButtonRelease\n");          break;            case KeyPress:      printf("KeyPress\n");               break;            case KeyRelease:    printf("KeyRelease\n");             break;            case SelectionClear:    printf("SelectionClear\n");         break;            case SelectionRequest:  printf("SelectionRequest\n");           break;            case PropertyNotify:    printf("PropertyNotify\n");         break;            case Expose:        printf("Expose\n");             break;            case MapNotify:     printf("MapNotify\n");              break;            case UnmapNotify:   printf("UnmapNotify\n");            break;            case ConfigureNotify:   printf("ConfigureNotify\n");            break;            case MappingNotify: printf("MappingNotify\n");          break;            case ClientMessage:             {                printf("ClientMessage\n");                  dndHandleClientMessage(&evt.xclient);                       break;            }            case SelectionNotify:               {                printf("SelectionNotify\n");                    dndHandleSelectionNotify(&evt.xselection);                  break;            }            default:        printf("unknown event type %d\n", evt.type);    break;        }    }}int get_linux_window_info(struct FullLinuxWindowAttributes* outPutAttributes){    int root_x_return;    int root_y_return;    int win_x_return;    int win_y_return;    int returnValue= 0;    //Display* stDisplay = XOpenDisplay(NULL);     if(!stDisplay)        return -1;    XWindowAttributes xWindowAttributes;    Window w;    Window root_window = DefaultRootWindow(stDisplay);    Window root_return;    Window parent_return;    Window child_window;    Window* child_window_spec = NULL;    ATOM XdndPositionAtom ;    ATOM XdndDropAtom ;    ATOM XdndActionCopyAtom ;    ATOM XdndStatusAtom ;    ATOM XdndFinishedAtom;    ATOM XdndAware;    XEvent event;    unsigned long type, len, remain =0;    int form = 0;    unsigned char *listAttribute;    unsigned int windowNum = 0;    unsigned int mask;    if(outPutAttributes)        outPutAttributes = malloc(sizeof(XWindowAttributes));    if(!outPutAttributes)        return -1;    returnValue = XQueryPointer(stDisplay, root_window, &root_window, &child_window, \&root_x_return, &root_y_return, \&win_x_return, &win_y_return, &mask);    returnValue = XQueryTree(stDisplay, root_window, &root_window, &parent_return, &child_window_spec, &windowNum);    if(windowNum>0)    {        for(unsigned int i = 0; i < windowNum; ++i)         {            XGetWindowAttributes(stDisplay, child_window_spec[i], &xWindowAttributes);            if (xWindowAttributes.map_state == 2)             { // IsViewable                char* buffer = NULL;                //                 XFetchName(stDisplay, child_window_spec[i], &buffer);                //                 printf("# %d :(attrs.x %d : attrs.y %d attrs.width %d , attrs.height %d ) name %s \n", \                            i , xWindowAttributes.x , xWindowAttributes.y ,  \                            xWindowAttributes.width , xWindowAttributes.height , buffer) ;                //                 outPutAttributes->sizeof_FullLinuxWindowAttributes = sizeof(struct FullLinuxWindowAttributes);                if(buffer)                     memcpy(outPutAttributes->windowName,buffer,strlen(buffer));                outPutAttributes->root_x_return = root_x_return;                outPutAttributes->root_y_return = root_y_return;                outPutAttributes->win_x_return = win_x_return;                outPutAttributes->win_y_return = win_y_return;                strcpy(outPutAttributes->typeof_currentX11Window,"Window");                memcpy(&(outPutAttributes->currentX11Window),&child_window_spec[i],sizeof(Window) );                outPutAttributes->sizeof_CurrentX11Window = sizeof(Window);                strcpy(outPutAttributes->typeof_xWindowAttributes,"XWindowAttributes");                memcpy(&(outPutAttributes->xWindowAttributes),&xWindowAttributes,sizeof(XWindowAttributes) );                outPutAttributes->sizeof_xWindowAttributes = sizeof(XWindowAttributes);                XdndAware = XInternAtom(stDisplay, "XdndAware", True);                /*XdndPositionAtom = XInternAtom(stDisplay, "XdndPosition", True);                XdndDropAtom = XInternAtom(stDisplay, "XdndDrop", True);                XdndActionCopyAtom = XInternAtom(stDisplay, "XdndActionCopy", True);                XdndStatusAtom = XInternAtom(stDisplay, "XdndStatus", True);                XdndFinishedAtom = XInternAtom(stDisplay, "XdndFinished", True);*/                /*xclipboard*/                if(buffer==NULL)                    continue;                if(strcmp(buffer,"Downloads")==0)                {                    int result =  XGetWindowProperty( stDisplay, child_window_spec[i], XdndAware,                            0, 65535, False, AnyPropertyType, &type, &form, &len, &remain,&listAttribute );                       if(type != None && result== Success)                    {                        result =  XGetWindowProperty( stDisplay, child_window_spec[i], XdndAware,                            0, remain, False, AnyPropertyType, &type, &form, &len, &remain,&listAttribute );                        if(type != None && result== Success)                        {                            printf("type %ld, form %d, len %ld, remain %ld \n",type, form, len, remain);                             ATOM tempAtom ;                            memcpy (&tempAtom,listAttribute,4);                            tempAtom = tempAtom & 0xFF;                            printf("tempAtom %lu\n",(unsigned long)tempAtom);                            /*char* tempAtomName = XGetAtomName(stDisplay,tempAtom);                            if(tempAtomName)                            printf("tempAtomName %s \n",tempAtomName); */                            run(child_window_spec[i]);                        }                     }                }                XFree(buffer);            }        }    }    return 0;}int select_file(){    struct FullLinuxWindowAttributes outPutAttributes;    get_linux_window_info(&outPutAttributes);}void main(){    stDisplay = XOpenDisplay(NULL);     stParent = DefaultRootWindow(stDisplay);    dndInitialise();    {        //run(stParent);        struct FullLinuxWindowAttributes outPutAttributes;        get_linux_window_info(&outPutAttributes);    }    //select_file();}

Viewing all articles
Browse latest Browse all 5962

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>