Subject: v15i057: Sun previewer for TeX DVI files, Part04/04 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: Neil Hunt Posting-number: Volume 15, Issue 57 Archive-name: dvisun/part04 #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 hunt 37610 Apr 13 10:39 dvipage.c (part 3) # echo 'x (append) - dvipage.c (part 3)' if test ! -f dvipage.c; then echo 'shar: earlier parts of dvipage.c not found; must unshar in order'; else sed 's/^X//' << '________This_Is_The_END________' >> dvipage.c X X/* X * Pixrect functions. X * ================= X */ X X/* X * sample_page: X * Filter and sample down page according to current sampling rate, X * and prepare for display. X */ X Xvoid Xsample_page() X{ X switch(sampling) X { X default: X case 1: X sample_pr = pr_link(&page_mpr, &sample_mpr); X break; X X case 2: X if(! (sample_pr = pr_sample_2(&page_mpr, &sample_mpr))) X message("Out of memory for resampling image"); X break; X X case 3: X if(! (sample_pr = pr_sample_3(&page_mpr, &sample_mpr))) X message("Out of memory for resampling image"); X break; X X case 4: X if(! (sample_pr = pr_sample_4(&page_mpr, &sample_mpr))) X message("Out of memory for resampling image"); X break; X } X} X X/* X * Here follow some functions to deal with pixrects under the special case X * assumption that they are mem_pixrects, where the mpr_data is part X * of a parent structure. X */ X Xextern struct pixrectops mem_ops; X X/* X * pr_alloc: X * Allocate memory for a pixrect of size w, h, d. X * Returns a pointer to the pixrect structure. X */ X Xstruct pixrect * Xpr_alloc(mpr, w, h, d) Xstruct mem_pixrect *mpr; Xint w, h, d; X{ X int size; X int linebytes; X short *image; X X /* X * Compute the size of memory needed, and alloc it. X */ X linebytes = mpr_linebytes(w, d); X size = linebytes * h; X if(! (image = (short *)malloc(size))) X return (struct pixrect *)NULL; X X /* X * Set up the pr. X */ X mpr->mpr_pr.pr_ops = &mem_ops; X mpr->mpr_pr.pr_width = w; X mpr->mpr_pr.pr_height = h; X mpr->mpr_pr.pr_depth = d; X mpr->mpr_pr.pr_data = (caddr_t)&mpr->mpr_data; X X /* X * Set up the mpr_data X */ X mpr->mpr_data.md_linebytes = linebytes; X mpr->mpr_data.md_image = image; X mpr->mpr_data.md_offset.x = 0; X mpr->mpr_data.md_offset.y = 0; X mpr->mpr_data.md_primary = TRUE; X mpr->mpr_data.md_flags = 0; X X /* X * Return the pr. X */ X return &mpr->mpr_pr; X} X X/* X * pr_free: X * Free the memory associated with a pixrect. X * Returns a pointer to no pixrect structure. X */ X Xstruct pixrect * Xpr_free(mpr) Xstruct mem_pixrect *mpr; X{ X short *image; X X if((image = mpr->mpr_data.md_image)) X { X if(mpr->mpr_data.md_primary) X free(image); X mpr->mpr_data.md_image = (short *)NULL; X } X mpr->mpr_pr.pr_width = 0; X mpr->mpr_pr.pr_height = 0; X X return (struct pixrect *)NULL; X} X X/* X * pr_check: X * Check that a designated pixrect has memory allocated for an image X * of size w, h, d. If not, free any existing memory and allocate X * more memory. This is equivalent to, but much faster than, a X * sequence of X * pr_destroy(mpr); X * mpr = mem_create(w, h, d); X */ X Xstruct pixrect * Xpr_check(mpr, w, h, d) Xstruct mem_pixrect *mpr; Xint w, h, d; X{ X /* X * If there is an image, check that it is the correct size. X */ X if(mpr->mpr_data.md_image) X { X if(mpr->mpr_pr.pr_width == w && X mpr->mpr_pr.pr_height == h && X mpr->mpr_pr.pr_depth == d) X return &mpr->mpr_pr; X X (void)pr_free(mpr); X } X X return pr_alloc(mpr, w, h, d); X} X X/* X * pr_link: X * Link the memory of mpr1 to mpr2, making mpr2 a secondary pixrect. X */ X Xstruct pixrect * Xpr_link(mpr1, mpr2) Xstruct mem_pixrect *mpr1; Xstruct mem_pixrect *mpr2; X{ X /* X * Free the existing memory, if any. X */ X (void)pr_free(mpr2); X X /* X * Set up the pr. X */ X mpr2->mpr_pr.pr_ops = &mem_ops; X mpr2->mpr_pr.pr_width = mpr1->mpr_pr.pr_width; X mpr2->mpr_pr.pr_height = mpr1->mpr_pr.pr_height; X mpr2->mpr_pr.pr_depth = mpr1->mpr_pr.pr_depth; X mpr2->mpr_pr.pr_data = (caddr_t)&mpr2->mpr_data; X X /* X * Set up the mpr_data X */ X mpr2->mpr_data.md_linebytes = mpr1->mpr_data.md_linebytes; X mpr2->mpr_data.md_image = mpr1->mpr_data.md_image; X mpr2->mpr_data.md_offset.x = mpr1->mpr_data.md_offset.x; X mpr2->mpr_data.md_offset.y = mpr1->mpr_data.md_offset.y; X mpr2->mpr_data.md_primary = FALSE; X mpr2->mpr_data.md_flags = 0; X X /* X * Return the pr. X */ X return &mpr2->mpr_pr; X} X X/* X * Tally table used to compute the number of bits in packed words. X * This is used in computing the number of bits in a 4x4 region of X * a packed image. X * X * The packed word is used as an index into this table; X * The most significant 16 bits of the value obtained represent the X * number of bits in the upper half of the index, with each bit counted X * with a weight of 15. X * The least significant 16 bits of the value obtained represent the X * number of bits in the l;ower hald of the index, with each bit counted X * with a weight of 15. X * X * By combining the upper and lower halves in a single word, the values X * for the four vertically adjacent words can be combined with each other X * in a single addition per word, adding simultaneously both the tallies X * for the left and the right halves of the word. X * X * The maximum number of bits which can be on is 4x4 = 16, having X * a maximum value of 16*15. A division by 16 gives 15 as the pixel X * value to be used. This saves a division to normalise a scale of X * 0..16 into 0..15. X */ X Xstatic int tally4[] = X{ X 0x00000000, 0x0000000f, 0x0000000f, 0x0000001e, X 0x0000000f, 0x0000001e, 0x0000001e, 0x0000002d, X 0x0000000f, 0x0000001e, 0x0000001e, 0x0000002d, X 0x0000001e, 0x0000002d, 0x0000002d, 0x0000003c, X 0x000f0000, 0x000f000f, 0x000f000f, 0x000f001e, X 0x000f000f, 0x000f001e, 0x000f001e, 0x000f002d, X 0x000f000f, 0x000f001e, 0x000f001e, 0x000f002d, X 0x000f001e, 0x000f002d, 0x000f002d, 0x000f003c, X 0x000f0000, 0x000f000f, 0x000f000f, 0x000f001e, X 0x000f000f, 0x000f001e, 0x000f001e, 0x000f002d, X 0x000f000f, 0x000f001e, 0x000f001e, 0x000f002d, X 0x000f001e, 0x000f002d, 0x000f002d, 0x000f003c, X 0x001e0000, 0x001e000f, 0x001e000f, 0x001e001e, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e001e, 0x001e002d, 0x001e002d, 0x001e003c, X 0x000f0000, 0x000f000f, 0x000f000f, 0x000f001e, X 0x000f000f, 0x000f001e, 0x000f001e, 0x000f002d, X 0x000f000f, 0x000f001e, 0x000f001e, 0x000f002d, X 0x000f001e, 0x000f002d, 0x000f002d, 0x000f003c, X 0x001e0000, 0x001e000f, 0x001e000f, 0x001e001e, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e001e, 0x001e002d, 0x001e002d, 0x001e003c, X 0x001e0000, 0x001e000f, 0x001e000f, 0x001e001e, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e001e, 0x001e002d, 0x001e002d, 0x001e003c, X 0x002d0000, 0x002d000f, 0x002d000f, 0x002d001e, X 0x002d000f, 0x002d001e, 0x002d001e, 0x002d002d, X 0x002d000f, 0x002d001e, 0x002d001e, 0x002d002d, X 0x002d001e, 0x002d002d, 0x002d002d, 0x002d003c, X 0x000f0000, 0x000f000f, 0x000f000f, 0x000f001e, X 0x000f000f, 0x000f001e, 0x000f001e, 0x000f002d, X 0x000f000f, 0x000f001e, 0x000f001e, 0x000f002d, X 0x000f001e, 0x000f002d, 0x000f002d, 0x000f003c, X 0x001e0000, 0x001e000f, 0x001e000f, 0x001e001e, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e001e, 0x001e002d, 0x001e002d, 0x001e003c, X 0x001e0000, 0x001e000f, 0x001e000f, 0x001e001e, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e001e, 0x001e002d, 0x001e002d, 0x001e003c, X 0x002d0000, 0x002d000f, 0x002d000f, 0x002d001e, X 0x002d000f, 0x002d001e, 0x002d001e, 0x002d002d, X 0x002d000f, 0x002d001e, 0x002d001e, 0x002d002d, X 0x002d001e, 0x002d002d, 0x002d002d, 0x002d003c, X 0x001e0000, 0x001e000f, 0x001e000f, 0x001e001e, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e000f, 0x001e001e, 0x001e001e, 0x001e002d, X 0x001e001e, 0x001e002d, 0x001e002d, 0x001e003c, X 0x002d0000, 0x002d000f, 0x002d000f, 0x002d001e, X 0x002d000f, 0x002d001e, 0x002d001e, 0x002d002d, X 0x002d000f, 0x002d001e, 0x002d001e, 0x002d002d, X 0x002d001e, 0x002d002d, 0x002d002d, 0x002d003c, X 0x002d0000, 0x002d000f, 0x002d000f, 0x002d001e, X 0x002d000f, 0x002d001e, 0x002d001e, 0x002d002d, X 0x002d000f, 0x002d001e, 0x002d001e, 0x002d002d, X 0x002d001e, 0x002d002d, 0x002d002d, 0x002d003c, X 0x003c0000, 0x003c000f, 0x003c000f, 0x003c001e, X 0x003c000f, 0x003c001e, 0x003c001e, 0x003c002d, X 0x003c000f, 0x003c001e, 0x003c001e, 0x003c002d, X 0x003c001e, 0x003c002d, 0x003c002d, 0x003c003c, X}; X X/* X * Tally table used to compute the number of bits in packed words. X * This is used in computing the number of bits in a 3x3 region of X * a packed image. X * X * The packed word is used as an index into this table; X * Bits 23..16 of the value obtained represent the number of bits in X * the upper 2.67 bits of the index, with each bit counted with a weight X * of 15. etc. etc. X * X * By combining the three parts in a single word, the values X * for the three vertically adjacent words can be combined with each other X * in a single addition per word, adding simultaneously both the tallies X * for the left and the right halves of the word. X * X * The maximum number of bits which can be on is 2.67x3 = 8, having X * a maximum value of 8*15. A division by 8 gives 15 as the pixel X * value to be used. This saves a division to normalise a scale of X * 0..8 into 0..15. X */ X Xstatic int tally3[] = X{ X 0x000000, 0x00000f, 0x00000f, 0x00001e, X 0x00050a, 0x000519, 0x000519, 0x000528, X 0x000f00, 0x000f0f, 0x000f0f, 0x000f1e, X 0x00140a, 0x001419, 0x001419, 0x001428, X 0x000f00, 0x000f0f, 0x000f0f, 0x000f1e, X 0x00140a, 0x001419, 0x001419, 0x001428, X 0x001e00, 0x001e0f, 0x001e0f, 0x001e1e, X 0x00230a, 0x002319, 0x002319, 0x002328, X 0x0a0500, 0x0a050f, 0x0a050f, 0x0a051e, X 0x0a0a0a, 0x0a0a19, 0x0a0a19, 0x0a0a28, X 0x0a1400, 0x0a140f, 0x0a140f, 0x0a141e, X 0x0a190a, 0x0a1919, 0x0a1919, 0x0a1928, X 0x0a1400, 0x0a140f, 0x0a140f, 0x0a141e, X 0x0a190a, 0x0a1919, 0x0a1919, 0x0a1928, X 0x0a2300, 0x0a230f, 0x0a230f, 0x0a231e, X 0x0a280a, 0x0a2819, 0x0a2819, 0x0a2828, X 0x0f0000, 0x0f000f, 0x0f000f, 0x0f001e, X 0x0f050a, 0x0f0519, 0x0f0519, 0x0f0528, X 0x0f0f00, 0x0f0f0f, 0x0f0f0f, 0x0f0f1e, X 0x0f140a, 0x0f1419, 0x0f1419, 0x0f1428, X 0x0f0f00, 0x0f0f0f, 0x0f0f0f, 0x0f0f1e, X 0x0f140a, 0x0f1419, 0x0f1419, 0x0f1428, X 0x0f1e00, 0x0f1e0f, 0x0f1e0f, 0x0f1e1e, X 0x0f230a, 0x0f2319, 0x0f2319, 0x0f2328, X 0x190500, 0x19050f, 0x19050f, 0x19051e, X 0x190a0a, 0x190a19, 0x190a19, 0x190a28, X 0x191400, 0x19140f, 0x19140f, 0x19141e, X 0x19190a, 0x191919, 0x191919, 0x191928, X 0x191400, 0x19140f, 0x19140f, 0x19141e, X 0x19190a, 0x191919, 0x191919, 0x191928, X 0x192300, 0x19230f, 0x19230f, 0x19231e, X 0x19280a, 0x192819, 0x192819, 0x192828, X 0x0f0000, 0x0f000f, 0x0f000f, 0x0f001e, X 0x0f050a, 0x0f0519, 0x0f0519, 0x0f0528, X 0x0f0f00, 0x0f0f0f, 0x0f0f0f, 0x0f0f1e, X 0x0f140a, 0x0f1419, 0x0f1419, 0x0f1428, X 0x0f0f00, 0x0f0f0f, 0x0f0f0f, 0x0f0f1e, X 0x0f140a, 0x0f1419, 0x0f1419, 0x0f1428, X 0x0f1e00, 0x0f1e0f, 0x0f1e0f, 0x0f1e1e, X 0x0f230a, 0x0f2319, 0x0f2319, 0x0f2328, X 0x190500, 0x19050f, 0x19050f, 0x19051e, X 0x190a0a, 0x190a19, 0x190a19, 0x190a28, X 0x191400, 0x19140f, 0x19140f, 0x19141e, X 0x19190a, 0x191919, 0x191919, 0x191928, X 0x191400, 0x19140f, 0x19140f, 0x19141e, X 0x19190a, 0x191919, 0x191919, 0x191928, X 0x192300, 0x19230f, 0x19230f, 0x19231e, X 0x19280a, 0x192819, 0x192819, 0x192828, X 0x1e0000, 0x1e000f, 0x1e000f, 0x1e001e, X 0x1e050a, 0x1e0519, 0x1e0519, 0x1e0528, X 0x1e0f00, 0x1e0f0f, 0x1e0f0f, 0x1e0f1e, X 0x1e140a, 0x1e1419, 0x1e1419, 0x1e1428, X 0x1e0f00, 0x1e0f0f, 0x1e0f0f, 0x1e0f1e, X 0x1e140a, 0x1e1419, 0x1e1419, 0x1e1428, X 0x1e1e00, 0x1e1e0f, 0x1e1e0f, 0x1e1e1e, X 0x1e230a, 0x1e2319, 0x1e2319, 0x1e2328, X 0x280500, 0x28050f, 0x28050f, 0x28051e, X 0x280a0a, 0x280a19, 0x280a19, 0x280a28, X 0x281400, 0x28140f, 0x28140f, 0x28141e, X 0x28190a, 0x281919, 0x281919, 0x281928, X 0x281400, 0x28140f, 0x28140f, 0x28141e, X 0x28190a, 0x281919, 0x281919, 0x281928, X 0x282300, 0x28230f, 0x28230f, 0x28231e, X 0x28280a, 0x282819, 0x282819, 0x282828, X}; X X/* X * Tally table used to compute the number of bits in packed words. X * This is used in computing the number of bits in a 2x2 region of X * a packed image. X * X * The packed word is used as an index into this table; X * The most significant 8 bits of the value obtained represent the X * number of bits in the upper half of the index, with each bit counted X * with a weight of 15. X * ... X * The least significant 8 bits of the value obtained represent the X * number of bits in the l;ower hald of the index, with each bit counted X * with a weight of 15. X * X * By combining the four pairs of tallies in a single word, the values X * for the two vertically adjacent words can be combined with each other X * in a single addition per word, adding simultaneously all four tallies X * for the four pairs of the word. X * X * The maximum number of bits which can be on is 2x2 = 4, having X * a maximum value of 4*15. A division by 4 gives 15 as the pixel X * value to be used. This saves a multiplication to normalise a scale of X * 0..4 into 0..15. X */ X Xstatic int tally2[] = X{ X 0x00000000, 0x0000000f, 0x0000000f, 0x0000001e, X 0x00000f00, 0x00000f0f, 0x00000f0f, 0x00000f1e, X 0x00000f00, 0x00000f0f, 0x00000f0f, 0x00000f1e, X 0x00001e00, 0x00001e0f, 0x00001e0f, 0x00001e1e, X 0x000f0000, 0x000f000f, 0x000f000f, 0x000f001e, X 0x000f0f00, 0x000f0f0f, 0x000f0f0f, 0x000f0f1e, X 0x000f0f00, 0x000f0f0f, 0x000f0f0f, 0x000f0f1e, X 0x000f1e00, 0x000f1e0f, 0x000f1e0f, 0x000f1e1e, X 0x000f0000, 0x000f000f, 0x000f000f, 0x000f001e, X 0x000f0f00, 0x000f0f0f, 0x000f0f0f, 0x000f0f1e, X 0x000f0f00, 0x000f0f0f, 0x000f0f0f, 0x000f0f1e, X 0x000f1e00, 0x000f1e0f, 0x000f1e0f, 0x000f1e1e, X 0x001e0000, 0x001e000f, 0x001e000f, 0x001e001e, X 0x001e0f00, 0x001e0f0f, 0x001e0f0f, 0x001e0f1e, X 0x001e0f00, 0x001e0f0f, 0x001e0f0f, 0x001e0f1e, X 0x001e1e00, 0x001e1e0f, 0x001e1e0f, 0x001e1e1e, X 0x0f000000, 0x0f00000f, 0x0f00000f, 0x0f00001e, X 0x0f000f00, 0x0f000f0f, 0x0f000f0f, 0x0f000f1e, X 0x0f000f00, 0x0f000f0f, 0x0f000f0f, 0x0f000f1e, X 0x0f001e00, 0x0f001e0f, 0x0f001e0f, 0x0f001e1e, X 0x0f0f0000, 0x0f0f000f, 0x0f0f000f, 0x0f0f001e, X 0x0f0f0f00, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f1e, X 0x0f0f0f00, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f1e, X 0x0f0f1e00, 0x0f0f1e0f, 0x0f0f1e0f, 0x0f0f1e1e, X 0x0f0f0000, 0x0f0f000f, 0x0f0f000f, 0x0f0f001e, X 0x0f0f0f00, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f1e, X 0x0f0f0f00, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f1e, X 0x0f0f1e00, 0x0f0f1e0f, 0x0f0f1e0f, 0x0f0f1e1e, X 0x0f1e0000, 0x0f1e000f, 0x0f1e000f, 0x0f1e001e, X 0x0f1e0f00, 0x0f1e0f0f, 0x0f1e0f0f, 0x0f1e0f1e, X 0x0f1e0f00, 0x0f1e0f0f, 0x0f1e0f0f, 0x0f1e0f1e, X 0x0f1e1e00, 0x0f1e1e0f, 0x0f1e1e0f, 0x0f1e1e1e, X 0x0f000000, 0x0f00000f, 0x0f00000f, 0x0f00001e, X 0x0f000f00, 0x0f000f0f, 0x0f000f0f, 0x0f000f1e, X 0x0f000f00, 0x0f000f0f, 0x0f000f0f, 0x0f000f1e, X 0x0f001e00, 0x0f001e0f, 0x0f001e0f, 0x0f001e1e, X 0x0f0f0000, 0x0f0f000f, 0x0f0f000f, 0x0f0f001e, X 0x0f0f0f00, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f1e, X 0x0f0f0f00, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f1e, X 0x0f0f1e00, 0x0f0f1e0f, 0x0f0f1e0f, 0x0f0f1e1e, X 0x0f0f0000, 0x0f0f000f, 0x0f0f000f, 0x0f0f001e, X 0x0f0f0f00, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f1e, X 0x0f0f0f00, 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f1e, X 0x0f0f1e00, 0x0f0f1e0f, 0x0f0f1e0f, 0x0f0f1e1e, X 0x0f1e0000, 0x0f1e000f, 0x0f1e000f, 0x0f1e001e, X 0x0f1e0f00, 0x0f1e0f0f, 0x0f1e0f0f, 0x0f1e0f1e, X 0x0f1e0f00, 0x0f1e0f0f, 0x0f1e0f0f, 0x0f1e0f1e, X 0x0f1e1e00, 0x0f1e1e0f, 0x0f1e1e0f, 0x0f1e1e1e, X 0x1e000000, 0x1e00000f, 0x1e00000f, 0x1e00001e, X 0x1e000f00, 0x1e000f0f, 0x1e000f0f, 0x1e000f1e, X 0x1e000f00, 0x1e000f0f, 0x1e000f0f, 0x1e000f1e, X 0x1e001e00, 0x1e001e0f, 0x1e001e0f, 0x1e001e1e, X 0x1e0f0000, 0x1e0f000f, 0x1e0f000f, 0x1e0f001e, X 0x1e0f0f00, 0x1e0f0f0f, 0x1e0f0f0f, 0x1e0f0f1e, X 0x1e0f0f00, 0x1e0f0f0f, 0x1e0f0f0f, 0x1e0f0f1e, X 0x1e0f1e00, 0x1e0f1e0f, 0x1e0f1e0f, 0x1e0f1e1e, X 0x1e0f0000, 0x1e0f000f, 0x1e0f000f, 0x1e0f001e, X 0x1e0f0f00, 0x1e0f0f0f, 0x1e0f0f0f, 0x1e0f0f1e, X 0x1e0f0f00, 0x1e0f0f0f, 0x1e0f0f0f, 0x1e0f0f1e, X 0x1e0f1e00, 0x1e0f1e0f, 0x1e0f1e0f, 0x1e0f1e1e, X 0x1e1e0000, 0x1e1e000f, 0x1e1e000f, 0x1e1e001e, X 0x1e1e0f00, 0x1e1e0f0f, 0x1e1e0f0f, 0x1e1e0f1e, X 0x1e1e0f00, 0x1e1e0f0f, 0x1e1e0f0f, 0x1e1e0f1e, X 0x1e1e1e00, 0x1e1e1e0f, 0x1e1e1e0f, 0x1e1e1e1e, X}; X X/* X * P_row: X * Access macro for obtaining a pointer to the bytes of a pixrect X * starting at row `row'. X */ X X#define P_row(mpr, row) \ X (uchar *)((int)((mpr)->mpr_data.md_image) + \ X (int)((short)(row) * (short)((mpr)->mpr_data.md_linebytes))); X X/* X * pr_sample_4: X * Filter and sample mpr1 on a 4x4 basis into mpr2. X */ X Xstruct pixrect * Xpr_sample_4(mpr1, mpr2) Xstruct mem_pixrect *mpr1; Xstruct mem_pixrect *mpr2; X{ X int cols, rows; X int j; X register uchar *p0; /* a5 */ X register uchar *p1; /* a4 */ X register uchar *p2; /* a3 */ X register uchar *p3; /* a2 */ X register uchar *pr; X register uchar *er; X register int tallies; /* d7 */ X int line_offset; X X cols = mpr1->mpr_pr.pr_width / 4; X rows = mpr1->mpr_pr.pr_height / 4; X X if(verbose & DEBUG_IMSIZE) X fprintf(stderr, "pr_sample_4: (%d x %d) -> (%d x %d)\n", X mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows); X X /* X * Allocate output image. X */ X if(! pr_check(mpr2, cols, rows, 8)) X return (struct pixrect *)NULL; X X /* X * Do the sampling. X */ X line_offset = mpr1->mpr_data.md_linebytes; X for(j = 0; j < rows; j++) X { X p0 = P_row(mpr1, j*4); X p1 = p0 + line_offset; X p2 = p1 + line_offset; X p3 = p2 + line_offset; X X pr = P_row(mpr2, j); X X for(er = pr + cols; pr < er; ) X { X /* X * Test for all zero. X */ X if(*p0 == 0 && *p1 == 0 && *p2 == 0 && *p3 == 0) X { X *pr++ = 0; X X if(pr >= er) X break; X X *pr++ = 0; X } X else X { X tallies = X tally4[*p0] + X tally4[*p1] + X tally4[*p2] + X tally4[*p3]; X X /* X * High order 4 bits X */ X *pr++ = (tallies >> 20); X X if(pr >= er) X break; X X /* X * Low order 4 bits X */ X *pr++ = (tallies >> 4); X } X p0++; X p1++; X p2++; X p3++; X } X } X X return &mpr2->mpr_pr; X} X X/* X * pr_sample_3: X * Filter and sample mpr1 on a 3x3 basis into mpr2. X * Note that the horizontal sampling is actually 3/8 rather than 1/3. X */ X Xstruct pixrect * Xpr_sample_3(mpr1, mpr2) Xstruct mem_pixrect *mpr1; Xstruct mem_pixrect *mpr2; X{ X int cols, rows; X int j; X register uchar *p0; /* a5 */ X register uchar *p1; /* a4 */ X register uchar *p2; /* a3 */ X register uchar *pr; /* a2 */ X register uchar *er; X register int tallies; /* d7 */ X int line_offset; X X cols = mpr1->mpr_pr.pr_width * 3 / 8; X rows = mpr1->mpr_pr.pr_height / 3; X X if(verbose & DEBUG_IMSIZE) X fprintf(stderr, "pr_sample_3: (%d x %d) -> (%d x %d)\n", X mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows); X X /* X * Allocate output image. X */ X if(! pr_check(mpr2, cols, rows, 8)) X return (struct pixrect *)NULL; X X /* X * Do the sampling. X */ X line_offset = mpr1->mpr_data.md_linebytes; X for(j = 0; j < rows; j++) X { X p0 = P_row(mpr1, j*3); X p1 = p0 + line_offset; X p2 = p1 + line_offset; X X pr = P_row(mpr2, j); X X for(er = pr + cols; pr < er; ) X { X /* X * Test for all zero. X */ X if(*p0 == 0 && *p1 == 0 && *p2 == 0) X { X *pr++ = 0; X X if(pr >= er) X break; X X *pr++ = 0; X X if(pr >= er) X break; X X *pr++ = 0; X } X else X { X tallies = X tally3[*p0] + X tally3[*p1] + X tally3[*p2]; X X /* X * High order 3 bits X */ X *pr++ = (tallies >> 19); X X if(pr >= er) X break; X X *pr++ = (tallies >> 11); X X if(pr >= er) X break; X X /* X * Low order 3 bits X */ X *pr++ = (tallies >> 3); X } X p0++; X p1++; X p2++; X } X } X X return &mpr2->mpr_pr; X} X X/* X * pr_sample_2: X * Filter and sample mpr1 on a 2x2 basis into mpr2. X */ X Xstruct pixrect * Xpr_sample_2(mpr1, mpr2) Xstruct mem_pixrect *mpr1; Xstruct mem_pixrect *mpr2; X{ X int cols, rows; X int j; X register uchar *p0; /* a5 */ X register uchar *p1; /* a4 */ X register uchar *pr; /* a3 */ X register uchar *er; /* a2 */ X register int tallies; /* d7 */ X int line_offset; X X cols = mpr1->mpr_pr.pr_width / 2; X rows = mpr1->mpr_pr.pr_height / 2; X X if(verbose & DEBUG_IMSIZE) X fprintf(stderr, "pr_sample_2: (%d x %d) -> (%d x %d)\n", X mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows); X X /* X * Allocate output image. X */ X if(! pr_check(mpr2, cols, rows, 8)) X return (struct pixrect *)NULL; X X /* X * Do the sampling. X */ X line_offset = mpr1->mpr_data.md_linebytes; X for(j = 0; j < rows; j++) X { X p0 = P_row(mpr1, j*2); X p1 = p0 + line_offset; X X pr = P_row(mpr2, j); X X for(er = pr + cols; pr < er; ) X { X /* X * Test for all zero. X */ X if(*p0 == 0 && *p1 == 0) X { X *pr++ = 0; X X if(pr >= er) X break; X X *pr++ = 0; X X if(pr >= er) X break; X X *pr++ = 0; X X if(pr >= er) X break; X X *pr++ = 0; X } X else X { X tallies = X tally2[*p0] + X tally2[*p1]; X X /* X * Highest two bits X */ X *pr++ = (tallies >> 26); X X if(pr >= er) X break; X X *pr++ = (tallies >> 18); X X if(pr >= er) X break; X X *pr++ = (tallies >> 10); X X if(pr >= er) X break; X X /* X * Lowest two bits X */ X *pr++ = (tallies >> 2); X } X p0++; X p1++; X } X } X X return &mpr2->mpr_pr; X} X X/* X * pw_cover: X * Function which writes a pixrect onto a pixwin; X * where there are no src pixels, it writes background colour. X */ X Xvoid Xpw_cover(dpw, dx, dy, dw, dh, op, spr, sx, sy) XPixwin *dpw; Xint dx, dy, dw, dh; Xint op; XPixrect *spr; Xint sx, sy; X{ X int aw, ah; X X /* X * Handle the left margin. X * If the left margin is less than the width to be painted, X * paint a margin, else paint the whole region and return. X */ X if(sx < 0) X { X if(-sx < dw) X { X pw_writebackground(dpw, dx, dy, -sx, dh, op); X dx -= sx; X sx = 0; X dw += sx; X } X else X { X pw_writebackground(dpw, dx, dy, dw, dh, op); X return; X } X } X X /* X * Handle the top margin. X * If the top margin is less thatn the width to be painted, X * paint a margin, else paint the whole region and return. X */ X if(sy < 0) X { X if(-sy < dh) X { X pw_writebackground(dpw, dx, dy, dw, -sy, op); X dy -= sy; X sy = 0; X dh += sy; X } X else X { X pw_writebackground(dpw, dx, dy, dw, dh, op); X return; X } X } X X /* X * Handle the right margin. X * aw = available width of source image. X * If available width > 0 paint a margin of dw-aw width, X * otherwise paint the whole region. X */ X aw = spr->pr_width-sx; X if(dw > aw) X { X if(aw > 0) X { X pw_writebackground(dpw, dx+aw, dy, dw-aw, dh, op); X dw = aw; X } X else X { X pw_writebackground(dpw, dx, dy, dw, dh, op); X return; X } X } X X /* X * Handle the bottom margin. X * ah = available height of source image. X * If available height > 0 paint a margin of dh-ah height, X * otherwise paint the whole region. X */ X ah = spr->pr_height-sy; X if(dh > ah) X { X if(ah > 0) X { X pw_writebackground(dpw, dx, dy+ah, dw, dh-ah, op); X dh = ah; X } X else X { X pw_writebackground(dpw, dx, dy, dw, dh, op); X return; X } X } X X /* X * Paint the image. X */ X pw_write(dpw, dx, dy, dw, dh, op, spr, sx, sy); X} X X/* X * pr_rect: X * Draws a box with op and colour as specified. X */ X Xvoid Xpr_rect(pr, x, y, w, h, t, op, value) Xstruct pixrect *pr; Xint x, y, w, h; Xint t; Xint op, value; X{ X int i; X X for(i = 0; i < t; i++) X { X pr_vector(pr, x, y, x+w-1, y, op, value); X pr_vector(pr, x+w-1, y+1, x+w-1, y+h-2, op, value); X pr_vector(pr, x, y+h-1, x+w-1, y+h-1, op, value); X pr_vector(pr, x, y+1, x, y+h-2, op, value); X X x += 1; X y += 1; X w -= 2; X h -= 2; X X if(w <= 0 || h <= 0) X break; X } X} X X/* X * pw_rect: X * Draws a box with op and colour as specified. X */ X Xvoid Xpw_rect(pw, x, y, w, h, t, op, value) XPixwin *pw; Xint x, y, w, h; Xint t; Xint op, value; X{ X int i; X Rect r; X X r.r_left = x; X r.r_top = y; X r.r_width = w; X r.r_height = h; X pw_lock(pw, &r); X X for(i = 0; i < t; i++) X { X pw_vector(pw, x, y, x+w-1, y, op, value); X pw_vector(pw, x+w-1, y+1, x+w-1, y+h-2, op, value); X pw_vector(pw, x, y+h-1, x+w-1, y+h-1, op, value); X pw_vector(pw, x, y+1, x, y+h-2, op, value); X X x += 1; X y += 1; X w -= 2; X h -= 2; X X if(w <= 0 || h <= 0) X break; X } X X pw_unlock(pw); X} X X/* X * Args stuff X * ========== X */ X Xstatic char * a_arg_ptr = NULL; Xstatic int a_arg_index = 0; Xstatic bool a_escape_seen; X Xchar * a_prog_name = "Anonymous"; X X/* X * a_next: X * Returns the next flag in the command line, X * or A_ARG if it is not a flag, X * or A_END if there are no more args. X */ X Xchar Xa_next(argc, argv) Xint argc; Xchar **argv; X{ X char opt; X X /* X * Checks. X */ X if(argv == NULL || argc < 1) X { X fprintf(stderr, "a_next: bad arguments\n"); X exit(2); X } X X /* X * Get program name on first call. X */ X if(a_arg_index == 0) X { X a_prog_name = argv[0]; X a_arg_index = 1; X } X X /* X * If there is part of the previous word left, then return it. X */ X if(a_arg_ptr && *a_arg_ptr) X return *a_arg_ptr++; X X /* X * Return A_END after the end of the list. X */ X if(a_arg_index >= argc) X return A_END; X X /* X * Look at the next word. X */ X a_arg_ptr = argv[a_arg_index++]; X X /* X * If we have seen the escape "--", X * or if the first char of the word * is not a '-', X * or if this is an isolated "-", X * then return ARG. X */ X if(a_escape_seen || a_arg_ptr[0] != '-' || a_arg_ptr[1] == '\0') X return A_ARG; X X /* X * Look at the next char. X */ X a_arg_ptr++; X opt = *a_arg_ptr++; X X /* X * If the next char is '-', then this is the escape. X * start over... X */ X if(opt == '-') X { X a_escape_seen = TRUE; X return a_next(argc, argv); X } X X /* X * Otherwise, return this option. X */ X return opt; X} X X/* X * a_arg: X * Returns the next argument in the command line, X * or NULL if there are no more args. X */ X Xchar * Xa_arg(argc, argv) Xint argc; Xchar **argv; X{ X char *arg; X X /* X * Checks. X */ X if(argv == NULL || argc < 1) X { X fprintf(stderr, "a_arg: bad arguments\n"); X exit(2); X } X X /* X * Get program name on first call. X */ X if(a_arg_index == 0) X { X a_prog_name = argv[0]; X a_arg_index = 1; X } X X /* X * If there is part of the previous word left, then return it. X */ X if(a_arg_ptr && *a_arg_ptr) X { X arg = a_arg_ptr; X a_arg_ptr = NULL; X return arg; X } X X /* X * Return NULL after the end of the list. X */ X if(a_arg_index >= argc) X return NULL; X X /* X * Return the next word. X */ X return argv[a_arg_index++]; X} X X/* X * a_number: X * Interpret the next word or part word as a number. X */ X Xdouble Xa_number(argc, argv) Xint argc; Xchar **argv; X{ X char *arg; X X if((arg = a_arg(argc, argv)) == NULL) X return 0.0; X else X return atof(arg); X} X X/* X * a_integer: X * Interpret the next word or part word as an integer. X */ X Xint Xa_integer(argc, argv) Xint argc; Xchar **argv; X{ X char *arg; X X if((arg = a_arg(argc, argv)) == NULL) X return 0; X else X return atoi(arg); X} X X/* X * Error panel functions X * ===================== X */ X Xvoid mess_done(); X Xstatic int errors_displayed = 0; X X/* X * message: X * Pops up a message window (if one is not already displayed) X * Formats a message (using fmt and args) and displays it into the window. X * Repeated calls to this function result in multiple lines of messages. X */ X Xvoid Xmessage(fmt, arg0, arg1, arg2, arg3) Xchar *fmt; Xvoid *arg0, *arg1, *arg2, *arg3; X{ X static char string[100]; X X if(silent) X return; X X sprintf(string, fmt, arg0, arg1, arg2, arg3); X X /* X * If there are no errors displayed, X * then build a window.. X */ X if(errors_displayed == 0) X { X mess_frame = window_create(disp_frame, FRAME, X FRAME_NO_CONFIRM, TRUE, X 0); X mess_panel = window_create(mess_frame, PANEL, X 0); X panel_create_item(mess_panel, PANEL_BUTTON, X PANEL_LABEL_IMAGE, X panel_button_image(mess_panel, "OK", 0, 0), X PANEL_ITEM_X, ATTR_COL(1), X PANEL_ITEM_Y, ATTR_ROW(0), X PANEL_NOTIFY_PROC, mess_done, X 0); X } X else X window_set(mess_frame, X WIN_SHOW, FALSE, X 0); X X panel_create_item(mess_panel, PANEL_MESSAGE, X PANEL_LABEL_STRING, string, X PANEL_ITEM_X, ATTR_COL(1), X PANEL_ITEM_Y, ATTR_ROW(++errors_displayed)+5, X 0); X X window_fit(mess_panel); X window_fit(mess_frame); X X window_set(mess_frame, X WIN_SHOW, TRUE, X 0); X} X X/* X * mess_done: X * This function is called when the OK button is pressed on the message X * window; the window is closed, and displayed messages are cleared. X */ X Xvoid Xmess_done() X{ X window_destroy(mess_frame); X X errors_displayed = 0; X} X X/* X * Pop up prompts: X * ============== X */ X Xstatic bool prompt_return_value = TRUE; X Xstatic Pixrect *ok_button = NULL; Xstatic Pixrect *abort_button = NULL; X Xstatic Panel_setting prompt_ok_proc(); Xstatic Panel_setting prompt_abort_proc(); Xstatic Panel_setting prompt_notify_proc(); X X/* X * strings_prompt: eg. X * strings_prompt(1152/2, 900/2, X * "Directory: ", &dir[0], X * "Filename: ", &fname[0], X * 0); X */ X X#define MAX_STRING_ITEMS 10 X Xbool Xstrings_prompt(x, y, first_prompt, first_value) Xint x, y; Xchar *first_prompt; Xchar *first_value; X{ X Frame frame; X Panel panel; X Panel_item string_item[MAX_STRING_ITEMS], ok_item, abort_item; X Event *event; X int w, h; X int i; X char **prompt; X char **value; X X /* X * Create the frame and panel. X */ X frame = window_create(NULL, FRAME, X FRAME_SHOW_LABEL, FALSE, X FRAME_NO_CONFIRM, TRUE, X 0); X X panel = window_create(frame, PANEL, X PANEL_ITEM_X_GAP, 1000, /* Enforces vertical layout */ X 0); X X prompt = &first_prompt; X value = &first_value; X for(i = 0; i < MAX_STRING_ITEMS; i++) X { X /* X * Stop if no more strings. X */ X if(*prompt == NULL) X break; X X /* X * Create a text item for the string. X */ X string_item[i] = panel_create_item(panel, PANEL_TEXT, X PANEL_LABEL_STRING, *prompt, X PANEL_VALUE, *value, X PANEL_VALUE_DISPLAY_LENGTH, 20, X PANEL_VALUE_STORED_LENGTH, 132, X PANEL_NOTIFY_LEVEL, PANEL_ALL, X PANEL_NOTIFY_PROC, prompt_notify_proc, X 0); X X /* X * Advance the prompt and value pointers up the list. X */ X prompt = value + 1; X value = prompt + 1; X } X X /* X * Create an OK button. X */ X if(ok_button == NULL) X ok_button = panel_button_image(panel, "OK", 0, 0); X X ok_item = panel_create_item(panel, PANEL_BUTTON, X PANEL_LABEL_IMAGE, ok_button, X PANEL_NOTIFY_PROC, prompt_ok_proc, X 0); X X /* X * Create an abort button. X */ X if(abort_button == NULL) X abort_button = panel_button_image(panel, "Abort", 0, 0); X X abort_item = panel_create_item(panel, PANEL_BUTTON, X PANEL_LABEL_IMAGE, abort_button, X PANEL_NOTIFY_PROC, prompt_abort_proc, X 0); X X /* X * Make them windows fit. X */ X window_fit(panel); X window_fit(frame); X X /* X * Centre the prompt X */ X w = (int)window_get(frame, WIN_WIDTH); X h = (int)window_get(frame, WIN_HEIGHT); X x -= w/2; X y -= h/2; X window_set(frame, X WIN_X, x, X WIN_Y, y, X 0); X X /* X * Set the flag to TRUE to indicate not aborted. X */ X prompt_return_value = TRUE; X X /* X * Display and wait for done. X */ X (void)window_loop(frame); X X /* X * If OK, then retrieve the window values and store them. X */ X if(prompt_return_value) X { X /* X * Loop through the items copying back values. X */ X prompt = &first_prompt; X value = &first_value; X for(i = 0; i < MAX_STRING_ITEMS; i++) X { X /* X * Stop if no more strings. X */ X if(*prompt == NULL) X break; X X /* X * Get the value of this item. X */ X strcpy(*value, panel_get_value(string_item[i])); X X /* X * Advance the prompt and value pointers up the list. X */ X prompt = value + 1; X value = prompt + 1; X } X } X X /* X * Destroy the window. X */ X window_destroy(frame); X X return prompt_return_value; X} X X/* X * integers_prompt: eg. X * integers_prompt(1152/2, 900/2, X * "Width: ", &w, X * "Height: ", &h, X * 0); X */ X X#define MAX_INTEGER_ITEMS MAX_STRING_ITEMS X Xbool Xintegers_prompt(x, y, first_prompt, first_value) Xint x, y; Xchar *first_prompt; Xint *first_value; X{ X Frame frame; X Panel panel; X Panel_item integer_item[MAX_INTEGER_ITEMS], ok_item, abort_item; X Event *event; X int w, h; X int i; X char **prompt; X int **value; X char value_string[20]; X X /* X * Create the frame and panel. X */ X frame = window_create(NULL, FRAME, X FRAME_SHOW_LABEL, FALSE, X FRAME_NO_CONFIRM, TRUE, X 0); X X panel = window_create(frame, PANEL, X PANEL_ITEM_X_GAP, 1000, /* Enforces vertical layout */ X 0); X X prompt = &first_prompt; X value = &first_value; X for(i = 0; i < MAX_INTEGER_ITEMS; i++) X { X /* X * Stop if no more strings. X */ X if(*prompt == NULL) X break; X X /* X * Create a text item for the string. X */ X sprintf(value_string, "%d", **value); X integer_item[i] = panel_create_item(panel, PANEL_TEXT, X PANEL_LABEL_STRING, *prompt, X PANEL_VALUE, value_string, X PANEL_VALUE_DISPLAY_LENGTH, 20, X PANEL_VALUE_STORED_LENGTH, 20, X PANEL_NOTIFY_STRING, "\033", X PANEL_NOTIFY_LEVEL, PANEL_ALL, X PANEL_NOTIFY_PROC, prompt_notify_proc, X 0); X X /* X * Advance the prompt and value pointers up the list. X */ X prompt = (char **)value + 1; X value = (int **)prompt + 1; X } X X /* X * Create an OK button. X */ X if(ok_button == NULL) X ok_button = panel_button_image(panel, "OK", 0, 0); X X ok_item = panel_create_item(panel, PANEL_BUTTON, X PANEL_LABEL_IMAGE, ok_button, X PANEL_NOTIFY_PROC, prompt_ok_proc, X 0); X X /* X * Create an abort button. X */ X if(abort_button == NULL) X abort_button = panel_button_image(panel, "Abort", 0, 0); X X abort_item = panel_create_item(panel, PANEL_BUTTON, X PANEL_LABEL_IMAGE, abort_button, X PANEL_NOTIFY_PROC, prompt_abort_proc, X 0); X X /* X * Make them windows fit. X */ X window_fit(panel); X window_fit(frame); X X /* X * Centre the prompt X */ X w = (int)window_get(frame, WIN_WIDTH); X h = (int)window_get(frame, WIN_HEIGHT); X x -= w/2; X y -= h/2; X window_set(frame, X WIN_X, x, X WIN_Y, y, X 0); X X /* X * Set the flag to TRUE to indicate not aborted. X */ X prompt_return_value = TRUE; X X /* X * Display and wait for done. X */ X (void)window_loop(frame); X X /* X * If OK, then retrieve the window values and store them. X */ X if(prompt_return_value) X { X /* X * Loop through the items copying back values. X */ X prompt = &first_prompt; X value = &first_value; X for(i = 0; i < MAX_INTEGER_ITEMS; i++) X { X /* X * Stop if no more strings. X */ X if(*prompt == NULL) X break; X X /* X * Get the value of this item. X */ X **value = atoi(panel_get_value(integer_item[i])); X X /* X * Advance the prompt and value pointers up the list. X */ X prompt = (char **)value + 1; X value = (int **)prompt + 1; X } X } X X /* X * Destroy the window. X */ X window_destroy(frame); X X return prompt_return_value; X} X X/* X * doubles_prompt: eg. X * doubles_prompt(1152/2, 900/2, X * "Width: ", &w, X * "Height: ", &h, X * 0); X */ X X#define MAX_DOUBLE_ITEMS MAX_INTEGER_ITEMS X Xbool Xdoubles_prompt(x, y, first_prompt, first_value) Xint x, y; Xchar *first_prompt; Xdouble *first_value; X{ X Frame frame; X Panel panel; X Panel_item double_item[MAX_DOUBLE_ITEMS], ok_item, abort_item; X Event *event; X int w, h; X int i; X char **prompt; X double **value; X char value_string[20]; X X /* X * Create the frame and panel. X */ X frame = window_create(NULL, FRAME, X FRAME_SHOW_LABEL, FALSE, X FRAME_NO_CONFIRM, TRUE, X 0); X X panel = window_create(frame, PANEL, X PANEL_ITEM_X_GAP, 1000, /* Enforces vertical layout */ X 0); X X prompt = &first_prompt; X value = &first_value; X for(i = 0; i < MAX_DOUBLE_ITEMS; i++) X { X /* X * Stop if no more strings. X */ X if(*prompt == NULL) X break; X X /* X * Create a text item for the string. X */ X sprintf(value_string, "%g", **value); X double_item[i] = panel_create_item(panel, PANEL_TEXT, X PANEL_LABEL_STRING, *prompt, X PANEL_VALUE, value_string, X PANEL_VALUE_DISPLAY_LENGTH, 20, X PANEL_VALUE_STORED_LENGTH, 40, X PANEL_NOTIFY_STRING, "\033", X PANEL_NOTIFY_LEVEL, PANEL_ALL, X PANEL_NOTIFY_PROC, prompt_notify_proc, X 0); X X /* X * Advance the prompt and value pointers up the list. X */ X prompt = (char **)value + 1; X value = (double **)prompt + 1; X } X X /* X * Create an OK button. X */ X if(ok_button == NULL) X ok_button = panel_button_image(panel, "OK", 0, 0); X X ok_item = panel_create_item(panel, PANEL_BUTTON, X PANEL_LABEL_IMAGE, ok_button, X PANEL_NOTIFY_PROC, prompt_ok_proc, X 0); X X /* X * Create an abort button. X */ X if(abort_button == NULL) X abort_button = panel_button_image(panel, "Abort", 0, 0); X X abort_item = panel_create_item(panel, PANEL_BUTTON, X PANEL_LABEL_IMAGE, abort_button, X PANEL_NOTIFY_PROC, prompt_abort_proc, X 0); X X /* X * Make them windows fit. X */ X window_fit(panel); X window_fit(frame); X X /* X * Centre the prompt X */ X w = (int)window_get(frame, WIN_WIDTH); X h = (int)window_get(frame, WIN_HEIGHT); X x -= w/2; X y -= h/2; X window_set(frame, X WIN_X, x, X WIN_Y, y, X 0); X X /* X * Set the flag to FALSE to indicate not aborted. X */ X prompt_return_value = FALSE; X X /* X * Display and wait for done. X */ X (void)window_loop(frame); X X /* X * If OK, then retrieve the window values and store them. X */ X if(prompt_return_value) X { X /* X * Loop through the items copying back values. X */ X prompt = &first_prompt; X value = &first_value; X for(i = 0; i < MAX_DOUBLE_ITEMS; i++) X { X /* X * Stop if no more strings. X */ X if(*prompt == NULL) X break; X X /* X * Get the value of this item. X */ X **value = atof(panel_get_value(double_item[i])); X X /* X * Advance the prompt and value pointers up the list. X */ X prompt = (char **)value + 1; X value = (double **)prompt + 1; X } X } X X /* X * Destroy the window. X */ X window_destroy(frame); X X return prompt_return_value; X} X X/* X * prompt_notify_proc: X */ X Xstatic Panel_setting Xprompt_notify_proc(item, event) XPanel_item item; XEvent *event; X{ X if(event_id(event) == ESC) X { X prompt_return_value = TRUE; X window_return(NULL); X return PANEL_NONE; X } X else if(event_id(event) == Control('C')) X { X prompt_return_value = FALSE; X window_return(NULL); X return PANEL_NONE; X } X else X return panel_text_notify(item, event); X} X X/* X * prompt_ok_proc: X * Normal return from string prompt. X */ X Xstatic Panel_setting Xprompt_ok_proc(item, event) XPanel_item item; XEvent *event; X{ X prompt_return_value = TRUE; X X window_return(NULL); X X return PANEL_NONE; X} X X/* X * prompt_abort_proc: X * Return from prompt with null string. X */ X Xstatic Panel_setting Xprompt_abort_proc(item, event) XPanel_item item; XEvent *event; X{ X prompt_return_value = FALSE; X X window_return(NULL); X X return PANEL_NONE; X} ________This_Is_The_END________ if test `wc -c < dvipage.c` -ne 99459; then echo 'shar: dvipage.c was damaged during transit (should have been 99459 bytes)' fi fi ; : end of overwriting check exit 0