How to capture orbit notification in rep input handling



Hello,

I am trying to add gconf to sawfish.

Currently, any ORBit messages sent by gconf (generated by calling
gconf_engine_set_string or gconf_engine_notify_add) do not get
to sawfish, which is in rep (lisp like interpreter) loop. 

Following is the input handling function of rep from librep (unix_main.c)


/* The input handler loop. */
repv
rep_event_loop(void)
{
    repv result = Qnil;

    if (rep_redisplay_fun != 0)
	    (*rep_redisplay_fun)();

    while(1)
    {
	    int ready;
	rep_bool refreshp = rep_FALSE;
	fd_set copy;

	if (rep_throw_value == rep_NULL)
	{
	    memcpy(&copy, &input_fdset, sizeof(copy));
	ready = wait_for_input(&copy, rep_input_timeout_secs * 1000);
	refreshp = handle_input(&copy, ready);
	 }

	/* Check for exceptional conditions. */
	 if(rep_throw_value != rep_NULL)
        {
	if(rep_handle_input_exception(&result))
			return result;
	else
			refreshp = rep_TRUE;
        }

	if(refreshp && rep_redisplay_fun != 0)
	(*rep_redisplay_fun)();

#ifdef C_ALLOCA
		/* Using the C implementation of alloca. So garbage collect
	anything below the current stack depth. */
	 alloca(0);
#endif
    }

    return result;
}

where wait_for_input() basically waits on a select().

If through a timer function i periodically call while gtk_events_pending()
gtk_main_iteration_do() the gconf callback registered with gconf, to be called
on a key change, gets called. But, this too is not very consistent. And using
a recurring timer is not an acceptable solution. And withouth this processing
of events sawfish does not get notifications from gconf_engine_set_string().

How can i change the above input handling mechanism of rep to capture the
ORBit messages sent by gconf? How do normal apps get notified?

Any pointers/help would be greatly appreciated.

Thanks,
--mahmood

ps: Following is the complete wait_for_input() and handle_input() (unix_main.c)

/* Wait for input for no longer than TIMEOUT-MSECS for input fds defined
   by INPUTS. If input arrived return the number of ready fds, with the
   actual fds defined by the fdset INPUTS. Return zero if the timeout
   was reached. */

static int
wait_for_input(fd_set *inputs, u_long timeout_msecs)
{
    fd_set copy;
    int ready = -1;

    if(input_pending_count > 0)
    {
		/* Check the pending inputs first.. */
	fd_set out;
	int i, count = 0, seen = 0;
	for(i = 0; seen < input_pending_count && i < FD_SETSIZE; i++)
	{
	    if(FD_ISSET(i, &input_pending))
	    {
		seen++;
		if(FD_ISSET(i, inputs))
		{
		    if(count == 0)
			FD_ZERO(&out);
		    FD_SET(i, &out);
		    count++;
		}
	    }
        }
	if(count > 0)
        {
	memcpy(inputs, &out, sizeof(out));
	return count;
        }
    }

    /* Break the timeout into one-second chunks, then check for
	interrupt between each call to select. */
    do {
	struct timeval timeout;
	u_long max_sleep = rep_max_sleep_for ();
	u_long this_timeout_msecs = MIN (timeout_msecs,
					 rep_input_timeout_secs * 1000);
	u_long actual_timeout_msecs = MIN (this_timeout_msecs, max_sleep);

	timeout.tv_sec = actual_timeout_msecs / 1000;
	 timeout.tv_usec = (actual_timeout_msecs % 1000) * 1000;
	 memcpy (&copy, inputs, sizeof (copy));

	/* Dont test for interrupts before the first call to select() */
	 if (ready == 0)
        {
	rep_TEST_INT_SLOW;
	if (rep_INTERRUPTP)
	  break;
        }

	/* Don't want select() to restart after a SIGCHLD or SIGALRM;
	there may be a notification to dispatch.  */
	 rep_sig_restart(SIGCHLD, rep_FALSE);
	 rep_sig_restart(SIGALRM, rep_FALSE);
	 ready = select(FD_SETSIZE, &copy, NULL, NULL, &timeout);
	 rep_sig_restart(SIGALRM, rep_TRUE);
	 rep_sig_restart(SIGCHLD, rep_TRUE);

	if (ready == 0 && actual_timeout_msecs < this_timeout_msecs)
        {
	Fthread_suspend (Qnil, rep_MAKE_INT (this_timeout_msecs
	- actual_timeout_msecs));
        }

	 timeout_msecs -= this_timeout_msecs;
    } while (ready == 0 && timeout_msecs > 0);

    memcpy (inputs, &copy, sizeof (copy));
    return ready;
}



/* Handle the READY fds with pending input (defined by fdset INPUTS).
   Return true if the display might require updating. Returns immediately
   if a Lisp error has occurred. */
static rep_bool
handle_input(fd_set *inputs, int ready)
{
    static long idle_period;
    rep_bool refreshp = rep_FALSE;

    if(ready > 0)
    {
	int i;

	idle_period = 0;

	for(i = 0; i < FD_SETSIZE && ready > 0 && !rep_INTERRUPTP; i++)
        {
	 if(FD_ISSET(i, inputs))
            {
		ready--;
		if(FD_ISSET(i, &input_pending))
		 {
		  FD_CLR(i, &input_pending);
		  input_pending_count--;
		 }
		if(input_actions[i] != NULL)
		 {
		  input_actions[i](i);
		  refreshp = rep_TRUE;
		 }
            }
        }
    }
    else if(ready == 0)
    {
	/* A timeout. */
	 if(rep_INTERRUPTP || rep_on_idle(idle_period))
	refreshp = rep_TRUE;

	idle_period++;
    }

    if(!rep_INTERRUPTP && rep_proc_periodically())
	refreshp = rep_TRUE;

    return refreshp;
}





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]