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!kevinleif@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*/ }