daven@maxine.wpi.edu (Dave Nedde) (06/27/90)
Submitted-by: daven@maxine.wpi.edu (Dave Nedde) Posting-number: Volume 8, Issue 4 Archive-name: ball2/part01 This is xball V2.0. Improvements include: - Athena widget interface (For either X11 R3 or X11 R4) - Dynamic gravity and elasticity adjustment via scrollbars - Colored balls work correctly now - Additional ball creation algorithms via buttons 2 & 3 As a bonus, A DrawingArea widget for use with Athena widgets is included, with documentation. This widget is modeled after Motif's DrawingArea widget, defining callbacks for input, resizing, pointer movement, and exposure. See DrawingA.doc for documentation. Please send me any comments, suggestions, ideas, and fixes. -Dave Nedde -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # xball # This archive created: Thu Jun 21 09:55:32 1990 export PATH; PATH=/bin:$PATH if test ! -d 'xball' then echo shar: creating directory "'xball'" mkdir 'xball' fi echo shar: entering directory "'xball'" cd 'xball' echo shar: extracting "'Makefile'" '(294 characters)' if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else sed 's/^X//' << \SHAR_EOF > 'Makefile' X X#R3 = -DX11_R3 # Use this if you have X11 R3 installed XCFLAGS = -O -DDELAY=1000 $(R3) X X Xxball: xball.c DrawingA.h DrawingA.o X $(CC) $(CFLAGS) -o xball xball.c DrawingA.o -lXaw -lXmu -lXt -lX11 X XDrawingA.o: DrawingA.c DrawingA.h DrawingAP.h X Xclean: X rm -f core xball xball.o DrawingA.o *~ #* X SHAR_EOF fi # end of overwriting check echo shar: extracting "'README'" '(1206 characters)' if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^X//' << \SHAR_EOF > 'README' XXBall V2.0 - By David Nedde 6/15/90 X XInfo: X This X11 program allows you to throw balls around in the window. X Hold down mouse button 1 to create a ball, then throw the ball X by moving the pointer and letting go of the button. The ball X will be going the speed of the pointer at release time. X Hold down button 2 and move the mouse to create random velocity balls. X Hold down button 3 and move the mouse to create zero velocity balls. X On color displays the balls are different, random colors. X XCompiling: X Uncomment the R3 variable in the Makefile if you are compiling on an X X11 R3 machine. Decrease the DELAY define in the Makefile if XBall X runs too slow on your machine. X XOptions: X Standard X11 options X XCopying: X Copyright 1990, David Nedde X X XBall is released into the public domain. X Permission to use, copy, modify, and distribute this X software and its documentation for any purpose and without X fee provided that the above copyright notice appears in all copies. X It is provided "as is" without express or implied warranty. X XHappy bouncing! X X-- XDavid Nedde, Computer Science Dept. daven@maxine.wpi.edu XWorcester Polytecnic Institute (508) 831-5117/5668 XWorcester, MA 01609 SHAR_EOF fi # end of overwriting check echo shar: extracting "'xball.c'" '(35731 characters)' if test -f 'xball.c' then echo shar: will not over-write existing file "'xball.c'" else sed 's/^X//' << \SHAR_EOF > 'xball.c' X/* XBall.c - Written by David Nedde (daven@maxine.wpi.edu) 6/15/90 X/* Features: Athena widget interface X/* Item collision detection X/* Window resize -> boundry change X/* Randomly colored balls X/* Different ball creation algorithms X/* X/* Copyright 1990, David Nedde X/* X/* XBall is released into the public domain. X/* Permission to use, copy, modify, and distribute this X/* software and its documentation for any purpose and without fee X/* is granted provided that the above copyright notice appears in all copies. X/* It is provided "as is" without express or implied warranty. X*/ X X#include <string.h> X#include <X11/Intrinsic.h> X#include <X11/StringDefs.h> X#include <X11/Xutil.h> X#include <X11/Shell.h> X#include "DrawingA.h" X#ifdef X11_R3 X#include <X11/Form.h> X#include <X11/Command.h> X#include <X11/Scroll.h> X#include <X11/AsciiText.h> X#else X#include <X11/Xaw/Form.h> X#include <X11/Xaw/Command.h> X#include <X11/Xaw/Scrollbar.h> X#include <X11/Xaw/AsciiText.h> X#endif X Xvoid quit(); /* Quit button callback */ Xvoid clear(); /* Clear button callback */ Xvoid about(); /* About button callback */ Xvoid author(); /* Author button callback */ Xvoid change_gravity(); /* Gravity scrollbar JumpProc callback */ Xvoid scroll_gravity(); /* Gravity scrollbar ScrollProc callback */ Xvoid change_elasticity(); /* Elasticity scrollbar JumpProc callback */ Xvoid scroll_elasticity(); /* Elasticity scrollbar ScrollProc callback */ Xint background_processing(); /* Background processing callback */ Xvoid redisplay(); /* DrawingArea canvas redisplay callback */ Xvoid resize(); /* DrawingArea canvas resize callback */ Xvoid process_input(); /* DrawingArea canvas input callback */ Xvoid process_motion(); /* DrawingArea canvas motion callback */ X X#define ABS(x) ((x) < 0 ? -(x) : (x)) X#define MIN(x,y) ((x) > (y) ? (y) : (x)) X#define SWAP(x,y,type) { type t; t = (x); (x) = (y); (y) = t; } X#define INTFAC 16 /* Multiplied to everything but velocities */ X#define MULI(x) ((x)*INTFAC) X#define DIVI(x) ((x)/INTFAC) X X#define MOTION_MODE 1 /* Ball creation modes for get_velocity() */ X#define RANDOM_MODE 2 X#define STILL_MODE 3 X X#define MAX_ITEM 500 /* Max items on the screen */ X#define MAX_COLORS 200 /* Max colors allocated */ X#define GRAVITY MULI(3) /* Default gravity */ X#define MAX_GRAVITY (5*GRAVITY) /* Max gravity allowable */ X#define ELASTICITY 10 /* Default elasticity */ X#define MAX_ELASTICITY (10*ELASTICITY) /* Max elasticity */ X X#define ITEM_WIDTH 10 /* The item's size */ X#define ITEM_HEIGHT 10 X#define WIN_HEIGHT 400 /* Default window's size */ X#define WIN_WIDTH 500 X X#ifdef X11_R3 Xtypedef char *XtPointer; X#define XawScrollbarSetThumb XtScrollBarSetThumb X#endif X X X/* Holds window information */ Xtypedef struct { X Widget w; X Colormap colormap; X GC set_gc; /* Draw item */ X GC unset_gc; /* Erase item */ X GC clear_gc; /* Draw in background color */ X GC color_gc; X int monochrome; /* True if screen is monochrome */ X} win_info_type; X X/* Holds one item's position and velocity */ Xstruct item_struct { X int x,y; /* Location of item */ X int y_velocity; /* vel < 0 means dropping, > 0 means climbing */ X int x_velocity; /* vel < 0 means to left, > 0 means to right */ X char valid; /* TRUE if item is valid */ X int rebounded; /* Used to determine if item collision */ X /* had already been calculated for this item */ X int p_index; /* Index of pixel map to use for drawing item */ X}; X Xtypedef struct data_package_struct { X win_info_type *winfo_ptr; /* Holds window info */ X struct item_struct item_list[MAX_ITEM]; /* Holds all items */ X Pixmap pixmaps[ MAX_COLORS]; /* Holds all ball drawings */ X int item_index; /* Points to next unused item in item_list */ X int max_color; /* Holds number of colors/pixmaps used */ X int curr_pixmap; /* Holds pixmap index to use for next ball */ X /********************************************************************** X * Used to calculate velocity when a item is let go. X * save_newx,save_newy is the most recent motion position X * from the pointer. save_oldx,save_oldy is the next oldest X ***********************************************************************/ X int save_oldx, save_oldy, save_newx, save_newy; X int button1_pressed,button2_pressed,button3_pressed; X int right_wall; /* Locations of room structures */ X int left_wall; X int ceiling; X int floor; X int gravity; /* Current gravity */ X int elasticity; /* current elasticity */ X} datap_type; X X X/*** Start of main program ***/ Xmain(argc,argv) Xint argc; Xchar **argv; X{ X datap_type datap; X win_info_type win_info; X Widget toplevel; /* The core widget */ X Widget form_widget; /* Holds stuff together */ X Widget title; /* Title widget */ X Widget title1; /* Second title widget */ X Widget quit_button; /* Quit button */ X Widget clear_button; /* Clear button */ X Widget grav_label; /* Gravity scroll bar label */ X Widget gravity_bar; /* Gravity scroll bar */ X Widget elas_label; /* Elasticity scroll bar label */ X Widget elasticity_bar; /* Elasticity scroll bar */ X Widget canvas_widget; /* Where balls are drawn */ X Arg wargs[10]; /* Used to set widget resources */ X int n; X X X datap.item_index = 0; /* No items yet */ X datap.winfo_ptr = &win_info; X datap.right_wall = MULI(WIN_WIDTH); /* Locations of room structures */ X datap.left_wall = 0; X datap.ceiling = 0; X datap.floor = MULI(WIN_HEIGHT); X datap.gravity = GRAVITY; X datap.elasticity = ELASTICITY; X datap.button1_pressed = FALSE; X datap.button2_pressed = FALSE; X datap.button3_pressed = FALSE; X X toplevel = XtInitialize(argv[0],"XBall", NULL, 0, &argc, argv); X X win_info.w = toplevel; X setup_win_info( toplevel, &win_info); X X X /* Setup a different colored item for each available color */ X if (win_info.monochrome) X { X datap.max_color = 0; X X /* Create pixmap for item */ X datap.pixmaps[datap.max_color] = XCreatePixmap( XtDisplay(toplevel), X DefaultRootWindow(XtDisplay(toplevel)), X ITEM_WIDTH, ITEM_HEIGHT, X DefaultDepth( XtDisplay(toplevel), X XtWindow(toplevel))); X /* Clear pixmap */ X XFillRectangle(XtDisplay(toplevel), datap.pixmaps[datap.max_color], X win_info.clear_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT); X /* Draw item */ X XDrawArc(XtDisplay(toplevel), datap.pixmaps[datap.max_color], X win_info.set_gc,0,0, ITEM_WIDTH-1,ITEM_HEIGHT-1,0,360*64); X XFillArc(XtDisplay(toplevel), datap.pixmaps[datap.max_color], X win_info.set_gc,0,0, ITEM_WIDTH-1,ITEM_HEIGHT-1,0,360*64); X datap.max_color++; X } X else X { X XColor color; X int cells[10]; X int back_g; X int max_colors; X X X max_colors = MIN(DisplayCells(XtDisplay(toplevel), X DefaultScreen(XtDisplay(toplevel))), X MAX_COLORS); X back_g = WhitePixel(XtDisplay(toplevel), X DefaultScreen(XtDisplay(toplevel))); X X color.flags = DoRed | DoGreen | DoBlue; X datap.curr_pixmap = 0; X for (datap.max_color = 0; datap.max_color < max_colors; datap.max_color++) X { X if (!XAllocColorCells( XtDisplay(toplevel),win_info.colormap, TRUE, NULL, X 0, cells,1)) X break; /* Can't allocate any more colors */ X X color.red = random()%65535; X color.green = random()%65535; X color.blue = random()%65535; X color.pixel = cells[0]; X XStoreColor( XtDisplay(toplevel), win_info.colormap, &color); X X /* Create pixmap for item */ X datap.pixmaps[datap.max_color] = X XCreatePixmap(XtDisplay(toplevel), X DefaultRootWindow(XtDisplay(toplevel)), X ITEM_WIDTH, ITEM_HEIGHT, X DefaultDepth(XtDisplay(toplevel), XtWindow(toplevel))); X /* Clear pixmap */ X XFillRectangle(XtDisplay(toplevel),datap.pixmaps[datap.max_color], X win_info.clear_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT); X /* Draw item */ X XSetForeground(XtDisplay(toplevel), win_info.color_gc, X color.pixel ^ back_g); X XDrawArc(XtDisplay(toplevel), datap.pixmaps[datap.max_color], X win_info.color_gc, 0, 0, ITEM_WIDTH-1,ITEM_HEIGHT-1,0,360*64); X XFillArc(XtDisplay(toplevel), datap.pixmaps[datap.max_color], X win_info.color_gc, 0, 0, ITEM_WIDTH-1,ITEM_HEIGHT-1,0,360*64); X } X } X X XSetFunction( XtDisplay(toplevel), win_info.set_gc, GXxor); X XCopyGC(XtDisplay(toplevel),win_info.set_gc,0x3fffffL,win_info.unset_gc); X X X n = 0; X form_widget = XtCreateManagedWidget("form", formWidgetClass, toplevel, X wargs,n); X X n = 0; X XtSetArg(wargs[n],XtNlabel,"XBall V2.0 "); n++; X title = XtCreateManagedWidget("Title", commandWidgetClass, form_widget, X wargs,n); X XtAddCallback(title,XtNcallback,about,NULL); X X n = 0; X XtSetArg(wargs[n],XtNlabel,"by David Nedde"); n++; X XtSetArg(wargs[n],XtNfromVert,title); n++; X title1 = XtCreateManagedWidget("Title1", commandWidgetClass, X form_widget,wargs,n); X XtAddCallback(title1,XtNcallback,author,NULL); X X n = 0; X XtSetArg(wargs[n],XtNlabel,"Quit "); n++; X XtSetArg(wargs[n],XtNfromHoriz,title); n++; X quit_button = XtCreateManagedWidget("Quit", commandWidgetClass, X form_widget,wargs,n); X XtAddCallback(quit_button,XtNcallback,quit,NULL); X X n = 0; X XtSetArg(wargs[n],XtNfromHoriz,title1); n++; X XtSetArg(wargs[n],XtNfromVert,quit_button); n++; X clear_button = XtCreateManagedWidget("Clear", commandWidgetClass, X form_widget,wargs,n); X XtAddCallback(clear_button,XtNcallback,clear,&datap); X X n = 0; X XtSetArg(wargs[n],XtNlabel,"Gravity "); n++; X XtSetArg(wargs[n],XtNborderWidth,0); n++; X XtSetArg(wargs[n],XtNfromHoriz,quit_button); n++; X XtSetArg(wargs[n],XtNhorizDistance,30); n++; X grav_label = XtCreateManagedWidget("GravLabel", labelWidgetClass, X form_widget,wargs,n); X X n = 0; X XtSetArg(wargs[n],XtNlength,100); n++; X XtSetArg(wargs[n],XtNorientation,XtorientHorizontal); n++; X XtSetArg(wargs[n],XtNfromHoriz,grav_label); n++; X gravity_bar = XtCreateManagedWidget("GravityBar", scrollbarWidgetClass, X form_widget,wargs,n); X XtAddCallback(gravity_bar,XtNjumpProc,change_gravity,&datap); X XtAddCallback(gravity_bar,XtNscrollProc,scroll_gravity,&datap); X XawScrollbarSetThumb(gravity_bar,(float)GRAVITY/MAX_GRAVITY, 0.1); X X n = 0; X XtSetArg(wargs[n],XtNlabel,"Elasticity"); n++; X XtSetArg(wargs[n],XtNborderWidth,0); n++; X XtSetArg(wargs[n],XtNfromHoriz,clear_button); n++; X XtSetArg(wargs[n],XtNfromVert,grav_label); n++; X XtSetArg(wargs[n],XtNhorizDistance,30); n++; X elas_label = XtCreateManagedWidget("ElasLabel", labelWidgetClass, X form_widget,wargs,n); X X n = 0; X XtSetArg(wargs[n],XtNfromVert,gravity_bar); n++; X XtSetArg(wargs[n],XtNfromHoriz,elas_label); n++; X XtSetArg(wargs[n],XtNorientation,XtorientHorizontal); n++; X XtSetArg(wargs[n],XtNlength,100); n++; X elasticity_bar = XtCreateManagedWidget("ElasticityBar", scrollbarWidgetClass, X form_widget,wargs,n); X XtAddCallback(elasticity_bar,XtNjumpProc,change_elasticity,&datap); X XtAddCallback(elasticity_bar,XtNscrollProc,scroll_elasticity,&datap); X XawScrollbarSetThumb(elasticity_bar,(1.0 - (float)ELASTICITY/MAX_ELASTICITY), X 0.1); X X n = 0; X XtSetArg(wargs[n],XtNwidth, WIN_WIDTH); n++; X XtSetArg(wargs[n],XtNheight,WIN_HEIGHT); n++; X XtSetArg(wargs[n],XtNfromVert,clear_button); n++; X canvas_widget = XtCreateManagedWidget("canvas", drawingAreaWidgetClass, X form_widget,wargs,n); X XtAddCallback(canvas_widget,XtNexposeCallback,redisplay,&datap); X XtAddCallback(canvas_widget,XtNinputCallback, process_input,&datap); X XtAddCallback(canvas_widget,XtNmotionCallback,process_motion,&datap); X XtAddCallback(canvas_widget,XtNresizeCallback,resize,&datap); X win_info.w = canvas_widget; X X XtAddWorkProc(background_processing, &datap); X X XtRealizeWidget(toplevel); X X XtMainLoop(); X} X X X/********************************************************************** X * Setup_win_info - Setup the window info X **********************************************************************/ Xsetup_win_info(w, winfo_ptr) XWidget w; Xwin_info_type *winfo_ptr; X{ X int fore_g,back_g; /* Fore and back ground pixels */ X X X /*** Start of code ***/ X back_g = WhitePixel(XtDisplay(w),DefaultScreen(XtDisplay(w))); X fore_g = BlackPixel(XtDisplay(w),DefaultScreen(XtDisplay(w))); X X /* Create drawing and erasing GC */ X X X winfo_ptr->set_gc = XCreateGC(XtDisplay(w), DefaultRootWindow(XtDisplay(w)), X 0, 0); X XSetBackground(XtDisplay(w), winfo_ptr->set_gc, 0); X XSetForeground(XtDisplay(w), winfo_ptr->set_gc, fore_g ^ back_g); X XSetGraphicsExposures(XtDisplay(w),winfo_ptr->set_gc,False); X winfo_ptr->unset_gc = XCreateGC(XtDisplay(w),DefaultRootWindow(XtDisplay(w)) X , 0, 0); X XSetBackground(XtDisplay(w), winfo_ptr->unset_gc, 0); X XSetForeground(XtDisplay(w), winfo_ptr->unset_gc, fore_g ^ back_g); X XSetGraphicsExposures(XtDisplay(w),winfo_ptr->unset_gc,False); X winfo_ptr->clear_gc = XCreateGC(XtDisplay(w),DefaultRootWindow(XtDisplay(w)) X , 0, 0); X XSetBackground(XtDisplay(w), winfo_ptr->clear_gc, fore_g ^ back_g); X XSetForeground(XtDisplay(w), winfo_ptr->clear_gc, 0); X XSetGraphicsExposures(XtDisplay(w),winfo_ptr->clear_gc,False); X /* Setup the color GC */ X winfo_ptr->color_gc = XCreateGC(XtDisplay(w),DefaultRootWindow(XtDisplay(w)) X , 0, 0); X XSetBackground(XtDisplay(w), winfo_ptr->color_gc, 0); X XSetForeground(XtDisplay(w), winfo_ptr->color_gc, fore_g ^ back_g); X XSetGraphicsExposures(XtDisplay(w),winfo_ptr->color_gc,False); X X winfo_ptr->colormap = DefaultColormap(XtDisplay(w), X DefaultScreen(XtDisplay(w))); X XSetWindowColormap( XtDisplay(w), DefaultRootWindow(XtDisplay(w)), X winfo_ptr->colormap); X winfo_ptr->monochrome = DisplayCells( XtDisplay(w), X DefaultScreen(XtDisplay(w))) == 2; X} X X X/* Called when DrawingArea canvas is redisplayed */ Xvoid redisplay(w, datap_ptr, call_data) XWidget w; Xdatap_type *datap_ptr; XXawDrawingAreaCallbackStruct *call_data; X{ X int x; X X X if (call_data->event->xexpose.count == 0) /* Wait until last expose event */ X { X XClearWindow( XtDisplay(w), XtWindow(w)); X for (x = 0; x < datap_ptr->item_index; x++) /* Redraw all items */ X XCopyArea( call_data->event->xexpose.display, X datap_ptr->pixmaps[datap_ptr->item_list[x].p_index], X call_data->event->xexpose.window, X datap_ptr->winfo_ptr->set_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT, X DIVI(datap_ptr->item_list[x].x) - ITEM_WIDTH/2, X DIVI(datap_ptr->item_list[x].y) - ITEM_HEIGHT/2); X } X} X X X/* Called when DrawingArea canvas is resized */ Xvoid resize (w, datap_ptr, call_data) XWidget w; Xdatap_type *datap_ptr; XXawDrawingAreaCallbackStruct *call_data; X{ X Arg wargs[2]; X int n; X Dimension width,height; X X n = 0; X XtSetArg(wargs[n], XtNwidth, &width); n++; X XtSetArg(wargs[n], XtNheight, &height); n++; X XtGetValues(w, wargs, n); X X datap_ptr->right_wall = MULI(width); X datap_ptr->floor = MULI(height); X} X X X/* Called when no events are in the queue */ Xint background_processing(datap_ptr) Xdatap_type *datap_ptr; X{ X int x,y; /* Index variables */ X int oldx,oldy; /* Save old item position while caclculating new pos */ X X X XFlush(XtDisplay(datap_ptr->winfo_ptr->w)); X delay(20 - datap_ptr->item_index); /* Slow down the first 20 balls */ X X /* Move each item on the screen */ X for (x = 0; x < datap_ptr->item_index; x++) X { X /* See if item is valid */ X if (!datap_ptr->item_list[x].valid) X { X /* Copy last item in list to here */ X datap_ptr->item_index--; X if (x != datap_ptr->item_index) X datap_ptr->item_list[x] = datap_ptr->item_list[datap_ptr->item_index]; X else X continue; /* Killed last item */ X } X X /* Calculate new position of item */ X /* Save old position so we can erase it */ X oldy = DIVI(datap_ptr->item_list[x].y); X oldx = DIVI(datap_ptr->item_list[x].x); X X /* Calculate new y position */ X /* Gravity adds to velocity */ X if ((datap_ptr->item_list[x].y < datap_ptr->floor) || X (datap_ptr->item_list[x].y_velocity != 0)) X datap_ptr->item_list[x].y_velocity += DIVI(datap_ptr->gravity); X X /* Move vertically based on velocity */ X datap_ptr->item_list[x].y += datap_ptr->item_list[x].y_velocity; X X if (datap_ptr->item_list[x].y >= datap_ptr->floor) X { X /* item hit floor -- bounce off floor */ X datap_ptr->item_list[x].y = 2*datap_ptr->floor - X datap_ptr->item_list[x].y; /* Bounce back */ X X datap_ptr->item_list[x].y_velocity = X (-datap_ptr->item_list[x].y_velocity) + /* Rev vel */ X DIVI(datap_ptr->gravity); X X if (ABS(datap_ptr->item_list[x].y_velocity) < datap_ptr->elasticity) X datap_ptr->item_list[x].y_velocity = 0; X else X /* Remove some inertia */ X datap_ptr->item_list[x].y_velocity += datap_ptr->elasticity; X } X else X if (datap_ptr->item_list[x].y < datap_ptr->ceiling) X { X /* item hit ceiling */ X datap_ptr->item_list[x].y = 2*datap_ptr->ceiling - X datap_ptr->item_list[x].y; /* Bounce off */ X datap_ptr->item_list[x].y_velocity = X -datap_ptr->item_list[x].y_velocity; /* Rev dir */ X } X X /* Calculate new x position */ X datap_ptr->item_list[x].x += X datap_ptr->item_list[x].x_velocity; /* Move horiz base on vel */ X if (datap_ptr->item_list[x].x > datap_ptr->right_wall) X { X /* Hit right wall */ X X datap_ptr->item_list[x].x = 2*datap_ptr->right_wall - X datap_ptr->item_list[x].x; /* Bounce off */ X datap_ptr->item_list[x].x_velocity = X -datap_ptr->item_list[x].x_velocity; /* Rev dir */ X } X else X if (datap_ptr->item_list[x].x < datap_ptr->left_wall) X { X /* Hit left wall */ X datap_ptr->item_list[x].x = 2 * datap_ptr->left_wall - X datap_ptr->item_list[x].x; /* Bounce off */ X datap_ptr->item_list[x].x_velocity = X -datap_ptr->item_list[x].x_velocity; /* Rev dir */ X } X X /* See if collided with another item */ X for (y = 0; y < datap_ptr->item_index && X datap_ptr->item_list[x].rebounded == FALSE; y++) X if (x != y) X rebound_item( &datap_ptr->item_list[x], &datap_ptr->item_list[y]); X datap_ptr->item_list[x].rebounded = FALSE; X X /* Don't redraw if item hasn't moved */ X if (oldx == DIVI(datap_ptr->item_list[x].x) && X oldy == DIVI(datap_ptr->item_list[x].y)) X continue; /* Item hasn't moved */ X X /* Erase old object */ X XCopyArea( XtDisplay(datap_ptr->winfo_ptr->w), X datap_ptr->pixmaps[datap_ptr->item_list[x].p_index], X XtWindow(datap_ptr->winfo_ptr->w), X datap_ptr->winfo_ptr->unset_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT, X oldx - ITEM_WIDTH/2, X oldy - ITEM_HEIGHT/2); X X /* See if item has come to a peaceful rest */ X if (ABS(datap_ptr->item_list[x].y - datap_ptr->floor) < X datap_ptr->gravity/4 && /* on floor */ X ABS(datap_ptr->item_list[x].y_velocity) <= X datap_ptr->elasticity*2) /* Not bouncing */ X { X if (ABS(datap_ptr->item_list[x].x_velocity) < X datap_ptr->gravity/10) /* No roll */ X { X datap_ptr->item_list[x].valid = FALSE; X continue; /* Don't draw item */ X } X X /* Slow down velocity once rolling */ X if (datap_ptr->item_list[x].x_velocity > 0) X datap_ptr->item_list[x].x_velocity -= DIVI(datap_ptr->gravity); X else X datap_ptr->item_list[x].x_velocity += DIVI(datap_ptr->gravity); X } X X /* Draw new item */ X XCopyArea( XtDisplay(datap_ptr->winfo_ptr->w), X datap_ptr->pixmaps[datap_ptr->item_list[x].p_index], X XtWindow(datap_ptr->winfo_ptr->w), X datap_ptr->winfo_ptr->set_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT, X DIVI(datap_ptr->item_list[x].x) - ITEM_WIDTH/2, X DIVI(datap_ptr->item_list[x].y) - ITEM_HEIGHT/2); X } X return(FALSE); /* Don't remove work procedure */ X} X X X/* Called when DrawingArea canvas has input */ Xvoid process_input(w, datap_ptr, call_data) XWidget w; Xdatap_type *datap_ptr; XXawDrawingAreaCallbackStruct *call_data; X{ X switch (call_data->event->type) X { X /* Process mouse button events */ X case ButtonPress: X switch (call_data->event->xbutton.button) X { X case 1: X if (datap_ptr->item_index == MAX_ITEM - 1) X break; /* Too many items already */ X datap_ptr->button1_pressed = TRUE; X datap_ptr->save_oldx = datap_ptr->save_newx = X call_data->event->xbutton.x; X datap_ptr->save_oldy = datap_ptr->save_newy = X call_data->event->xbutton.y; X /* Draw an item under the pointer */ X XCopyArea(call_data->event->xbutton.display, X datap_ptr->pixmaps[datap_ptr->curr_pixmap], X call_data->event->xbutton.window, X datap_ptr->winfo_ptr->set_gc, 0, 0, X ITEM_WIDTH, ITEM_HEIGHT, X call_data->event->xbutton.x - ITEM_WIDTH/2, X call_data->event->xbutton.y - ITEM_HEIGHT/2); X break; X X /* Not used */ X case 2: datap_ptr->button2_pressed = TRUE; break; X case 3: datap_ptr->button3_pressed = TRUE; break; X } X break; X X case ButtonRelease: X switch (call_data->event->xbutton.button) X { X case 1: X { X int x_vel,y_vel; X X if (datap_ptr->button1_pressed == FALSE) X break; /* Item was never created */ X X datap_ptr->button1_pressed = FALSE; X X /* Erase button ball */ X XCopyArea(call_data->event->xbutton.display, X datap_ptr->pixmaps[datap_ptr->curr_pixmap], X call_data->event->xbutton.window, X datap_ptr->winfo_ptr->unset_gc, 0, 0, X ITEM_WIDTH, ITEM_HEIGHT, X call_data->event->xbutton.x - ITEM_WIDTH/2, X call_data->event->xbutton.y - ITEM_HEIGHT/2); X X /* Create new item when button let go */ X get_velocity( &x_vel,&y_vel, MOTION_MODE, datap_ptr); X create_item( datap_ptr->save_newx, datap_ptr->save_newy, X x_vel, y_vel, datap_ptr); X XCopyArea( call_data->event->xbutton.display, X datap_ptr-> X pixmaps[datap_ptr->item_list[datap_ptr->item_index-1].p_index], X call_data->event->xbutton.window, X datap_ptr->winfo_ptr->set_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT, X call_data->event->xbutton.x - ITEM_WIDTH/2, X call_data->event->xbutton.y - ITEM_HEIGHT/2); X break; X } X X /* Not used */ X case 2: datap_ptr->button2_pressed = FALSE; break; X case 3: datap_ptr->button3_pressed = FALSE; break; X } X break; X } X} X X X X/* Velocity is based on how fast the pointer is moving which is based */ X/* on the last two motion events received's delta-x and delta-y */ Xget_velocity( x_vel_ptr, y_vel_ptr, mode, datap_ptr) Xint *x_vel_ptr; Xint *y_vel_ptr; Xint mode; Xdatap_type *datap_ptr; X{ X switch (mode) X { X case MOTION_MODE: X *x_vel_ptr = (datap_ptr->save_newx - datap_ptr->save_oldx) * 10; X *y_vel_ptr = (datap_ptr->save_newy - datap_ptr->save_oldy) * 10; X break; X X case RANDOM_MODE: X *x_vel_ptr = (random() & 0xff) - 128; /* Random x velocity */ X *y_vel_ptr = (random() & 0x3f) - 128; /* Random, but up, y vel */ X break; X X case STILL_MODE: X *x_vel_ptr = 0; /* No x velocity */ X *y_vel_ptr = 0; /* No y velocity */ X break; X } X} X X X/* See if items have hit and rebound them if they have */ X/* Itema is assumed to have just been moved */ Xrebound_item( itema_ptr, itemb_ptr) Xstruct item_struct *itema_ptr, *itemb_ptr; X{ X int xdiff,ydiff; X X xdiff = DIVI(itema_ptr->x - itemb_ptr->x); X ydiff = DIVI(itema_ptr->y - itemb_ptr->y); X if (ABS(xdiff) < ITEM_WIDTH && ABS(ydiff) < ITEM_HEIGHT) X { X itema_ptr->rebounded = TRUE; /* Mark as rebound */ X itemb_ptr->rebounded = TRUE; /* Mark as rebound */ X X SWAP( itema_ptr->x_velocity, itemb_ptr->x_velocity, int); X SWAP( itema_ptr->y_velocity, itemb_ptr->y_velocity, int); X X if (itema_ptr->y_velocity <= ITEM_WIDTH && X itemb_ptr->y_velocity <= ITEM_WIDTH) X { X itema_ptr->y_velocity += ydiff; X itemb_ptr->y_velocity -= ydiff; X } X if (itema_ptr->x_velocity <= ITEM_WIDTH && X itemb_ptr->x_velocity <= ITEM_WIDTH) X { X itema_ptr->x_velocity += xdiff; X itemb_ptr->x_velocity -= xdiff; X } X } X} X X X/* Initialize an item in the main data structure */ Xcreate_item(x,y, x_vel, y_vel, datap_ptr) Xint x,y; Xint x_vel, y_vel; Xdatap_type *datap_ptr; X{ X datap_ptr->item_list[datap_ptr->item_index].x = MULI(x); X datap_ptr->item_list[datap_ptr->item_index].y = MULI(y); X datap_ptr->item_list[datap_ptr->item_index].x_velocity = x_vel; X datap_ptr->item_list[datap_ptr->item_index].y_velocity = y_vel; X datap_ptr->item_list[datap_ptr->item_index].valid = TRUE; X datap_ptr->item_list[datap_ptr->item_index].p_index = datap_ptr->curr_pixmap; X datap_ptr->curr_pixmap = (datap_ptr->curr_pixmap + 1) % datap_ptr->max_color; X datap_ptr->item_list[datap_ptr->item_index].rebounded = FALSE; X X datap_ptr->item_index++; X} X X X#ifndef DELAY X#define DELAY 100 X#endif X Xdelay(length) Xint length; X{ X int x,y,sum; X X X /* Yes, a delay loop to slow small amounts of items */ X for (x = 0; x < length; x++) X for (y = 0; y < DELAY; y++) X sum = sum + y * x; X X return(sum); /* Try to keep it from getting optimized out */ X} X X X/* Called when DrawingArea canvas have pointer motion events */ Xvoid process_motion(w, datap_ptr, call_data) XWidget w; Xdatap_type *datap_ptr; XXawDrawingAreaCallbackStruct *call_data; X{ X int x_vel,y_vel; X X X if (datap_ptr->button1_pressed) X { X /* When button 1 pressed during movement */ X datap_ptr->save_oldx = datap_ptr->save_newx; /* Save 'speed' */ X datap_ptr->save_oldy = datap_ptr->save_newy; X datap_ptr->save_newx = call_data->event->xmotion.x; X datap_ptr->save_newy = call_data->event->xmotion.y; X X /* Erase old object */ X XCopyArea( call_data->event->xmotion.display, X datap_ptr->pixmaps[datap_ptr->curr_pixmap], X call_data->event->xmotion.window, X datap_ptr->winfo_ptr->unset_gc, 0, 0, X ITEM_WIDTH, ITEM_HEIGHT, X datap_ptr->save_oldx - ITEM_WIDTH/2, X datap_ptr->save_oldy - ITEM_HEIGHT/2); X X /* Draw new one */ X XCopyArea( call_data->event->xmotion.display, X datap_ptr->pixmaps[datap_ptr->curr_pixmap], X call_data->event->xmotion.window, X datap_ptr->winfo_ptr->set_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT, X datap_ptr->save_newx - ITEM_WIDTH/2, X datap_ptr->save_newy - ITEM_HEIGHT/2); X } X else X if (datap_ptr->button2_pressed && datap_ptr->item_index < MAX_ITEM-1) X { X get_velocity( &x_vel,&y_vel, RANDOM_MODE, datap_ptr); X create_item( call_data->event->xmotion.x, call_data->event->xmotion.y, X x_vel, y_vel, datap_ptr); X XCopyArea( call_data->event->xmotion.display, X datap_ptr-> X pixmaps[datap_ptr->item_list[datap_ptr->item_index-1].p_index], X call_data->event->xmotion.window, X datap_ptr->winfo_ptr->set_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT, X call_data->event->xmotion.x - ITEM_WIDTH/2, X call_data->event->xmotion.y - ITEM_HEIGHT/2); X } X else X if (datap_ptr->button3_pressed && datap_ptr->item_index < MAX_ITEM-1) X { X get_velocity( &x_vel,&y_vel, STILL_MODE, datap_ptr); X create_item( call_data->event->xmotion.x,call_data->event->xmotion.y, X x_vel, y_vel, datap_ptr); X XCopyArea( call_data->event->xmotion.display, X datap_ptr-> X pixmaps[datap_ptr->item_list[datap_ptr->item_index-1].p_index], X call_data->event->xmotion.window, X datap_ptr->winfo_ptr->set_gc, 0, 0, ITEM_WIDTH, ITEM_HEIGHT, X call_data->event->xmotion.x - ITEM_WIDTH/2, X call_data->event->xmotion.y - ITEM_HEIGHT/2); X } X} X X X/* Called when quit button pressed */ Xvoid quit(w, closure, call_data) XWidget w; Xcaddr_t closure; Xcaddr_t call_data; X{ X XtCloseDisplay(XtDisplay(w)); X exit(0); X} X X X/* Called when clear button pressed */ Xvoid clear(w, datap_ptr, call_data) XWidget w; Xdatap_type *datap_ptr; Xcaddr_t call_data; X{ X XClearWindow( XtDisplay(datap_ptr->winfo_ptr->w), X XtWindow(datap_ptr->winfo_ptr->w)); X datap_ptr->item_index = 0; X} X X X/* Called when gravity bar's JumpProc callback is called */ Xvoid change_gravity(w, datap_ptr, percent_ptr) XWidget w; Xdatap_type *datap_ptr; XXtPointer percent_ptr; X{ X float percent = *(float *)percent_ptr; X X datap_ptr->gravity = MAX_GRAVITY * percent; X} X X X/* Called when gravity bar's ScrollProc callback is called */ Xvoid scroll_gravity(w,datap_ptr,position_ptr) XWidget w; Xdatap_type *datap_ptr; XXtPointer position_ptr; X{ X Arg args[10]; X Dimension length; X int n; X int position = (int)position_ptr; X float percent_change; X X X n = 0; X XtSetArg(args[n], XtNlength, &length); n++; X XtGetValues(w, args, n); X X percent_change = (float)position / (length*3); X X datap_ptr->gravity = datap_ptr->gravity + MAX_GRAVITY * percent_change; X if (datap_ptr->gravity >= MAX_GRAVITY) X datap_ptr->gravity = MAX_GRAVITY; X else X if (datap_ptr->gravity <= 0) X datap_ptr->gravity = 0; X X XawScrollbarSetThumb(w,(float)datap_ptr->gravity/MAX_GRAVITY, 0.1); X} X X X/* Called when elasticity bar's ScrollProc callback is called */ Xvoid scroll_elasticity(w,datap_ptr,position_ptr) XWidget w; Xdatap_type *datap_ptr; XXtPointer position_ptr; X{ X Arg args[10]; X Dimension length; X int n; X int position = (int)position_ptr; X float percent_change; X X X n = 0; X XtSetArg(args[n], XtNlength, &length); n++; X XtGetValues(w, args, n); X X percent_change = (float)position / (length*3); X X datap_ptr->elasticity = datap_ptr->elasticity -MAX_ELASTICITY*percent_change; X if (datap_ptr->elasticity > MAX_ELASTICITY) X datap_ptr->elasticity = MAX_ELASTICITY; X else X if (datap_ptr->elasticity < 1) X datap_ptr->elasticity = 1; X X XawScrollbarSetThumb(w,1.0 -(float)datap_ptr->elasticity/MAX_ELASTICITY,0.1); X} X X X/* Called when elasticity bar's JumpProc callback is called */ Xvoid change_elasticity(w, datap_ptr, percent_ptr) XWidget w; Xdatap_type *datap_ptr; XXtPointer percent_ptr; X{ X float percent = *(float *)percent_ptr; X X /* ... + 1 is because 0 elasticity reveales algotithm deficiencies */ X datap_ptr->elasticity = MAX_ELASTICITY * (1.0 - percent) + 1; X} X Xchar *malloc(); Xchar *concat_words(n, words) Xint n; Xchar *words[]; X{ X char *str; X int i, len = 0; X X X if (n <= 0) X return(NULL); X X str = NULL; X X for (i = 0; i < n; i++) X len += strlen(words[i]) + 1; X X str = malloc(len); X str[0] = '\0'; X X for (i = 0; i < n; i++) X strcat(str,words[i]); X X return(str); X} X X X/* Called when OK button pressed */ Xvoid finish_ok(w, popup_parent, call_data) XWidget w; XWidget popup_parent; Xcaddr_t call_data; X{ X XtPopdown(popup_parent); X} X Xvoid free_string(w, temp_str, call_data) XWidget w; XWidget *temp_str; Xcaddr_t call_data; X{ X free(temp_str); X} X X X/* Author message */ Xstatic char *author_string[] = { X "XBall V2.0\n", X "David Nedde, Computer Science Dept. daven@maxine.wpi.edu\n", X "Worcester Polytechnic Institute (508) 831-5117/5668\n", X "Worcester, MA 01609\n" X}; X X X/* Called when author button pressed */ Xvoid author(w, closure, call_data) XWidget w; Xcaddr_t closure; Xcaddr_t call_data; X{ X Widget popup_parent; X Widget form_widget; X Widget text_widget; X Widget ok_btn; X Widget title; X char *temp_str; X int n; X Arg wargs[10]; X X popup_parent = XtCreatePopupShell("AuthorParent",overrideShellWidgetClass, X w,NULL,0); X n = 0; X form_widget = XtCreateManagedWidget("PopupForm", formWidgetClass, X popup_parent,wargs,n); X X n = 0; X XtSetArg(wargs[n],XtNlabel,"OK"); n++; X ok_btn = XtCreateManagedWidget("OkBtn", commandWidgetClass, X form_widget,wargs,n); X XtAddCallback(ok_btn,XtNcallback,finish_ok,popup_parent); X X n = 0; X XtSetArg(wargs[n],XtNborderWidth,0); n++; X XtSetArg(wargs[n],XtNfromHoriz,ok_btn); n++; X XtSetArg(wargs[n],XtNlabel,"XBall's Author"); n++; X title = XtCreateManagedWidget("Title2", labelWidgetClass, X form_widget,wargs,n); X XtAddCallback(ok_btn,XtNcallback,finish_ok,popup_parent); X X temp_str = concat_words(sizeof(author_string)/sizeof(char *),author_string); X n = 0; X#ifdef X11_R3 X XtSetArg(wargs[n],XtNfromVert,ok_btn); n++; X XtSetArg(wargs[n],XtNheight,100); n++; X XtSetArg(wargs[n],XtNwidth,450); n++; X XtSetArg(wargs[n],XtNstring,temp_str); n++; X text_widget = XtCreateManagedWidget("TextWidget", asciiStringWidgetClass, X form_widget,wargs,n); X#else X XtSetArg(wargs[n],XtNscrollVertical,XawtextScrollWhenNeeded); n++; X XtSetArg(wargs[n],XtNwrap,XawtextWrapWord); n++; X XtSetArg(wargs[n],XtNfromVert,ok_btn); n++; X XtSetArg(wargs[n],XtNheight,70); n++; X XtSetArg(wargs[n],XtNwidth,450); n++; X XtSetArg(wargs[n],XtNstring,temp_str); n++; X text_widget = XtCreateManagedWidget("TextWidget", asciiTextWidgetClass, X form_widget,wargs,n); X#endif X XtAddCallback(text_widget,XtNdestroyCallback,free_string,temp_str); X X XtPopup(popup_parent,XtGrabNone); X} X X/* About message */ Xstatic char *about_string[] = { X "XBall V2.0\n", X "Written by David Nedde 6/15/90\n\n", X "This program allows you to throw balls around in the window.\n", X "Hold down button 1 to create a ball, then throw the ball by\n", X "moving the pointer and letting go of the button.\n", X "The ball will be going the speed of the pointer at release time.\n", X "Hold down button 2 and move the mouse to create random velocity balls.\n", X "Hold down button 3 and move the mouse to create zero velocity balls.\n", X "On color displays the balls are different, random colors.\n\n\n", X "Copyright 1990, David Nedde\n\n", X "XBall is released into the public domain.\n", X "Permission to use, copy, modify, and distribute this software\n", X "and its documentation for any purpose and without fee is granted\n", X "provided that the above copyright notice appears in all copies.\n", X "It is provided \"as is\" without express or implied warranty.\n" X }; X X/* Called when about button pressed */ Xvoid about(w, closure, call_data) XWidget w; Xcaddr_t closure; Xcaddr_t call_data; X{ X Widget popup_parent; X Widget form_widget; X Widget text_widget; X Widget ok_btn; X Widget title; X char *temp_str; X int n; X Arg wargs[10]; X X popup_parent = XtCreatePopupShell("AuthorParent",overrideShellWidgetClass, X w,NULL,0); X n = 0; X form_widget = XtCreateManagedWidget("PopupForm", formWidgetClass, X popup_parent,wargs,n); X X n = 0; X XtSetArg(wargs[n],XtNlabel,"OK"); n++; X ok_btn = XtCreateManagedWidget("OkBtn", commandWidgetClass, X form_widget,wargs,n); X XtAddCallback(ok_btn,XtNcallback,finish_ok,popup_parent); X X n = 0; X XtSetArg(wargs[n],XtNborderWidth,0); n++; X XtSetArg(wargs[n],XtNfromHoriz,ok_btn); n++; X XtSetArg(wargs[n],XtNlabel,"About XBall"); n++; X title = XtCreateManagedWidget("Title2", labelWidgetClass, X form_widget,wargs,n); X XtAddCallback(ok_btn,XtNcallback,finish_ok,popup_parent); X X temp_str = concat_words(sizeof(about_string)/sizeof(char *),about_string); X n = 0; X#ifdef X11_R3 X XtSetArg(wargs[n],XtNfromVert,ok_btn); n++; X XtSetArg(wargs[n],XtNheight,350); n++; X XtSetArg(wargs[n],XtNwidth,450); n++; X XtSetArg(wargs[n],XtNstring,temp_str); n++; X text_widget = XtCreateManagedWidget("TextWidget", asciiStringWidgetClass, X form_widget,wargs,n); X#else X XtSetArg(wargs[n],XtNfromVert,ok_btn); n++; X XtSetArg(wargs[n],XtNscrollVertical,XawtextScrollWhenNeeded); n++; X XtSetArg(wargs[n],XtNheight,150); n++; X XtSetArg(wargs[n],XtNwidth,450); n++; X XtSetArg(wargs[n],XtNwrap,XawtextWrapWord); n++; X XtSetArg(wargs[n],XtNstring,temp_str); n++; X text_widget = XtCreateManagedWidget("TextWidget", asciiTextWidgetClass, X form_widget,wargs,n); X#endif X XtAddCallback(text_widget,XtNdestroyCallback,free_string,temp_str); X X XtPopup(popup_parent,XtGrabNone); X} SHAR_EOF fi # end of overwriting check echo shar: extracting "'DrawingA.c'" '(4789 characters)' if test -f 'DrawingA.c' then echo shar: will not over-write existing file "'DrawingA.c'" else sed 's/^X//' << \SHAR_EOF > 'DrawingA.c' X/* DrawingA.c: The DrawingArea Widget Methods */ X X/* Copyright 1990, David Nedde X/* X/* This software is released into the public domain. X/* Permission to use, copy, modify, and distribute this X/* software and its documentation for any purpose and without fee X/* is granted provided that the above copyright notice appears in all copies. X/* It is provided "as is" without express or implied warranty. X*/ X X#include <X11/IntrinsicP.h> X#include <X11/StringDefs.h> X#include "DrawingAP.h" X Xstatic void Initialize(); Xstatic void Redisplay(); Xstatic void input_draw(); Xstatic void motion_draw(); Xstatic void resize_draw(); X Xstatic char defaultTranslations[] = "<BtnDown>: input() \n <BtnUp>: input() \n <KeyDown>: input() \n <KeyUp>: input() \n <Motion>: motion() \n <Configure>: resize()"; Xstatic XtActionsRec actionsList[] = { X { "input", (XtActionProc)input_draw }, X { "motion", (XtActionProc)motion_draw }, X { "resize", (XtActionProc)resize_draw }, X}; X X/* Default instance record values */ Xstatic XtResource resources[] = { X {XtNexposeCallback, XtCCallback, XtRCallback, sizeof(caddr_t), X XtOffset(DrawingAreaWidget, drawing_area.expose_callbacks), X XtRCallback, NULL }, X {XtNinputCallback, XtCCallback, XtRCallback, sizeof(caddr_t), X XtOffset(DrawingAreaWidget, drawing_area.input_callbacks), X XtRCallback, NULL }, X {XtNmotionCallback, XtCCallback, XtRCallback, sizeof(caddr_t), X XtOffset(DrawingAreaWidget, drawing_area.motion_callbacks), X XtRCallback, NULL }, X {XtNresizeCallback, XtCCallback, XtRCallback, sizeof(caddr_t), X XtOffset(DrawingAreaWidget, drawing_area.resize_callbacks), X XtRCallback, NULL }, X}; X X XDrawingAreaClassRec drawingAreaClassRec = { X /* CoreClassPart */ X{ X (WidgetClass) &widgetClassRec, /* superclass */ X "DrawingArea", /* class_name */ X sizeof(DrawingAreaRec), /* size */ X NULL, /* class_initialize */ X NULL, /* class_part_initialize */ X FALSE, /* class_inited */ X Initialize, /* initialize */ X NULL, /* initialize_hook */ X XtInheritRealize, /* realize */ X actionsList, /* actions */ X XtNumber(actionsList), /* num_actions */ X resources, /* resources */ X XtNumber(resources), /* resource_count */ X NULLQUARK, /* xrm_class */ X FALSE, /* compress_motion */ X FALSE, /* compress_exposure */ X TRUE, /* compress_enterleave */ X FALSE, /* visible_interest */ X NULL, /* destroy */ X NULL, /* resize */ X Redisplay, /* expose */ X NULL, /* set_values */ X NULL, /* set_values_hook */ X XtInheritSetValuesAlmost, /* set_values_almost */ X NULL, /* get_values_hook */ X NULL, /* accept_focus */ X XtVersion, /* version */ X NULL, /* callback_private */ X defaultTranslations, /* tm_table */ X XtInheritQueryGeometry, /* query_geometry */ X XtInheritDisplayAccelerator, /* display_accelerator */ X NULL /* extension */ X }, /* CoreClass fields initialization */ X { X 0, /* field not used */ X }, /* LabelClass fields initialization */ X { X 0, /* field not used */ X }, /* DrawingAreaClass fields initialization */ X}; X X XWidgetClass drawingAreaWidgetClass = (WidgetClass)&drawingAreaClassRec; X X Xstatic void Initialize( request, new) XDrawingAreaWidget request, new; X{ X if (request->core.width == 0) X new->core.width = 100; X if (request->core.height == 0) X new->core.height = 100; X} X X X/* Invoke expose callbacks */ Xstatic void Redisplay(w, event, region) XDrawingAreaWidget w; XXEvent *event; XRegion region; X{ X XawDrawingAreaCallbackStruct cb; X X cb.reason = XawCR_EXPOSE; X cb.event = event; X cb.window = XtWindow(w); X XtCallCallbacks(w, XtNexposeCallback, &cb); X} X X/* Invoke resize callbacks */ Xstatic void resize_draw(w, event, args, n_args) XDrawingAreaWidget w; XXEvent *event; Xchar *args[]; Xint n_args; X{ X XawDrawingAreaCallbackStruct cb; X X cb.reason = XawCR_RESIZE; X cb.event = event; X cb.window = XtWindow(w); X XtCallCallbacks(w, XtNresizeCallback, &cb); X} X X/* Invoke input callbacks */ Xstatic void input_draw(w, event, args, n_args) XDrawingAreaWidget w; XXEvent *event; Xchar *args[]; Xint n_args; X{ X XawDrawingAreaCallbackStruct cb; X X cb.reason = XawCR_INPUT; X cb.event = event; X cb.window = XtWindow(w); X XtCallCallbacks(w, XtNinputCallback, &cb); X} X X/* Invoke motion callbacks */ Xstatic void motion_draw(w, event, args, n_args) XDrawingAreaWidget w; XXEvent *event; Xchar *args[]; Xint n_args; X{ X XawDrawingAreaCallbackStruct cb; X X cb.reason = XawCR_MOTION; X cb.event = event; X cb.window = XtWindow(w); X XtCallCallbacks(w, XtNmotionCallback, &cb); X} X SHAR_EOF fi # end of overwriting check echo shar: extracting "'DrawingA.doc'" '(4316 characters)' if test -f 'DrawingA.doc' then echo shar: will not over-write existing file "'DrawingA.doc'" else sed 's/^X//' << \SHAR_EOF > 'DrawingA.doc' XDrawingArea Widget X X XSYNOPSIS X Application header file "DrawingA.h" X Class header file "DrawingAP.h" X Class drawingAreaWidgetClass X Class Name DrawingArea X Superclass Label X X XOVERVIEW X This widget was needed to allow a drawing area in the Athena widget X set that doesn't require hacking up the Label widget by adding X complicated actions. This widget follows Motif's DrawingArea widget X closely, except that it follows Athena's naming conventions and there X is no resize policy. Also, Motif's Drawing area is a composite widget, X while this one is a simple widget. This widget is NOT officially X part of the Athena widget set. X X XDESCRIPTION X The DrawingArea widget is modeled after Motif's DrawingArea widget. X The DrawingArea widget is an empty widget that is easily adaptable to X a variety of purposes. It does no drawing and defines no behavior X except for invoking callbacks. Callbacks notify the application when X graphics need to be drawn (exposure events or widget resize) and when X the widget receives input from the keyboard or mouse. Applications X are responsible for defining appearence and behavior as needed in X response to DrawingArea callbacks. X X XClasses X DrawingArea inherits behavior and resources from the Core, Simple, and Label X classes. X The class pointer if DrawingAreaWidgetClass. The class name if DrawingArea. X X XNew Resources X Name Class RepType Default Value X ---- ----- ------- ------------- X exposeCallback Callback Pointer NULL X inputCallback Callback Pointer NULL X motionCallback Callback Pointer NULL X resizeCallback Callback Pointer NULL X X XtNexposeCallback X Specifies list of callbacks that is called when DrawingArea recieves X an exposure event. The callback reason is XawCR_EXPOSE. X XtNinputCallback X Specifies list of callbacks that is called when DrawingArea recieves X an keyboard or mouse event (key or button, up or down). The callback X reason is XawCR_INPUT. X XtNmotionCallback X Specifies list of callbacks that is called when DrawingArea recieves X a mouse motion event. The callback reason is XawCR_MOTION. X XtNresizeCallback X Specifies list of callbacks that is called when the DrawingArea is X resized. The callback reason is XawCR_RESIZE. X X XInherited Resources, Changed defaults X Name Class RepType Default Value X ---- ----- ------- ------------- X height Height Dimension 100 X width Width Dimension 100 X X XCallback Information X The following structure is returned with each callback. X X typedef struct { X int reason; X XEvent *event; X Window window; X } XawDrawingAreaCallbackStruct; X X reason: Indicates why the callback was invoked X event: Points to the XEvent that triggered the callback X window: Is set to the widget window X X XBehavior X <KeyDown>,<KeyUp>,<BtnDown>,<BtnUp>: X The callbacks for XtNinputCallback are called when a key or button is X pressed or released. X <Expose>: X The callbacks for XtNexposeCallbacks are called when the widget recieves X an exposure event. X <Configure>: X The callbacks for XtNresizeCallbacks are called when the widget is resized. X <Motion>: X The callbacks for XtNresizeCallbacks are called when the widget recieves a X pointer motion event. X X XDefault Translations X <BtnDown>: input() X <BtnUp>: input() X <KeyDown>: input() X <KeyUp>: input() X <Motion>: motion() X <ResReq>: resize() X X XSEE ALSO X OSF/Motif Programmer's reference: XmDrawingArea X Open Software Foundation X Athena Widget Set - C Language Interface Rel 4: 3.3 Label Widget X Chris D. Peterson X X Toolkit Intrinsics - C Language Interface X Joel McCormack, Paul Asenta, Ralph R. Swick X The X Window System, programming and Applications with Xt, OSF/Motif Edition X Douglas A. Young X X XCOPYRIGHT X Copyright 1990, David Nedde X X This software is released into the public domain. X Permission to use, copy, modify, and distribute this X software and its documentation for any purpose and without X fee is provided that the above copyright notice appears in all copies. X It is provided "as is" without express or implied warranty. X X XAUTHOR X David Nedde, Computer Science Dept. daven@maxine.wpi.edu X Worcester Polytechnic Institute (508) 831-5117/5668 X Worcester, MA 01609 SHAR_EOF fi # end of overwriting check echo shar: extracting "'DrawingA.h'" '(1452 characters)' if test -f 'DrawingA.h' then echo shar: will not over-write existing file "'DrawingA.h'" else sed 's/^X//' << \SHAR_EOF > 'DrawingA.h' X/* DrawingA.h - Public Header file */ X X/* Copyright 1990, David Nedde X/* X/* This software is released into the public domain. X/* Permission to use, copy, modify, and distribute this X/* software and its documentation for any purpose and without fee X/* is granted provided that the above copyright notice appears in all copies. X/* It is provided "as is" without express or implied warranty. X*/ X X/* Define widget's class pointer and strings used to specify resources */ X X#ifndef _XawDrawingArea_h X#define _XawDrawingArea_h X X/* Resources ADDED to label widget: X X Name Class RepType Default Value X ---- ----- ------- ------------- X exposeCallback Callback Pointer NULL X inputCallback Callback Pointer NULL X motionCallback Callback Pointer NULL X resizeCallback Callback Pointer NULL X*/ X X Xextern WidgetClass drawingAreaWidgetClass; X Xtypedef struct _DrawingAreaClassRec *DrawingAreaWidgetClass; Xtypedef struct _DrawingAreaRec *DrawingAreaWidget; X X X/* Resource strings */ X#define XtNexposeCallback "exposeCallback" X#define XtNinputCallback "inputCallback" X#define XtNmotionCallback "motionCallback" X#define XtNresizeCallback "resizeCallback" X X Xtypedef struct _XawDrawingAreaCallbackStruct { X int reason; X XEvent *event; X Window window; X} XawDrawingAreaCallbackStruct; X X/* Reasons */ X#define XawCR_EXPOSE 1 X#define XawCR_INPUT 2 X#define XawCR_MOTION 3 X#define XawCR_RESIZE 4 X X#endif /* _XawDrawingArea_h */ SHAR_EOF fi # end of overwriting check echo shar: extracting "'DrawingAP.h'" '(1476 characters)' if test -f 'DrawingAP.h' then echo shar: will not over-write existing file "'DrawingAP.h'" else sed 's/^X//' << \SHAR_EOF > 'DrawingAP.h' X/* DrawingArea Private header file */ X X/* Copyright 1990, David Nedde X/* X/* This software is released into the public domain. X/* Permission to use, copy, modify, and distribute this X/* software and its documentation for any purpose and without fee X/* is granted 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 _XtDrawingAreaP_h X#define _XtDrawingAreaP_h X X#include "DrawingA.h" X#ifdef X11_R3 X#include <X11/LabelP.h> X#else X#include <X11/Xaw/LabelP.h> X#endif X X/* The drawing area's contribution to the class record */ Xtypedef struct _DrawingAreaClassPart { X int ignore; X} DrawingAreaClassPart; X X/* Drawing area's full class record */ Xtypedef struct _DrawingAreaClassRec { X CoreClassPart core_class; X SimpleClassPart simple_class; X LabelClassPart label_class; X DrawingAreaClassPart drawing_area; X} DrawingAreaClassRec; X Xextern DrawingAreaClassRec drawingAreaClassRec; X X/* Resources added and status of drawing area widget */ Xtypedef struct _XsDrawingAreaPart { X /* Resources */ X XtCallbackList expose_callbacks; X XtCallbackList input_callbacks; X XtCallbackList motion_callbacks; X XtCallbackList resize_callbacks; X} DrawingAreaPart; X X X/* Drawing area's instance record */ Xtypedef struct _DrawingAreaRec { X CorePart core; X SimplePart simple; X LabelPart label; X DrawingAreaPart drawing_area; X} DrawingAreaRec; X X#endif /* _XawDrawingAreaP_h */ SHAR_EOF fi # end of overwriting check echo shar: done with directory "'xball'" cd .. # End of shell archive exit 0 dan ---------------------------------------------------- O'Reilly && Associates argv@sun.com / argv@ora.com Opinions expressed reflect those of the author only.