Exemple #1
0
/***************************************************************************
 *
 * Waits for next X event, or for an auto-raise timeout.
 *
 ****************************************************************************/
int My_XNextEvent(Display *dpy, XEvent *event)
{
  fd_set in_fdset;
  static int miss_counter = 0;

  if(XPending(dpy))
  {
    XNextEvent(dpy,event);
    return 1;
  }

  FD_ZERO(&in_fdset);
  FD_SET(x_fd,&in_fdset);
  FD_SET(fd[1],&in_fdset);

  if (fvwmSelect(fd_width, &in_fdset, 0, 0, NULL) > 0)
  {
  if(FD_ISSET(x_fd, &in_fdset))
    {
      if(XPending(dpy))
	{
	  XNextEvent(dpy,event);
	  miss_counter = 0;
	  return 1;
	}
	miss_counter++;
#ifdef WORRY_ABOUT_MISSED_XEVENTS
	if(miss_counter > 100)
          DeadPipe(0);
#endif
    }

  if(FD_ISSET(fd[1], &in_fdset))
    {
      FvwmPacket* packet = ReadFvwmPacket(fd[1]);
      if ( packet == NULL )
	  exit(0);
      process_message( packet );
    }
  }
  return 0;
}
Exemple #2
0
/*
 *
 * send command to and receive message from the server
 *
 */
int main ( int argc, char *argv[])
{
  char cmd[MAX_MODULE_INPUT_TEXT_LEN + 1];
  char *f_stem, *fc_name, *fm_name;
  char *sf_stem;
  char *s;
  int  i;
  int  opt;
  int  ncnt;
  int  count;
  int  Rc;
  struct timeval tv2;
  extern char *optarg;
  extern int  optind;

#ifdef HAVE_SIGACTION
  {
    struct sigaction sigact;

    sigemptyset(&sigact.sa_mask);
#ifdef SA_RESTART
    sigact.sa_flags = SA_RESTART;
#else
    sigact.sa_flags = 0;
#endif
    sigact.sa_handler = sig_ttin;
    sigaction(SIGTTIN, &sigact, NULL);
    sigaction(SIGTTOU, &sigact, NULL);

    sigaddset(&sigact.sa_mask, SIGINT);
    sigaddset(&sigact.sa_mask, SIGHUP);
    sigaddset(&sigact.sa_mask, SIGQUIT);
    sigaddset(&sigact.sa_mask, SIGTERM);

#ifdef SA_INTERRUPT
    sigact.sa_flags = SA_INTERRUPT;
#else
    sigact.sa_flags = 0;
#endif
    sigact.sa_handler = sig_quit;
    sigaction(SIGINT, &sigact, NULL);
    sigaction(SIGHUP, &sigact, NULL);
    sigaction(SIGQUIT, &sigact, NULL);
    sigaction(SIGTERM, &sigact, NULL);
    sigaction(SIGPIPE, &sigact, NULL);
  }
#else
#ifdef USE_BSD_SIGNALS
  fvwmSetSignalMask(
	  sigmask(SIGINT) | sigmask(SIGHUP) | sigmask(SIGQUIT) |
	  sigmask(SIGTERM) | sigmask(SIGPIPE));
#endif
  signal(SIGINT, sig_quit);
  signal(SIGHUP, sig_quit);
  signal(SIGQUIT, sig_quit);
  signal(SIGTERM, sig_quit);
  signal(SIGPIPE, sig_quit);
  signal(SIGTTIN, sig_ttin);
  signal(SIGTTOU, sig_ttin);
#ifdef HAVE_SIGINTERRUPT
  siginterrupt(SIGINT, 1);
  siginterrupt(SIGHUP, 1);
  siginterrupt(SIGQUIT, 1);
  siginterrupt(SIGTERM, 1);
  siginterrupt(SIGPIPE, 1);
  siginterrupt(SIGTTIN, 0);
  siginterrupt(SIGTTOU, 0);
#endif
#endif

  Opt_reply = 0;
  Opt_info = -1;
  f_stem = NULL;
  sf_stem = NULL;
  Opt_monitor = 0;
  Opt_stdin = 0;
  Opt_Serv = 0;
  Opt_flags = 2;
  Tv.tv_sec = 0;
  Tv.tv_usec = 500000;
  Rc = 0;
  Bg = 0;


  while( (opt = getopt( argc, argv, "S:hvF:f:w:i:rmc" )) != EOF )
  {
    switch(opt)
    {
    case 'h':
      usage();
      exit(0);
      break;
    case 'f':
      f_stem = optarg;
      break;
    case 'F':
      Opt_flags = atoi (optarg);
      break;
    case 'S':
      sf_stem = optarg;
      Opt_Serv = 1;
      break;
    case 'i':
      Opt_info = atoi( optarg );
      break;
    case 'v':
      printf("%s %s\n", MYNAME, VERSION );
      exit(0);
    case 'w':
      Tv.tv_usec = atoi( optarg ) % 1000000;
      Tv.tv_sec = atoi( optarg ) / 1000000;
      break;
    case 'm':
      Opt_monitor = 1;
      break;
    case 'r':
      Opt_reply = 1;
      break;
    case 'c':
      Opt_stdin = 1;
      break;
    case '?':
      exit(3);
    }
  }

  if( f_stem == NULL )
  {
    if ((f_stem = fifos_get_default_name()) == NULL)
    {
       fprintf (stderr, "\n%s can't decide on fifo-name. "
	       "Make sure that $FVWM_USERDIR is set.\n",
	       MYNAME );
       exit(1);
    }
  }

  /* create 2 fifos */
  fm_name = safemalloc( strlen(f_stem) + 2 );
  strcpy(fm_name,f_stem);
  strcat(fm_name, "M");
  fc_name = safemalloc( strlen(f_stem) + 2 );
  strcpy(fc_name,f_stem);
  strcat(fc_name, "C");
  s = safemalloc( strlen(f_stem) + 2 );
  strcpy(s,f_stem);
  strcat(s, "R");

  Fdrun = open(s, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
  if (Fdrun < 0)
  {
    FILE *f;

    if ((f = fopen (s,"r" )) != NULL)
    {
      char *p;

      *cmd = 0;
      p = fgets(cmd, 20, f);
      (void)p;
      fclose(f);
      fprintf (stderr, "\nFvwmCommand lock file %sR is detected. "
	       "This may indicate another FvwmCommand is running. "
	       "It appears to be running under process ID:\n%s\n",
	       f_stem, (*cmd) ? cmd : "(unknown)" );
      fprintf (stderr, "You may either kill the process or run FvwmCommand "
	       "with another FIFO set using option -S and -f. "
	       "If the process doesn't exist, simply remove file:\n%sR\n\n",
	       f_stem);
      exit(1);
    }
    else
    {
      err_quit ("writing lock file");
    }
  }
  Fr_name = s;

  if( Opt_Serv )
  {
    int n;

    sprintf (cmd,"%s '%sS %s'", argv[0], MYNAME, sf_stem);
    n = system (cmd);
    (void)n;
  }

  {
    char buf[64];
    int n;

    sprintf(buf, "%d\n", (int)getpid());
    n = write(Fdrun, buf, strlen(buf));
    (void)n;
    close(Fdrun);
  }

  Fdr = Fdw = -1;
  count = 0;
  while ((Fdr=open (fm_name, O_RDONLY | O_NOFOLLOW)) < 0)
  {
    if (count++>5)
    {
      err_quit ("opening message fifo");
    }
    sleep(1);
  }
  count = 0;
  while ((Fdw=open (fc_name, O_WRONLY | O_NOFOLLOW)) < 0)
  {
    if (count++>2)
    {
      err_quit ("opening command fifo");
    }
    sleep(1);
  }

  i = optind;

  if (Opt_stdin)
  {
    while (fgets(cmd, MAX_MODULE_INPUT_TEXT_LEN - 1, stdin))
    {
      sendit(cmd);
    }
  }

  else if( Opt_monitor )
  {

    /* test if its stdin is closed for coprocess */
    tv2.tv_sec = 0;
    tv2.tv_usec = 5;
    FD_ZERO(&fdset);
    FD_SET(STDIN_FILENO, &fdset);
    ncnt = fvwmSelect(FD_SETSIZE, &fdset, 0, 0, &tv2);
    if( ncnt && (fgets( cmd, 1, stdin )==0 || cmd[0] == 0))
    {
      Bg = 1;
    }

    /* line buffer stdout for coprocess */
    setvbuf( stdout, NULL, _IOLBF, 0);

    /* send arguments first */
    for( ;i < argc; i++ )
    {
      strncpy( cmd, argv[i], MAX_MODULE_INPUT_TEXT_LEN - 1 );
      sendit( cmd );
    }


    while( !isTerminated )
    {
      FD_ZERO(&fdset);
      FD_SET(Fdr, &fdset);
      if( Bg == 0 )
      {
	FD_SET(STDIN_FILENO, &fdset);
      }
      ncnt = fvwmSelect(FD_SETSIZE, &fdset, 0, 0, NULL);

      /* message from fvwm */
      if (FD_ISSET(Fdr, &fdset))
      {
	process_message();
      }

      if( Bg == 0 )
      {
	/* command input */
	if( FD_ISSET(STDIN_FILENO, &fdset) )
	{
	  if( fgets( cmd, MAX_MODULE_INPUT_TEXT_LEN - 1, stdin ) == 0 )
	  {
	    if( Bg == 0 )
	    {
	      /* other than SIGTTIN */
	      break;
	    }
	    continue;
	  }
	  sendit( cmd );
	}
      }
    }
  }
  else
  {
    for( ;i < argc; i++ )
    {
      strncpy( cmd, argv[i], MAX_MODULE_INPUT_TEXT_LEN - 1 );
      sendit( cmd );
      if (Opt_info >= 0)
	receive();
    }
  }
  close_fifos();
  return Rc;
}
Exemple #3
0
/*
 *
 *  Procedure:
 *      main - start of module
 *
 */
int
main(int argc, char **argv)
{
	/* The struct holding the module info */
	static ModuleArgs* module;
	char *enter_fn="Silent Raise";        /* default */
	char *leave_fn=NULL;
	char *buf;
	int len;
	unsigned long m_mask;
	unsigned long mx_mask;
	unsigned long last_win = 0;   /* last window handled */
	unsigned long focus_win = 0;  /* current focus */
	unsigned long raised_win = 0;
	fd_set_size_t fd_width;
	int fd[2];
	int timeout;
	int sec = 0;
	int usec = 0;
	int n;
	struct timeval value;
	struct timeval *delay;
	fd_set in_fdset;
	Bool do_pass_id = False;
	Bool use_enter_mode = False;
	Bool use_leave_mode = False;
#ifdef DEBUG
	int count = 0;
#endif

#ifdef DEBUGTOFILE
	freopen(".FvwmAutoDebug","w",stderr);
#endif

	module = ParseModuleArgs(argc,argv,0); /* no alias in this module */
	if (module==NULL)
	{
		fprintf(stderr,"FvwmAuto Version "VERSION" should only be executed by fvwm!\n");
		exit(1);
	}


	if (module->user_argc < 1 || module->user_argc > 5)
	{
		fprintf(stderr,"FvwmAuto can use one to five arguments.\n");
		exit(1);
	}

	/* Dead pipes mean fvwm died */
#ifdef HAVE_SIGACTION
	{
		struct sigaction  sigact;

		sigemptyset(&sigact.sa_mask);
		sigaddset(&sigact.sa_mask, SIGPIPE);
		sigaddset(&sigact.sa_mask, SIGINT);
		sigaddset(&sigact.sa_mask, SIGHUP);
		sigaddset(&sigact.sa_mask, SIGQUIT);
		sigaddset(&sigact.sa_mask, SIGTERM);
#ifdef SA_RESTART
		sigact.sa_flags = SA_RESTART;
# else
		sigact.sa_flags = 0;
#endif
		sigact.sa_handler = TerminateHandler;

		sigaction(SIGPIPE, &sigact, NULL);
		sigaction(SIGINT,  &sigact, NULL);
		sigaction(SIGHUP,  &sigact, NULL);
		sigaction(SIGQUIT, &sigact, NULL);
		sigaction(SIGTERM, &sigact, NULL);
	}
#else
	/* We don't have sigaction(), so fall back to less robust methods.  */
#ifdef USE_BSD_SIGNALS
	fvwmSetSignalMask( sigmask(SIGPIPE) |
			   sigmask(SIGINT)  |
			   sigmask(SIGHUP)  |
			   sigmask(SIGQUIT) |
			   sigmask(SIGTERM) );
#endif

	signal(SIGPIPE, TerminateHandler);
	signal(SIGINT,  TerminateHandler);
	signal(SIGHUP,  TerminateHandler);
	signal(SIGQUIT, TerminateHandler);
	signal(SIGTERM, TerminateHandler);
#ifdef HAVE_SIGINTERRUPT
	siginterrupt(SIGPIPE, 0);
	siginterrupt(SIGINT, 0);
	siginterrupt(SIGHUP, 0);
	siginterrupt(SIGQUIT, 0);
	siginterrupt(SIGTERM, 0);
#endif
#endif

	fd[0] = module->to_fvwm;
	fd[1] = module->from_fvwm;

	if ((timeout = atoi(module->user_argv[0]) ))
	{
		sec = timeout / 1000;
		usec = (timeout % 1000) * 1000;
	}
	else
	{
		sec = 0;
		usec = 1000;
	}
	delay = &value;

	n = 1;
	if (n < module->user_argc && module->user_argv[n])
	{
		char *token;

		/* -passid option */
		if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-passid"))
		{
			do_pass_id = True;
			n++;
		}
		if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-menterleave"))
		{
			/* enterleave mode */
			use_leave_mode = True;
			use_enter_mode = True;
			n++;
		}
		else if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-menter"))
		{
			/* enter mode */
			use_leave_mode = False;
			use_enter_mode = True;
			n++;
		}
		else if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "-mfocus"))
		{
			/* focus mode */
			use_leave_mode = False;
			use_enter_mode = False;
			n++;
		}
		/*** enter command ***/
		if (n < module->user_argc && *module->user_argv[n] && StrEquals(module->user_argv[n], "Nop"))
		{
			/* nop */
			enter_fn = NULL;
			n++;
		}
		else if (n < module->user_argc)
		{
			/* override default */
			enter_fn = module->user_argv[n];
			n++;
		}
		/* This is a hack to prevent user interaction with old configs.
		 */
		if (enter_fn)
		{
			token = PeekToken(enter_fn, NULL);
			if (!StrEquals(token, "Silent"))
			{
				enter_fn = safestrdup(
					CatString2("Silent ", enter_fn));
			}
		}
		/*** leave command ***/
		if (n < module->user_argc && module->user_argv[n] && *module->user_argv[n] &&
		    StrEquals(module->user_argv[n], "Nop"))
		{
			/* nop */
			leave_fn = NULL;
			n++;
		}
		else if (n < module->user_argc)
		{
			/* leave function specified */
			leave_fn=module->user_argv[n];
			n++;
		}
		if (leave_fn)
		{
			token = PeekToken(leave_fn, NULL);
			if (!StrEquals(token, "Silent"))
			{
				leave_fn = safestrdup(
					CatString2("Silent ", leave_fn));
			}
		}
	}

	/* Exit if nothing to do. */
	if (!enter_fn && !leave_fn)
	{
		return -1;
	}

	if (use_enter_mode)
	{
		m_mask = 0;
		mx_mask = MX_ENTER_WINDOW | MX_LEAVE_WINDOW | M_EXTENDED_MSG;
	}
	else
	{
		mx_mask = M_EXTENDED_MSG;
		m_mask = M_FOCUS_CHANGE;
	}
	/* Disable special raise/lower support on general actions. *
	 * This works as expected in most of cases. */
	if (matchWildcards("*Raise*", CatString2(enter_fn, leave_fn)) ||
	    matchWildcards("*Lower*", CatString2(enter_fn, leave_fn)))
	{
		m_mask |= M_RAISE_WINDOW | M_LOWER_WINDOW;
	}

	/* migo (04/May/2000): It is simply incorrect to listen to raise/lower
	 * packets and change the state if the action itself has no raise/lower.
	 * Detecting whether to listen or not by the action name is good enough.
	 m_mask = M_FOCUS_CHANGE | M_RAISE_WINDOW | M_LOWER_WINDOW;
	*/

	SetMessageMask(fd, m_mask);
	SetMessageMask(fd, mx_mask);
	/* tell fvwm we're running */
	SendFinishedStartupNotification(fd);
	/* tell fvwm that we want to be lock on send */
	SetSyncMask(fd, m_mask);
	SetSyncMask(fd, mx_mask);

	fd_width = fd[1] + 1;
	FD_ZERO(&in_fdset);

	/* create the command buffer */
	len = 0;
	if (enter_fn != 0)
	{
		len = strlen(enter_fn);
	}
	if (leave_fn != NULL)
	{
		len = max(len, strlen(leave_fn));
	}
	if (do_pass_id)
	{
		len += 32;
	}
	buf = safemalloc(len);

	while (!isTerminated)
	{
		char raise_window_now;
		static char have_new_window = 0;

		FD_SET(fd[1], &in_fdset);

		myfprintf(
			(stderr, "\nstart %d (hnw = %d, usec = %d)\n", count++,
			 have_new_window, usec));
		/* fill in struct - modified by select() */
		delay->tv_sec = sec;
		delay->tv_usec = usec;
#ifdef DEBUG
		{
			char tmp[32];

			sprintf(tmp, "%d usecs", (delay) ?
				(int)delay->tv_usec : -1);
			myfprintf((stderr, "select: delay = %s\n",
				   (have_new_window) ? tmp : "infinite" ));
		}
#endif
		if (fvwmSelect(fd_width, &in_fdset, NULL, NULL,
			       (have_new_window) ? delay : NULL) == -1)
		{
			myfprintf(
				(stderr, "select: error! (%s)\n",
				 strerror(errno)));
			break;
		}

		raise_window_now = 0;
		if (FD_ISSET(fd[1], &in_fdset))
		{
			FvwmPacket *packet = ReadFvwmPacket(fd[1]);

			if (packet == NULL)
			{
				myfprintf(
					(stderr,
					 "Leaving because of null packet\n"));
				break;
			}

			myfprintf(
				(stderr,
				 "pw = 0x%x, fw=0x%x, rw = 0x%x, lw=0x%x\n",
				 (int)packet->body[0], (int)focus_win,
				 (int)raised_win, (int)last_win));

			switch (packet->type)
			{
			case MX_ENTER_WINDOW:
				focus_win = packet->body[0];
				if (focus_win != raised_win)
				{
					myfprintf((stderr,
						   "entered new window\n"));
					have_new_window = 1;
					raise_window_now = 0;
				}
				else if (focus_win == last_win)
				{
					have_new_window = 0;
				}
				else
				{
					myfprintf((stderr,
						   "entered other window\n"));
				}
				break;

			case MX_LEAVE_WINDOW:
				if (use_leave_mode)
				{
					if (focus_win == raised_win)
					{
						focus_win = 0;
					}
					myfprintf((stderr,
						   "left raised window\n"));
					have_new_window = 1;
					raise_window_now = 0;
				}
				break;

			case M_FOCUS_CHANGE:
				/* it's a focus package */
				focus_win = packet->body[0];
				if (focus_win != raised_win)
				{
					myfprintf((stderr,
						   "focus on new window\n"));
					have_new_window = 1;
					raise_window_now = 0;
				}
				else
				{
					myfprintf((stderr,
						   "focus on old window\n"));
				}
				break;

			case M_RAISE_WINDOW:
				myfprintf(
					(stderr, "raise packet 0x%x\n",
					 (int)packet->body[0]));
				raised_win = packet->body[0];
				if (have_new_window && focus_win == raised_win)
				{
					myfprintf(
						(stderr, "its the old window:"
						 " don't raise\n"));
					have_new_window = 0;
				}
				break;

			case M_LOWER_WINDOW:
				myfprintf(
					(stderr, "lower packet 0x%x\n",
					 (int)packet->body[0]));
				if (have_new_window &&
				    focus_win == packet->body[0])
				{
					myfprintf(
						(stderr,
						 "window was explicitly"
						 " lowered, don't raise it"
						 " again\n"));
					have_new_window = 0;
				}
				break;
			} /* switch */
			SendUnlockNotification(fd);
		}
		else
		{
			if (have_new_window)
			{
				myfprintf((stderr, "must raise now\n"));
				raise_window_now = 1;
			}
		}

		if (raise_window_now)
		{
			myfprintf((stderr, "raising 0x%x\n", (int)focus_win));

			if (leave_fn &&
			    ((last_win && !use_leave_mode) ||
			     (raised_win && use_enter_mode)))
			{
				/* if focus_win isn't the root */
				if (do_pass_id)
				{
					sprintf(buf, "%s 0x%x\n", leave_fn,
						(int)last_win);
				}
				else
				{
					sprintf(buf, "%s\n", leave_fn);
				}
				SendInfo(fd, buf, last_win);
				if (use_enter_mode)
				{
					raised_win = 0;
				}
			}

			if (focus_win && enter_fn)
			{
				/* if focus_win isn't the root */
				if (do_pass_id)
				{
					sprintf(buf, "%s 0x%x\n", enter_fn,
						(int)focus_win);
				}
				else
				{
					sprintf(buf, "%s\n", enter_fn);
				}
				SendInfo(fd, buf, focus_win);
				raised_win = focus_win;
			}
			else if (focus_win && enter_fn == NULL)
			{
				raised_win = focus_win;
			}
			/* force fvwm to synchronise on slow X connections to
			 * avoid a race condition.  Still possible, but much
			 * less likely. */
			SendInfo(fd, "XSync", focus_win);

			/* switch to wait mode again */
			last_win = focus_win;
			have_new_window = 0;
		}
	} /* while */

	return 0;
}