|
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 */