File:  [Research Unix] / researchv9 / X11 / src / X.V11R1 / clients / xmh / bbox.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:22:00 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#ifndef lint
static char rcs_id[] = "$Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/clients/xmh/bbox.c,v 1.1.1.1 2018/04/24 17:22:00 root Exp $";
#endif lint
/*
 *			  COPYRIGHT 1987
 *		   DIGITAL EQUIPMENT CORPORATION
 *		       MAYNARD, MASSACHUSETTS
 *			ALL RIGHTS RESERVED.
 *
 * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
 * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
 * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
 * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
 *
 * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
 * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
 * SET FORTH ABOVE.
 *
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting documentation,
 * and that the name of Digital Equipment Corporation not be used in advertising
 * or publicity pertaining to distribution of the software without specific,
 * written prior permission.
 */

/* bbox.c -- management of buttons and buttonbox's. */

/* This module implements a simple interface to buttonboxes, allowing a client
   to create new buttonboxes and manage their contents.  It is a layer hiding
   the toolkit interfaces. */

#include "xmh.h"
#include "bboxint.h"


/* Free the storage for the given button. */

FreeButton(button)
Button button;
{
    XtFree(button->name);
    XtFree((char *) button);
}



/* Handle a buttonbox getting resized.  In particular, tell the VPane widget
   the new range of legal sizes for this buttonbox. */

#ifdef X11
static XtEventReturnCode HandleBBoxResize(event, buttonbox)
XEvent *event;
ButtonBox buttonbox;
{
    switch (event->type) {
      case ConfigureNotify:
	if (event->xconfigure.height != buttonbox->maxheight) {
	    buttonbox->maxheight = event->xconfigure.height;
	    XtVPanedSetMinMax(DISPLAY buttonbox->scrn->window,
			      buttonbox->outer,
			      buttonbox->fullsized ? buttonbox->maxheight : 5,
			      buttonbox->maxheight);
	}
	return XteventHandled;
      case DestroyNotify:
	XtFree((char *) buttonbox->button);
	XtFree((char *) buttonbox);
	return XteventHandled;
    }
    return XteventNotHandled;
}
#endif X11

#ifdef X10
static XtEventReturnCode HandleBBoxResize(event, buttonbox)
XExposeEvent *event;
ButtonBox buttonbox;
{
    switch (event->type) {
      case ResizeWindow:
	if (event->height != buttonbox->maxheight) {
	    buttonbox->maxheight = event->height;
	    XtVPanedSetMinMax(DISPLAY buttonbox->scrn->window,
			      buttonbox->outer,
			      buttonbox->fullsized ? buttonbox->maxheight : 5,
			      buttonbox->maxheight);
	}
	return XteventHandled;
      case DestroyWindow:
	XtFree((char *) buttonbox->button);
	XtFree((char *) buttonbox);
	return XteventHandled;
    }
    return XteventNotHandled;
}
#endif X10    


/* Create a new button box.  The window for it will be a child of the given
   scrn's window, and it will be added to the scrn's vpane. */

ButtonBox BBoxRadioCreate(scrn, position, name, radio)
  Scrn scrn;
  int position;			/* Position to put it in the vpane. */
  char *name;			/* Name of the buttonbox widget. */
  Button *radio;		/* Pointer to place to store which radio
				   button is active. */
{
    static Arg arglist[] = {
	{XtNname, (XtArgVal)NULL},
	{XtNwidth, NULL},
	{XtNinnerWidth, NULL},
	{XtNallowVert, (XtArgVal)TRUE},
    };
    static Arg arglist2[] = {
	{XtNwidth, NULL},
    };
    int width, height;
    ButtonBox buttonbox;

    arglist[0].value = (XtArgVal)name;
    GetWindowSize(scrn->window, &width, &height);
    arglist[1].value = arglist[2].value = arglist2[0].value = (XtArgVal) width;
    buttonbox = (ButtonBox) XtMalloc(sizeof(ButtonBoxRec));
    bzero((char *)buttonbox, sizeof(ButtonBoxRec));
    buttonbox->updatemode = TRUE;
    buttonbox->scrn = scrn;
    buttonbox->outer = XtScrolledWindowCreate(DISPLAY scrn->window, arglist,
					      XtNumber(arglist));
    buttonbox->inner =
	XtButtonBoxCreate(DISPLAY XtScrolledWindowGetFrame(DISPLAY
							   buttonbox->outer),
			  arglist2, XtNumber(arglist2));
    XtScrolledWindowSetChild(DISPLAY buttonbox->outer, buttonbox->inner);
    buttonbox->numbuttons = 0;
    buttonbox->button = (Button *) XtMalloc(1);
    XtVPanedWindowAddPane(DISPLAY scrn->window, buttonbox->outer, position, 5,
			  5, FALSE);
    buttonbox->maxheight = 5;
    buttonbox->radio = radio;
    if (radio) *radio = NULL;
    XtSetEventHandler(DISPLAY buttonbox->inner, HandleBBoxResize,
#ifdef X11
		      StructureNotifyMask,
#endif
#ifdef X10
		      ExposeWindow,
#endif
		      (caddr_t) buttonbox);
    return buttonbox;
}



/* Create a new buttonbox which does not manage radio buttons. */

ButtonBox BBoxCreate(scrn, position, name)
  Scrn scrn;
  int position;
  char *name;
{
    return BBoxRadioCreate(scrn, position, name, (Button *)NULL);
}



/* Set the current button in a radio buttonbox. */

void BBoxSetRadio(buttonbox, button)
ButtonBox buttonbox;
Button button;
{
    if (buttonbox->radio && *(buttonbox->radio) != button) {
	if (*(buttonbox->radio)) FlipColors(*(buttonbox->radio));
	FlipColors(button);
	*(buttonbox->radio) = button;
    }
}



/* Some buttons have been added to the buttonbox structure; go and actually
   add the button widgets to the buttonbox widget.  (It is much more
   efficient to add several buttons at once rather than one at a time.) */

static ProcessAddedButtons(buttonbox)
ButtonBox buttonbox;
{
    int i, position, index;
    ArgList arglist, ptr;
    Button button;
    if (buttonbox->updatemode == FALSE) {
	buttonbox->needsadding = TRUE;
	return;
    }
    position = 0;
    ptr = arglist = (ArgList)
	XtMalloc((unsigned)sizeof(Arg) * (buttonbox->numbuttons + 1));
    for (i=0 ; i<buttonbox->numbuttons ; i++) {
	button = buttonbox->button[i];
	if (button->needsadding) {
	    if (ptr == arglist) {
		ptr->name = XtNindex;
		index = position;
		ptr->value = (XtArgVal)index;
		ptr++;
	    }
	    ptr->name = XtNwindow;
	    ptr->value = (XtArgVal)(button->window);
	    ptr++;
	    button->needsadding = FALSE;
	} else if (ptr != arglist) {
	    (void)XtButtonBoxAddButton(DISPLAY buttonbox->inner,
				       arglist, ptr-arglist);
	    ptr = arglist;
	}
	position++;
    }
    if (ptr != arglist) {
	(void)XtButtonBoxAddButton(DISPLAY buttonbox->inner,
				   arglist, ptr-arglist);
    }
    XtFree((char *) arglist);
    buttonbox->needsadding = FALSE;
}



/* Create a new button, and add it to a buttonbox. */

void BBoxAddButton(buttonbox, name, func, position, enabled)
  ButtonBox buttonbox;
  char *name;			/* Name of button. */
  void (*func)();		/* Func to call when button pressed. */
  int position;			/* Position to put button in box. */
  int enabled;			/* Whether button is initially enabled. */
{
    extern void DoButtonPress();
    Button button;
    int i;
    static Arg arglist[] = {
	{XtNname, NULL},
	{XtNfunction, (XtArgVal)DoButtonPress},
	{XtNparameter, NULL},
    };
    if (position > buttonbox->numbuttons) position = buttonbox->numbuttons;
    buttonbox->numbuttons++;
    buttonbox->button = (Button *)
	XtRealloc((char *) buttonbox->button,
		  (unsigned) buttonbox->numbuttons * sizeof(Button));
    for (i=buttonbox->numbuttons-1 ; i>position ; i--)
	buttonbox->button[i] = buttonbox->button[i-1];
    button = buttonbox->button[position] =
	(Button) XtMalloc(sizeof(ButtonRec));
    bzero((char *) button, sizeof(ButtonRec));
    arglist[0].value = (XtArgVal)name;
    arglist[2].value = (XtArgVal)button;
    button->buttonbox = buttonbox;
    button->name = MallocACopy(name);
    button->window = XtCommandCreate(DISPLAY buttonbox->inner, arglist,
				     XtNumber(arglist));
    button->func = func;
    button->needsadding = TRUE;
    button->enabled = TRUE;
    if (!enabled) BBoxDisable(button);
    ProcessAddedButtons(buttonbox);
    if (buttonbox->radio && *(buttonbox->radio) == NULL) {
	*(buttonbox->radio) = button;
	FlipColors(button);
    }
}



/* Remove the given button from its buttonbox.  The button widget is
   destroyed.  If it was the current button in a radio buttonbox, then the
   current button becomes the first button in the box. */

void BBoxDeleteButton(button)
Button button;
{
    ButtonBox buttonbox = button->buttonbox;
    int i, found, reradio;
    static Arg arglist[] = {
	{XtNwindow, (XtArgVal)NULL}
    };
    found = FALSE;
    for (i=0 ; i<buttonbox->numbuttons; i++) {
	if (found) buttonbox->button[i-1] = buttonbox->button[i];
	else if (buttonbox->button[i] == button) {
	    found = TRUE;
	    arglist[0].value = (XtArgVal) button->window;
	    (void)XtButtonBoxDeleteButton(DISPLAY buttonbox->inner,
					  arglist, XtNumber(arglist));
	    QXDestroyWindow(theDisplay, button->window);
	    (void) XtSendDestroyNotify(DISPLAY button->window);
	    reradio = (buttonbox->radio && *(buttonbox->radio) == button);
	    FreeButton(button);
	}
    }
    if (found) {
	buttonbox->numbuttons--;
	if (reradio) {
	    *(buttonbox->radio) = NULL;
	    if (buttonbox->numbuttons)
		BBoxSetRadio(buttonbox, buttonbox->button[0]);
	}
    }
}
	    


/* Enable or disable the given command button widget. */

static void SendEnableMsg(window, value)
Window window;
int value;			/* TRUE for enable, FALSE for disable. */
{
    static Arg arglist[] = {XtNsensitive, NULL};
    arglist[0].value = (XtArgVal) value;
    XtCommandSetValues(DISPLAY window, arglist, XtNumber(arglist));
}



/* Enable the given button (if it's not already). */

void BBoxEnable(button)
Button button;
{
    if (!button->enabled) {
	button->enabled = TRUE;
	SendEnableMsg(button->window, TRUE);
    }
}



/* Disable the given button (if it's not already). */

void BBoxDisable(button)
Button button;
{
    if (button->enabled) {
	button->enabled = FALSE;
	SendEnableMsg(button->window, FALSE);
    }
}


/* Given a buttonbox and a button name, find the button in the box with that
   short name. */

Button BBoxFindButtonNamed(buttonbox, name)
ButtonBox buttonbox;
char *name;
{
    int i;
    for (i=0 ; i<buttonbox->numbuttons; i++)
	if (strcmp(name, buttonbox->button[i]->name) == 0)
	    return buttonbox->button[i];
    return NULL;
}



/* Return the nth button in the given buttonbox. */

Button BBoxButtonNumber(buttonbox, n)
ButtonBox buttonbox;
int n;
{
    return buttonbox->button[n];
}



/* Return how many buttons are in a buttonbox. */

int BBoxNumButtons(buttonbox)
ButtonBox buttonbox;
{
    return buttonbox->numbuttons;
}


/* Given a button, return its name. */

char *BBoxNameOfButton(button)
Button button;
{
    return button->name;
}



/* The client calls this routine before doing massive updates to a buttonbox.
   It then must call BBoxStartUpdate when it's finished.  This allows us to
   optimize things.  Right now, the only optimization performed is to batch
   together requests to add buttons to a buttonbox. */

void BBoxStopUpdate(buttonbox)
ButtonBox buttonbox;
{
    buttonbox->updatemode = FALSE;
}



/* The client has finished its massive updates; go and handle any batched
   requests. */

void BBoxStartUpdate(buttonbox)
ButtonBox buttonbox;
{
    buttonbox->updatemode = TRUE;
    if (buttonbox->needsadding) ProcessAddedButtons(buttonbox);
}



/* Set things to always display the entire contents of this buttonbox.  In
   otherwords, tells the VPane to not let the user make this pane any smaller
   than the buttonbox. */

void BBoxForceFullSize(buttonbox)
ButtonBox buttonbox;
{
#ifdef X10	/* X10 toolkit doesn't have magic configurenotify events */
    WindowInfo info;
    XQueryWindow(buttonbox->inner, &info);
    buttonbox->maxheight = info.height;
#endif
    XtVPanedSetMinMax(DISPLAY buttonbox->scrn->window, buttonbox->outer, 
		      buttonbox->maxheight, buttonbox->maxheight);
    buttonbox->fullsized = TRUE;
}


/* Set things to allow the user to show only part of a buttonbox.  This is the
   default action. */

void BBoxAllowAnySize(buttonbox)
ButtonBox buttonbox;
{
#ifdef X10
    BBoxForceFullSize(buttonbox); /* VERY hackish; works only because of the
				     limited way I use BBoxForceFullSize.%%% */
#endif
    XtVPanedSetMinMax(DISPLAY buttonbox->scrn->window, buttonbox->outer, 
		      5, buttonbox->maxheight);
    buttonbox->fullsized = FALSE;
}



/* Destroy the given buttonbox. */

void BBoxDeleteBox(buttonbox)
ButtonBox buttonbox;
{
    if (buttonbox->radio) *(buttonbox->radio) = NULL;
    QXDestroyWindow(theDisplay, buttonbox->outer);
    (void) XtSendDestroyNotify(DISPLAY buttonbox->outer);
}



/* Change the borderwidth of the given button. */

void BBoxChangeBorderWidth(button, borderWidth)
Button button;
unsigned int borderWidth;
{
#ifdef X11
    XSetWindowBorderWidth(DISPLAY button->window, borderWidth);
#endif
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.