kevin@drogges.tti.com (04/04/91)
Hi - Although this is primarily an OpenLook/XView question, I am circulating it to c.w.x hoping to get some illumination on InterClientCommunications. Does anyone have any idea as to what the protocol sequence is to send a filename for printing to the Sun Desktop "print tool" from a client OTHER than OpenLook's "file manager"? The sequence of events that I see (while running "xscope") that are generated by file manager are: 1. filemgr generates an "InternAtom" request for name: "FVDROP670614812" (this happens when I start "dragging" a filename glyph). returns Atom = 0xb6; 2. filemgr gets a set of "FocusOut" events. 3. filemgr does a "ChangeProperty" request to set Atom (0xb6) to the compleat pathname/filename string "/usr/kevin/abc.dat" 4. filemgr does a "GetSelectionOwner" request to (i assume) find out what window "owns" the glyph. 5. filemgr now generates another "InternAtom" request for name: "SELECTION_PROPERTY0". returns Atom = 0x76. (---IS THIS EVEN RELATED???---) 6. filemgr does a "ConvertSelection" request on Atom 0x75 to to type 0x76 ("_SUN_SELN_YIELD") (AGAIN; related??) 7. filemgr now generates ANOTHER "InternAtom" request for name: "_SUN_SELN_END_REQUEST". returns Atom = 0x7ce; 8. filemgr does a "GetSelectionOwner" request to find the window id of the owner of "XA_PRIMARY" (why? i have NO idea) 9. filemgr now generates "InternAtom" for name: "XV_DO_DRAG_LOAD". server returns 0xb2; 10. filemgr does a "SendEvent" call, using the win id of the print too as the destination in the XClientMessage. The data sent is: event->ie_xevent->xclient.data.l[0] = protocol (=0) event->ie_xevent->xclient.data.l[1] = timestamp event->ie_xevent->xclient.data.l[2] = serial no event->ie_xevent->xclient.data.l[3] = win id event->ie_xevent->xclient.data.l[4] = Atom # (XV_DO_DRAG_LOAD, = 0xb6 ...And at THIS point, "Printtool" magically starts printing the file. whew! Now MY question: does anybody know how I can DUPLICATE" the drag-n-drop protocol sequence above without actually *DOING* a drag-n-drop, such that printtool will act on the XClientMessage? Angst in Advance: -- Kevin Carothers {csun,psivax,philabs,retix}!ttidca!kevin
leif@winsoft.se (Leif Samuelsson) (04/07/91)
In article <25276@ttidca.TTI.COM> kevin@drogges.tti.com writes: >whew! Now MY question: > > does anybody know how I can DUPLICATE" the drag-n-drop protocol sequence above > without actually *DOING* a drag-n-drop, such that printtool will act on the > XClientMessage? I had the same need with PageView a while back and came up with the following program. It sends an ACTION_DRAG_LOAD event to the receiving application and passes on a filename. It is a bit kludgey and will most definitely not work on any version of OpenWindows other than 2.0. It can be used with other applications as well, the problem is just to find out which subwindow to send the message to. I suggest using xlswins for browsing. Does anyone know of an easier way of finding the id of the receiving window? ---- Leif Samuelsson Winsoft Data AB Phone: +46 8 7301240 Lidgatan 18 Fax: +46 8 7303102 S-171 58 SOLNA E-mail: leif@winsoft.se Sweden ----Cut---here---- /* * dragload.c -- Send an ACTION_DRAG_LOAD event to predefined application * * Only works with OpenWindows 2.0 * * Compile with: cc -o dragload dragload.c -lxview -lolgx -lX11 */ #include <xview/xview.h> #include <xview/seln.h> enum apptype { PageView, PrintTool }; enum apptype app = PrintTool; char *filename; static Seln_result request_proc(); static Window get_child_by_name(), get_nth_child(); main(argc, argv) int argc; char *argv[]; { Frame frame; Window window = 0; Window root, w; Display *dpy; Seln_client client; int data[4]; if (argc != 2) { fprintf(stderr, "Usage: %s filename\n", argv[0]); exit(1); } filename = argv[1]; /* Create a frame just to make XView happy */ frame = xv_create(0, FRAME, 0); dpy = (Display *)xv_get(frame, XV_DISPLAY); root = (Window)xv_get(xv_get(frame, XV_ROOT), XV_XID); /* Now find the window to send the event to */ switch (app) { case PageView: window = get_child_by_name(dpy, root, "PageView"); if (window) window = get_nth_child(dpy, window, 1); if (window) window = get_nth_child(dpy, window, 0); if (window) window = get_nth_child(dpy, window, 0); break; case PrintTool: window = get_child_by_name(dpy, root, "Print Tool"); if (window) window = get_nth_child(dpy, window, 0); break; default: fprintf(stderr, "%s: Unknown application.\n", argv[0]); exit(1); } if (!window) { fprintf(stderr, "%s: Can not talk to application.\n", argv[0]); exit(1); } /* Set up selection service */ client = seln_create(0, request_proc, &client); seln_acquire(client, SELN_PRIMARY); /* Send the event */ data[0] = window; data[3] = xv_get(frame, XV_XID); xv_send_message(frame, window, "XV_DO_DRAG_LOAD", 32, data, 16); notify_start(); } static Window get_child_by_name(dpy, w, name) /* Recursively search tree for win by name */ Display *dpy; Window w; char *name; { Window root, parent; Window *children; int i, nchildren; char *win_name; XQueryTree(dpy, w, &root, &parent, &children, &nchildren); for (i = 0; i < nchildren; i++) { w = children[i]; if (XFetchName(dpy, w, &win_name)) { if (!strcmp(win_name, name)) { XFree(win_name); XFree(children); return (w); } XFree(win_name); } w = get_child_by_name(dpy, w, name); /* recursive call */ if (w) { XFree(children); return (w); } } XFree(children); return ((Window)NULL); } static Window get_nth_child(dpy, w, i) /* Return child i of window w */ Display *dpy; Window w; int i; { Window root, parent; Window *children; int nchildren; XQueryTree(dpy, w, &root, &parent, &children, &nchildren); if (nchildren > i) w = children[i]; else w = (Window)NULL; XFree(children); return (w); } static Seln_result request_proc(attr, context, max_length) int attr; Seln_replier_data *context; int max_length; { int i; static char buf[256]; char *p; switch (attr) { case SELN_REQ_BYTESIZE: *context->response_pointer++ = (char *)strlen(filename); return SELN_SUCCESS; case SELN_REQ_CONTENTS_ASCII: strcpy(context->response_pointer, filename); context->response_pointer += strlen(filename) / 4; if ((strlen(filename) % 4) > 0) context->response_pointer++; *context->response_pointer++ = 0; /* Null terminate value */ return SELN_SUCCESS; case SELN_REQ_END_REQUEST: notify_stop(); return SELN_FAILED; case SELN_REQ_IS_READONLY: return SELN_FAILED; default: printf("request_proc 0x%x 0x%x %d\n", attr, context, max_length); fflush(stdout); return SELN_FAILED; } /*NOTREACHED*/ }