Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 6 of 7
Finally, you need to ensure that the legacy application listens to the messages sent. In the main.c file, all the events concerning the legacy code proceed into the XtAppMainLoop() method. Fortunately, the XtAppAddInput() method lets you add a socket to the current event sources checked by XtAppMainLoop(). That socket is associated with a native callback method provided as an argument to XtAppAddInput(). That callback is built into the legacy application and called from the Xt main loop and therefore executed in the legacy application main thread. Depending on the message sent, the callback calls
the legacy method you want to execute.
Listing 5 illustrates the socket creation for the legacy application and the addition of that socket to the event source:
Listing 5: Add a datagram socket as an input source to XtAppMainLoop()
/** File main.c **/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <X11/Intrinsic.h>
#define IN_PORT 9970 /* Must be the same than outPort in SwingMenu.java */
int initInputSocket() {
int s;
struct sockaddr_in addIN;
/*
* Creating a socket for listening to the requests coming from the JVM.
*/
if ( (s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror ("initInputSocket: socket()");
exit(2);
}
addIN.sin_family = AF_INET;
addIN.sin_port = IN_PORT;
addIN.sin_addr.s_addr = INADDR_ANY;
if ( bind(s, (struct sockaddr *)&addIN, sizeof(addIN) ) < 0
) {
perror ("initInputSocket: bind()");
close(s);
exit(3);
}
return(s);
}
/*
* Function to proceed the packet received
*/
proceedJavaClientRequest(XtPointer clientData, int *socket, XtInputId *id)
{
ssize_t size;
char buf[256];
/*
* Note that when proceedJavaClientRequest() is called there is always something to read on the socket.
* Hence the call to recv() is not blocking.
*/
size = recv(*socket, buf, sizeof(buf), 0);
if ( strncmp("CreateOGLWindow", buf, size)==0 ) createOGLwindow(NULL);
if ( strncmp("Animate", buf, size)==0 ) toggleMotionFromJVM();
}
static XtAppContext app;
static String fallbackResources[] = {
"*title: Motif GUI.",
"*glxarea*width: 400", "*glxarea*height: 400", NULL
};
main (int argc, char *argv[])
{
int inputSocket;
Widget toplevel;
/*
* The main thread of the application will act as a datagram socket server.
* The JVM will be the client. This way the Java code will be able to call
* some native functions and make sure they are executed in the main thread.
*/
inputSocket = initInputSocket();
/*
* Create the top level shell.
*/
toplevel = XtVaAppInitialize(&app,
"SWING-MOTIF",
NULL,
0,
&argc,
argv,
fallbackResources,
NULL,0);
/*
* Adding our socket to the input sources checked by the Xtoolkit.
*/
XtAppAddInput(app, inputSocket, XtInputReadMask,
proceedJavaClientRequest, NULL);
/*
* Listen for events.
* This must be the only blocking call in the main thread.
*/
XtAppMainLoop(app);
}
You've browsed through many files throughout this article. I'll quickly summarize the source code required by the application presented here.