home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-05-26 | 79.1 KB | 2,928 lines |
- Newsgroups: comp.sources.x
- From: daven@ctron.com ("David N. Nedde")
- Subject: v20i003: xball - simulate bouncing balls in a window, Part03/05
- Message-ID: <1993May24.202855.24118@sparky.imd.sterling.com>
- X-Md4-Signature: e6b47154145105c76681b5d0c0bea571
- Sender: chris@sparky.imd.sterling.com (Chris Olson)
- Organization: Sterling Software
- Date: Mon, 24 May 1993 20:28:55 GMT
- Approved: chris@sparky.imd.sterling.com
-
- Submitted-by: daven@ctron.com ("David N. Nedde")
- Posting-number: Volume 20, Issue 3
- Archive-name: xball/part03
- Environment: X11, OSF/Motif, Athena
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 5)."
- # Contents: item.c menu.c room.c scrollbar.c sim.c table.c intf.h
- # miscx.h
- # Wrapped by daven@osiris on Tue May 4 16:35:08 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'item.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'item.c'\"
- else
- echo shar: Extracting \"'item.c'\" \(22401 characters\)
- sed "s/^X//" >'item.c' <<'END_OF_FILE'
- X/**********************************************************************
- X * item.c - defines the item object
- X *
- X * Copyright 1993, David Nedde
- X *
- X * Permission to use, copy, modify, and distribute this software
- X * and its documentation for any purpose and without fee is granted
- X * provided that the above copyright notice appears in all copies.
- X * It is provided "as is" without express or implied warranty.
- X **********************************************************************/
- X
- X/* System Headers */
- X#include <stdlib.h>
- X#include <X11/StringDefs.h>
- X
- X#ifdef MOTIF
- X#include <Xm/ToggleB.h>
- X#endif
- X
- X/* Local headers */
- X#include "item.h"
- X#include "room.h"
- X#include "scrollbar.h"
- X#include "color_l.h"
- X#include "menu.h"
- X#include "misc.h"
- X#include "stipple.xbm"
- X
- X/* Macros */
- X#define SHADES 4 /* Number of shades for colors in the rgb.txt file */
- X#define ITEM_WIDTH 10 /* The item's default size */
- X#define ITEM_HEIGHT 10
- X#ifndef RGB_TXT
- X#define RGB_TXT "/usr/lib/X11/rgb.txt"
- X#endif
- X
- X/* put_pixmap - Draws the item's pixmap to the specified location */
- X#define put_pixmap( item, x, y) \
- X XCopyArea(item->display, item->pixmap, item->window, \
- X item->static_data->gc, \
- X 0, 0, \
- X item->static_data->width, \
- X item->static_data->height, \
- X intf2int(x) - item->static_data->half_width, \
- X intf2int(y) - item->static_data->half_height)
- X
- X/* File scope variables */
- Xstatic item_static_struct_type static_struct; /* Item object static data */
- Xitem_static_type static_data = &static_struct;
- Xstatic Bool static_data_initted = False;
- X
- X/* Resources */
- Xtypedef struct {
- X int item_width;
- X int item_height;
- X char * rgb_txt;
- X int elasticity;
- X} app_data,*app_data_ptr;
- Xstatic app_data res_data;
- Xstatic XtResource resources[] = {
- X { "itemWidth", "ItemWidth", XtRInt, sizeof(int),
- X XtOffset(app_data_ptr,item_width), XtRImmediate, (caddr_t)ITEM_WIDTH },
- X { "itemHeight", "ItemHeight", XtRInt, sizeof(int),
- X XtOffset(app_data_ptr,item_height),XtRImmediate, (caddr_t)ITEM_HEIGHT},
- X { "rgbTxt", "RgbTxt", XtRString, sizeof(char *),
- X XtOffset(app_data_ptr,rgb_txt), XtRString, RGB_TXT}
- X};
- X
- X/* Functions */
- Xstatic item_static_type static_data__create(/*display, window, background*/);
- Xstatic void draw_item(/* static_data, display, clear_gc, colors,
- X pixmap, background*/);
- Xstatic void draw_circle(/* display, pixmap,
- X x_offset, y_offset,
- X width, height*/);
- Xstatic void draw_black_ball(/* display, background*/);
- Xstatic void draw_ball(/* display, pixmap, x_offset, y_offset,
- X width, height*/);
- X
- X
- X/* Public object methods */
- X
- X/* Create the item object. The item is the thing that bounces on the screen */
- X/* The item is drawn to the screen after it is created */
- Xitem_type item__create( x, y, x_vel, y_vel)
- Xint x;
- Xint y;
- Xint x_vel;
- Xint y_vel;
- X{
- X item_type item;
- X
- X
- X item = (item_type)malloc( sizeof( item_struct_type));
- X
- X item->static_data = static_data;
- X
- X item->display = static_data->display;
- X item->window = static_data->window;
- X
- X /* Draw with the next avaliable pixmap image (color) */
- X static_data->curr_pixmap =
- X (static_data->curr_pixmap + 1) % static_data->num_colors;
- X
- X item->pixmap = static_data->pixmaps[ static_data->curr_pixmap];
- X
- X /* Position are stored as intf (int-floats) to get more precision
- X out of an int */
- X item->x = int2intf( x);
- X item->y = int2intf( y);
- X item->x_vel = int2intf( x_vel);
- X item->y_vel = int2intf( y_vel);
- X item->shown = False;
- X
- X item->rebounded = False;
- X
- X item__draw( item);
- X
- X#if 0
- X /* To generate demos */
- X printf("create %d,%d,%d,%d\n",
- X intf2int(item->x),intf2int(item->y),
- X intf2int(item->x_vel),intf2int(item->y_vel));
- X#endif
- X
- X return item;
- X}
- X
- X
- X/* Initializes the item's static data. This can only be done once
- X there is a window, sice we have to get the background color. Thus, we
- X are called from room's first refresh callback */
- Xvoid item__init(toplevel, display, window, background)
- XWidget toplevel;
- XDisplay * display;
- XWindow window;
- XPixel background;
- X{
- X static_data = static_data__create( toplevel, display, window, background);
- X static_data_initted = True;
- X}
- X
- X/* Returns true of the item's static data is initialized */
- XBool item__initted()
- X{
- X return static_data_initted;
- X}
- X
- X
- X/* Destroys an item */
- Xvoid item__destroy( item)
- Xitem_type item;
- X{
- X item__undraw( item, item->x, item->y); /* Erase item from screen */
- X
- X free( (char *)item);
- X}
- X
- X
- X/* Draws the item to the screen if it is visible. Handles the case
- X where the item was already visible on the screen. */
- Xvoid item__draw( item)
- Xitem_type item;
- X{
- X if (!item->shown && item->static_data->visible)
- X {
- X put_pixmap( item, item->x, item->y);
- X item->shown = True;
- X }
- X}
- X
- X
- X/* Erases the item from the screen */
- X
- Xvoid item__undraw( item, x, y)
- Xitem_type item;
- Xintf x,y;
- X{
- X if (item->shown && item->static_data->visible)
- X {
- X put_pixmap( item, x, y);
- X item->shown = False;
- X }
- X}
- X
- X
- X/* Redraws the item on the screen, regardless of whether it is shown.
- X This method shoulw be used when the window has to be refreshed.
- X invisible items will not be drawn. */
- Xvoid item__redraw( item)
- Xitem_type item;
- X{
- X if (item->static_data->visible)
- X {
- X put_pixmap( item, item->x, item->y);
- X item->shown = True;
- X }
- X}
- X
- X
- X/* Move an item's image to a new location */
- Xvoid item__move_pos( item, x, y)
- Xitem_type item;
- Xint x,y;
- X{
- X item__undraw( item, item->x, item->y);
- X
- X item->x = int2intf(x);
- X item->y = int2intf(y);
- X
- X item__draw( item);
- X}
- X
- X
- X/* Give an item a random velocity, based on the passed ranges */
- Xvoid item__randomize( item, min_x_vel, max_x_vel, min_y_vel, max_y_vel)
- Xitem_type item;
- Xint min_x_vel;
- Xint max_x_vel;
- Xint min_y_vel;
- Xint max_y_vel;
- X{
- X item->x_vel = int2intf(rand_range( min_x_vel, max_x_vel));
- X item->y_vel = int2intf(rand_range( min_y_vel, max_y_vel));
- X}
- X
- X
- X/* Perform one item movement iteration, taking into account other
- X balls, gravity, elasticity, and the room boundaries. The item's new
- X position is calculated and the item's image is moved to the new
- X location. Invisible items are not redrawn. */
- Xvoid item__move( item, room, items)
- Xitem_type item;
- Xroom_type room;
- Xitems_type items;
- X{
- X /* Calculate new position of item */
- X
- X intf oldx = item->x;
- X intf oldy = item->y;
- X
- X /* Calculate new y position */
- X /* Gravity adds to velocity */
- X if ((item->y < room__get_floor( room)) || (item->y_vel != 0))
- X {
- X item->y_vel += room__get_gravity( room);
- X }
- X
- X
- X /* Move vertically based on velocity */
- X item->y += item->y_vel;
- X
- X if (item->y >= room__get_floor( room))
- X {
- X /* item hit floor -- bounce off floor */
- X
- X /* Reverse ball velocity */
- X item->y_vel = -item->y_vel;
- X
- X item->y += item->y_vel;
- X
- X if (ABS(item->y_vel) < room__get_gravity(room))
- X /* This helps dampen rounding errors that cause balls to
- X bounce forever */
- X item->y_vel = 0;
- X else
- X {
- X /* Ball velocity is reduced by the percentage elasticity */
- X item->y_vel *= item->static_data->elasticity;
- X#if 1
- X item->y = room__get_floor( room) -
- X (room__get_floor( room) - item->y) *
- X item->static_data->elasticity;
- X#else
- X item->y = -item->y + room__get_floor( room)*2;
- X#endif
- X }
- X }
- X else
- X if (item->y < room__get_ceiling( room))
- X {
- X /* Reverse ball velocity */
- X item->y_vel = -item->y_vel;
- X
- X /* Ball velocity is reduced by the percentage elasticity */
- X item->y_vel *= item->static_data->elasticity;
- X
- X /* Bounce off the wall */
- X item->y = -item->y + room__get_ceiling( room)*2;
- X }
- X
- X
- X /* Calculate new x position */
- X /* Move horizontally based on velocity */
- X item->x += item->x_vel;
- X
- X if (item->x > room__get_right_wall(room))
- X {
- X /* Hit right wall */
- X /* Reverse ball velocity */
- X item->x_vel = -item->x_vel;
- X
- X /* Ball velocity is reduced by the percentage elasticity */
- X item->x_vel *= item->static_data->elasticity;
- X
- X /* Bounce off the wall */
- X item->x = -item->x + room__get_right_wall( room)*2;
- X }
- X else
- X if (item->x < room__get_left_wall( room))
- X {
- X /* Hit left wall */
- X /* Reverse ball velocity */
- X item->x_vel = -item->x_vel;
- X
- X /* Ball velocity is reduced by the percentage elasticity */
- X item->x_vel *= item->static_data->elasticity;
- X
- X /* Bounce off the wall */
- X item->x = -item->x + room__get_left_wall( room)*2;
- X }
- X
- X
- X /* Slow ball if it is rolling on the floor */
- X
- X if (ABS(item->y) >= room__get_floor(room) - room__get_gravity(room) &&
- X item->y_vel == 0)
- X item->x_vel *= item->static_data->elasticity;
- X
- X
- X /* Collide with other balls or ball being created */
- X if (item->static_data->ball_collide)
- X {
- X /* See if collided with the ball under the pointer being created */
- X item_type room_item = room__get_item( room);
- X if (room_item != (item_type)0)
- X {
- X item__rebound_item(item, room_item);
- X }
- X
- X /* See if collided with another item */
- X items__rebound_items( item, items);
- X }
- X
- X /* See if item has come to a peaceful rest */
- X if (item__stopped(item, room))
- X {
- X /* on floor && Not bouncing */
- X if (item->static_data->perpetual)
- X {
- X /* Just drop the ball from the ceiling */
- X item->y = room__get_ceiling( room);
- X }
- X else
- X {
- X if (item__stopped( item, room))
- X {
- X item__undraw( item, oldx, oldy);
- X return; /* Don't draw item */
- X }
- X
- X /* Slow down velocity once rolling based on elasticity */
- X if (item->x_vel > 0)
- X item->x_vel *= item->static_data->elasticity;
- X }
- X }
- X
- X /* If item moved, redraw it in the new position */
- X if ((item->y != oldy || item->x != oldx) && static_data->visible)
- X {
- X /* Erase old object */
- X item__undraw( item, oldx, oldy);
- X item__draw( item);
- X }
- X}
- X
- X
- X
- X/* See if items have hit and rebound them if they have.
- X Moved_item is assumed to have just been moved.
- X Only the moved item will have its x,y positions potentially changed. */
- Xvoid item__rebound_item( moved_item, fixed_item)
- Xitem_type moved_item;
- Xitem_type fixed_item;
- X{
- X intf xdiff,ydiff;
- X
- X xdiff = moved_item->x - fixed_item->x;
- X ydiff = moved_item->y - fixed_item->y;
- X
- X if (ABS(xdiff) < int2intf(moved_item->static_data->width) &&
- X ABS(ydiff) < int2intf(moved_item->static_data->height))
- X {
- X SWAP( moved_item->x_vel, fixed_item->x_vel, intf);
- X SWAP( moved_item->y_vel, fixed_item->y_vel, intf);
- X
- X if (moved_item->y_vel <= int2intf(moved_item->static_data->height) &&
- X fixed_item->y_vel <= int2intf(moved_item->static_data->height))
- X {
- X moved_item->y += moved_item->y_vel;
- X moved_item->y_vel += ydiff * moved_item->static_data->elasticity/10;
- X fixed_item->y_vel -= ydiff * moved_item->static_data->elasticity/10;
- X }
- X if (moved_item->x_vel <= int2intf(moved_item->static_data->width) &&
- X fixed_item->x_vel <= int2intf(moved_item->static_data->width))
- X {
- X moved_item->x += moved_item->x_vel;
- X moved_item->x_vel += xdiff * moved_item->static_data->elasticity/10;
- X fixed_item->x_vel -= xdiff * moved_item->static_data->elasticity/10;
- X }
- X }
- X}
- X
- X
- X/* A scrollbar callback method that sets all the balls' elasticity */
- Xvoid item__set_elasticity_cb(w, closure, call_data)
- XWidget w;
- Xcaddr_t closure;
- XscrollbarCallbackStruct * call_data;
- X{
- X static_data->elasticity = call_data->value / 100.0;
- X}
- X
- X
- X/* Return all items' width */
- Xint item__get_width()
- X{
- X return static_data->width;
- X}
- X
- X
- X/* Return all items' height */
- Xint item__get_height()
- X{
- X return static_data->height;
- X}
- X
- X
- X/* A menu callback (mcb) that sets all items' perpetual status */
- Xvoid item__perpetual_mcb(w, closure, call_data, extra)
- XWidget w;
- Xcaddr_t closure;
- XmenuCallbackStruct * call_data;
- Xchar * extra;
- X{
- X static_data->perpetual = call_data->set;
- X}
- X
- X
- X/* A menu callback (mcb) that sets all items' collide status */
- Xvoid item__collide_mcb(w, closure, call_data, extra)
- XWidget w;
- Xcaddr_t closure;
- XmenuCallbackStruct * call_data;
- Xchar *extra;
- X{
- X static_data->ball_collide = call_data->set;
- X}
- X
- X
- X/* Semi-private object methods */
- X
- X/* Sets all items' perpetual status */
- X/* Note that the toggle must be set properly also */
- Xvoid item__set_perpetual(set)
- XBool set;
- X{
- X static_data->perpetual = set;
- X}
- X
- X
- X/* Sets all items' collide status */
- X/* Note that the toggle must be set properly also */
- Xvoid item__set_ball_collide(set)
- XBool set;
- X{
- X static_data->ball_collide = set;
- X}
- X
- X
- X/* Set all item's visible status */
- X/* Note that all items must be undrawn from the screen */
- Xvoid item__set_visible(visible)
- XBool visible;
- X{
- X static_data->visible = visible;
- X}
- X
- X
- X/* Private object methods */
- X
- X/* Load items resources */
- Xstatic void get_resources( toplevel, display, window, background)
- XWidget toplevel;
- XDisplay *display;
- XWindow window;
- XPixel background;
- X{
- X XtGetApplicationResources(toplevel, (XtPointer)&res_data,
- X resources, XtNumber(resources),
- X (ArgList)NULL,(Cardinal)0);
- X
- X static_data->width = res_data.item_width;
- X static_data->height = res_data.item_height;
- X static_data->half_width = static_data->width / 2;
- X static_data->half_height = static_data->height / 2;
- X static_data->rgb_txt = res_data.rgb_txt;
- X}
- X
- X
- X/* Initialize the item's static data object */
- Xstatic item_static_type static_data__create( toplevel, display, window,
- X background)
- XWidget toplevel;
- XDisplay * display;
- XWindow window;
- XPixel background;
- X{
- X GC clear_gc;
- X
- X
- X /* The following already set in xball_sys object:
- X static_data->elasticity
- X static_data->ball_collide
- X static_data->perpetual */
- X
- X get_resources( toplevel, display, window, background);
- X
- X static_data->visible = True;
- X static_data->background = background;
- X
- X
- X static_data->display = display;
- X static_data->window = window;
- X static_data->gc = XCreateGC(display, window, 0, 0);
- X clear_gc = XCreateGC(display, window, 0, 0);
- X static_data->curr_pixmap = 0;
- X
- X
- X if (DisplayCells( display, DefaultScreen(display)) > 2)
- X {
- X /* Non-monochrome system */
- X color_list_type color_list = color_list__create(static_data->rgb_txt);
- X color_type color;
- X Colormap colormap = DefaultColormap(display, DefaultScreen(display));
- X XColor colors[ SHADES]; /* The color shades */
- X Pixel cells[ SHADES];
- X int pixmap_index;
- X int shade;
- X
- X
- X for (shade = 0; shade < SHADES; shade++)
- X colors[ shade].flags = DoRed | DoGreen | DoBlue;
- X
- X for (color = color_list__get_last( color_list), pixmap_index = 0;
- X color != (color_type)0;
- X pixmap_index++)
- X {
- X if (!XAllocColorCells( display, colormap, /*contig =*/True,
- X /*plane_masks=*/NULL, /*nplanes=*/0,
- X /*pixels =*/cells, /*ncolors=*/SHADES))
- X break; /* All out of colors */
- X
- X for (shade = SHADES-1; shade >= 0; shade--)
- X {
- X colors[ shade].red = color->r * 65535 / 255;
- X colors[ shade].green = color->g * 65535 / 255;
- X colors[ shade].blue = color->b * 65535 / 255;
- X colors[ shade].pixel = cells[ shade];
- X
- X color = color_list__get_prev( color_list);
- X }
- X
- X if (shade == -1)
- X {
- X XStoreColors( display, colormap, colors, SHADES);
- X }
- X else
- X {
- X /* Problem with color list */
- X pixmap_index--;
- X XFreeColors( display, colormap, cells, SHADES,
- X /*nplanes=*/0);
- X break;
- X }
- X
- X static_data->pixmaps[ pixmap_index] =
- X XCreatePixmap(display, window,
- X static_data->width,static_data->height,
- X DefaultDepth(display, DefaultScreen(display)));
- X
- X /* Draw the item onto the pixmap */
- X draw_item(static_data, display, clear_gc, colors,
- X static_data->pixmaps[ pixmap_index], background);
- X }
- X
- X /* printf("Created %d different colored balls (%d possible).\n",
- X pixmap_index, color_list__get_count( color_list) / 4); */
- X
- X color_list__destroy( color_list);
- X
- X static_data->num_colors = pixmap_index;
- X }
- X
- X
- X if ((static_data->num_colors == 0) ||
- X (DisplayCells( display, DefaultScreen(display)) == 2))
- X {
- X /* Monochrome system or cannot allocate colors -
- X just have 1 pixmap of a black ball */
- X draw_black_ball( display, background);
- X }
- X
- X
- X XFreeGC( display, clear_gc);
- X
- X XSetFunction( display, static_data->gc, GXxor);
- X
- X return static_data;
- X}
- X
- X
- X
- X
- X/* Draw an item in the passed colors on the passed pixmap */
- Xstatic void draw_item( static_data, display, clear_gc, colors, pixmap,
- X background)
- Xitem_static_type static_data;
- XDisplay *display;
- XGC clear_gc;
- XXColor *colors;
- XPixmap pixmap;
- XPixel background;
- X{
- X static struct
- X {
- X double x_offset, y_offset; /* The circle's offset on the item */
- X double width, height; /* The width & height of the circle */
- X } offsets[SHADES-1] =
- X {
- X 0.2, 0.2, 0.3, 0.3,
- X 0.1, 0.1, 0.5, 0.5,
- X 0.0, 0.0, 0.8, 0.8
- X };
- X int x;
- X
- X
- X /* Clear pixmap */
- X XFillRectangle(display, pixmap, clear_gc, 0, 0,
- X static_data->width,
- X static_data->height);
- X
- X XSetForeground( display, static_data->gc,
- X colors[SHADES-1].pixel ^ background);
- X draw_circle(display, pixmap, static_data->gc,
- X 0, 0, static_data->width-1, static_data->height-1);
- X
- X /* Draw the circles in the different shades. Shade SHADES-1 is darkest. */
- X for (x = SHADES-2; x >= 0; x--)
- X {
- X XSetForeground(display, static_data->gc, colors[x].pixel ^ background);
- X draw_ball( display, pixmap,
- X offsets[x].x_offset, offsets[x].y_offset,
- X offsets[x].width, offsets[x].height);
- X }
- X
- X /* Draw a white specularity smallest and offset */
- X XSetForeground(display, static_data->gc,
- X WhitePixel(display, DefaultScreen(display)) ^ background);
- X draw_ball( display, pixmap, 0.3, 0.3, 0.1, 0.1);
- X
- X /* Draw a little black shadow in the lower right corner */
- X XSetForeground(display, static_data->gc,
- X BlackPixel(display, DefaultScreen(display)) ^ background);
- X XDrawArc(display, pixmap, static_data->gc, 0, 0,
- X static_data->width - 1, static_data->height - 1,
- X 300*64, 35*64);
- X}
- X
- X
- X/* Draw a circle outline and filling at the size and offet determined by
- X the ball's size */
- Xstatic void draw_ball( display, pixmap, x_offset, y_offset, width, height)
- XDisplay * display;
- XPixmap pixmap;
- Xdouble x_offset, y_offset;
- Xdouble width, height;
- X{
- X draw_circle( display, pixmap, static_data->gc,
- X (int)(static_data->width * x_offset),
- X (int)(static_data->height * y_offset),
- X (int)(static_data->width * width),
- X (int)(static_data->height * height));
- X}
- X
- X
- X/* Draw a filled circle of the specified size and position */
- Xstatic void draw_circle( display, pixmap, gc, x, y, width, height)
- XDisplay * display;
- XPixmap pixmap;
- XGC gc;
- Xint x, y;
- Xint width, height;
- X{
- X XDrawArc(display, pixmap, static_data->gc, x, y, width, height, 0, 360*64);
- X XFillArc(display, pixmap, static_data->gc, x, y, width, height, 0, 360*64);
- X}
- X
- X
- X/* Draw a black ball onto the first pixmap */
- Xstatic void draw_black_ball( display, background)
- XDisplay * display;
- XPixel background;
- X{
- X Pixmap stipple_bitmap =
- X XCreateBitmapFromData( display,
- X RootWindow( display, DefaultScreen( display)),
- X stipple_bits, stipple_width, stipple_height);
- X
- X static_data->pixmaps[ 0] =
- X XCreatePixmap(display,
- X RootWindow(display, DefaultScreen(display)),
- X static_data->width,
- X static_data->height,
- X DefaultDepth( display, DefaultScreen(display)));
- X
- X /* Reset all pixels in the background so they will not have
- X any effect when the pixmap is xor-copied */
- X XSetBackground(display, static_data->gc, 0);
- X XFillRectangle(display, static_data->pixmaps[0], static_data->gc, 0, 0,
- X static_data->width, static_data->height);
- X
- X XSetForeground(display, static_data->gc,
- X BlackPixel(display,DefaultScreen(display)) ^background);
- X
- X /* Draw item */
- X draw_circle( display, static_data->pixmaps[0], static_data->gc, 0, 0,
- X static_data->width-1, static_data->height-1);
- X
- X /* draw a grey specularity small and offset */
- X XSetStipple( display, static_data->gc, stipple_bitmap);
- X XSetFillStyle( display, static_data->gc, FillOpaqueStippled);
- X
- X draw_ball( display, static_data->pixmaps[0], 0.2, 0.2, 0.3, 0.3);
- X
- X XSetFillStyle( display, static_data->gc, FillSolid);
- X
- X
- X /* draw a white specularity smallest and offset */
- X XSetForeground(display, static_data->gc,
- X WhitePixel(display,DefaultScreen(display)) ^background);
- X
- X draw_ball( display, static_data->pixmaps[0], 0.3, 0.3, 0.1, 0.1);
- X
- X
- X static_data->num_colors = 1;
- X
- X XFreePixmap( display, stipple_bitmap);
- X}
- X
- X
- X#ifdef DEBUG
- X
- Xitem__print( item)
- Xitem_type item;
- X{
- X printf("x,y_pos: %4d,%4d; x,y_vel: %4d,%4d, collide = %d\n",
- X item__get_x( item), item__get_y( item),
- X item__get_x_vel( item), item__get_y_vel( item),
- X (int)static_data->ball_collide);
- X
- X}
- X
- X#endif
- X
- END_OF_FILE
- if test 22401 -ne `wc -c <'item.c'`; then
- echo shar: \"'item.c'\" unpacked with wrong size!
- fi
- # end of 'item.c'
- fi
- if test -f 'menu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'menu.c'\"
- else
- echo shar: Extracting \"'menu.c'\" \(18009 characters\)
- sed "s/^X//" >'menu.c' <<'END_OF_FILE'
- X/**********************************************************************
- X * menu.c - defines the menu object
- X *
- X * Copyright 1993, David Nedde
- X *
- X * Permission to use, copy, modify, and distribute this software
- X * and its documentation for any purpose and without fee is granted
- X * provided that the above copyright notice appears in all copies.
- X * It is provided "as is" without express or implied warranty.
- X **********************************************************************/
- X
- X/* System Headers */
- X#include <stdio.h>
- X#include <string.h>
- X#include <sys/types.h>
- X#include <ctype.h> /* For isspace */
- X
- X#include <X11/StringDefs.h>
- X#include <X11/Intrinsic.h>
- X
- X#ifdef MOTIF
- X#include <Xm/Xm.h>
- X#include <Xm/RowColumn.h>
- X#include <Xm/CascadeB.h>
- X#include <Xm/PushBG.h>
- X#include <Xm/SeparatoG.h>
- X#include <Xm/ToggleBG.h>
- X#endif
- X
- X#ifdef ATHENA
- X#include <X11/Xaw/Box.h>
- X#include <X11/Xaw/Form.h>
- X#include <X11/Xaw/SmeBSB.h>
- X#include <X11/Xaw/SmeLine.h>
- X#include <X11/Xaw/MenuButton.h>
- X#include <X11/Xaw/SimpleMenu.h>
- X#endif
- X
- X/* Local headers */
- X#include "menu.h"
- X#include "misc.h"
- X#include "table.h"
- X#include "miscx.h"
- X
- X#ifdef ATHENA
- X#include "on.xbm"
- X#include "off.xbm"
- X#endif
- X
- X/* Macros */
- X#define WPATH_LEN 40
- X
- X/* File scope variables */
- Xtypedef struct {
- X char *menu_def;
- X} app_data,*app_data_ptr;
- Xstatic app_data res_data;
- Xstatic XtResource resources[] = {
- X { "menuDef", "MenuDef", XtRString, sizeof(char *),
- X XtOffset( app_data_ptr, menu_def), XtRString, NULL}
- X};
- X
- X/* Structures */
- Xtypedef struct {
- X char * name;
- X menuCallbackProc proc;
- X caddr_t closure;
- X} menuCallback;
- X
- Xtypedef struct {
- X char * menu_callback_name;
- X char * optional_params;
- X char * widget_class;
- X} closure_type;
- X
- X/* Functions */
- Xstatic void menu_callback(/* w, menu, call_data*/);
- Xstatic void create_menus(/*menu, menubar, menu_def*/);
- Xstatic void create_menubar(/* menu, form, name*/);
- Xstatic void set_widget_and_do_callback(/* menu, w, set*/);
- Xstatic void set_widget_state(/* menu, w, state*/);
- Xstatic Widget get_menu_widget(/* menu, widget_name*/);
- Xstatic Bool get_widget_state(/* menu, w*/);
- Xstatic Widget create_pulldown(/* menubar, menu_button_name, pull_down_name*/);
- Xstatic WidgetClass * get_pushbutton_class(/**/);
- Xstatic char * get_pushbutton_callback(/**/);
- Xstatic WidgetClass * get_separator_class(/**/);
- Xstatic char * get_separator_callback(/**/);
- Xstatic WidgetClass * get_togglebutton_class(/**/);
- Xstatic char * get_togglebutton_callback(/**/);
- X
- X
- X/* Public object methods */
- X
- X/* Create the menu object. The menubar definition resource is loaded
- X and used to create the widgets that make up the menu system. */
- Xmenu_type menu__create( form)
- XWidget form;
- X{
- X menu_type menu = XtNew( menu_struct_type);
- X
- X menu->mc_table = table__create();
- X
- X menu->closure_table = table__create();
- X
- X create_menubar( menu, form, "menuBar");
- X
- X XtGetApplicationResources(get_toplevel(form), (XtPointer)&res_data,
- X resources, XtNumber(resources),
- X (ArgList)NULL,(Cardinal)0);
- X
- X
- X convert_newlines( res_data.menu_def);
- X
- X create_menus( menu, menu->menubar, res_data.menu_def);
- X
- X XtManageChild( menu->menubar);
- X
- X return menu;
- X}
- X
- X
- X/* Destroy the menu system object */
- Xvoid menu__destroy(menu)
- Xmenu_type menu;
- X{
- X table__destroy( menu->mc_table);
- X table__destroy( menu->closure_table);
- X XtDestroyWidget( menu->menubar);
- X
- X XtFree( (char *)menu);
- X}
- X
- X
- X/* Registers an avaliable callback. This callback can then be
- X referenced by the menu definition resource. If the callback is
- X referenced, the menuCallbackProc is invoked. */
- Xvoid menu__add_callback( menu, action_name, menu_callback_proc, user_data)
- Xmenu_type menu;
- Xchar *action_name;
- XmenuCallbackProc menu_callback_proc;
- Xcaddr_t user_data;
- X{
- X /* Store avaliable callback into table */
- X menuCallback *menu_node = XtNew( menuCallback);
- X
- X
- X menu_node->name = my_strdup( action_name);
- X menu_node->proc = menu_callback_proc;
- X menu_node->closure = user_data;
- X
- X table__store( menu->mc_table, menu_node->name, (void *)menu_node);
- X}
- X
- X
- X/* Given the menu item widget name, toggles the widget's state and
- X performs any menu callbacks registered for the callback that the
- X widget references */
- Xvoid menu__set_toggle( menu, widget_name, set)
- Xmenu_type menu;
- Xchar * widget_name;
- XBool set;
- X{
- X Widget w = get_menu_widget( menu, widget_name);
- X
- X if (w == (Widget)0)
- X return;
- X
- X set_widget_and_do_callback( menu, w, set);
- X}
- X
- X
- X
- X/* Return the state of the named widget's toggle state */
- XBool menu__get_toggle( menu, widget_name)
- Xmenu_type menu;
- Xchar *widget_name;
- X{
- X Widget w = get_menu_widget( menu, widget_name);
- X
- X
- X if (w == (Widget)0)
- X return False;
- X
- X return get_widget_state( menu, w);
- X}
- X
- X
- X/* Set or unset the sensitivity of the specified menu widget */
- Xvoid menu__set_sensitivity( menu, widget_name, sensitive)
- Xmenu_type menu;
- Xchar * widget_name;
- XBoolean sensitive;
- X{
- X Widget w = get_menu_widget( menu, widget_name);
- X
- X
- X if (w == (Widget)0)
- X return;
- X
- X XtVaSetValues( w, XtNsensitive, sensitive, NULL);
- X}
- X
- X
- X/* Returned the named menu widget, or NULL if not found */
- Xstatic Widget get_menu_widget( menu, widget_name)
- Xmenu_type menu;
- Xchar * widget_name;
- X{
- X Widget w;
- X char widget_path[50];
- X
- X
- X sprintf(widget_path,"*%s", widget_name);
- X w = XtNameToWidget( menu->menubar, widget_path);
- X
- X if (w == (Widget)0)
- X {
- X fprintf(stderr,"get_menu_widget: Cannot find menu widget '%s'\n",
- X widget_name);
- X }
- X
- X return w;
- X}
- X
- X
- X/* menu_callback
- X Called for any menu item that is selected. Sets up the parameters
- X and makes the callback to the proper menuCallbackProc function. */
- Xstatic void menu_callback( w, menu, call_data)
- XWidget w;
- Xmenu_type menu;
- Xcaddr_t * call_data;
- X{
- X closure_type * closure;
- X menuCallback * mc_node;
- X menuCallbackStruct menu_cbs;
- X
- X
- X /* Get data passed when callback was referenced in menu configuration */
- X closure = (closure_type *)table__retrieve( menu->closure_table, XtName(w));
- X
- X
- X if (closure == (closure_type *)0)
- X {
- X fprintf(stderr,"Cannot find menu callback closure for widget %s.\n",
- X XtName(w));
- X return;
- X }
- X
- X if (strcmp( closure->widget_class, "ToggleButton") == 0)
- X {
- X#ifdef ATHENA
- X /* We have to toggle the athena widget by hand */
- X set_widget_state( menu, w, !get_widget_state( menu, w));
- X#endif
- X
- X menu_cbs.set = get_widget_state( menu, w);
- X }
- X else
- X /* Non-toggle button - just put any value there */
- X menu_cbs.set = True;
- X
- X
- X /* Get the callback information stored when the callback was registered */
- X mc_node = (menuCallback *)table__retrieve( menu->mc_table,
- X closure->menu_callback_name);
- X
- X if (mc_node == (menuCallback *)0)
- X {
- X fprintf(stderr,"Cannot find menu callback '%s'\n",
- X closure->menu_callback_name);
- X return;
- X }
- X
- X /* Call the menu callback function */
- X (*mc_node->proc)(w, mc_node->closure, &menu_cbs, closure->optional_params);
- X}
- X
- X
- X/**********************************************************************
- X * Menu config text format:
- X *
- X * XBall.menu:
- X * pulldownName~
- X * widgetName,widgetClass,menuCallbackName,optionalParams...~
- X * .
- X * .
- X * .
- X * pulldownName2~
- X * widgetName,widgetClass,menuCallbackName,optionalParams...~
- X * .
- X * .
- X * .
- X **********************************************************************/
- X
- Xstatic void create_menus(menu, menubar, menu_def)
- Xmenu_type menu;
- XWidget menubar;
- Xchar * menu_def;
- X{
- X Widget pull_down;
- X Widget button;
- X char pull_down_name[30];
- X char * curr_pt = menu_def;
- X char * comma;
- X char * newline;
- X char * next_pt;
- X WidgetClass * w_class_p;
- X Arg args[10];
- X int n;
- X
- X
- X while (curr_pt != NULL)
- X {
- X /*next_pt = strpbrk( curr_pt, "\"{}");*/
- X
- X /* Search for first non-space */
- X for (next_pt = curr_pt;
- X next_pt != '\0' && isspace( *next_pt);
- X next_pt++)
- X /* Do nothing*/;
- X
- X if (*next_pt == '\0')
- X break;
- X
- X switch (*next_pt)
- X {
- X case '{':
- X printf("Sorry - '{' not yet implemented\n");
- X curr_pt = strchr( next_pt, '\n'); /* Go to next line */
- X break;
- X case '}':
- X printf("Sorry - '}' not yet implemented\n");
- X curr_pt = strchr( next_pt, '\n'); /* Go to next line */
- X break;
- X default:
- X comma = strchr( next_pt, ',');
- X newline = strpbrk( next_pt, "\n ");
- X /*newline = strchr( next_pt, '\n');*/
- X if (newline == NULL || comma == NULL ||
- X newline < comma)
- X {
- X /* At a menu header since no commas before the next newline */
- X char *menu_button_name = get_string( next_pt);
- X
- X sprintf(pull_down_name, "%sPullDown", menu_button_name);
- X
- X pull_down = create_pulldown( menubar, menu_button_name,
- X pull_down_name);
- X
- X free( menu_button_name);
- X
- X curr_pt = strchr( next_pt, '\n'); /* Go to next line */
- X }
- X else
- X {
- X /* At a menu item. Get the parameters */
- X char *item_str = get_string( next_pt);
- X char *w_name;
- X char *w_class;
- X char *menu_callback_name;
- X char *optional_params;
- X char *callback;
- X
- X w_name = strtok( item_str, ",");
- X w_class = strtok( (char *)0, ",");
- X menu_callback_name = strtok( (char *)0, ",");
- X optional_params = strtok( (char *)0, "\n");
- X
- X n = 0;
- X
- X if (strcmp( w_class, "PushButton") == 0)
- X {
- X w_class_p = get_pushbutton_class();
- X callback = get_pushbutton_callback();
- X }
- X else
- X if (strcmp( w_class, "Separator") == 0)
- X {
- X w_class_p = get_separator_class();
- X callback = get_separator_callback();
- X }
- X else
- X if (strcmp( w_class, "ToggleButton") == 0)
- X {
- X w_class_p = get_togglebutton_class();
- X callback = get_togglebutton_callback();
- X
- X#ifdef ATHENA
- X /* Need to initialize some values for the athena toggle */
- X XtSetArg(args[n], XtNleftBitmap, menu->off_bitmap); n++;
- X XtSetArg(args[n], XtNleftMargin, off_width+4); n++;
- X XtSetArg(args[n], XtNvertSpace, 50); n++;
- X#endif
- X }
- X
- X button = XtCreateManagedWidget( w_name, *w_class_p, pull_down,
- X args, n);
- X
- X if (callback != (char *)0)
- X {
- X closure_type * closure;
- X
- X if (optional_params == (char *)0)
- X optional_params = "";
- X
- X closure = (closure_type *)XtNew( closure_type);
- X closure->menu_callback_name= my_strdup(menu_callback_name);
- X closure->optional_params = my_strdup( optional_params);
- X closure->widget_class = my_strdup( w_class);
- X
- X XtAddCallback( button, callback,menu_callback,
- X (XtPointer)menu);
- X
- X table__store( menu->closure_table, w_name,(void *)closure);
- X }
- X free( item_str);
- X
- X curr_pt = strchr( next_pt, '\n'); /* Go to next line */
- X }
- X break;
- X }
- X }
- X}
- X
- X
- X/* Private object methods */
- X
- X#ifdef MOTIF
- X
- Xstatic void create_menubar( menu, form, name)
- Xmenu_type menu;
- XWidget form;
- Xchar * name;
- X{
- X menu->menubar = XmCreateMenuBar( form, name, NULL, 0);
- X}
- X
- X
- X/* Sets the toggle widget to the specified value and performs menu
- X callbacks to inform of the new value */
- Xstatic void set_widget_and_do_callback( menu, w, set)
- Xmenu_type menu;
- XWidget w;
- XBool set;
- X{
- X set_widget_state( menu, w, set);
- X
- X XtCallCallbacks( w, XmNvalueChangedCallback, (char *)0);
- X}
- X
- X
- X/* Ser the state of the Motif menu "toggle" widget */
- Xstatic void set_widget_state( menu, w, state)
- Xmenu_type menu;
- XWidget w;
- XBool state;
- X{
- X XtVaSetValues( w, XmNset, state, NULL);
- X}
- X
- X
- X/* Returns the state of the Motif menu widget */
- Xstatic Bool get_widget_state( menu, w)
- Xmenu_type menu;
- XWidget w;
- X{
- X return XmToggleButtonGadgetGetState( w);
- X}
- X
- X
- X/* Create the pull down menu for Motif. If the menu_button is named
- X "help", it is designated the menu help button. */
- Xstatic Widget create_pulldown( menubar, menu_button_name, pull_down_name)
- XWidget menubar;
- Xchar * menu_button_name;
- Xchar * pull_down_name;
- X{
- X Widget pull_down;
- X Widget button;
- X
- X
- X pull_down = XmCreatePulldownMenu( menubar, pull_down_name, NULL, 0);
- X
- X button =
- X XtVaCreateManagedWidget( menu_button_name, xmCascadeButtonWidgetClass,
- X menubar,
- X XmNsubMenuId, pull_down,
- X NULL);
- X
- X if (strcmp( menu_button_name, "help") == 0)
- X {
- X XtVaSetValues(menubar, XmNmenuHelpWidget, button, NULL);
- X }
- X
- X return pull_down;
- X}
- X
- X
- Xstatic WidgetClass * get_pushbutton_class()
- X{
- X return &xmPushButtonGadgetClass;
- X}
- X
- X
- Xstatic char * get_pushbutton_callback()
- X{
- X return XmNactivateCallback;
- X}
- X
- X
- Xstatic WidgetClass * get_separator_class()
- X{
- X return &xmSeparatorGadgetClass;
- X}
- X
- X
- Xstatic char * get_separator_callback()
- X{
- X return (char *)0;
- X}
- X
- X
- Xstatic WidgetClass * get_togglebutton_class()
- X{
- X return &xmToggleButtonGadgetClass;
- X}
- X
- X
- Xstatic char * get_togglebutton_callback()
- X{
- X return XmNvalueChangedCallback;
- X}
- X
- X
- X#endif
- X
- X
- X#ifdef ATHENA
- X
- Xmenu_type global_action_menu; /* We need to have a global menu object,
- X because actions do not pass client_data */
- X
- Xstatic void menu_action(/* w, event, params, num_params*/);
- X
- Xstatic void create_menubar( menu, form, name)
- Xmenu_type menu;
- XWidget form;
- Xchar * name;
- X{
- X XtActionsRec action;
- X
- X
- X menu->menubar =
- X XtVaCreateManagedWidget( name, boxWidgetClass, form,
- X XtNorientation, XtorientHorizontal,
- X XtNresizable, True,
- X NULL);
- X
- X menu->off_bitmap =
- X XCreateBitmapFromData( XtDisplay( form),
- X RootWindowOfScreen( XtScreen( form)),
- X off_bits, off_width, off_height);
- X menu->on_bitmap =
- X XCreateBitmapFromData( XtDisplay( form),
- X RootWindowOfScreen( XtScreen( form)),
- X on_bits, on_width, on_height);
- X
- X
- X global_action_menu = menu;
- X
- X /* Add a global action for menu actions */
- X /* Athena needs global actions to implement "menu accelerators" */
- X action.string = "menu_action";
- X action.proc = menu_action;
- X XtAppAddActions( XtWidgetToApplicationContext( menu->menubar),
- X &action, (Cardinal)1);
- X}
- X
- X
- X/* Sets the toggle widget to the specified value and performs menu
- X callbacks to inform of the new value */
- Xstatic void set_widget_and_do_callback( menu, w, set)
- Xmenu_type menu;
- XWidget w;
- XBool set;
- X{
- X /* We set the toggle to the opposite of what we finally want,
- X because of the way the Athena menu callback works with toggles is that
- X it toggles the value for each callback. */
- X
- X set_widget_state( menu, w, !set);
- X
- X XtCallCallbacks( w, XtNcallback, (char *)0);
- X}
- X
- X
- X/* Set the state of the athena menu "toggle" widget */
- Xstatic void set_widget_state( menu, w, state)
- Xmenu_type menu;
- XWidget w;
- XBool state;
- X{
- X XtVaSetValues(w, XtNleftBitmap, state ? menu->on_bitmap : menu->off_bitmap,
- X NULL);
- X}
- X
- X
- X/* Returns the state of the Athena menu "toggle" widget */
- Xstatic Bool get_widget_state( menu, w)
- Xmenu_type menu;
- XWidget w;
- X{
- X Pixmap pixmap_set;
- X
- X
- X XtVaGetValues( w, XtNleftBitmap, &pixmap_set, NULL);
- X
- X return (pixmap_set == menu->on_bitmap);
- X}
- X
- X
- X/* Create the Athena pulldown widget */
- Xstatic Widget create_pulldown( menubar, menu_button_name, pull_down_name)
- XWidget menubar;
- Xchar * menu_button_name;
- Xchar * pull_down_name;
- X{
- X Widget button;
- X Widget pull_down;
- X
- X
- X button = XtVaCreateManagedWidget( menu_button_name, menuButtonWidgetClass,
- X menubar, NULL);
- X
- X pull_down = XtCreatePopupShell( "menu", simpleMenuWidgetClass, button,
- X NULL, 0);
- X
- X return pull_down;
- X}
- X
- X
- Xstatic WidgetClass * get_pushbutton_class()
- X{
- X return &smeBSBObjectClass;
- X}
- X
- X
- Xstatic char * get_pushbutton_callback()
- X{
- X return XtNcallback;
- X}
- X
- X
- Xstatic WidgetClass * get_separator_class()
- X{
- X return &smeLineObjectClass;
- X}
- X
- X
- Xstatic char * get_separator_callback()
- X{
- X return (char *)0;
- X}
- X
- X
- Xstatic WidgetClass * get_togglebutton_class()
- X{
- X return &smeBSBObjectClass;
- X}
- X
- X
- Xstatic char *get_togglebutton_callback()
- X{
- X return XtNcallback;
- X}
- X
- X
- X/* This global action is used to implement keyboard accelerators in
- X Athena. To get a keyboard accelerator, a widget sets it translations
- X to call the global "menu_callback" action, passing the menu action
- X they want to perform. */
- Xstatic void menu_action( w, event, params, num_params)
- XWidget w;
- XXEvent * event;
- XString * params;
- XCardinal num_params;
- X{
- X char buff[50];
- X menu_type menu = global_action_menu;
- X
- X
- X /* Get the action name passed to the menu_action */
- X if (num_params < 1)
- X {
- X fprintf(stderr,
- X "No menu action name passed to the menu_action action\n");
- X return;
- X }
- X
- X
- X /* Type of menu action is passed to the action */
- X w = get_menu_widget( menu, params[0]);
- X
- X if (w == (Widget)0)
- X return;
- X
- X menu_callback( w, menu, NULL);
- X}
- X
- X#endif
- END_OF_FILE
- if test 18009 -ne `wc -c <'menu.c'`; then
- echo shar: \"'menu.c'\" unpacked with wrong size!
- fi
- # end of 'menu.c'
- fi
- if test -f 'room.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'room.c'\"
- else
- echo shar: Extracting \"'room.c'\" \(15176 characters\)
- sed "s/^X//" >'room.c' <<'END_OF_FILE'
- X/**********************************************************************
- X * room.c - Room object definition
- X *
- X * Copyright 1993, David Nedde
- X *
- X * Permission to use, copy, modify, and distribute this software
- X * and its documentation for any purpose and without fee is granted
- X * provided that the above copyright notice appears in all copies.
- X * It is provided "as is" without express or implied warranty.
- X **********************************************************************/
- X
- X/* System Headers */
- X#include <stdio.h>
- X
- X#include <X11/Intrinsic.h>
- X#include <X11/StringDefs.h>
- X#include <X11/cursorfont.h>
- X
- X#ifdef MOTIF
- X#include <Xm/DrawingA.h>
- X#endif
- X
- X#ifdef ATHENA
- X#include <X11/Xaw_d/DrawingA.h>
- X#endif
- X
- X/* Local headers */
- X#include "room.h"
- X#include "misc.h"
- X#include "scrollbar.h"
- X
- X/* Macros */
- X/* This is the spacing between the balls representing pixels on the bitmap */
- X#define SF 1.5 /* FIX - make a resource */
- X
- X/* Functions */
- Xstatic void redisplay_cb(/*w, room, call_data*/);
- Xstatic void resize_cb(/*w, datap_ptr, call_data*/);
- Xstatic void process_input_cb(/*w, room, call_data*/);
- Xstatic void wait_for_resize(/* room*/);
- Xstatic Widget create_canvas(/* parent, name*/);
- X
- X
- X/* Object public methods */
- X
- X/* Create the room object */
- Xroom_type room__create( form_w, items, file_sel)
- XWidget form_w;
- Xitems_type items;
- Xfile_sel_type file_sel;
- X{
- X Dimension right_wall;
- X Dimension floor;
- X
- X
- X Widget canvas;
- X
- X room_type room = XtNew( room_struct_type);
- X
- X room->item = (item_type)0;
- X room->items = items;
- X room->file_sel = file_sel;
- X room->left_wall = int2intf(0);
- X room->ceiling = int2intf(0);
- X /* room->gravity is set in xball_sys via scrollbar callback */
- X
- X room->button1 = False;
- X room->button2 = False;
- X room->button3 = False;
- X
- X
- X room->canvas = canvas = create_canvas( room, form_w, "canvas");
- X
- X XtVaGetValues(canvas,
- X XtNbackground, &room->background,
- X XtNwidth, &right_wall,
- X XtNheight, &floor,
- X NULL);
- X
- X room->right_wall = int2intf( right_wall);
- X room->floor = int2intf( floor);
- X
- X return room;
- X}
- X
- X
- X/* Destroy the room object */
- Xvoid room__destroy( room)
- Xroom_type room;
- X{
- X XtDestroyWidget( room->canvas);
- X XtFree( (char *)room);
- X}
- X
- X
- X/* Called when the scrollbar changes. Sets the gravity value */
- Xvoid room__set_gravity_cb(w, room, call_data)
- XWidget w;
- Xroom_type room;
- XscrollbarCallbackStruct * call_data;
- X{
- X room->gravity = call_data->value;
- X}
- X
- X
- X/* A menu callback that clears the room of all balls */
- Xvoid room__clear_mcb(w, room, call_data, extra)
- XWidget w;
- Xroom_type room;
- Xcaddr_t call_data;
- Xchar * extra;
- X{
- X items__destroy_all( room->items);
- X}
- X
- X
- X/* A menu callback that randomizes all balls in the room */
- Xvoid room__randomize_mcb(w, room, call_data, extra)
- XWidget w;
- Xroom_type room;
- Xcaddr_t call_data;
- Xchar * extra;
- X{
- X item_type item;
- X
- X
- X for (item = items__get_first( room->items);
- X item != (item_type)0;
- X item = items__get_next( room->items))
- X {
- X item__randomize( item, -16, 16, -16, 16);
- X }
- X}
- X
- X
- X/* A menu callback that queries the user for a bitmap and then loads it */
- Xvoid room__load_bitmap_mcb(w, room, call_data, extra)
- XWidget w;
- Xroom_type room;
- Xcaddr_t call_data;
- Xchar * extra;
- X{
- X char *file_name = file_sel__display( room->file_sel, "Load Bitmap");
- X
- X if (file_name != (char *)0)
- X room__load_bitmap( room, file_name, 10, 10);
- X}
- X
- X
- X/* Loads the specified bitmap file at the specified position in the room */
- Xvoid room__load_bitmap(room, filename, pos_x, pos_y)
- Xroom_type room;
- Xchar * filename;
- Xint pos_x;
- Xint pos_y;
- X{
- X unsigned width, height; /* Bitmap dimensions */
- X int x_hot, y_hot;
- X Pixmap bitmap; /* The bitmap as a pixmap */
- X XImage * ximage; /* The bitmap as an image */
- X int x, y;
- X int status;
- X Dimension new_width, new_height;
- X
- X
- X status = XReadBitmapFile(XtDisplay(room->canvas), XtWindow(room->canvas),
- X filename, &width, &height, &bitmap,
- X &x_hot, &y_hot);
- X switch (status)
- X {
- X case BitmapOpenFailed:
- X fprintf(stderr,
- X "room__load_bitmap: Could not open bitmap file %s\n",filename);
- X return;
- X break;
- X
- X case BitmapFileInvalid:
- X fprintf(stderr,
- X "room__load_bitmap: Bitmap file %s does not contain valid data\n",
- X filename);
- X return;
- X break;
- X
- X case BitmapNoMemory:
- X fprintf(stderr,
- X "room__load_bitmap: Not enough memory to open bitmap file %s\n",
- X filename);
- X return;
- X break;
- X }
- X
- X /* Get a local copy of the pixmap so we can query the pixel values */
- X ximage = XGetImage(XtDisplay(room->canvas),
- X bitmap,0,0,width,height,AllPlanes,XYPixmap);
- X if (ximage == NULL)
- X {
- X fprintf(stderr,"room__load_bitmap: Problem getting bitmap image\n");
- X return;
- X }
- X
- X new_width = MAX( intf2int(room->right_wall),
- X pos_x + width * item__get_width() * SF+10);
- X new_height = MAX( intf2int(room->floor),
- X pos_y + height * item__get_height() * SF+10);
- X
- X if (new_width != intf2int(room->right_wall) ||
- X new_height != intf2int(room->floor))
- X {
- X room->resized = False;
- X
- X /* Set the window width and height so the balls fit on it */
- X XtVaSetValues(room->canvas,
- X XtNwidth, new_width,
- X XtNheight, new_height,
- X NULL);
- X
- X wait_for_resize( room);
- X }
- X
- X /* Create a ball for each pixel set in the bitmap */
- X for (y = 0; y < height; y++)
- X {
- X for (x = 0; x < width; x++)
- X {
- X if (XGetPixel(ximage, x, y))
- X items__new_item(room->items,
- X (int)(x * item__get_width() * SF + pos_x),
- X (int)(y * item__get_height() * SF + pos_y),
- X /*x_vel*/0, /*y_vel*/0);
- X }
- X }
- X}
- X
- X
- X
- X/* Set the room's width and wait for the window to resize before returning */
- Xvoid room__set_width(room, width)
- Xroom_type room;
- Xint width;
- X{
- X Dimension d_width = width;
- X
- X
- X if (intf2int(room->right_wall) == width)
- X return;
- X
- X room->resized = False;
- X
- X XtVaSetValues(room->canvas,
- X XtNwidth, d_width,
- X NULL);
- X
- X /* room->right_wall = int2intf(width); Set in window resize callback */
- X
- X wait_for_resize( room);
- X}
- X
- X
- X/* Set the height of the room, resize the actual room and wait for it
- X to resize before returning. */
- Xvoid room__set_height(room, height)
- Xroom_type room;
- XDimension height;
- X{
- X Dimension d_height = height;
- X
- X
- X if (intf2int(room->floor) == height)
- X return;
- X
- X room->resized = False;
- X
- X XtVaSetValues(room->canvas,
- X XtNheight, d_height,
- X NULL);
- X
- X /* room->floor = int2intf(height); set in the window resize callback */
- X
- X wait_for_resize( room);
- X}
- X
- X
- X/* Private object methods */
- X
- X
- X/**********************************************************************
- X * redisplay - Called when DrawingArea canvas gets an expose event
- X * Redraws all balls in room
- X **********************************************************************/
- Xstatic void redisplay(room, event)
- Xroom_type room;
- XXEvent * event;
- X{
- X Display * display = XtDisplay( room->canvas);
- X Window window = XtWindow ( room->canvas);
- X
- X
- X if (!item__initted())
- X {
- X Cursor cursor = XCreateFontCursor( display, XC_watch );
- X XDefineCursor( display, window, cursor);
- X
- X item__init( get_toplevel( room->canvas), display, window,
- X room->background);
- X
- X XFreeCursor( display, cursor);
- X XUndefineCursor( display, window);
- X }
- X
- X
- X if (event->xexpose.count == 0) /* Wait until last expose event*/
- X {
- X item_type item;
- X
- X XClearWindow( display, window);
- X
- X for (item = items__get_first( room->items);
- X item != (item_type)0;
- X item = items__get_next( room->items))
- X {
- X item__redraw( item);
- X }
- X }
- X}
- X
- X
- X/**********************************************************************
- X * resize_cb - Called when DrawingArea canvas is resized
- X * Adjusts the right wall and floor
- X **********************************************************************/
- Xstatic void resize_cb(w, room, call_data)
- XWidget w;
- Xroom_type room;
- Xcaddr_t call_data;
- X{
- X Dimension width,height;
- X
- X XtVaGetValues(w,
- X XtNwidth, &width,
- X XtNheight, &height,
- X NULL);
- X
- X room->right_wall = int2intf(width);
- X room->floor = int2intf(height);
- X
- X /* Set flag in case someone is waiting for the resize */
- X room->resized = True;
- X}
- X
- X
- X/* Waits for the window to actually resize. This depends on the
- X resize callback code setting the room->resized flag to True. Callers
- X should set the room->resized flag to False before calling. */
- Xstatic void wait_for_resize( room)
- Xroom_type room;
- X{
- X XEvent event;
- X XtAppContext app_context;
- X
- X
- X app_context = XtWidgetToApplicationContext( room->canvas);
- X
- X /* Wait for the window resize to occur */
- X while (!room->resized)
- X {
- X XtAppNextEvent(app_context, &event);
- X XtDispatchEvent(&event);
- X }
- X}
- X
- X
- X/**********************************************************************
- X * process_input - Called when DrawingArea canvas has input
- X * Handles mouse button events
- X **********************************************************************/
- Xstatic void process_input( room, event)
- Xroom_type room;
- XXEvent * event;
- X{
- X switch (event->type)
- X {
- X /* Process mouse button events */
- X case ButtonPress:
- X switch (event->xbutton.button)
- X {
- X case 1:
- X /* Button 1 - Create 1 item under the pointer */
- X
- X room->oldx = room->newx = event->xbutton.x;
- X room->oldy = room->newy = event->xbutton.y;
- X
- X /* Create an item under the pointer */
- X room->item = item__create(event->xbutton.x,
- X event->xbutton.y,
- X /*x,y velocity*/ 0, 0);
- X
- X room->button1 = True;
- X break;
- X
- X /* Remember the button we have pressed (used in mouse motion) */
- X case 2: room->button2 = True; break;
- X case 3: room->button3 = True; break;
- X }
- X break;
- X
- X case ButtonRelease:
- X switch (event->xbutton.button)
- X {
- X /* button 1 release - move item to items list */
- X case 1:
- X item__set_x_vel( room->item, room->newx - room->oldx);
- X item__set_y_vel( room->item, room->newy - room->oldy);
- X
- X items__add( room->items, room->item);
- X room->item = (item_type)0;
- X
- X room->button1 = False;
- X break;
- X
- X /* Remember the button we have unpressed (used in mouse motion) */
- X case 2: room->button2 = False; break;
- X case 3: room->button3 = False; break;
- X }
- X }
- X}
- X
- X
- X/**********************************************************************
- X * process_motion - Called when DrawingArea canvas have pointer motion events
- X **********************************************************************/
- Xstatic void process_motion( room, event)
- Xroom_type room;
- XXEvent * event;
- X{
- X if (room->button1)
- X {
- X /* When button 1 pressed during movement */
- X /* Save 'speed' of pointer for when the button is released */
- X room->oldx = room->newx;
- X room->oldy = room->newy;
- X room->newx = event->xmotion.x;
- X room->newy = event->xmotion.y;
- X
- X item__set_x_vel( room->item, (room->newx - room->oldx));
- X item__set_y_vel( room->item, (room->newy - room->oldy));
- X
- X item__move_pos( room->item,
- X event->xmotion.x, event->xmotion.y);
- X }
- X else
- X if (room->button2)
- X {
- X /* Create a random velocity ball */
- X items__new_item(room->items, event->xmotion.x, event->xmotion.y,
- X rand_range( -8, 8),
- X rand_range( -8, 0));
- X }
- X else
- X if (room->button3)
- X {
- X items__new_item(room->items, event->xmotion.x, event->xmotion.y,
- X 0, 0);
- X }
- X}
- X
- X
- X#ifdef MOTIF
- X
- Xstatic void process_motion_act(/*w, datap_ptr, event*/);
- X
- X
- X/* Create motif canvas as a DrawingArea Widget */
- Xstatic Widget create_canvas( room, parent, name)
- Xroom_type room;
- XWidget parent;
- Xchar * name;
- X{
- X Widget canvas =
- X XtCreateManagedWidget("canvas", xmDrawingAreaWidgetClass, parent,
- X NULL, 0);
- X
- X XtAddCallback(canvas, XmNexposeCallback, redisplay_cb, (XtPointer)room);
- X XtAddCallback(canvas, XmNinputCallback, process_input_cb,(XtPointer)room);
- X XtAddCallback(canvas, XmNresizeCallback, resize_cb, (XtPointer)room);
- X XtAddEventHandler(canvas, ButtonMotionMask, FALSE,
- X process_motion_act, (XtPointer)room);
- X
- X return canvas;
- X}
- X
- X
- Xstatic void redisplay_cb(w, room, call_data)
- XWidget w;
- Xroom_type room;
- XXmDrawingAreaCallbackStruct * call_data;
- X{
- X redisplay( room, call_data->event);
- X}
- X
- X
- Xstatic void process_input_cb(w, room, call_data)
- XWidget w;
- Xroom_type room;
- XXmDrawingAreaCallbackStruct * call_data;
- X{
- X process_input( room, call_data->event);
- X}
- X
- X
- Xstatic void process_motion_act(w, room, event)
- XWidget w;
- Xroom_type room;
- XXEvent * event;
- X{
- X process_motion( room, event);
- X}
- X
- X#endif
- X
- X
- X#ifdef ATHENA
- X
- X
- Xstatic void process_motion_cb(/*w, room, call_data*/);
- X
- X
- X/* Create canvas as a DrawingArea widget */
- Xstatic Widget create_canvas( room, parent, name)
- Xroom_type room;
- XWidget parent;
- Xchar * name;
- X{
- X Widget canvas =
- X XtCreateManagedWidget("canvas", drawingAreaWidgetClass, parent,
- X NULL, 0);
- X
- X XtAddCallback(canvas,XtNexposeCallback,redisplay_cb, (XtPointer)room);
- X XtAddCallback(canvas,XtNinputCallback, process_input_cb, (XtPointer)room);
- X XtAddCallback(canvas,XtNresizeCallback,resize_cb, (XtPointer)room);
- X XtAddCallback(canvas,XtNmotionCallback,process_motion_cb, (XtPointer)room);
- X
- X return canvas;
- X}
- X
- X
- Xstatic void redisplay_cb(w, room, call_data)
- XWidget w;
- Xroom_type room;
- XXawDrawingAreaCallbackStruct * call_data;
- X{
- X redisplay( room, call_data->event);
- X}
- X
- X
- Xstatic void process_input_cb(w, room, call_data)
- XWidget w;
- Xroom_type room;
- XXawDrawingAreaCallbackStruct * call_data;
- X{
- X process_input( room, call_data->event);
- X}
- X
- X
- Xstatic void process_motion_cb(w, room, call_data)
- XWidget w;
- Xroom_type room;
- XXawDrawingAreaCallbackStruct * call_data;
- X{
- X process_motion( room, call_data->event);
- X}
- X
- X
- X#endif
- X
- END_OF_FILE
- if test 15176 -ne `wc -c <'room.c'`; then
- echo shar: \"'room.c'\" unpacked with wrong size!
- fi
- # end of 'room.c'
- fi
- if test -f 'scrollbar.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'scrollbar.c'\"
- else
- echo shar: Extracting \"'scrollbar.c'\" \(10512 characters\)
- sed "s/^X//" >'scrollbar.c' <<'END_OF_FILE'
- X/**********************************************************************
- X * scrollbar.c
- X *
- X * Copyright 1993, David Nedde
- X *
- X * Permission to use, copy, modify, and distribute this software
- X * and its documentation for any purpose and without fee is granted
- X * provided that the above copyright notice appears in all copies.
- X * It is provided "as is" without express or implied warranty.
- X **********************************************************************/
- X
- X/* System Headers */
- X#ifdef MOTIF
- X#include <Xm/Scale.h>
- X#include <Xm/Label.h>
- X#include <Xm/Form.h>
- X#endif
- X
- X#ifdef ATHENA
- X#include <X11/Intrinsic.h>
- X#include <X11/StringDefs.h>
- X#include <X11/Xaw/Scrollbar.h>
- X#include <X11/Xaw/Label.h>
- X#include <X11/Xaw/Text.h>
- X#include <X11/Xaw/Form.h>
- X#endif
- X
- X/* Local headers */
- X#include "scrollbar.h"
- X#include "misc.h"
- X
- X/* Structures */
- X/* A node in the scrollbar callbacks list */
- Xtypedef struct {
- X scrollbarCallbackProc proc;
- X caddr_t closure;
- X} callback_node;
- X
- X/* Functions */
- Xvoid create_widgets(/* scrollbar, parent, name*/);
- Xstatic void call_callbacks(/* scrollbar, value*/);
- X
- X
- X/* Public object methods */
- X
- X/* Creates a scrollbar object. Consists of a label, a scrollbar and a
- X label giving feedback to the user */
- Xscrollbar_type scrollbar__create( parent, name)
- XWidget parent;
- Xchar * name;
- X{
- X scrollbar_type scrollbar;
- X
- X
- X scrollbar = XtNew( scrollbar_struct);
- X
- X /* We need to have our own callback list, because callbacks from
- X Motif and Athea are so different */
- X scrollbar->callbacks = list__create();
- X
- X create_widgets( scrollbar, parent, name);
- X
- X return scrollbar;
- X}
- X
- X
- X/* Destroy the scrollbar object */
- Xvoid scrollbar__destroy( scrollbar)
- Xscrollbar_type scrollbar;
- X{
- X int i;
- X
- X
- X for (i = 0; i < list__get_count( scrollbar->callbacks); i++)
- X {
- X free( list__get_cell( scrollbar->callbacks, i));
- X }
- X list__destroy( scrollbar->callbacks);
- X
- X XtDestroyWidget( scrollbar->scale);
- X XtDestroyWidget( scrollbar->label);
- X XtFree( (char *)scrollbar);
- X}
- X
- X
- X/* Set the value of the scrollbar and make any callbacks */
- Xvoid scrollbar__set_value( scrollbar, value)
- Xscrollbar_type scrollbar;
- Xint value;
- X{
- X scrollbar->value = value;
- X
- X scale_set_value( scrollbar, value);
- X
- X call_callbacks( scrollbar, value);
- X}
- X
- X
- X/* Add a scrollbar callback. When the scrollbar value changes, the
- X proc will be called back with a scrollbarCallbackStruct. */
- Xvoid scrollbar__add_callback( scrollbar, proc, closure)
- Xscrollbar_type scrollbar;
- XXtCallbackProc proc;
- XXtPointer closure;
- X{
- X callback_node *node_ptr = (callback_node *)malloc( sizeof( callback_node));
- X
- X
- X node_ptr->proc = proc;
- X node_ptr->closure = closure;
- X
- X list__add_end( scrollbar->callbacks, node_ptr);
- X}
- X
- X
- X
- X/* Private object methods */
- X
- X/* Make the scrollbar callbacks */
- Xstatic void call_callbacks( scrollbar, value)
- Xscrollbar_type scrollbar;
- Xint value;
- X{
- X int i;
- X callback_node * node_ptr;
- X scrollbarCallbackStruct scrollbar_call_data;
- X
- X
- X scrollbar_call_data.reason = 0;
- X scrollbar_call_data.event = 0;
- X scrollbar_call_data.pixel = 0;
- X scrollbar_call_data.value = value;
- X
- X for (i = 0; i < list__get_count( scrollbar->callbacks); i++)
- X {
- X node_ptr = (callback_node *)list__get_cell( scrollbar->callbacks, i);
- X (*node_ptr->proc)( scrollbar->scale, node_ptr->closure,
- X &scrollbar_call_data);
- X }
- X}
- X
- X
- X#ifdef MOTIF
- X
- X/* Called when the motif scrollbar moves. Makes all registered
- X scrollbar callbacks */
- Xstatic void scrollbar_callback( w, scrollbar, call_data)
- XWidget w;
- Xscrollbar_type scrollbar;
- Xcaddr_t call_data;
- X{
- X call_callbacks( scrollbar,
- X ((XmScaleCallbackStruct *)call_data)->value);
- X}
- X
- X
- X#ifdef NOTUSED
- X
- X/* Returns the scrollbar widget's value */
- Xstatic int scrollbar_get_value( scrollbar)
- Xscrollbar_type scrollbar;
- X{
- X int value;
- X
- X XmScaleGetValue( scrollbar->scale, &value);
- X
- X return value;
- X}
- X
- X#endif
- X
- X
- X/* Sets the scrollbar widget's value */
- Xstatic int scale_set_value( scrollbar, value)
- Xscrollbar_type scrollbar;
- Xint value;
- X{
- X XmScaleSetValue( scrollbar->scale, value);
- X}
- X
- X
- X/* Creates the scrollbar widgets */
- Xvoid create_widgets( scrollbar, parent, name)
- Xscrollbar_type scrollbar;
- XWidget parent;
- Xchar * name;
- X{
- X scrollbar->form =
- X XtVaCreateManagedWidget(name, xmFormWidgetClass, parent,
- X NULL);
- X
- X scrollbar->label =
- X XtVaCreateManagedWidget("label", xmLabelWidgetClass, scrollbar->form,
- X NULL);
- X scrollbar->scale =
- X XtVaCreateManagedWidget("bar", xmScaleWidgetClass, scrollbar->form,
- X XmNleftAttachment, XmATTACH_WIDGET,
- X XmNleftWidget, scrollbar->label,
- X NULL);
- X
- X XmScaleGetValue( scrollbar->scale, &scrollbar->value);
- X
- X XtAddCallback( scrollbar->scale, XmNvalueChangedCallback,
- X scrollbar_callback, (XtPointer)scrollbar);
- X XtAddCallback( scrollbar->scale, XmNdragCallback,
- X scrollbar_callback, (XtPointer)scrollbar);
- X}
- X
- X#endif
- X
- X
- X#ifdef ATHENA
- X
- X/* Functions */
- Xstatic void set_feedback_value(/* scrollbar, value*/);
- Xstatic void move_thumb(/* scrollbar, thumb, shown*/);
- Xstatic void set_label_value(/* label_w, value*/);
- X
- X
- X/* Macros */
- X#define SB_MAX 100.0
- X#define SB_MIN 0.0
- X
- X#define thumb_to_value( thumb, shown) \
- X ((int)((thumb) / (1-(shown))* (SB_MAX - SB_MIN) + 0.5 - SB_MIN))
- X#define value_to_thumb( value, shown) \
- X ((value)*(1-(shown) + SB_MIN) / (SB_MAX - SB_MIN))
- X
- X
- X/* Called when the athena scrollbar is scrolled incrementally.
- X Updates the feedback value and makes all registered callbacks. */
- Xstatic void scrollbar_scroll_callback( w, scrollbar, position_ptr)
- XWidget w;
- Xscrollbar_type scrollbar;
- XXtPointer position_ptr;
- X{
- X Dimension length;
- X float thumb;
- X float shown;
- X int position = (int)position_ptr;
- X float change; /* 0.0 .. 1.0 - percentage of full-page change
- X we should do */
- X
- X
- X /* Position is the number of pixels from left of scrollbar pointer is.
- X Position > 0 indicates button 1, position < 0 indicates button 3 */
- X
- X
- X XtVaGetValues( scrollbar->scale,
- X XtNlength, &length,
- X XtNtopOfThumb, &thumb,
- X XtNshown, &shown,
- X NULL);
- X
- X change = (float)position / length;
- X
- X /* Scroll by the amount of thumb shown * amount of change we
- X should for the given pointer position */
- X thumb += shown * change;
- X
- X move_thumb( scrollbar, thumb, shown);
- X}
- X
- X
- X/* Called when the athena scrollbar is moved in a jumpy fashion.
- X Updates the feedback value and makes all registered callbacks. */
- Xstatic void scrollbar_jump_callback( w, scrollbar, percent_ptr)
- XWidget w;
- Xscrollbar_type scrollbar;
- Xfloat * percent_ptr;
- X{
- X float shown;
- X float thumb = *percent_ptr;
- X
- X XtVaGetValues( scrollbar->scale,
- X XtNshown, &shown,
- X NULL);
- X
- X move_thumb( scrollbar, thumb, shown);
- X}
- X
- X
- X/* Moves thumb within valid values and updates the feedback value */
- Xstatic void move_thumb( scrollbar, thumb, shown)
- Xscrollbar_type scrollbar;
- Xdouble thumb;
- Xdouble shown;
- X{
- X int value;
- X
- X
- X /* Keep the value within the proper range */
- X if (thumb >= 1 - shown)
- X /* Keep below 1, otherwise thumb stops redrawing due to Athena bug */
- X thumb = 1 - shown;
- X else
- X if (thumb < 0)
- X thumb = 0;
- X
- X /* Set the thumb to the new position */
- X XawScrollbarSetThumb( scrollbar->scale, thumb, -1.0);
- X
- X value = thumb_to_value( thumb, shown);
- X
- X set_feedback_value( scrollbar, value);
- X
- X call_callbacks( scrollbar, value);
- X}
- X
- X
- X/* Returns the value of the scrollbar */
- Xstatic int scrollbar_get_value( scrollbar)
- Xscrollbar_type scrollbar;
- X{
- X float thumb;
- X float shown;
- X
- X
- X XtVaGetValues( scrollbar->scale,
- X XtNtopOfThumb, &thumb,
- X XtNshown, &shown,
- X NULL);
- X
- X return thumb_to_value( thumb, shown);
- X}
- X
- X
- X/* Sets the value of the scrollbar - updates thumb and feedback value */
- Xstatic int scale_set_value( scrollbar, value)
- Xscrollbar_type scrollbar;
- Xint value;
- X{
- X float shown;
- X
- X
- X XtVaGetValues( scrollbar->scale, XtNshown, &shown, NULL);
- X
- X /* Set the thumb to the new position */
- X XawScrollbarSetThumb( scrollbar->scale,
- X value_to_thumb( value, shown), -1.0);
- X
- X
- X set_feedback_value( scrollbar, value);
- X}
- X
- X
- X/* Updates the feedback label to the passed value */
- Xstatic void set_feedback_value( scrollbar, value)
- Xscrollbar_type scrollbar;
- Xint value;
- X{
- X set_label_value( scrollbar->feedback, value);
- X}
- X
- X
- X/* Sets an athena label so it displays the passed value */
- Xstatic void set_label_value( label_w, value)
- XWidget label_w;
- Xint value;
- X{
- X char buff[15];
- X
- X
- X sprintf(buff,"%d", value);
- X
- X
- X XtVaSetValues( label_w, XtNlabel, buff, NULL);
- X}
- X
- X
- X/* Create Athena widgets to simulate a scale witget with a label */
- Xvoid create_widgets( scrollbar, parent, name)
- Xscrollbar_type scrollbar;
- XWidget parent;
- Xchar * name;
- X{
- X scrollbar->form = XtVaCreateWidget(name, formWidgetClass, parent, NULL);
- X
- X scrollbar->label =
- X XtVaCreateManagedWidget("label", labelWidgetClass, scrollbar->form,
- X NULL);
- X
- X scrollbar->feedback =
- X XtVaCreateManagedWidget("feedback",
- X labelWidgetClass, scrollbar->form,
- X XtNfromHoriz, scrollbar->label,
- X NULL);
- X
- X scrollbar->scale =
- X XtVaCreateManagedWidget("bar",
- X scrollbarWidgetClass, scrollbar->form,
- X XtNfromVert, scrollbar->label,
- X XtNfromHoriz, scrollbar->label,
- X NULL);
- X
- X scrollbar->value = scrollbar_get_value( scrollbar);
- X
- X set_feedback_value( scrollbar, scrollbar->value);
- X
- X XtAddCallback( scrollbar->scale, XtNscrollProc,
- X scrollbar_scroll_callback, (XtPointer)scrollbar);
- X XtAddCallback( scrollbar->scale, XtNjumpProc,
- X scrollbar_jump_callback, (XtPointer)scrollbar);
- X
- X XtManageChild( scrollbar->form);
- X}
- X
- X#endif
- END_OF_FILE
- if test 10512 -ne `wc -c <'scrollbar.c'`; then
- echo shar: \"'scrollbar.c'\" unpacked with wrong size!
- fi
- # end of 'scrollbar.c'
- fi
- if test -f 'sim.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sim.c'\"
- else
- echo shar: Extracting \"'sim.c'\" \(4262 characters\)
- sed "s/^X//" >'sim.c' <<'END_OF_FILE'
- X/**********************************************************************
- X * sim.c - definition of the sim object - controls the simlation
- X *
- X * Copyright 1993, David Nedde
- X *
- X * Permission to use, copy, modify, and distribute this software
- X * and its documentation for any purpose and without fee is granted
- X * provided that the above copyright notice appears in all copies.
- X * It is provided "as is" without express or implied warranty.
- X **********************************************************************/
- X
- X/* System Headers */
- X#include <X11/Intrinsic.h>
- X#include <X11/StringDefs.h>
- X
- X/* Local headers */
- X#include "sim.h"
- X#include "misc.h"
- X#include "names.h"
- X
- X/* Macros */
- X#define INVALID_WPID 0
- X#ifndef DELAY
- X#define DELAY 0
- X#endif
- X
- X/* Structures */
- Xtypedef struct {
- X int delay;
- X} app_data,*app_data_ptr;
- Xstatic app_data res_data;
- Xstatic XtResource resources[] = {
- X { "delay", "Delay", XtRInt, sizeof(int),
- X XtOffset(app_data_ptr,delay), XtRImmediate, (caddr_t)DELAY}
- X};
- X
- X/* Functions */
- Xstatic Boolean background_processing(/*sim*/);
- Xstatic int delay(/*sim, length*/);
- Xstatic int process_invisible_backwards(/*datap_ptr*/);
- X
- X
- X/* Public object methods */
- X
- X/* Create the simulation object */
- Xsim_type sim__create(w, menu, items, room, demo)
- XWidget w;
- Xmenu_type menu;
- Xitems_type items;
- Xroom_type room;
- Xdemo_type demo;
- X{
- X sim_type sim = (sim_type)malloc( sizeof( sim_struct_type));
- X
- X sim->menu = menu;
- X sim->items = items;
- X sim->room = room;
- X sim->demo = demo;
- X
- X XtGetApplicationResources(w, (XtPointer)&res_data,
- X resources, XtNumber(resources),
- X (ArgList)NULL,(Cardinal)0);
- X
- X sim->step_simulation = False;
- X sim->delay = res_data.delay;
- X
- X sim->wpid = INVALID_WPID;
- X
- X return sim;
- X}
- X
- X
- X/* Destroys the simulation object */
- Xvoid sim__destroy(sim)
- Xsim_type sim;
- X{
- X XtRemoveWorkProc(sim->wpid);
- X
- X free( sim);
- X}
- X
- X
- X/* Steps the simulation one iteration */
- Xvoid sim__step_mcb(w, sim, call_data, extra)
- XWidget w;
- Xsim_type sim;
- Xcaddr_t call_data;
- Xchar * extra;
- X{
- X background_processing( sim);
- X}
- X
- X
- X/* Halts the simulation */
- Xvoid sim__halt_mcb(w, sim, call_data, extra)
- XWidget w;
- Xsim_type sim;
- XmenuCallbackStruct * call_data;
- Xchar * extra;
- X{
- X sim->step_simulation = call_data->set;
- X
- X if (!sim->step_simulation)
- X {
- X /* Stepping currently turned off */
- X /* Add background processing to perform simulation in real-time */
- X sim->wpid = XtAppAddWorkProc(XtWidgetToApplicationContext(w),
- X background_processing, (char *)sim);
- X
- X /* The 'Step simulation' menu item is greyed since sim is running */
- X menu__set_sensitivity( sim->menu, STEP_SIM, /*sensitive=*/False);
- X }
- X else
- X {
- X /* Stepping turned on - remove the work proc if it has been started */
- X if (sim->wpid != INVALID_WPID)
- X XtRemoveWorkProc(sim->wpid);
- X
- X sim->wpid = INVALID_WPID;
- X
- X /* The 'Step simulation' menu item is ungreyed since sim not running */
- X menu__set_sensitivity( sim->menu, STEP_SIM, /*sensitive=*/True);
- X }
- X}
- X
- X
- X/* Private object methods */
- X
- X/* Performs one iteration of the demo and simulation */
- Xstatic Boolean background_processing(sim)
- Xsim_type sim;
- X{
- X room_type room = sim->room;
- X
- X if (demo__running(sim->demo))
- X demo__process( sim->demo);
- X
- X /* Delay based on the number of items */
- X delay(sim, items__get_count( sim->items));
- X
- X items__move_items( sim->items, room);
- X
- X return /*remove work procedure=*/False;
- X}
- X
- X
- X/* Slow the simulation some amount */
- X/* Slow more if there are less balls, less if there are more balls */
- Xstatic int delay(sim, item_count)
- Xsim_type sim;
- Xint item_count;
- X{
- X int utime;
- X
- X utime = sim->delay - item_count;
- X
- X#ifdef HAVE_USLEEP
- X
- X if (utime < 0)
- X utime = 0;
- X
- X usleep(utime);
- X#else
- X /* Use this part if you don't have a usleep() */
- X {
- X int x,y,sum;
- X
- X /* Yes, a delay loop to slow small amounts of items */
- X for (x = 0; x < utime; x++)
- X for (y = 0; y < sim->delay; y++)
- X sum = sum + y * x;
- X
- X return sum; /* Try to keep it from getting optimized out */
- X }
- X#endif
- X}
- END_OF_FILE
- if test 4262 -ne `wc -c <'sim.c'`; then
- echo shar: \"'sim.c'\" unpacked with wrong size!
- fi
- # end of 'sim.c'
- fi
- if test -f 'table.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'table.c'\"
- else
- echo shar: Extracting \"'table.c'\" \(2535 characters\)
- sed "s/^X//" >'table.c' <<'END_OF_FILE'
- X/**********************************************************************
- X * table.c - table object definition
- X *
- X * Copyright 1993, David Nedde
- X *
- X * Permission to use, copy, modify, and distribute this software
- X * and its documentation for any purpose and without fee is granted
- X * provided that the above copyright notice appears in all copies.
- X * It is provided "as is" without express or implied warranty.
- X **********************************************************************/
- X
- X/* System Headers */
- X#include <malloc.h>
- X#include <string.h>
- X
- X/* Local headers */
- X#include "misc.h"
- X#include "table.h"
- X
- X/* Structures */
- Xtypedef struct {
- X char *key;
- X void *data;
- X} table_node_struct_type, *table_node_type;
- X
- X
- X/* Public object methods */
- X
- X/* Create a table object */
- Xtable_type table__create()
- X{
- X table_type table = (table_type)malloc( sizeof(table_struct_type));
- X
- X
- X table->list = list__create();
- X
- X return table;
- X}
- X
- X
- X/* Free table but not the data contained by the table */
- Xvoid table__destroy( table)
- Xtable_type table;
- X{
- X table_node_type table_node;
- X
- X
- X while ((table_node =
- X (table_node_type)list__remove_last(table->list)) !=
- X (table_node_type)0)
- X {
- X free( table_node->key);
- X free( table_node);
- X }
- X
- X list__destroy( table->list);
- X free( table);
- X}
- X
- X
- X/* Store data in the table by key */
- Xvoid table__store( table, key, data)
- Xtable_type table;
- Xchar * key;
- Xvoid * data;
- X{
- X table_node_type table_node =
- X (table_node_type)malloc( sizeof(table_node_struct_type));
- X
- X table_node->key = my_strdup( key);
- X table_node->data = data;
- X
- X
- X list__add_end( table->list, (void *)table_node);
- X}
- X
- X
- X/* Get a value out of the table, given its key */
- Xvoid *table__retrieve( table, key)
- Xtable_type table;
- Xchar * key;
- X{
- X table_node_type table_node;
- X
- X
- X for (table_node = (table_node_type)list__get_first( table->list);
- X table_node != (table_node_type)0;
- X table_node = (table_node_type)list__get_next( table->list))
- X {
- X if (strcmp( table_node->key, key) == 0)
- X return table_node->data;
- X }
- X
- X return (void *)0;
- X}
- X
- X
- X#ifdef DEBUG
- X
- Xvoid table__dump( table)
- Xtable_type table;
- X{
- X table_node_type table_node;
- X
- X
- X for (table_node = (table_node_type)list__get_first( table->list);
- X table_node != (table_node_type)0;
- X table_node = (table_node_type)list__get_next( table->list))
- X {
- X printf("key = %s\n", table_node->key);
- X }
- X}
- X
- X#endif
- END_OF_FILE
- if test 2535 -ne `wc -c <'table.c'`; then
- echo shar: \"'table.c'\" unpacked with wrong size!
- fi
- # end of 'table.c'
- fi
- if test -f 'intf.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'intf.h'\"
- else
- echo shar: Extracting \"'intf.h'\" \(234 characters\)
- sed "s/^X//" >'intf.h' <<'END_OF_FILE'
- X#ifndef __INTF_H__
- X#define __INTF_H__
- X
- X#define INTFAC 16 /* Multiplied to everything but velocities */
- X
- Xtypedef long intf;
- X
- X#define int2intf( val) ((intf)((val)*INTFAC))
- X#define intf2int( val) ((long)((val)/INTFAC))
- X
- X#endif
- END_OF_FILE
- if test 234 -ne `wc -c <'intf.h'`; then
- echo shar: \"'intf.h'\" unpacked with wrong size!
- fi
- # end of 'intf.h'
- fi
- if test -f 'miscx.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'miscx.h'\"
- else
- echo shar: Extracting \"'miscx.h'\" \(600 characters\)
- sed "s/^X//" >'miscx.h' <<'END_OF_FILE'
- X/**********************************************************************
- X * miscx.h - Misc X, Xt and Xmu related functions
- X *
- X * Copyright 1993, David Nedde
- X *
- X * Permission to use, copy, modify, and distribute this software
- X * and its documentation for any purpose and without fee is granted
- X * provided that the above copyright notice appears in all copies.
- X * It is provided "as is" without express or implied warranty.
- X **********************************************************************/
- X
- X#ifndef __MISCX_H__
- X#define __MISCX_H__
- X
- Xvoid setupConverters();
- XWidget get_toplevel(/*w*/);
- X
- X
- X#endif
- END_OF_FILE
- if test 600 -ne `wc -c <'miscx.h'`; then
- echo shar: \"'miscx.h'\" unpacked with wrong size!
- fi
- # end of 'miscx.h'
- fi
- echo shar: End of archive 3 \(of 5\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 5 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
- exit 0 # Just in case...
- --
- // chris@IMD.Sterling.COM | Send comp.sources.x submissions to:
- \X/ Amiga - The only way to fly! | sources-x@imd.sterling.com
- "It's intuitively obvious to the |
- most casual observer..." | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
-