source: abuse/trunk/src/imlib/readxwd.cpp @ 2

Last change on this file since 2 was 2, checked in by Sam Hocevar, 14 years ago
  • imported original 0.7.0 tarball
File size: 18.1 KB
Line 
1#include "image.hpp"
2#include "palette.hpp"
3#define MAXCOLORS 256
4//#define MC(x) (((x)<3)==0)
5#define MC(x) (x!=0)
6
7// the following table converts rgb to cym.
8int ca[8]={1,1,1,1,0,0,0,0},
9    ma[8]={1,0,1,0,1,0,1,0},
10    ya[8]={1,1,0,0,1,1,0,0};
11// the following defines make a color threshold
12#define RGB2C(r,g,b) (char)(ca[MC(b)|MC(g)<<1|MC(r)<<2])
13#define RGB2Y(r,g,b) (char)(ya[MC(b)|MC(g)<<1|MC(r)<<2])
14#define RGB2M(r,g,b) (char)(ma[MC(b)|MC(g)<<1|MC(r)<<2])
15
16#define LSBFirst        0
17#define MSBFirst        1
18
19#define XYBitmap        0
20#define XYPixmap        1
21#define ZPixmap         2
22
23#define StaticGray      0
24#define GrayScale       1
25#define StaticColor     2
26#define PseudoColor     3
27#define TrueColor       4
28#define DirectColor     5
29
30typedef unsigned long xwdval;
31#define X11WD_FILE_VERSION 7
32typedef struct {
33    xwdval header_size;         /* Size of the entire file header (bytes). */
34    xwdval file_version;        /* X11WD_FILE_VERSION */
35    xwdval pixmap_format;       /* Pixmap format */
36    xwdval pixmap_depth;        /* Pixmap depth */
37    xwdval pixmap_width;        /* Pixmap width */
38    xwdval pixmap_height;       /* Pixmap height */
39    xwdval xoffset;             /* Bitmap x offset */
40    xwdval byte_order;          /* MSBFirst, LSBFirst */
41    xwdval bitmap_unit;         /* Bitmap unit */
42    xwdval bitmap_bit_order;    /* MSBFirst, LSBFirst */
43    xwdval bitmap_pad;          /* Bitmap scanline pad */
44    xwdval bits_per_pixel;      /* Bits per pixel */
45    xwdval bytes_per_line;      /* Bytes per scanline */
46    xwdval visual_class;        /* Class of colormap */
47    xwdval red_mask;            /* Z red mask */
48    xwdval green_mask;          /* Z green mask */
49    xwdval blue_mask;           /* Z blue mask */
50    xwdval bits_per_rgb;        /* Log base 2 of distinct color values */
51    xwdval colormap_entries;    /* Number of entries in colormap */
52    xwdval ncolors;             /* Number of Color structures */
53    xwdval window_width;        /* Window width */
54    xwdval window_height;       /* Window height */
55    long window_x;              /* Window upper left X coordinate */
56    long window_y;              /* Window upper left Y coordinate */
57    xwdval window_bdrwidth;     /* Window border width */
58    } X11WDFileHeader;
59
60typedef struct {
61    unsigned long pixel;
62    unsigned short red, green, blue;
63    char flags;                 /* do_red, do_green, do_blue */
64    char pad;
65    } X11XColor;
66
67image *getinit(FILE *file, palette *&pal, int *padrightP);
68void getimage(FILE *file,image *image, int pad);
69int getpixnum(FILE *file);
70
71
72HBITMAP readxwd(char *input_file,palette *&pal)
73//char *hdfpal,int *palsize,int *cols,int *rows)
74{
75  FILE *ifd;
76  char *imageP;
77  unsigned int nspace;
78  int padright;
79  HBITMAP im;
80
81  /* open input file */
82  if (strcmp(input_file,"-") == 0)
83    ifd = stdin;d)
84  { printf("Unable to open %s\n"
85           "Get your story right and try again.\n",input_file);
86    exit(0);
87  }
88  printf("Reading image\n");
89  im=getinit( ifd, pal, &padright, int &xres, int &yres);
90//cols, rows, &padright, palsize, hdfpal);
91
92  /* alloc image array */
93
94  /* fill image array */
95  getimage(ifd, im, padright);
96
97  return(im);
98}
99
100int bits_per_item, bits_used, bit_shift, bits_per_pixel, pixel_mask;
101int bit_order, byte_swap;
102char buf[4];
103char *byteP;
104short *shortP;
105long *longP;
106
107
108int bs_int(int s);
109long bs_long(long s);
110short bs_short(short s );
111
112
113HBITMAP getinit(FILE *file, palette *&pal, int *padrightP, int &xres, int &yres);)
114{
115  /* Assume X11 headers are larger than X10 ones. */
116  unsigned char header[sizeof(X11WDFileHeader)];
117  image *im;
118  X11WDFileHeader *h11P;
119  char junk[800];
120  int i, np, dummy1, dummy2, dummy3;
121  unsigned  short minred, maxred;
122  X11XColor x11col;
123
124  h11P = (X11WDFileHeader *) header;
125
126  if (fread(header,sizeof(*h11P),1,file) != 1 )
127    {
128      fprintf(stderr,"couldn't read X11 XWD file header");
129      exit(-1);
130    }
131  if ( h11P->file_version != X11WD_FILE_VERSION )
132    {
133      byte_swap = 1;
134      h11P->header_size = bltl(h11P->header_size);
135      h11P->file_version = bltl(h11P->file_version);
136      h11P->pixmap_format = bltl(h11P->pixmap_format);
137      h11P->pixmap_depth = bltl(h11P->pixmap_depth);
138      h11P->pixmap_width = bltl(h11P->pixmap_width);
139      h11P->pixmap_height = bltl(h11P->pixmap_height);
140      h11P->xoffset =  bltl(h11P->xoffset);
141      h11P->byte_order =  bltl(h11P->byte_order);
142      h11P->bitmap_unit = bltl(h11P->bitmap_unit);
143      h11P->bitmap_bit_order = bltl(h11P->bitmap_bit_order);
144      h11P->bitmap_pad = bltl(h11P->bitmap_pad);
145      h11P->bits_per_pixel = bltl(h11P->bits_per_pixel);
146      h11P->bytes_per_line = bltl(h11P->bytes_per_line);
147      h11P->visual_class = bltl(h11P->visual_class);
148      h11P->red_mask = bltl(h11P->red_mask);
149      h11P->green_mask = bltl(h11P->green_mask);
150      h11P->blue_mask = bltl(h11P->blue_mask);
151      h11P->bits_per_rgb = bltl(h11P->bits_per_rgb);
152      h11P->colormap_entries = bltl(h11P->colormap_entries);
153      h11P->ncolors = bltl(h11P->ncolors);
154      h11P->window_width = bltl(h11P->window_width);
155      h11P->window_height = bltl(h11P->window_height);
156      h11P->window_x = bltl(h11P->window_x);
157      h11P->window_y = bltl(h11P->window_y);
158      h11P->window_bdrwidth = bltl(h11P->window_bdrwidth);
159    }
160
161  if ( fread( junk, 1, h11P->header_size - sizeof(*h11P), file ) !=
162      h11P->header_size - sizeof(*h11P) )
163    {
164      fprintf(stderr,"couldn't read rest of X11 XWD file header");
165      exit(-1);
166    }
167
168  /* Check whether we can handle this dump. */
169  if ( h11P->pixmap_depth > 8 )
170    {
171      fprintf(stderr,"can't handle X11 pixmap_depth > 8");
172      exit(-1);
173    }
174  if ( h11P->bits_per_rgb > 8 )
175    {
176      fprintf(stderr,"can't handle X11 bits_per_rgb > 8");
177      exit(-1);
178    }
179  if ( h11P->ncolors > MAXCOLORS )
180    {
181      fprintf(stderr,"can't handle X11 ncolors > %d");
182      exit(-1);
183    }
184  if ( h11P->pixmap_format != ZPixmap )
185    {
186      fprintf(stderr,"can't handle X11 pixmap_format %d", h11P->pixmap_format,
187              0,0,0,0 );
188      exit(-1);
189    }
190  if ( h11P->bitmap_unit != 8 && h11P->bitmap_unit != 16 &&
191      h11P->bitmap_unit != 32 )
192    {
193      fprintf(stderr,"X11 bitmap_unit (%d) is non-standard - can't handle");
194      exit(-1);
195    }
196  xres=h11P->pixmap_width;
197  yres=h11P->pixmap_height;
198  im=new image(h11P->pixmap_width,h11P->pixmap_height);
199  pal=new palette(h11P->colormap_entries);
200  *padrightP = h11P->bytes_per_line * 8 / h11P->bits_per_pixel - im->width();
201
202/*****************************************************************************/
203  /* Read X11 colormap. */
204minred = 65535;
205maxred = 0;
206  for ( i = 0; i < h11P->colormap_entries; i++ )
207    {
208      if ( fread( &x11col, sizeof(X11XColor), 1, file ) != 1 )
209        {
210          fprintf(stderr,"couldn't read X11 XWD colormap");
211          exit(-1);
212        }
213        else
214        {
215          x11col.pixel=bltl(x11col.pixel);
216          x11col.red=bstl(x11col.red);
217          x11col.green=bstl(x11col.green);
218          x11col.blue=bstl(x11col.blue);
219        }
220      if (x11col.pixel < 256)
221        {
222          if (minred > x11col.red) minred = x11col.red;
223          if (maxred < x11col.red) maxred = x11col.red;
224          dummy1 = (unsigned) x11col.red / 256 ;
225          dummy2 = (unsigned) x11col.green / 256 ;
226          dummy3 = (unsigned) x11col.blue / 256 ;
227          pal->set(i,dummy1,dummy2,dummy3);
228        }
229      else
230        {
231          fprintf(stderr,"pixel value outside of valid HDF palette\n");
232          exit(-1);
233        }
234    }
235  /* rest of stuff for getpixnum */
236  bits_per_item = h11P->bitmap_unit;
237  bits_used = bits_per_item;
238  bits_per_pixel = h11P->bits_per_pixel;
239  bit_order = h11P->bitmap_bit_order;
240  pixel_mask = ( 1 << bits_per_pixel ) - 1;
241
242  byteP = (char *) buf;
243  shortP = (short *) buf;
244  longP = (long *) buf;
245  return im;
246}
247
248void getimage(FILE *file,HBITMAP &im.int pad)
249{
250  int i,j;
251  unsigned char *sl;
252  for (i=0; i<im->height(); i++)
253    {
254      if (i%50==0)
255        printf("Line %d of %d\n",i+1,im->height());
256      sl=im->scan_line(i);
257      for (j=0; j<im->width(); j++)
258        sl[j]= getpixnum(file);
259
260      for ( j = 0; j < pad; j++ )
261        getpixnum( file );
262    }
263}
264
265
266int getpixnum(FILE *file)
267{
268  int p;
269
270  if ( bits_used == bits_per_item )
271    {
272      if ( fread( buf, bits_per_item / 8, 1, file ) != 1 )
273        fprintf(stderr, "couldn't read bits" );
274      if ( byte_swap )
275        switch ( bits_per_item )
276          {
277          case 8:
278            break;
279
280          case 16:
281            *shortP = bstl(*shortP) ;
282            break;
283
284          case 32:
285            *longP = bltl(*longP) ;
286            break;
287
288          default:
289            fprintf(stderr, "can't happen" );
290          }
291      bits_used = 0;
292
293//      if ( bit_order == MSBFirst )
294        bit_shift = bits_per_item - bits_per_pixel;
295//      else
296//      bit_shift = 0;
297    }
298
299  switch ( bits_per_item )
300    {
301    case 8:
302      p = ( *byteP >> bit_shift) & pixel_mask;
303      break;
304
305    case 16:
306      p = ( *shortP >> bit_shift) & pixel_mask;
307      break;
308
309    case 32:
310      p = ( *longP >> bit_shift) & pixel_mask;
311      break;
312
313    default:
314      fprintf(stderr, "can't happen" );
315    }
316
317//  if ( bit_order == MSBFirst )
318    bit_shift -= bits_per_pixel;
319//  else
320//    bit_shift += bits_per_pixel;
321  bits_used += bits_per_pixel;
322
323  return p;
324}
325
326
327short bs_short(short s )
328{
329  short ss;
330  unsigned char *bp, t;
331
332  ss = s;
333  bp = (unsigned char *) &ss;
334  t = bp[0];
335  bp[0] = bp[1];
336  bp[1] = t;
337  return ss;
338}
339
340int bs_int(int i )
341{
342  int ii;
343  unsigned char *bp, t;
344
345  ii = i;
346  bp = (unsigned char *) &ii;
347  t = bp[0];
348  bp[0] = bp[3];
349  bp[3] = t;
350  t = bp[1];
351  bp[1] = bp[2];
352  bp[2] = t;
353  return ii;
354}
355
356long bs_long(long l )
357{
358  return bs_int( l );
359}
360
361struct BMP_header
362{
363  char id[2];
364  long filesize;
365  int reserved[2];
366  long headersize,infosize,width,height;
367  int biplanes,bits;
368  long bicompression, bisizeimage, bixpelspermeter, biypelspermeter,
369       biclrused,biclrimportant;
370} bmp;
371
372void write_bmp(image *im, palette *pal, char *filename)
373{
374  FILE *fp;
375  int i,bytes;
376  unsigned char pal_quad[4];
377//  fp=fopen("d:\\windows\\256color.bmp","rb");
378//  fread(&bmp,1,sizeof(bmp),fp);
379//  fclose(fp);
380  fp=fopen(filename,"wb");
381  if (!fp)
382  { printf("Error : unable to open %s for writing!\n");
383    exit(0);
384  }
385  bytes=(im->width()+3)/4;
386  memset((char *)&bmp,0,sizeof(bmp));
387  memcpy(bmp.id,"BM",2);
388  bmp.width=im->width();
389  bmp.height=im->height();
390  bmp.bits=8;
391  bmp.infosize=0x28L;
392  bmp.biplanes=1;
393  bmp.headersize=1078;
394  bmp.filesize=bmp.headersize+bytes*im->height()*4;
395  bmp.bisizeimage=im->width()*im->height();
396  bmp.biclrused=256;
397  bmp.biclrimportant=256;
398  fwrite(&bmp,1,sizeof(bmp),fp);
399  pal_quad[3]=0;
400  for (i=0;i<256;i++)
401  {
402    pal->get(i,pal_quad[2],pal_quad[1],pal_quad[0]);
403    fwrite(pal_quad,1,4,fp);
404  }
405  for (i=im->height();i;i--)
406    fwrite(im->scan_line(i-1),1,bytes*4,fp);
407  fclose(fp);
408}
409
410image *image24(image *im, palette *pal, int rev)
411{
412  image *ni;
413  unsigned char *sl1,*sl2;
414  int i,x;
415  unsigned char r,g,b;
416  printf("Creating image size (%d, %d)\n",im->width()*3,im->height());
417  ni=new image(im->width()*3,im->height());
418  printf("Image created\n");
419  for (i=0;i<im->height();i++)
420  {
421    if (i%50==0)
422      printf("Line %d of %d\n",i+1,im->height());
423
424    sl1=   sl2[x*3]=r; sl2[x*3+1]=g; sl2[x*3+2]=b;
425    }
426    im->set_page_swapable();
427  }
428  return ni;
429}
430
431unsigned char addb(int n1, int n2)
432{ int n3;
433  n3=n1+n2;
434  return n3>255 ? 255 : (n3<0 ? 0 : n3);
435}
436
437// this function takes an image min 8 bit format, converts it to 24 bit
438// color and dithers it so that it can be printed on an deskjet
439/// (i.e it reduces it down to 8 colors)
440image *color_dither(image *im, palette *pal, int rev)
441{
442  image *i24;
443  unsigned char min[3],max[3],mid[3],*ad,*sl,*sl2,crimp;
444  int i,j,x,y,delta;
445  (void *)ad=pal->addr();
446
447  // find the minimum and maximum  red green and blue in the image
448  memset(min,0xff,3); memset(max,0,3);
449  for (j=0;j<3;j++,ad++)
450    for (y=0;y<im->height();y++)
451    { sl2=im->scan_line(y);
452      for (x=0;x<im->width();x++)
453      {
454        if (ad[sl2[x]*3]<min[j]) min[j]=ad[i*3];
455        if (ad[sl2[x]*3]>max[j]) max[j]=ad[i*3];
456      }
457    }
458  // find the middle color used for red green and blue
459  for (i=0;i<3;i++)
460    mid[i]=(int)((int)max[i]+(int)min[i])/2;
461  // convert the image to 24 bit color.
462  printf("Converting to 24 bit color...\n");
463  i24=image24(im,pal,rev);
464  printf("Dithering using flyod stienberg algorithm\n");
465  for (y=0;y<im->height();y++)
466  { if (y%20==0)
467      printf("Line %d of %d\n",y+1,im->height());
468    sl=i24->scan_line(y);
469    i24->set_page_unswapable();
470
471    if (y+1<im->height())
472      sl2=i24->scan_line(y+1);  // get the scan line below this one
473    for (x=0;x<im->width();x++)
474    {
475      // diffuse the colors using flyod stienburg dithering algorithm
476      for (j=0;j<3;j++)
477      {
478        crimp = sl[x*3+j]>mid[j] ? 255 : 0;
479        delta=sl[x*3+j]-crimp;
480        sl[x*3+j]=crimp;
481        if (x+1<im->width())
482        { sl[(x+1)*3+j]=addb(sl[(x+1)*3+j],delta*7/16);
483          if (y+1<im->height())
484            sl2[(x+1)*3+j]=addb(sl2[(x+1)*3+j],delta*1/16);
485        }
486        if (y+1<im->height())
487        { if (x>0)
488            sl2[(x-1)*3+j]=addb(sl2[(x-1)*3+j],delta*3/16);
489          sl2[(x)*3+j]=addb(sl2[(x)*3+j],delta*5/16);
490        }
491      }
492    }
493    sl=i24->scan_line(y);
494    i24->set_page_swapable();
495
496  }
497  return i24;
498}
499
500image *rotate90(image *im)
501{
502  image *i;
503  int x,y,w,h;
504  w=im->width();
505  h=im->height();
506  printf("Rotating image 90 deg\n");
507  i=new image(im->height(),im->width());
508  for (x=0;x<w;x++)
509  {
510    if (x%20==0)
511      printf("Row %d of %d\n",x,im->width());
512    for (y=0;y<h;y++)
513      i->putpixel(y,w-x-1,im->pixel(x,y));
514  }
515  return i;
516}
517
518void deskjet_print(int argc, char **argv)
519{
520  int i,dpi=100;
521  int y,x,byteo,bito,outc,outy,outm,outcv, outyv,outmv, w,rev,inten,val,
522      display=0,bad=0,bmp=0,land=0,ch,xo=0,yo=0;
523  image *im,*i24;
524  palette *pal;
525  unsigned char *sl;
526  FILE *fp;
527  char def_name[10],*dev_name,*fname=NULL;
528  unsigned char cp[500],mp[500],yp[500],kp[500];
529  strcpy(def_name,"\\dev\\lp");  // set the default output device to /dev/lp
530                // since we are in vpix, however we will use the backslash
531  dev_name=def_name; rev=0;
532  for (i=1;i<argc;i++)
533    if (!strcmp(argv[i],"-dpi"))
534    { i++; dpi=atoi(argv[i]);
535      if (dpi!=75 && dpi!=100 && dpi!=150 && dpi!=300) bad=1; }
536    else if (!strcmp(argv[i],"-dev"))
537    { i++; dev_name=argv[i]; }
538    else if (!strcmp(argv[i],"-rev"))
539    { rev=1; }
540    else if (!strcmp(argv[i],"-land"))
541    { land=1; }
542    else if (!strcmp(argv[i],"-2bmp"))
543    { bmp=1; }
544    else if (!strcmp(argv[i],"-display"))
545    { display=1; }
546    else fname=argv[i];
547
548  if (!fname || bad)
549  { printf("usage : %s [-dev device] [-dpi 75,100,150,300]\n"
550           "     [-rev] [-display] [-2bmp] [-land] filename\n\n"
551           "  default dpi is 100 (possible are 75/100/150/300)\n"
552           "  default printer is /dev/lp\n"
553           "  -rev, reverse black and white on the print out\n"
554           "  -display only displays the image to the screen and does not print it\n"
555           "    all ither options will be ignored\n"
556           "  -2bmp converts the image X window dump to a MicroSoft Windows bitmap (BMP)\n"
557           "    the file written to must be specified by -dev [filename]\n"
558           "    all other options will be ignored\n"
559           "  -land prints the image in landscape mode (sideways)\n"
560           "  filename is the name of the dump created by xwd\n"
561           "  Using Dos, the command [%s -dev lpt1] should be used\n",argv[0],argv[0]);
562    exit(0);
563  }
564  im=readxwd(fname,pal);
565  if (!im || !pal)
566  { printf("failed to read the image or the palette!\n");
567    exit(0);
568  }
569  if (display)
570  {
571    set_mode(19,argc,argv);
572    pal->load();                         // set the palette for the image we are going to print
573    im->put_image(screen,0,0);          // put the image on thge söööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööööö<0) yo+=10; break;
574      }
575    } while (ch!=' ' && ch!='q' && ch!=13);
576    close_graphics();
577  }
578  else if (bmp)
579    write_bmp(im,pal,dev_name);
580  else
581  {
582    fp=fopen(dev_name,"wb");  // open the output device for printing
583    if (!fp)
584    { printf("Unable to open %s for writing, make sure the path exsist and you\n"
585             "have write permission to the file\n",dev_name);
586      exit(0);
587    }
588    if (land)
589      im=rotate90(im);
590
591    w=im->width()+7; w/=8; w*=8;
592    fprintf(fp,"E"           // reset the printer
593               "&l%dO"      // portrait/landscape mode
594               "*rbC"        // reset graphics
595               "*t%dR"        // set the resolution
596               "*r%dS"       // set the image width
597               "*r1A"        // start raster graphics at left edge
598               "*r-4U"         // set to CYM mode
599               ,land,dpi,w);
600  // now loop through all the scan lines of the image and pcik out the planes
601  // we need
602    i24=color_dither(im,pal,rev);
603    rev=0;  // turn off the revser option because the conversion to 24 bit takes care of it
604    printf("Printing...");
605    for (y=0;y<im->height();y++)
606    {
607      if (y%20==0)
608        printf(".");
609
610      sl=i24->scan_line(y);
611  //initally set all the planes to clear, this should leave the paper white
612      memset(cp,0,500);  memset(mp,0,500);  memset(yp,0,500); memset(kp,0,500);
613  // now scan through the cyan plane of this scan line and pick out the bits
614      for (x=0,bito=7;x<im->width();x++)
615      {
616        outcv=RGB2C(sl[x*3],sl[x*3+1],sl[x*3+2]);
617        outyv=RGB2Y(sl[x*3],sl[x*3+1],sl[x*3+2]);
618        outmv=RGB2M(sl[x*3],sl[x*3+1],sl[x*3+2]);
619        if (outcv==outyv && outyv==outmv)
620        {
621          if ((rev && !outcv) || (!rev && outcv))
622            kp[x/8]^=(1<<bito);
623        } else
624        {
625          cp[x/8]^=(outcv<<bito);
626          yp[x/8]^=(outyv<<bito);
627          mp[x/8]^=(outmv<<bito);
628        }
629        if ((bito--)==0)
630          bito=7;
631      }
632      fprintf(fp,"%c*b%dV",27,w/8);  // print out the black plane first
633      fwrite(kp,1,w/8,fp);
634      fprintf(fp,"%c*b%dV",27,w/8);  // now the cyan plane
635      fwrite(cp,1,w/8,fp);
636      fprintf(fp,"%c*b%dV",27,w/8);  // now the yellow plane
637      fwrite(yp,1,w/8,fp);
638      fprintf(fp,"%c*b%dW",27,w/8);  // now the magenta plane
639      fwrite(mp,1,w/8,fp);
640    }
641    fprintf(fp,"%c*rbC%c",27,12);  // end graphics, switch everthing back to defaults
642                                   // and print a form feed to eject the paper.
643    fclose(fp); // flush out anything in the buffers and close the file
644    delete i24;  // clean up the memory that we allocated to the image and the palette
645  }
646  printf("\n");
647  delete im;
648  delete pal;
649}
650
651main(int argc, char **argv)
652{
653  setcbrk(1);  // set the control break on, so that printing can be interrupted
654  deskjet_print(argc,argv);
Note: See TracBrowser for help on using the repository browser.