home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
m
/
motifpg2.zip
/
ch04
/
xbitmap5.c
< prev
Wrap
C/C++ Source or Header
|
1992-07-08
|
15KB
|
475 lines
/*
* Copyright 1989, 1992 O'Reilly and Associates, Inc.
* See ../Copyright for complete rights and liability information.
*/
/*
* xbitmap5.c - bitmap in main window with small pixmaps
*/
/*
* So that we can use fprintf:
*/
#include <stdio.h>
/*
* Standard Toolkit include files:
*/
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
/*
* Public include files for widgets used in this file.
*/
#include <Xm/PanedW.h> /* paned window */
#include <Xm/PushB.h> /* push button */
#include <Xm/MessageB.h> /* message box */
#include <Xm/CascadeB.h> /* cascade button */
#include <Xm/RowColumn.h> /* row column (for menus) */
#include <Xm/DrawingA.h> /* drawing area */
#include <Xm/Form.h> /* pixmap box */
#include <Xm/Frame.h> /* frame */
#include <Xm/ScrolledW.h> /* scrolled window */
#include "BitmapEdit.h"
#define DRAWN 1
#define UNDRAWN 0
struct {
GC draw_gc, undraw_gc, invert_gc;
Pixmap normal_bitmap, reverse_bitmap;
Widget showNormalBitmap, showReverseBitmap;
String filename; /* filename to read and write */
Dimension pixmap_width_in_cells, pixmap_height_in_cells;
} bitmap_stuff;
static Boolean file_contained_good_data = False;
static void CellToggled(), SetUpThings();
/*ARGSUSED*/
static void
RedrawSmallPicture(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
Pixmap pixmap;
if (w == bitmap_stuff.showNormalBitmap)
pixmap = bitmap_stuff.normal_bitmap;
else
pixmap = bitmap_stuff.reverse_bitmap;
if (DefaultDepthOfScreen(XtScreen(w)) == 1)
XCopyArea(XtDisplay(w), pixmap, XtWindow(w),
DefaultGCOfScreen(XtScreen(w)), 0, 0,
bitmap_stuff.pixmap_width_in_cells,
bitmap_stuff.pixmap_height_in_cells,
0, 0);
else
XCopyPlane(XtDisplay(w), pixmap, XtWindow(w),
DefaultGCOfScreen(XtScreen(w)), 0, 0,
bitmap_stuff.pixmap_width_in_cells,
bitmap_stuff.pixmap_height_in_cells,
0, 0, 1);
}
/*
* The printout routine writes the data into a standard X11 bitmap file.
*/
/* ARGSUSED */
static void
PrintOut(widget, client_data, call_data)
Widget widget;
XtPointer client_data; /* unused */
XtPointer call_data; /* unused */
{
XWriteBitmapFile(XtDisplay(widget), bitmap_stuff.filename,
bitmap_stuff.normal_bitmap,
bitmap_stuff.pixmap_width_in_cells,
bitmap_stuff.pixmap_height_in_cells, 0, 0);
}
String
FillCell(w)
Widget w;
{
String cell;
int x, y;
XImage *image;
cell = XtCalloc(bitmap_stuff.pixmap_width_in_cells
* bitmap_stuff.pixmap_height_in_cells, sizeof(char));
/* Convert pixmap into image, so that we can
* read individual pixels */
image = XGetImage(XtDisplay(w), bitmap_stuff.normal_bitmap, 0, 0,
bitmap_stuff.pixmap_width_in_cells,
bitmap_stuff.pixmap_height_in_cells,
AllPlanes, XYPixmap);
for (x = 0; x < bitmap_stuff.pixmap_width_in_cells; x++) {
for (y = 0; y < bitmap_stuff.pixmap_height_in_cells; y++) {
cell[x + (y * bitmap_stuff.pixmap_width_in_cells)] =
XGetPixel(image, x, y);
}
}
return(cell);
}
/*
* callback to pop up help dialog widget
*/
/*ARGSUSED*/
void ShowHelp(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
Widget dialog = (Widget) client_data;
XtManageChild(dialog);
}
/*
* quit button callback function
*/
/*ARGSUSED*/
void Quit(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{
exit(0);
}
main(argc, argv)
int argc;
char **argv;
{
XtAppContext app_context;
Widget topLevel, mainWindow, menuBar;
Widget fileButton, fileMenu, quit, helpButton, helpMenu, help, helpBox;
Widget temp;
Widget bigBitmap, output, smallPixmapBox;
Widget scrolledWin, frame1, frame2;
Arg args[5];
int i;
unsigned int width, height;
int junk;
String cell;
/* never call a Widget variable "exit"! */
extern exit();
static XrmOptionDescRec table[] = {
{"-pw", "*pixmapWidthInCells", XrmoptionSepArg, NULL},
{"-pixmapwidth", "*pixmapWidthInCells", XrmoptionSepArg, NULL},
{"-ph", "*pixmapHeightInCells", XrmoptionSepArg, NULL},
{"-pixmapheight", "*pixmapHeightInCells", XrmoptionSepArg, NULL},
{"-cellsize", "*cellSizeInPixels", XrmoptionSepArg, NULL},
};
XtSetLanguageProc(NULL, (XtLanguageProc)NULL, NULL);
topLevel = XtVaAppInitialize(
&app_context, /* Application context */
"XBitmap5", /* Application class */
table, XtNumber(table), /* command line option list */
&argc, argv, /* command line args */
NULL, /* for missing app-defaults file */
NULL); /* terminate varargs list */
if (argv[1] != NULL)
bitmap_stuff.filename = argv[1];
else {
fprintf(stderr, "xbitmap: must specify filename on command line\n");
exit(1);
}
/* create main window */
mainWindow = XtVaCreateManagedWidget(
"mainWindow", /* widget name */
xmPanedWindowWidgetClass, /* widget class */
topLevel, /* parent widget*/
NULL); /* terminate varargs list */
/* create menu bar along top inside of main window */
menuBar = XmCreateMenuBar(
mainWindow, /* parent widget*/
"menuBar", /* widget name */
NULL, /* no arguments needed */
0); /* no arguments needed */
XtManageChild(menuBar);
scrolledWin = XtVaCreateManagedWidget("scrolledWin",
xmScrolledWindowWidgetClass, mainWindow,
NULL);
switch (XReadBitmapFile(XtDisplay(topLevel),
RootWindowOfScreen(XtScreen(topLevel)), bitmap_stuff.filename,
&width, &height, &bitmap_stuff.normal_bitmap, &junk, &junk)) {
case BitmapSuccess:
file_contained_good_data = True;
if ((bitmap_stuff.pixmap_width_in_cells != width) ||
(bitmap_stuff.pixmap_height_in_cells != height)) {
i = 0;
XtSetArg(args[i], XtNpixmapWidthInCells, width); i++;
XtSetArg(args[i], XtNpixmapHeightInCells, height); i++;
bitmap_stuff.pixmap_width_in_cells = width;
bitmap_stuff.pixmap_height_in_cells = height;
cell = FillCell(topLevel);
XtSetArg(args[i], XtNcellArray, cell); i++;
}
break;
case BitmapOpenFailed:
fprintf(stderr,
"xbitmap: could not open bitmap file, using fresh bitmap.\n");
i = 0;
file_contained_good_data = False;
break;
case BitmapFileInvalid:
fprintf(stderr, "xbitmap: bitmap file invalid.\n");
exit(1);
case BitmapNoMemory:
fprintf(stderr,
"xbitmap: insufficient server memory to create bitmap.\n");
exit(1);
default:
fprintf(stderr, "xbitmap: programming error.\n");
exit(1);
}
bigBitmap = XtCreateManagedWidget("bigBitmap",
bitmapEditWidgetClass, scrolledWin, args, i);
XtAddCallback(bigBitmap, XtNtoggleCallback, CellToggled, NULL);
if (!file_contained_good_data) {
XtVaGetValues(bigBitmap,
XtNpixmapWidthInCells, &bitmap_stuff.pixmap_width_in_cells,
XtNpixmapHeightInCells, &bitmap_stuff.pixmap_height_in_cells,
NULL);
}
/*
* CREATE FILE MENU AND CHILDREN
*/
/* create button that will pop up the menu */
fileButton = XtVaCreateManagedWidget(
"fileButton", /* widget name */
xmCascadeButtonWidgetClass, /* widget class */
menuBar, /* parent widget*/
NULL); /* terminate varargs list */
/* create menu (really a Shell widget and RowColumn widget combo) */
fileMenu = XmCreatePulldownMenu(
menuBar, /* parent widget*/
"fileMenu", /* widget name */
NULL, /* no argument list needed */
0); /* no argument list needed */
/*
* CREATE BUTTON TO OUTPUT BITMAP
*/
/* create button that will pop up the menu */
output = XtVaCreateManagedWidget(
"output", /* widget name */
xmPushButtonWidgetClass, /* widget class */
fileMenu, /* parent widget*/
NULL); /* terminate varargs list */
XtAddCallback(output, XmNactivateCallback, PrintOut, 0);
/* create the quit button up in the menu */
quit = XtVaCreateManagedWidget(
"quit", /* widget name */
xmPushButtonWidgetClass, /* widget class */
fileMenu, /* parent widget*/
NULL); /* terminate varargs list */
/*
* Specify which menu fileButton will pop up.
*/
XtVaSetValues(fileButton,
XmNsubMenuId, fileMenu,
NULL);
/* arrange for quit button to call function that exits. */
XtAddCallback(quit, XmNactivateCallback, Quit, 0);
/*
* CREATE HELP BUTTON AND BOX
*/
/* create button that will bring up help menu */
helpButton = XtVaCreateManagedWidget( "helpButton",
xmCascadeButtonWidgetClass, menuBar, NULL);
/* tell menuBar which is the help button (will be specially positioned) */
XtVaSetValues(menuBar,
XmNmenuHelpWidget, helpButton,
NULL);
/* create menu (really a Shell widget and RowColumn widget combo) */
helpMenu = XmCreatePulldownMenu( menuBar,
"helpMenu", NULL, 0);
/* create the help button up in the menu */
help = XtVaCreateManagedWidget( "help",
xmPushButtonWidgetClass, helpMenu, NULL);
/*
* Specify which menu helpButton will pop up.
*/
XtVaSetValues(helpButton,
XmNsubMenuId, helpMenu,
NULL);
/* create popup that will contain help */
helpBox = XmCreateMessageDialog(
help, /* parent widget*/
"helpBox", /* widget name */
NULL, /* no arguments needed */
0); /* no arguments needed */
temp = XmMessageBoxGetChild (helpBox, XmDIALOG_CANCEL_BUTTON);
XtUnmanageChild (temp);
temp = XmMessageBoxGetChild (helpBox, XmDIALOG_HELP_BUTTON);
XtUnmanageChild (temp);
/* arrange for getHelp button to pop up helpBox */
XtAddCallback(help, XmNactivateCallback, ShowHelp, helpBox);
smallPixmapBox = XtVaCreateManagedWidget("smallPixmapBox",
xmFormWidgetClass, mainWindow,
NULL);
frame1 = XtVaCreateManagedWidget("frameNormal",
xmFrameWidgetClass, smallPixmapBox,
XmNleftAttachment, XmATTACH_FORM,
NULL);
SetUpThings(topLevel);
bitmap_stuff.showNormalBitmap = XtVaCreateManagedWidget("showNormalBitmap",
xmDrawingAreaWidgetClass, frame1,
XmNwidth, bitmap_stuff.pixmap_width_in_cells,
XmNheight, bitmap_stuff.pixmap_height_in_cells,
NULL);
frame2 = XtVaCreateManagedWidget("frameReverse",
xmFrameWidgetClass, smallPixmapBox,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, frame1,
NULL);
bitmap_stuff.showReverseBitmap = XtVaCreateManagedWidget("showReverseBitmap",
xmDrawingAreaWidgetClass, frame2,
XmNwidth, bitmap_stuff.pixmap_width_in_cells,
XmNheight, bitmap_stuff.pixmap_height_in_cells,
NULL);
XtAddCallback(bitmap_stuff.showNormalBitmap, XmNexposeCallback,
RedrawSmallPicture, NULL);
XtAddCallback(bitmap_stuff.showReverseBitmap, XmNexposeCallback,
RedrawSmallPicture, NULL);
XtRealizeWidget(topLevel);
XtAppMainLoop(app_context);
}
static void
SetUpThings(w)
Widget w;
{
XGCValues values;
if (!file_contained_good_data) {
bitmap_stuff.normal_bitmap = XCreatePixmap(XtDisplay(w),
RootWindowOfScreen(XtScreen(w)),
bitmap_stuff.pixmap_width_in_cells,
bitmap_stuff.pixmap_height_in_cells, 1);
}
values.foreground = 1;
values.background = 0;
/* note that normal_bitmap is used as the drawable because it
* is one bit deep. The root window may not be one bit deep */
bitmap_stuff.draw_gc = XCreateGC(XtDisplay(w),
bitmap_stuff.normal_bitmap,
GCForeground | GCBackground, &values);
values.foreground = 0;
values.background = 1;
bitmap_stuff.undraw_gc = XCreateGC(XtDisplay(w),
bitmap_stuff.normal_bitmap,
GCForeground | GCBackground, &values);
bitmap_stuff.reverse_bitmap = XCreatePixmap(XtDisplay(w),
RootWindowOfScreen(XtScreen(w)),
bitmap_stuff.pixmap_width_in_cells,
bitmap_stuff.pixmap_height_in_cells, 1);
if (file_contained_good_data) {
XImage *image;
int x, y;
image = XGetImage (XtDisplay(w), bitmap_stuff.normal_bitmap, 0, 0,
bitmap_stuff.pixmap_width_in_cells,
bitmap_stuff.pixmap_height_in_cells,
AllPlanes, XYPixmap);
for (x = 0; x < bitmap_stuff.pixmap_width_in_cells; x++) {
for (y = 0; y < bitmap_stuff.pixmap_height_in_cells; y++) {
XDrawPoint(XtDisplay(w), bitmap_stuff.reverse_bitmap,
((XGetPixel(image, x, y) == DRAWN) ? bitmap_stuff.undraw_gc :
bitmap_stuff.draw_gc), x, y);
}
}
}
else {
/* pixmaps must be cleared - may contain garbage */
XFillRectangle(XtDisplay(w),
bitmap_stuff.reverse_bitmap, bitmap_stuff.draw_gc,
0, 0, bitmap_stuff.pixmap_width_in_cells + 1,
bitmap_stuff.pixmap_height_in_cells + 1);
XFillRectangle(XtDisplay(w),
bitmap_stuff.normal_bitmap, bitmap_stuff.undraw_gc,
0, 0, bitmap_stuff.pixmap_width_in_cells + 1,
bitmap_stuff.pixmap_height_in_cells + 1);
}
}
/* ARGSUSED */
static void
CellToggled(w, client_data, call_data)
Widget w;
XtPointer client_data; /* unused */
XtPointer call_data; /* will be cast to cur_info */
{
/* cast pointer to needed type: */
BitmapEditPointInfo *cur_info = (BitmapEditPointInfo *) call_data;
/*
* Note, BitmapEditPointInfo is defined in BitmapEdit.h
*/
XDrawPoint(XtDisplay(w), bitmap_stuff.normal_bitmap,
((cur_info->mode == DRAWN) ? bitmap_stuff.draw_gc :
bitmap_stuff.undraw_gc), cur_info->newx, cur_info->newy);
XDrawPoint(XtDisplay(w), bitmap_stuff.reverse_bitmap,
((cur_info->mode == DRAWN) ? bitmap_stuff.undraw_gc :
bitmap_stuff.draw_gc), cur_info->newx, cur_info->newy);
RedrawSmallPicture(bitmap_stuff.showNormalBitmap,
cur_info->newx, cur_info->newy);
RedrawSmallPicture(bitmap_stuff.showReverseBitmap,
cur_info->newx, cur_info->newy);
}