|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 8918 (0x22d6)
Types: TextFile
Names: »icon.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/X/Dragon/icon.c«
/******************************************************************************
* Dragon - a version of Mah-Jongg for X Windows
*
* Author: Gary E. Barnes March 1989
*
* icon.c - Deals with our icon. Setup and execution.
******************************************************************************/
#include "main.h"
#include "ic/dragon_icon32.ic"
#include "ic/dragon_icon64.ic"
extern char * malloc();
extern free();
GC Icon_GC = (GC)0; /* GC used for Icon window. */
\f
/*ARGSUSED*/
static void Icon_Expose( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called when our Icon window receives an Expose event. This is only called
* when we are using an Icon window. If we managed to use an Icon pixmap then
* this routine is not called at all.
******************************************************************************/
{
Display *dpy = XtDisplay(w);
Window win = XtWindow(w);
XImage ximage;
XGCValues gcv;
unsigned int wid = 64;
unsigned int hei = 64;
unsigned int bw = 0;
unsigned int depth;
int x, y;
Window root;
unsigned int size;
/*--Figure out how big our window is. */
DEBUG_CALL(Icon_Expose);
XGetGeometry( dpy, win, &root, &x, &y,
&wid, &hei, &bw, &depth );
if (wid < 64 || hei < 64) {
size = 32;
} else {
size = 64;
}
/*--Get a GC and create an image of an appropriate size using one of our
* preexisting Icon images. */
if (Icon_GC == (GC)0) {
gcv.foreground = Dragon_Resources.Foreground;
gcv.background = Dragon_Resources.Background;
Icon_GC = XtGetGC( w, GCForeground|GCBackground, &gcv );
}
ximage.height = size;
ximage.width = size;
ximage.depth = 1;
ximage.xoffset = 0;
ximage.format = XYBitmap;
ximage.data =
(size == 64 ? &dragon_icon64_bits[0] :&dragon_icon32_bits[0]);
ximage.byte_order = LSBFirst;
ximage.bitmap_unit = 8;
ximage.bitmap_bit_order = LSBFirst;
ximage.bitmap_pad = 8;
ximage.bytes_per_line = (size+7)/8;
/*--Draw the bitmap on the window. */
XClearWindow( dpy, win );
XPutImage( dpy, win, Icon_GC, &ximage, 0, 0,
(int)(wid-size)/2, (int)(hei-size)/2,
(unsigned int)size, (unsigned int)size );
DEBUG_RETURN(Icon_Expose);
} /* Icon_Expose */
\f
void Icon_Setup( args, argn, argi )
Arg *args;
int argn;
int *argi;
/******************************************************************************
* args - Specifies the ArgList to fill in
* argn - Specifies the length of args
* argi - Specifies the ArgList allocation index
*
* Called to handle all of the Icon setup for our main shell.
******************************************************************************/
{
XIconSize *ic;
int nic;
int i;
int size;
int accept;
Pixmap Icon_Pixmap = (Pixmap)NULL;
unsigned int W, H;
int X, Y;
unsigned long flags;
int scr;
#define SETARG(name,value) \
DEBUG_ERROR( *argi >= argn, "IS args overrun!\n" ); \
XtSetArg( args[*argi], name, (XtArgVal)value ); ++*argi;
/*--If we've been asked to set up the Icon geometry then do that. */
DEBUG_CALL(Icon_Setup);
for(scr = 0; /* Figure out which screen we are on.*/
XtScreen(Dragon) != ScreenOfDisplay(XtDisplay(Dragon),scr);
scr++);
flags = XParseGeometry( Dragon_Resources.Icon_Geometry,
&X, &Y, &W, &H );
if (flags & XValue) {
SETARG( XtNiconX, X );
}
if (flags & YValue) {
SETARG( XtNiconY, Y );
}
/*--Set/Get the Icon_Name. */
if (Dragon_Resources.Icon_Name == NULL) {
SETARG( XtNiconName, "Dragon" );
}
/*--Set up the Icon pixmap or window. We try to use a pixmap instead of a
* window because it is simply less overhead. If there are supported Icon
* pixmap sizes then maybe we can use an icon pixmap. */
if (XGetIconSizes( XtDisplay(Dragon),
RootWindowOfScreen(XtScreen(Dragon)),
&ic,
&nic )) {
/*--Run over all of the sizes. We try to get a 64x64 pixmap but we are willing
* to settle for a 32x32. We grab the first size that allows us to create
* a pixmap of exactly one of these sizes. If we cannot find an exact match
* then "accept" is set to point to an acceptable size. */
size = 64;
accept = -1;
for (;;) {
for (i = 0; i <= nic; ++i) {
if (ic[i].max_width < size ||
ic[i].max_height < size) {
continue; /* Size completely wrong */
}
if (accept < 0 ||
ic[i].max_width < ic[accept].max_width ||
ic[i].max_height < ic[accept].max_height) {
accept = i; /* Size is acceptable */
}
if (ic[i].min_width <= size &&
size-ic[i].min_width % ic[i].width_inc == 0 &&
ic[i].min_height <= size &&
size-ic[i].min_height & ic[i].height_inc == 0) {
Icon_Pixmap = /* Size is perfect */
XCreatePixmapFromBitmapData
( XtDisplay(Dragon),
RootWindowOfScreen(XtScreen(Dragon)),
(size == 64
? &dragon_icon64_bits[0]
: &dragon_icon32_bits[0]),
(unsigned int)size, (unsigned int)size,
Dragon_Resources.Foreground,
Dragon_Resources.Background,
DefaultDepthOfScreen(XtScreen(Dragon)) );
}
}
if (Icon_Pixmap != (Pixmap)NULL || /* Stop on success */
accept >= 0 || /* Stop on acceptable */
size == 32) { break; } /* Stop when exhausted */
size = 32;
}
/*--If we don't have a pixmap yet and if accept is set then set up an "odd
* size" (from our viewpoint) pixmap. */
if (Icon_Pixmap == (Pixmap)NULL && accept >= 0) {
char *data;
char *orig;
char *ptr;
unsigned int w, wb, h, hb;
int inc;
/*--Figure out which of our pixmaps we will copy into this odd pixmap. */
if (ic[accept].max_width < 64 ||
ic[accept].max_height < 64) {
orig = &dragon_icon32_bits[0];
size = 32 / 8;
} else {
orig = &dragon_icon64_bits[0];
size = 64 / 8;
}
/*--Calculate the exact size of the pixmap that we will be using; size is in
* bits (w,h) and also in bytes (wb,hb). */
w = ic[accept].min_width;
if (w < size) {
inc = ic[accept].width_inc;
w = w + (size - w + inc - 1) / inc * inc;
}
h = ic[accept].min_height;
if (h < size) {
inc = ic[accept].height_inc;
h = h + (size - h + inc - 1) / inc * inc;
}
wb = (w + 7) / 8;
hb = (h + 7) / 8;
/*--Allocate space for the pixmap and copy our existing pixmap into it. */
data = (char*)malloc( (unsigned)(wb * hb) );
for (ptr = data, nic = size;
nic >= 0;
ptr += wb, orig += size,--nic) {
bcopy( orig, ptr, size );
}
/*--Create the pixmap and free up the data area. */
Icon_Pixmap =
XCreatePixmapFromBitmapData
( XtDisplay(Dragon), RootWindowOfScreen(XtScreen(Dragon)),
data, w, h,
Dragon_Resources.Foreground, Dragon_Resources.Background,
DefaultDepthOfScreen(XtScreen(Dragon)) );
free( data );
}
XFree( ic );
}
/*--If we managed to create a pixmap then use that. Otherwise we need a window
* for our icon. */
if (Icon_Pixmap != NULL) {
DEBUG_OTHER(Icon_Setup,Icon Pixmap);
SETARG( XtNiconPixmap, Icon_Pixmap );
} else {
/* No Pixmap found (or possibly none supported). Try an Icon
* window instead. */
static char actions[] = "<Expose>: IconExpose()\n";
XtActionsRec SomeActions[1];
Arg SomeArgs[5];
int SomeArgsi;
Widget Icon_Shell;
Widget Icon_Core;
#define LCLARG(name,value) \
DEBUG_ERROR( SomeArgsi >= XtNumber(SomeArgs), \
"IS SomeArgs overrun!\n" ); \
XtSetArg( SomeArgs[SomeArgsi], name, (XtArgVal)value ); ++SomeArgsi;
;
/*--Create a shell to contain the Icon window. */
DEBUG_OTHER(Icon_Setup,Icon Window);
SomeArgsi = 0;
LCLARG( XtNgeometry, Dragon_Resources.Icon_Geometry);
LCLARG( XtNmappedWhenManaged, FALSE );
Icon_Shell = XtCreateApplicationShell( "dragonicon",
topLevelShellWidgetClass,
SomeArgs, (Cardinal)SomeArgsi );
/*--We want the Icon window to be 64x64 if possible; and, when the Icon window
* gets Expose events we want to call the IconExpose routine to redraw the
* window. */
SomeActions[0].string = "IconExpose";
SomeActions[0].proc = (XtActionProc)Icon_Expose;
XtAddActions( SomeActions, (Cardinal)1 );
SomeArgsi = 0;
LCLARG( XtNtranslations, XtParseTranslationTable( actions ) );
Icon_Core = XtCreateManagedWidget( "drawable", widgetClass,
Icon_Shell,
SomeArgs, (Cardinal)SomeArgsi );
if (flags & WidthValue) {
Icon_Core->core.width = W;
}
if (flags & HeightValue) {
Icon_Core->core.height = H;
}
/*--Realize and use the Icon window. */
XtRealizeWidget( Icon_Shell );
SETARG( XtNiconWindow, XtWindow(Icon_Shell) );
}
DEBUG_RETURN(Icon_Setup);
} /* Icon_Setup */