Logo Search packages:      
Sourcecode: xcal version File versions  Download package

xcal_buts.c

#ifndef lint
static char    *sccsid = "@(#)xcal_buts.c 1.3 (Hillside Systems) 10/25/93";
static char    *copyright = "@(#)Copyright 1989,1990,1993 Peter Collinson, Hillside Systems";
#endif                        /* lint */
/***

* module name:
      xcal_buts.c
* function:
      Deal with callback management for sensitive buttons
      When a button is pressed we make it insensitive.
      In general a button starts a popup - when the popup
      dies we reset the button.
      Problem is when the button dies before the popup.

* history:
      Written October 1993
      Peter Collinson
      Hillside Systems
* (C) Copyright: 1989 Hillside Systems/Peter Collinson

      For full permissions and copyright notice - see xcal.c
***/
#include <stdio.h>
#include <ctype.h>
#include <pwd.h>
#include <X11/Intrinsic.h>
#include <X11/Xos.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Command.h>
#include "xcal.h"

typedef struct active {
      struct active   *next;
      Widget            button;
      Widget            popup;
} Active;

static Active *act;

/*
 * Local routines
 */
static void AddToActive();
static Active *LookActive();
static Active *LookPopup();
static void DeleteFromActive();
static void PopupIsDead();
static void ButtonIsDead();

/*
 * Here's the global entry point
 * given a button and a popup
 * make the button insensitive
 * add a destroy callback to the popup to turn the button on again when
 * the popup dies - assuming the button is in the list
 * add a destroy callback to the button to remove the button from the list
 */
void
ButtonOff(but, popup)
      Widget            but;
      Widget            popup;
{
      
      XtSetSensitive(but, False);
      
      XtAddCallback(popup, XtNdestroyCallback, PopupIsDead, but);

      XtAddCallback(but, XtNdestroyCallback, ButtonIsDead, but);

      AddToActive(but, popup);
}

/*
 * Turn a button on
 */
void
ButtonOn(but)
      Widget            but;
{
      Active            *ap;

      if (ap = LookActive(but)) {
            XtRemoveCallback(but, XtNdestroyCallback, ButtonIsDead, but);
            XtSetSensitive(but, True);
            DeleteFromActive(but);
      }
}

/*
 * Turn a help button on
 */
void
HelpButtonOn(popup)
      Widget            popup;
{
      Active            *ap;

      while (ap = LookPopup(popup))
            ButtonOn(ap->button);
}

/*
 * Callbacks
 * 1) called from popup when it dies
 */
/* ARGSUSED */
static void
PopupIsDead(w, closure, call_data)
      Widget            w;
      caddr_t         closure;
      caddr_t         call_data;
      
{
      ButtonOn((Widget) closure);
}

/*
 * Callbacks
 * 2) called when button is dead
 */
/* ARGSUSED */
static void
ButtonIsDead(w, closure, call_data)
      Widget            w;
      caddr_t         closure;
      caddr_t         call_data;
      
{
      Active             *ap;
      Widget            but = (Widget)closure;

      if (ap = LookActive(but)) {
            XtRemoveCallback(ap->popup, XtNdestroyCallback, PopupIsDead, but);
            DeleteFromActive(but);
      }
}

/*
 * Add a button to the active list
 */
static void
AddToActive(but, popup)
      Widget            but;
      Widget            popup;
{
      Active              *ap;

      if (LookActive(but) == NULL) {
            ap = (Active *) XtMalloc(sizeof (Active));
            ap->button = but;
            ap->popup = popup;
            ap->next = act;
            act = ap;
      } /* not convinced that the else arm here is a never happen */
}

static Active *
LookActive(but)
      Widget            but;
{
      Active             *ap;
      
      for (ap = act; ap; ap = ap->next) {
            if (ap->button == but)
                  return ap;
      }
      return NULL;
}

static Active *
LookPopup(popup)
      Widget            popup;
{
      Active             *ap;
      
      for (ap = act; ap; ap = ap->next) {
            if (ap->popup == popup)
                  return ap;
      }
      return NULL;
}

/*
 * remove an active entry
 */
static void
DeleteFromActive(but)
      Widget            but;
{
      Active             *ap;
      Active             *lp = NULL;

      for (ap = act; ap; ap = ap->next) {
            if (ap->button == but) {
                  if (lp == NULL) 
                        act = ap->next;
                  else
                        lp->next = ap->next;
                  XtFree((char *)ap);
                  return;
            }
            lp = ap;
      }
}


Generated by  Doxygen 1.6.0   Back to index