Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!network!ucsd!hub!orange!dz From: dz@orange.ucsb.edu (Daniel James Zerkle) Newsgroups: comp.sys.next Subject: communication between programs with Speaker and Listener Keywords: speaker listener ipc port kernel preview Message-ID: <2220@hub.UUCP> Date: 17 Aug 89 16:41:26 GMT Sender: news@hub.UUCP Reply-To: dz@cornu.ucsb.edu (Daniel James Zerkle) Distribution: usa Organization: University of California, Santa Barbara Lines: 121 You know the way that Digital Librarian can communicate with WriteNow to display certain documents? Ever notice that the print panel does the same thing with Preview in many applications? I am trying to do something similar, but I am having no luck at all. I want to be able to send a message to Preview to display certain PostScript documents. I have not gotten this to work, so if anything I say is clearly wrong, let me know, as I may have some misconceptions. Anyway, this is what I understand so far: The standard way to do inter-process communication on a NeXT is with the Speaker and Listener objects. An application that wants to be able to receive messages from other programs to do such useful procedures as display or print files has a listener object that gets the messages and passes them off to some sort of delegate, which takes care of the actual work. Preview should have one of these objects. If a program wants to *send* messages to other programs, it has a Speaker object for each such program with which it wants to communicate. You message the Speaker when you want something interesting to happen at the other end. As I'm not familiar with the special features of Mach over UNIX, this part is where I'm a bit fuzzy. The Listener listens and the Speaker speaks over something called a "port". When a Listener object is started up, it creates the port and registers it with the Mach kernel. A program with a speaker object can find that port somehow by looking it up with the kernel. Once it is found, there is an object method to set that port as the one used. Anyway, this is the code given as a typical use of the Speaker object (this is in the documentation for Speaker): /*****************************/ SpeakerId = [Speaker new]; port = NXPortFromName("someapp",NULL); // get port for "someapp" if (port != PORT_NULL) [SpeakerId setSendPort:port]; ec = [SpeakerId openFile:"/usr/foo" ok:&returnOk]; // any method if (ec == 0) // fiddle with return results, like returnOk above [SpeakerId free] // when we quit /*****************************/ This is the code I made that is utterly failing to work: /*****************************/ - doDisplay:sender { printf("Displayer is messaged...\n"); [inputForm selectTextAt:0]; SpeakerId = [Speaker new]; port = NXPortFromName("/NextDeveloper/Demos/Preview",NULL); strcpy(dfile, [inputForm stringValueAt:0]); printf("File name is %s.\n",dfile); if (port != PORT_NULL) { printf("messaging the speaker\n"); [SpeakerId openFile:dfile ok:&returnOk]; } [SpeakerId free]; return self; } /*****************************/ This bit of code is obviously just to test things out. I'll clean up later. The assorted printf's (I don't grok gdb yet) show that the openFile method does not get called (the file name and all else seem correct). Thusly, port must in fact == PORT_NULL (whatever that is). The problem is, therefore, in the NXPortFromName() call. Unfortunately, I could find no online documentation anywhere for this call. The best I could do was the following line from /usr/include/appkit/Listener.h: extern port_t NXPortFromName(const char *portName, const char *hostName); Seeing "hostName", I tried changing the NULL to both "." and "pab" (our NeXT is christened "pab", and it isn't my fault). That had no effect whatsoever. These are some good questions to answer: 1. How do I get the proper port identification, when all I know is the name of the program I want to use? Will this work if I don't even have the full pathname? Should I use just the name and not the full path? 2a.Applications such as Digital Librarian and WriteNow (not to mention the Workspace Manager) will start up an application they need if it is not already started. Is this automatic, or do I need to do it myself upon receipt of some error saying that there is no port registered under the desired application's name? 2b.How do I get this error message? How do I know that the receiving program is ready (it may take awhile to start up)? 3. Who takes care of these sorts of things? Should I be talking to the Workspace Manager, or directly to the kernel? Is there more than one option? If so, what is better under which circumstances? 4. Will the documentation be any better under 1.0? It was rather a cheap shot to bring up NXPortFromName() and not have it documented anywhere. 5. Just what exactly do ports do? How do they do it? Chapter 15 of the technical manual talks about them but it is rather hard to follow. 6. Is there anything else I should know? Obviously, the most useful thing for me right now would be a little piece of Obj-C that would tell Preview what to do when I need it. If you can answer a couple of these questions, I'll probably be able to figure out the code for myself. (Just wish I had the source....) Many thanks (in advance, of course). May your family be blessed for generations to come if you actually figure this out. | Dan Zerkle home:(805) 968-4683 morning:961-2434 afternoon:687-0110 | | dz@cornu.ucsb.edu dz%cornu@ucsbuxa.bitnet ...ucbvax!hub!cornu!dz | | Snailmail: 6681 Berkshire Terrace #5, Isla Vista, CA 93117 | | Disclaimer: If it's wrong or stupid, pretend I didn't do it. |