예제 #1
0
void FlushQueue(int module)
{
  char *dptr;
  struct queue_buff_struct *d;
  int a;
  extern int errno;

  if ((pipeOn[module] <= 0) || (pipeQueue[module] == NULL))
    return;

  while (pipeQueue[module] != NULL) {
    d = pipeQueue[module];
    dptr = (char *) d->data;
    while (d->done < d->size) {
      a = write(writePipes[module], &dptr[d->done], d->size - d->done);
      if (a >= 0)
	d->done += a;
      /* the write returns EWOULDBLOCK or EAGAIN if the pipe is full.
       * (This is non-blocking I/O). SunOS returns EWOULDBLOCK, OSF/1
       * returns EAGAIN under these conditions. Hopefully other OSes
       * return one of these values too. Solaris 2 doesn't seem to have
       * a man page for write(2) (!) */
      else if ((errno == EWOULDBLOCK) || (errno == EAGAIN)
	       || (errno == EINTR)) {
	return;
      } else {
	KillModule(module, 123);
	return;
      }
    }
    DeleteQueueBuff(module);
  }
}
예제 #2
0
void KillModuleByName(char *name)
{
  int i = 0;

  if (name == NULL)
    return;

  while (i < npipes) {
    if ((pipeName[i] != NULL) && (matchWildcards(name, pipeName[i]))) {
      KillModule(i, 10);
    }
    i++;
  }
  return;
}
예제 #3
0
void HandleModuleInput(Window w, int channel)
{
  char text[256];
  int size;
  int cont, n;

  /* Already read a (possibly NULL) window id from the pipe,
   * Now read an fvwm bultin command line */
  n = read(readPipes[channel], &size, sizeof(size));
  if (n < sizeof(size)) {
    KillModule(channel, 1);
    return;
  }

  if (size > 255) {
    fvwm_msg(ERR, "HandleModuleInput",
	     "Module command is too big (%d)", (void *) size);
    size = 255;
  }

  pipeOn[channel] = 1;

  n = read(readPipes[channel], text, size);
  if (n < size) {
    KillModule(channel, 2);
    return;
  }

  text[n] = 0;
  n = read(readPipes[channel], &cont, sizeof(cont));
  if (n < sizeof(cont)) {
    KillModule(channel, 3);
    return;
  }
  if (cont == 0) {
    KillModule(channel, 4);
  }
  if (strlen(text) > 0) {
    extern int Context;
    FvwmWindow *tmp_win;

    /* first, check to see if module config line */
    if (text[0] == '*') {
      AddToModList(text);
      return;
    }

    /* perhaps the module would like us to kill it? */
    if (strncasecmp(text, "KillMe", 6) == 0) {
      KillModule(channel, 12);
      return;
    }


    /*Event.xany.type = ButtonRelease; hmmm... */
    /* If a module does XUngrabPointer(), it can now get proper Popups */
    if (strncasecmp(text, "popup", 5) == 0)
      Event.xany.type = ButtonPress;
    else
      Event.xany.type = ButtonRelease;
    Event.xany.window = w;

    if ((w == None) ||
        (XFindContext(dpy, w, FvwmContext, (caddr_t *) &tmp_win) == XCNOENT)) {
      tmp_win = NULL;
      w = None;
    }
    if (tmp_win) {
      Event.xbutton.button = 1;
      Event.xbutton.x_root = tmp_win->frame_x;
      Event.xbutton.y_root = tmp_win->frame_y;
      Event.xbutton.x = 0;
      Event.xbutton.y = 0;
      Event.xbutton.subwindow = None;
    } else {
      Event.xbutton.button = 1;
      Event.xbutton.x_root = 0;
      Event.xbutton.y_root = 0;
      Event.xbutton.x = 0;
      Event.xbutton.y = 0;
      Event.xbutton.subwindow = None;
    }
    Context = GetContext(tmp_win, &Event, &w);
    ExecuteFunction(text, tmp_win, &Event, Context, channel);
    SendPacket(channel, M_FUNCTION_END, 1, 0, 0, 0, 0, 0, 0, 0);
  }
  return;
}
예제 #4
0
/***************************************************************************
 *
 * Waits for next X event, or for an auto-raise timeout.
 *
 ****************************************************************************/
int My_XNextEvent(Display *dpy, XEvent *event)
{
  extern int fd_width, x_fd;
  fd_set in_fdset, out_fdset;
  Window targetWindow;
  int i;

  DBUG("My_XNextEvent","Routine Entered");

  /* Do this IMMEDIATELY prior to select, to prevent any nasty
   * queued up X events from just hanging around waiting to be
   * flushed */
  XFlush(dpy);
  if(XPending(dpy))
    {
      DBUG("My_XNextEvent","taking care of queued up events & returning");
      XNextEvent(dpy,event);
      StashEventTime(event);
      return 1;
    }

  DBUG("My_XNextEvent","no X events waiting - about to reap children");
  /* Zap all those zombies! */
  /* If we get to here, then there are no X events waiting to be processed.
   * Just take a moment to check for dead children. */
  ReapChildren();

  FD_ZERO(&in_fdset);
  FD_SET(x_fd,&in_fdset);
  FD_ZERO(&out_fdset);
  for(i=0; i<npipes; i++)
    {
      if(readPipes[i]>=0)
	{
	  FD_SET(readPipes[i], &in_fdset);
	}
      if(pipeQueue[i]!= NULL)
	{
	  FD_SET(writePipes[i], &out_fdset);
	}
    }

  DBUG("My_XNextEvent","waiting for module input/output");
  XFlush(dpy);
  if (select((SELECT_TYPE_ARG1)fd_width,
             SELECT_TYPE_ARG234 &in_fdset,
             SELECT_TYPE_ARG234 &out_fdset,
             SELECT_TYPE_ARG234 0,
             SELECT_TYPE_ARG5   NULL) > 0)
  {

  /* Check for module input. */
  for(i=0;i<npipes;i++)
    {
      if(readPipes[i] >= 0)
	{
	  if(FD_ISSET(readPipes[i], &in_fdset))
	    {
	      if( read(readPipes[i],&targetWindow, sizeof(Window)) >0 )
		{
                  DBUG("My_XNextEvent","calling HandleModuleInput");
		  HandleModuleInput(targetWindow,i);
		}
              else
		{
                  DBUG("My_XNextEvent","calling KillModule");
		  KillModule(i,10);
		}
	    }
	}
      if(writePipes[i] >= 0)
	{
	  if(FD_ISSET(writePipes[i], &out_fdset))
	    {
              DBUG("My_XNextEvent","calling FlushQueue");
	      FlushQueue(i);
	    }
	}
    } /* for */
  }
  DBUG("My_XNextEvent","leaving My_XNextEvent");
  return 0;
}