home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / lib / image.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-10  |  9.7 KB  |  324 lines

  1. /*    IMAGE . C
  2. #
  3. %    Copyright (c)    Jin Guojun
  4. %
  5. %    image & window creating and handling
  6. %
  7. % AUTHOR:    Jin Guojun - LBL    4/1/91
  8. */
  9.  
  10. #include "panel.h"
  11.  
  12. #ifndef    ScrollBarSIZE
  13. #define    ScrollBarSIZE    HandleWidth
  14. #endif
  15. #ifndef    MaxWindowSIZE
  16. #define    MaxWindowSIZE    768
  17. #endif
  18.  
  19. WinAttribute    Monitor[2];
  20. ScrollBar    **SB_Stack;
  21. int    SB_SP;
  22.  
  23. XImage*
  24. get_XImage(img, width, height, buf_need)
  25. Image    *img;
  26. {
  27. XImage    *image = XCreateImage(img->dpy, img->dpy_visual,
  28.             (img->binary_img ? 1 : img->dpy_depth),
  29.             (img->binary_img ? XYBitmap : ZPixmap),
  30.             0, NULL, width, height, img->dpy_depth==8 ? 8 : 32, 0);
  31.  
  32.     if (image && buf_need &&
  33.         !(image->data = NZALLOC(image->bytes_per_line, height, No))) {
  34.         perror("malloc image->data");
  35.         XDestroyImage(image);    image = NULL;
  36.     }
  37. return    image;
  38. }
  39.  
  40. get_iconsize(img, width)
  41. Image    *img;
  42. {
  43. XIconSize    *icon_sizes;
  44. int    count, factor, height = DESIRED_ICON_HEIGHT;
  45.  
  46.     if (width<32 || width>384)
  47.         width = DESIRED_ICON_WIDTH;
  48.  
  49.     if (XGetIconSizes(img->dpy, Root_window, &icon_sizes, &count) && count > 0){
  50.     while (count--)
  51.         if (icon_sizes[count].min_width <= width
  52.         && icon_sizes[count].max_width >= width
  53.         && icon_sizes[count].min_height <= height
  54.         && icon_sizes[count].max_height >= height)
  55.         break;
  56.  
  57.     if (count < 0) {
  58.         width = icon_sizes[0].max_width;
  59.         height= icon_sizes[0].max_height;
  60.     }
  61.     }
  62.  
  63.     factor = img->width / width;
  64.     if (factor < img->height / height)
  65.     factor = img->height / height;
  66.     factor += factor & 1 | !factor;
  67.  
  68. /* icon_height need plus 1, otherwise get BadValue or BadGC problem    */
  69.     img->icon_height = img->height / factor + 1;
  70.     img->icon_width = img->width / factor;
  71. return    factor;
  72. }
  73.  
  74. void    /*    initializing Maximum window size    */
  75. MaximumWindowSize(I, wattr, cw, dpy_depth)
  76. register Image    *I;
  77. XSetWindowAttributes    *wattr;
  78. {
  79. register int    l, v;
  80. if (!I->event)    return;    /* no image    */
  81. if (!I->resize_h)    /* ensure resize_? to be set    */
  82.     I->resize_h = MIN(I->height, MaxWindowSIZE);
  83. if (!I->resize_w)
  84.     I->resize_w = MIN(I->width, MaxWindowSIZE);
  85. l = I->width != I->resize_w,    v = I->height != I->resize_h;
  86.     if (l | v)    {
  87.     v += l & v;
  88.     l = ScrollBarSIZE;
  89.     XResizeWindow(I->dpy, I->frame, I->resize_w + l, I->resize_h + l);
  90. #ifdef    SCROLLBAR_on_CANVAS
  91.     wattr->override_redirect = True;
  92.     I->win = XCreateWindow(I->dpy, I->frame, 0, 0,
  93.         I->width + l, I->height + l, 0, dpy_depth, InputOutput,
  94.         I->dpy_visual, cw | CWOverrideRedirect, wattr);
  95. #endif
  96.     if (!SB_Stack)
  97.         SB_Stack = nzalloc(sizeof(*SB_Stack), 1, "sb_stack");
  98.     else    SB_Stack = realloc(SB_Stack, sizeof(*SB_Stack) * (1+SB_SP));
  99.     I->parts = (PanelParts *) (SB_Stack[I->stack_num = SB_SP++] =
  100.         CreateScrollBar(I, 0, I->resize_h, I->resize_w, 0, l,
  101.         I->resize_w, I->resize_h, v, I->name,
  102.         darkGray ? darkGray : Black, Gray ? Gray : White));
  103.     }
  104. }
  105.  
  106. Font
  107. SetFontGetSize(aw, fontname)
  108. AnyWindow*    aw;
  109. char    *fontname;
  110. {
  111. /* Font = u_long defined in L42 X.h
  112. int    cdir, ascent, descent;
  113. Font    fid = XLoadFont(aw->dpy, fontname);
  114. XCharStruct    XCharS;
  115. XSetFont(dpy, gc, fid);
  116. XQueryTextExtents(aw->dpy, FontP->fid, "H", 1, &cdir, &ascent, &descent, &XCharS);
  117. *fw = XCharS.width;
  118. *fh = ascent + descent;
  119. */
  120. XFontStruct    *FontP = XLoadQueryFont(aw->dpy, fontname);
  121.  
  122. if (!FontP)
  123.     FontP = XLoadQueryFont(aw->dpy, "fixed");
  124. XSetFont(aw->dpy, aw->gc, FontP->fid);
  125. aw->font_w = FontP->max_bounds.width;
  126. aw->font_h = (aw->ascent=FontP->ascent) + FontP->descent;
  127. XFreeFont(aw->dpy, FontP);
  128. DEBUGMESSAGE("GC[%d] fontW=%d, fontH=%d\n", aw->gc, aw->font_w, aw->font_h);
  129. return    FontP->fid;
  130. }
  131.  
  132. #define    BaseCW    CWBackPixel | CWBorderPixel | CWEventMask
  133. #define    GC_Mask    GCFunction | GCPlaneMask | GCForeground | GCBackground
  134.  
  135. CreateWindow(W, parent, cursor, mask, fixedframe, wm_flag)
  136. AnyWindow*    W;
  137. WinAttribute*    parent;
  138. Cursor    cursor;
  139. {
  140. XGCValues    gc_val;        /* p4 Xlib.h    */
  141. XSetWindowAttributes    wattr;    /* for window self    */
  142. XSizeHints    szhints;    /* for window manager    */
  143. XWMHints    wmhints;
  144. Display    *dpy = parent->dpy;
  145. int    scr = parent->screen, dpy_depth = XDefaultDepth(dpy, scr),
  146.     cw = BaseCW | CWCursor | CWColormap;
  147.  
  148. if (!cursor)
  149.     cursor = XCreateFontCursor(dpy, XC_heart);
  150. /* Get window attributes, these wattr.{ebc} MUST be set up here */
  151. wattr.event_mask = mask | ExposureMask;
  152. wattr.background_pixel = Black;
  153. wattr.border_pixel = White;
  154. wattr.colormap = parent->cmap;
  155. wattr.cursor = cursor;
  156. if (!W->frame | !W->win)
  157.     W->frame = W->win = XCreateWindow(dpy, parent->root,
  158.         W->x0, W->y0, W->width, W->height, 5,
  159.         dpy_depth, InputOutput, parent->visual, cw, &wattr);
  160. MaximumWindowSize(W, &wattr, cw, dpy_depth);
  161. if (!W->frame | !W->win)
  162.     return    prgmerr(0, "%s -> win", W->name);
  163. wattr.event_mask = ExposureMask;
  164. if (W->icon_width > 7 && W->icon_height > 7)    {
  165.     W->icon = XCreateWindow(dpy, parent->root, 0, 0,
  166.         W->icon_width, W->icon_height, 0, dpy_depth,
  167.         InputOutput, parent->visual, BaseCW, &wattr);
  168.     if (!W->icon)    return    prgmerr(0, "%s -> icon", W->name);
  169. }
  170. /*=======================================================
  171. %    set window manager hints for normal window    %
  172. %    If size not been set, icon will not work. ???    %
  173. %    Any flag is set, set corresponding properties    %
  174. %    also. Otherwise, window manager will dead.    %
  175. =======================================================*/
  176. szhints.flags = PPosition | PSize | PMinSize | PMaxSize;
  177. szhints.max_width = szhints.min_width = szhints.width = W->width;
  178. szhints.max_height= szhints.min_height= szhints.height = W->height;
  179. if (!fixedframe)    {
  180.     szhints.min_width = MIN(W->width, 512);
  181.     szhints.min_height = MIN(W->height, 256);
  182.     szhints.max_width = MAX(MIN(DisplayWidth(dpy, scr), (W->width+16)), 512);
  183.     szhints.max_height = MAX(MIN(DisplayHeight(dpy, scr), (W->height+16)), 256);
  184. }
  185. szhints.x = szhints.y = 0;
  186. XSetStandardProperties(dpy, W->frame, W->name, W->name, None, NULL, 0, &szhints);
  187.  
  188. /* set hints for iconified window */
  189. if (W->icon)    {
  190.     szhints.flags = PSize;
  191.     szhints.width = szhints.max_width = W->icon_width;
  192.     szhints.height = szhints.max_height = W->icon_height;
  193.     szhints.min_height = szhints.min_width = 32;
  194.     {
  195.     char    ibuf[64];    /* make Icon name */
  196.     sprintf(ibuf, "Icon-%s", W->name);
  197.     XSetStandardProperties(dpy, W->icon, ibuf, ibuf,
  198.             None, NULL, 0, &szhints);
  199.     }
  200. }
  201. wmhints.icon_window = W->icon;
  202. wmhints.icon_x = szhints.max_width - 64;
  203. wmhints.icon_y = szhints.max_height >> 1;
  204. wmhints.flags = InputHint | wm_flag;
  205. wmhints.input = True;
  206. XSetWMHints(dpy, W->win, &wmhints);
  207.  
  208. gc_val.function = GXcopy;
  209. gc_val.plane_mask = AllPlanes;
  210. gc_val.foreground = fixedframe ? black1 : White;
  211. gc_val.background = fixedframe ? white1 : Black;
  212. W->gc = XCreateGC(dpy, W->win, GC_Mask, &gc_val);
  213. if (W->icon)
  214.     W->igc = XCreateGC(dpy, W->icon, GC_Mask, &gc_val);
  215.  
  216. return    SetFontGetSize(W, "8x13");
  217. }
  218.  
  219. /*===============================================================
  220. %    Create Window, GC and Image Copy for given image data    %
  221. ===============================================================*/
  222. Image*
  223. CreateImage(ip, name, parent, width, height, icon_width, WEMask, need)
  224. Image    **ip;
  225. char    *name;
  226. WinAttribute    *parent;
  227. {
  228. Image    *I;
  229. int    bsize=height*width;
  230.  
  231. if (*ip==NULL)    *ip = zalloc(sizeof(**ip), 1, "Image");
  232. I = *ip;
  233. I->resize_w = MIN((I->width = width), MaxWindowSIZE);
  234. I->resize_h = MIN((I->height = height), MaxWindowSIZE);
  235. I->dpy = parent->dpy;
  236. I->colormap = parent->cmap;
  237. if (!I->dpy_visual)
  238.     I->dpy_visual = parent->visual;
  239. if (!I->dpy_depth)
  240.     I->dpy_depth = parent->dpy_depth;
  241. if (name && strlen(name))    I->name = str_save(name);
  242. else    I->name = str_save("standard-in");
  243.  
  244. get_iconsize(I, icon_width);
  245. DEBUGMESSAGE("icon = %d x %d\n", I->icon_width, I->icon_height);
  246.  
  247. I->icon_image = get_XImage(I, I->icon_width, I->icon_height, True);
  248. I->image = get_XImage(I, I->width, I->height, need);
  249. I->img_buf = (byte *) I->image->data;
  250. I->icon_buf = (byte *) I->icon_image->data;
  251. I->event++;    /* flag to generate canvas    */
  252. CreateWindow(I, parent, 0, WEMask | StructureNotifyMask, 0,
  253.         IconWindowHint | IconPositionHint);
  254. return    I;
  255. }
  256.  
  257. void
  258. DestroyImage(img)
  259. Image    *img;
  260. {
  261.     if (img->icon_buf)    free(img->icon_buf);
  262.     if (img->img_buf)    free(img->img_buf);    /* == img->image->data */
  263.     if (img->hist)        free(img->hist);
  264.     if (img->gc)    XFreeGC(img->dpy, img->gc),
  265.             XDestroyImage(img->image),
  266.             XDestroyWindow(img->dpy, img->win),
  267.             XFreeColormap(img->dpy, img->colormap);
  268.     if (img->frame && img->frame != img->win)
  269.         XDestroyWindow(img->dpy, img->frame);
  270.     if (img->igc)    XFreeGC(img->dpy, img->igc),
  271.             XDestroyWindow(img->dpy, img->icon);
  272.     if (img->icon_image)    XDestroyImage(img->icon_image);
  273.     img->frame = img->win = img->icon = img->colormap = 0;
  274.     img->gc = img->igc = (GC)(img->image = NULL);
  275. }
  276. /*===============================
  277. %    Destroy Color Image    %
  278. ===============================*/
  279. Window    DestroyColorImage(img)
  280. image_information    *img;
  281. {
  282. Window    window=img->window;
  283.     DestroyImage(img);
  284.     if (img->title)        free(img->title);
  285.     if (img->scan_data)    free(img->scan_data);
  286.     if (img->pixmap)    XFreePixmap(img->dpy, img->pixmap);
  287.     if (img->mag_pixmap)    XFreePixmap(img->dpy, img->mag_pixmap);
  288.     if (img->icn_pixmap)    XFreePixmap(img->dpy, img->icn_pixmap);
  289.     img->pixmap = img->mag_pixmap = img->icn_pixmap = 0;
  290. return    window;
  291. }
  292.  
  293. /*=======================================================
  294. %    RETURN image array position if image found    %
  295. %        Otherwise, return EOF (-1)        %
  296. =======================================================*/
  297. WhichImage(win, imgp, num)
  298. Window    win;
  299. Image    **imgp;
  300. register int    num;
  301. {
  302. while (num--)
  303. if (win==imgp[num]->frame || win==imgp[num]->win || win==imgp[num]->icon)
  304.     break;
  305. return    num;
  306. }
  307.  
  308. /*===============================================================
  309. %    Load Icon buffer dynamically for both b/w and color    %
  310. ===============================================================*/
  311. void
  312. LoadIcon(I)
  313. register Image    *I;
  314. {
  315. register int    h, w, fact = I->width / I->icon_width;
  316. register char    *dp = I->icon_image->data;
  317.  
  318. for (h=0; h < I->icon_height; h++)    {
  319. register char    *bp = I->image->data + h * I->width * fact;
  320.     for (w=0; w < I->icon_width; w++, bp+=fact)
  321.     *dp++ = *bp;
  322. }
  323. }
  324.