home *** CD-ROM | disk | FTP | other *** search
- /* IMAGE . C
- #
- % Copyright (c) Jin Guojun
- %
- % image & window creating and handling
- %
- % AUTHOR: Jin Guojun - LBL 4/1/91
- */
-
- #include "panel.h"
-
- #ifndef ScrollBarSIZE
- #define ScrollBarSIZE HandleWidth
- #endif
- #ifndef MaxWindowSIZE
- #define MaxWindowSIZE 768
- #endif
-
- WinAttribute Monitor[2];
- ScrollBar **SB_Stack;
- int SB_SP;
-
- XImage*
- get_XImage(img, width, height, buf_need)
- Image *img;
- {
- XImage *image = XCreateImage(img->dpy, img->dpy_visual,
- (img->binary_img ? 1 : img->dpy_depth),
- (img->binary_img ? XYBitmap : ZPixmap),
- 0, NULL, width, height, img->dpy_depth==8 ? 8 : 32, 0);
-
- if (image && buf_need &&
- !(image->data = NZALLOC(image->bytes_per_line, height, No))) {
- perror("malloc image->data");
- XDestroyImage(image); image = NULL;
- }
- return image;
- }
-
- get_iconsize(img, width)
- Image *img;
- {
- XIconSize *icon_sizes;
- int count, factor, height = DESIRED_ICON_HEIGHT;
-
- if (width<32 || width>384)
- width = DESIRED_ICON_WIDTH;
-
- if (XGetIconSizes(img->dpy, Root_window, &icon_sizes, &count) && count > 0){
- while (count--)
- if (icon_sizes[count].min_width <= width
- && icon_sizes[count].max_width >= width
- && icon_sizes[count].min_height <= height
- && icon_sizes[count].max_height >= height)
- break;
-
- if (count < 0) {
- width = icon_sizes[0].max_width;
- height= icon_sizes[0].max_height;
- }
- }
-
- factor = img->width / width;
- if (factor < img->height / height)
- factor = img->height / height;
- factor += factor & 1 | !factor;
-
- /* icon_height need plus 1, otherwise get BadValue or BadGC problem */
- img->icon_height = img->height / factor + 1;
- img->icon_width = img->width / factor;
- return factor;
- }
-
- void /* initializing Maximum window size */
- MaximumWindowSize(I, wattr, cw, dpy_depth)
- register Image *I;
- XSetWindowAttributes *wattr;
- {
- register int l, v;
- if (!I->event) return; /* no image */
- if (!I->resize_h) /* ensure resize_? to be set */
- I->resize_h = MIN(I->height, MaxWindowSIZE);
- if (!I->resize_w)
- I->resize_w = MIN(I->width, MaxWindowSIZE);
- l = I->width != I->resize_w, v = I->height != I->resize_h;
- if (l | v) {
- v += l & v;
- l = ScrollBarSIZE;
- XResizeWindow(I->dpy, I->frame, I->resize_w + l, I->resize_h + l);
- #ifdef SCROLLBAR_on_CANVAS
- wattr->override_redirect = True;
- I->win = XCreateWindow(I->dpy, I->frame, 0, 0,
- I->width + l, I->height + l, 0, dpy_depth, InputOutput,
- I->dpy_visual, cw | CWOverrideRedirect, wattr);
- #endif
- if (!SB_Stack)
- SB_Stack = nzalloc(sizeof(*SB_Stack), 1, "sb_stack");
- else SB_Stack = realloc(SB_Stack, sizeof(*SB_Stack) * (1+SB_SP));
- I->parts = (PanelParts *) (SB_Stack[I->stack_num = SB_SP++] =
- CreateScrollBar(I, 0, I->resize_h, I->resize_w, 0, l,
- I->resize_w, I->resize_h, v, I->name,
- darkGray ? darkGray : Black, Gray ? Gray : White));
- }
- }
-
- Font
- SetFontGetSize(aw, fontname)
- AnyWindow* aw;
- char *fontname;
- {
- /* Font = u_long defined in L42 X.h
- int cdir, ascent, descent;
- Font fid = XLoadFont(aw->dpy, fontname);
- XCharStruct XCharS;
- XSetFont(dpy, gc, fid);
- XQueryTextExtents(aw->dpy, FontP->fid, "H", 1, &cdir, &ascent, &descent, &XCharS);
- *fw = XCharS.width;
- *fh = ascent + descent;
- */
- XFontStruct *FontP = XLoadQueryFont(aw->dpy, fontname);
-
- if (!FontP)
- FontP = XLoadQueryFont(aw->dpy, "fixed");
- XSetFont(aw->dpy, aw->gc, FontP->fid);
- aw->font_w = FontP->max_bounds.width;
- aw->font_h = (aw->ascent=FontP->ascent) + FontP->descent;
- XFreeFont(aw->dpy, FontP);
- DEBUGMESSAGE("GC[%d] fontW=%d, fontH=%d\n", aw->gc, aw->font_w, aw->font_h);
- return FontP->fid;
- }
-
- #define BaseCW CWBackPixel | CWBorderPixel | CWEventMask
- #define GC_Mask GCFunction | GCPlaneMask | GCForeground | GCBackground
-
- CreateWindow(W, parent, cursor, mask, fixedframe, wm_flag)
- AnyWindow* W;
- WinAttribute* parent;
- Cursor cursor;
- {
- XGCValues gc_val; /* p4 Xlib.h */
- XSetWindowAttributes wattr; /* for window self */
- XSizeHints szhints; /* for window manager */
- XWMHints wmhints;
- Display *dpy = parent->dpy;
- int scr = parent->screen, dpy_depth = XDefaultDepth(dpy, scr),
- cw = BaseCW | CWCursor | CWColormap;
-
- if (!cursor)
- cursor = XCreateFontCursor(dpy, XC_heart);
- /* Get window attributes, these wattr.{ebc} MUST be set up here */
- wattr.event_mask = mask | ExposureMask;
- wattr.background_pixel = Black;
- wattr.border_pixel = White;
- wattr.colormap = parent->cmap;
- wattr.cursor = cursor;
- if (!W->frame | !W->win)
- W->frame = W->win = XCreateWindow(dpy, parent->root,
- W->x0, W->y0, W->width, W->height, 5,
- dpy_depth, InputOutput, parent->visual, cw, &wattr);
- MaximumWindowSize(W, &wattr, cw, dpy_depth);
- if (!W->frame | !W->win)
- return prgmerr(0, "%s -> win", W->name);
- wattr.event_mask = ExposureMask;
- if (W->icon_width > 7 && W->icon_height > 7) {
- W->icon = XCreateWindow(dpy, parent->root, 0, 0,
- W->icon_width, W->icon_height, 0, dpy_depth,
- InputOutput, parent->visual, BaseCW, &wattr);
- if (!W->icon) return prgmerr(0, "%s -> icon", W->name);
- }
- /*=======================================================
- % set window manager hints for normal window %
- % If size not been set, icon will not work. ??? %
- % Any flag is set, set corresponding properties %
- % also. Otherwise, window manager will dead. %
- =======================================================*/
- szhints.flags = PPosition | PSize | PMinSize | PMaxSize;
- szhints.max_width = szhints.min_width = szhints.width = W->width;
- szhints.max_height= szhints.min_height= szhints.height = W->height;
- if (!fixedframe) {
- szhints.min_width = MIN(W->width, 512);
- szhints.min_height = MIN(W->height, 256);
- szhints.max_width = MAX(MIN(DisplayWidth(dpy, scr), (W->width+16)), 512);
- szhints.max_height = MAX(MIN(DisplayHeight(dpy, scr), (W->height+16)), 256);
- }
- szhints.x = szhints.y = 0;
- XSetStandardProperties(dpy, W->frame, W->name, W->name, None, NULL, 0, &szhints);
-
- /* set hints for iconified window */
- if (W->icon) {
- szhints.flags = PSize;
- szhints.width = szhints.max_width = W->icon_width;
- szhints.height = szhints.max_height = W->icon_height;
- szhints.min_height = szhints.min_width = 32;
- {
- char ibuf[64]; /* make Icon name */
- sprintf(ibuf, "Icon-%s", W->name);
- XSetStandardProperties(dpy, W->icon, ibuf, ibuf,
- None, NULL, 0, &szhints);
- }
- }
- wmhints.icon_window = W->icon;
- wmhints.icon_x = szhints.max_width - 64;
- wmhints.icon_y = szhints.max_height >> 1;
- wmhints.flags = InputHint | wm_flag;
- wmhints.input = True;
- XSetWMHints(dpy, W->win, &wmhints);
-
- gc_val.function = GXcopy;
- gc_val.plane_mask = AllPlanes;
- gc_val.foreground = fixedframe ? black1 : White;
- gc_val.background = fixedframe ? white1 : Black;
- W->gc = XCreateGC(dpy, W->win, GC_Mask, &gc_val);
- if (W->icon)
- W->igc = XCreateGC(dpy, W->icon, GC_Mask, &gc_val);
-
- return SetFontGetSize(W, "8x13");
- }
-
- /*===============================================================
- % Create Window, GC and Image Copy for given image data %
- ===============================================================*/
- Image*
- CreateImage(ip, name, parent, width, height, icon_width, WEMask, need)
- Image **ip;
- char *name;
- WinAttribute *parent;
- {
- Image *I;
- int bsize=height*width;
-
- if (*ip==NULL) *ip = zalloc(sizeof(**ip), 1, "Image");
- I = *ip;
- I->resize_w = MIN((I->width = width), MaxWindowSIZE);
- I->resize_h = MIN((I->height = height), MaxWindowSIZE);
- I->dpy = parent->dpy;
- I->colormap = parent->cmap;
- if (!I->dpy_visual)
- I->dpy_visual = parent->visual;
- if (!I->dpy_depth)
- I->dpy_depth = parent->dpy_depth;
- if (name && strlen(name)) I->name = str_save(name);
- else I->name = str_save("standard-in");
-
- get_iconsize(I, icon_width);
- DEBUGMESSAGE("icon = %d x %d\n", I->icon_width, I->icon_height);
-
- I->icon_image = get_XImage(I, I->icon_width, I->icon_height, True);
- I->image = get_XImage(I, I->width, I->height, need);
- I->img_buf = (byte *) I->image->data;
- I->icon_buf = (byte *) I->icon_image->data;
- I->event++; /* flag to generate canvas */
- CreateWindow(I, parent, 0, WEMask | StructureNotifyMask, 0,
- IconWindowHint | IconPositionHint);
- return I;
- }
-
- void
- DestroyImage(img)
- Image *img;
- {
- if (img->icon_buf) free(img->icon_buf);
- if (img->img_buf) free(img->img_buf); /* == img->image->data */
- if (img->hist) free(img->hist);
- if (img->gc) XFreeGC(img->dpy, img->gc),
- XDestroyImage(img->image),
- XDestroyWindow(img->dpy, img->win),
- XFreeColormap(img->dpy, img->colormap);
- if (img->frame && img->frame != img->win)
- XDestroyWindow(img->dpy, img->frame);
- if (img->igc) XFreeGC(img->dpy, img->igc),
- XDestroyWindow(img->dpy, img->icon);
- if (img->icon_image) XDestroyImage(img->icon_image);
- img->frame = img->win = img->icon = img->colormap = 0;
- img->gc = img->igc = (GC)(img->image = NULL);
- }
- /*===============================
- % Destroy Color Image %
- ===============================*/
- Window DestroyColorImage(img)
- image_information *img;
- {
- Window window=img->window;
- DestroyImage(img);
- if (img->title) free(img->title);
- if (img->scan_data) free(img->scan_data);
- if (img->pixmap) XFreePixmap(img->dpy, img->pixmap);
- if (img->mag_pixmap) XFreePixmap(img->dpy, img->mag_pixmap);
- if (img->icn_pixmap) XFreePixmap(img->dpy, img->icn_pixmap);
- img->pixmap = img->mag_pixmap = img->icn_pixmap = 0;
- return window;
- }
-
- /*=======================================================
- % RETURN image array position if image found %
- % Otherwise, return EOF (-1) %
- =======================================================*/
- WhichImage(win, imgp, num)
- Window win;
- Image **imgp;
- register int num;
- {
- while (num--)
- if (win==imgp[num]->frame || win==imgp[num]->win || win==imgp[num]->icon)
- break;
- return num;
- }
-
- /*===============================================================
- % Load Icon buffer dynamically for both b/w and color %
- ===============================================================*/
- void
- LoadIcon(I)
- register Image *I;
- {
- register int h, w, fact = I->width / I->icon_width;
- register char *dp = I->icon_image->data;
-
- for (h=0; h < I->icon_height; h++) {
- register char *bp = I->image->data + h * I->width * fact;
- for (w=0; w < I->icon_width; w++, bp+=fact)
- *dp++ = *bp;
- }
- }
-