ipc.c


/*
   $Header: ipc.c,v 1.16 97/04/14 15:54:35 doomer Exp $
   $Revision: 1.16 $
   $Date: 97/04/14 15:54:35 $
   $Author: doomer $
   Copyright (c) 1997 John Dumais.  All rights reserved.
*/

#include "ipc.h"

/*
   This application builds a simple user interface with a bunch of
   buttons to illustrate our library capabilities.  The following array
   of strings defines the button labels.
*/

static char *buttonText[]={
	"Run",
	"Pause",
	"Step",
	"Cont",
	"F1",
	"Hide",
	"Iconize",
	"Restore",
	"Pid",
	"Quit",
};

/*
   A utility function to tell us how many buttons we have defined.
*/

int nButtons(){
	return(sizeof(buttonText)/sizeof(char *));
};

/*
   We might need to know the id for the process which created the
   VEE window we found.  When a VEE process is asked for its process
   id, it stores that id in an atom.
*/

static Atom wmPid=(Atom)0;

/*
   When a VEE process starts, it puts its window id in an atom.
   We read this atom to find a VEE window we can control.
*/

extern Atom wmVeeWindow;

/*
   Find the process id for the process that ceated our VEE window.
   We do this by first finding the VEE window id.  Once we do that,
   we instruct VEE to store its process id in an atom we have created
   in the sample application's window.

   When VEE starts, it places its process id in an atom identified by
   the variable wmVeeWindow.  To get VEE to tell us the pid, we tell it
   to make the atom available as an integer and put it in an atom we 
   define in our application window.  We do this using the X call
   XConvertSelection().
*/

void pid(widget, clientData, cbs)
Widget widget;
XtPointer clientData;
XmPushButtonCallbackStruct *cbs;{
   Window appWindow;
   Window aWindow;

   aWindow=findVeeWin(XtDisplay(widget));
   
   if(!aWindow){
      return;
   }

   appWindow=(Window)clientData;

   if(!wmPid){
      wmPid=XInternAtom(XtDisplay(widget), "WM_VEEPID", False);
   }   

   if(wmVeeWindow){
      XConvertSelection(XtDisplay(widget),
			wmVeeWindow,
			XA_INTEGER,
			wmPid,
			appWindow,
			XtLastTimestampProcessed(XtDisplay(widget)));
   }

   return;
}

/*
   When we ask VEE to tell us its process id, it responds by
   changing the value of the wmPid atom on our application
   window.  The changed value is the VEE process id.
*/

void veePid(anEvent)
XEvent *anEvent;{
   
   int actualFormat;
   Atom actualType;
   unsigned long nItems;
   unsigned long bytesAfter;
   unsigned char *propValue;
   int getPropResult;
   pid_t aPid;

   if(anEvent->xproperty.atom != wmPid){
      return;
   }

   getPropResult=XGetWindowProperty(anEvent->xproperty.display,
				    anEvent->xproperty.window,
				    wmPid,
				    0,
				    1,
				    True,
				    AnyPropertyType,
				    &actualType,
				    &actualFormat,
				    &nItems,
				    &bytesAfter,
				    &propValue);

   if(getPropResult != Success){
      return;
   }
   
   if(bytesAfter != 0){
      return;
   }

   if(actualType == XA_INTEGER){
      aPid = * (pid_t *) propValue;
      printf("%ld\n", aPid);
   }

   return;
}

void quit(widget, clientData, cbs)
Widget widget;
XtPointer clientData;
XmPushButtonCallbackStruct *cbs;{
   
   XFlush(XtDisplay(widget));

   exit(0);
}

void main( argc, argv )

int	argc;
char	*argv[];

{	/* main */
   XtAppContext app;
   Widget topLevel, rowColumn, buttons[10];
   Window veeWindow;
   XmString label;
   XEvent event;
   int i;
   int numButtons;

   topLevel=XtVaAppInitialize(&app, "IPC_demo", NULL, 0, 
			    &argc, argv, NULL, NULL);

   /*
	  Create a manager widget to group our buttons
	  vertically
   */

   rowColumn=XtVaCreateManagedWidget("rowColumn",
				     xmRowColumnWidgetClass, topLevel,
				     NULL);

   numButtons=nButtons();

   /*
	  Create the buttons and assign parentage.
   */

   for(i=0; i<numButtons; i++){
	   label=XmStringCreateSimple(buttonText[i]);	   
	   buttons[i]=XtVaCreateManagedWidget(buttonText[i],
										  xmPushButtonWidgetClass, rowColumn,
										  XmNlabelString, label,
										  NULL);
	   XmStringFree(label);
   }

   XtRealizeWidget(topLevel);

   /*
	  Assign functions to handle button press events.
   */

   XtAddCallback(buttons[0], XmNactivateCallback, run, (XtPointer)0);
   XtAddCallback(buttons[1], XmNactivateCallback, pauseVee, (XtPointer)0);
   XtAddCallback(buttons[2], XmNactivateCallback, step, (XtPointer)0);
   XtAddCallback(buttons[3], XmNactivateCallback, cont, (XtPointer)0);
   XtAddCallback(buttons[4], XmNactivateCallback, f1, (XtPointer)0);
   XtAddCallback(buttons[5], XmNactivateCallback, hide, (XtPointer)0);
   XtAddCallback(buttons[6], XmNactivateCallback, iconize, (XtPointer)0);
   XtAddCallback(buttons[7], XmNactivateCallback, restore, (XtPointer)0);
   XtAddCallback(buttons[8], XmNactivateCallback, pid,
				 (XtPointer)XtWindow(topLevel));
   XtAddCallback(buttons[9], XmNactivateCallback, quit, (XtPointer)0);

   /*
	  Set ourselves up to receive PropertyNotify events.  This will
	  happen when VEE puts its process id in our wmPid atom.
   */

   XSelectInput(XtDisplay(topLevel), XtWindow(topLevel), PropertyChangeMask);

   /*
	  Loop, reading and dispatching events.  When we detect a PropertyNotify
	  event, indicating that VEE has stored its process id in our atom, dispatch
	  that event.
   */

   for(;;){
      XtAppNextEvent(app, &event);
      if(!XtDispatchEvent(&event) && (event.type == PropertyNotify)){
		  veePid(&event);
      }
   }
}	/* main */

/*
   $Log:	ipc.c,v $
 * Revision 1.16  97/04/14  15:54:35  15:54:35  doomer (John Dumais)
 * typo
 * 
 * Revision 1.15  97/04/14  15:49:39  15:49:39  doomer (John Dumais)
 * fixed rcs header
 * 
 * Revision 1.14  97/04/14  15:45:36  15:45:36  doomer (John Dumais)
 * documentation
 * 
*/