1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2000, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 #define MAIN
8 
9 #include <X11/Intrinsic.h>
10 #include <X11/StringDefs.h>
11 #include <X11/Shell.h>
12 #include <stdio.h>
13 
14 #include <Xm/XmAll.h>
15 #include "mrilib.h"
16 
17 static char * vcl[] =  { "StaticGray"  , "GrayScale" , "StaticColor" ,
18                          "PseudoColor" , "TrueColor" , "DirectColor"  } ;
19 
20 static XImage * xim    = NULL ;
21 static int      xim_ww = 0 ;
22 static int      xim_hh = 0 ;
23 
24 #undef USE_TRUECOLOR
25 
26 #define USE_PIXMAP
27 #ifdef  USE_PIXMAP
28 # define WANT_LOGO_BITMAP
29 # include "logo.h"
30 #endif
31 
32 XImage * rgb_to_XImage( Display * dis , XVisualInfo * vin , MRI_IMAGE * im ) ;
33 
fred_CB(Widget w,XtPointer cd,XtPointer cb)34 void fred_CB( Widget w , XtPointer cd , XtPointer cb ){ exit(0); }
35 
elvis_CB(Widget w,XtPointer cd,XtPointer cb)36 void elvis_CB( Widget w , XtPointer cd , XtPointer cb )
37 {
38    static int needGC = 1 ;
39    static  GC myGC ;
40    XmDrawingAreaCallbackStruct * cbs = (XmDrawingAreaCallbackStruct *) cb ;
41    XExposeEvent * ev = (XExposeEvent *) cbs->event ;
42    Dimension nx=0 , ny=0 ;
43    int ii , jj ;
44 
45    if( cbs->reason != XmCR_EXPOSE || ev->count > 0 ) return ;
46 
47    if( needGC ){
48      XGCValues  gcv;
49      gcv.function = GXcopy ;
50      myGC  = XCreateGC( XtDisplay(w) , XtWindow(w) , GCFunction , &gcv ) ;
51      needGC = 0 ;
52    }
53 
54    XtVaGetValues( w , XmNwidth  , &nx , XmNheight , &ny , NULL ) ;
55 
56 #ifdef USE_TRUECOLOR
57    ii = 0 ;
58    do{
59       jj = 0 ;
60       do{
61          XPutImage( XtDisplay(w),XtWindow(w),myGC,xim,0,0,ii,jj,xim_ww,xim_hh) ;
62          jj += xim_hh + 4 ;
63       } while( jj < ny ) ;
64       ii += xim_ww ;
65    } while( ii < nx ) ;
66 #else
67 # ifdef USE_PIXMAP
68    ii = 0 ;
69    do{ jj = 0 ;
70        do{
71           XCopyArea( XtDisplay(w),logo_pixmap , XtWindow(w),myGC ,
72                      0,0,logo_width,logo_height , ii,jj ) ;
73          jj += logo_height + 4 ;
74       } while( jj < ny ) ;
75       ii += logo_width ;
76    } while( ii < nx ) ;
77 # endif /* USE_PIXMAP */
78 #endif /* USE_TRUECOLOR */
79 
80    return ;
81 }
82 
main(int argc,char * argv[])83 int main( int argc , char * argv[] )
84 {
85         XtAppContext    app;            /* the application context */
86         Widget          top;            /* toplevel widget */
87         Display         *dpy;           /* display */
88         Colormap        colormap;       /* created colormap */
89         XVisualInfo     vinfo;          /* template for find visual */
90         Visual          *vis ;          /* the Visual itself */
91         XVisualInfo     *vinfo_list;    /* returned list of visuals */
92         int             count;          /* number of matchs (only 1?) */
93         int             vid , stat ;
94         Widget          fred , fff ;
95 
96         top = XtVaAppInitialize( &app , "test" , NULL , 0 , &argc , argv , NULL , NULL ) ;
97         dpy = XtDisplay (top);
98 
99 #ifndef USE_TRUECOLOR
100         stat = XMatchVisualInfo( dpy,XScreenNumberOfScreen(XtScreen(top)),
101                                  8,PseudoColor,&vinfo ) ;
102         if( stat == 0 ){ printf("no 8 bit visual\n") ; exit(1) ; }
103 #else
104         vid = strtol( argv[1] , NULL , 0 ) ;
105         vinfo.visualid = (VisualID) vid ;
106         vinfo_list = XGetVisualInfo (dpy, VisualIDMask, &vinfo, &count);
107         if( count == 0 || vinfo_list == NULL ){fprintf(stderr,"no match\n");exit(1);}
108         vinfo = vinfo_list[0] ;
109 #endif
110         vid = vinfo.visualid ;
111         vis = vinfo.visual ;
112 
113         colormap = XCreateColormap( dpy, RootWindowOfScreen(XtScreen(top)) ,
114                                     vis , AllocNone ) ;
115 
116         XtVaSetValues( top ,
117                           XtNborderColor , 0 ,
118                           XtNbackground  , 0 ,
119                           XtNdepth       , vinfo.depth ,
120                           XtNcolormap    , colormap ,
121                           XtNvisual      , vis ,
122                        NULL ) ;
123 
124         fff = XtVaCreateWidget( "dialog" , xmFormWidgetClass , top ,
125                                    XmNborderWidth , 0 ,
126                                 NULL ) ;
127 
128 #ifndef LABEL_ARG
129 #define LABEL_ARG(str) \
130   XtVaTypedArg , XmNlabelString , XmRString , (str) , strlen(str)+1
131 #endif
132 
133         fred = XtVaCreateManagedWidget( "dialog" , xmPushButtonWidgetClass , fff ,
134                                           LABEL_ARG("Jumpback") ,
135                                           XmNtopAttachment    , XmATTACH_FORM ,
136                                           XmNleftAttachment   , XmATTACH_FORM ,
137                                           XmNrightAttachment  , XmATTACH_FORM ,
138                                          NULL ) ;
139         XtAddCallback( fred , XmNactivateCallback , fred_CB , NULL ) ;
140 
141         fred = XtVaCreateManagedWidget( "dialog" , xmDrawingAreaWidgetClass , fff ,
142                                           XmNtopAttachment    , XmATTACH_WIDGET ,
143                                           XmNtopWidget        , fred ,
144                                           XmNleftAttachment   , XmATTACH_FORM ,
145                                           XmNrightAttachment  , XmATTACH_FORM ,
146                                           XmNbottomAttachment , XmATTACH_FORM ,
147                                         NULL ) ;
148 
149         XtAddCallback( fred , XmNexposeCallback , elvis_CB , NULL ) ;
150 
151 #ifdef USE_TRUECOLOR
152         { MRI_IMAGE * im ;
153           im = mri_read_ppm( "bob.ppm" ) ;
154           xim = rgb_to_XImage( XtDisplay(top) , &vinfo , im ) ;
155           xim_ww = im->nx ; xim_hh = im->ny ;
156           mri_free(im) ;
157         }
158 #else
159         xim_ww = xim_hh = 77 ;
160 #endif
161 
162         XtVaSetValues( top ,
163                          XmNwidth , xim_ww ,
164                          XmNheight , xim_hh+40 ,
165                        NULL ) ;
166 
167 #ifdef USE_PIXMAP
168    {  Pixel bg_pix=0  , fg_pix=0  ;
169 # define ICON_bg bg_pix
170 # define ICON_fg fg_pix
171 
172       XtVaGetValues( fred ,
173                        XmNforeground , &bg_pix ,  /* note reversal of roles here! */
174                        XmNbackground , &fg_pix ,
175                      NULL ) ;
176 
177       logo_pixmap = XCreatePixmapFromBitmapData(
178                         XtDisplay(top) ,
179                         RootWindowOfScreen(XtScreen(top)) ,
180                         logo_bits , logo_width , logo_height ,
181                         fg_pix , bg_pix ,
182                         DefaultDepthOfScreen(XtScreen(top)) ) ;
183 
184       XtVaSetValues( top , XmNiconPixmap , logo_pixmap , NULL ) ;
185    }
186 #endif
187 
188 
189         XtManageChild(fff) ;
190         XtRealizeWidget(top); NI_sleep(1);
191         XtAppMainLoop(app);
192 
193         exit(0); /* never reached */
194 }
195 
196 #ifdef USE_TRUECOLOR
197 /*---------------------------------------------------------------------------
198    Create an XImage from an RGB image.  Adapted from program "xv".
199    The output of this can be XPutImage-d to a window.
200 -----------------------------------------------------------------------------*/
201 
202 static int highbit(unsigned long ul) ;  /* prototype */
203 
rgb_to_XImage(Display * dis,XVisualInfo * vin,MRI_IMAGE * im)204 XImage * rgb_to_XImage( Display * dis , XVisualInfo * vin , MRI_IMAGE * im )
205 {
206    unsigned long r, g, b, rmask, gmask, bmask ;
207    int           rshift, gshift, bshift, bperpix, bperline, border, i,j ;
208    int           wide, high ;
209    byte         *imagedata, *lip, *ip, *pp ;
210    XImage       *xim = NULL ;
211    int          *xcol ;
212 
213    /* check inputs */
214 
215 #if defined(__cplusplus) || defined(c_plusplus)
216    if( vin==NULL || vin->c_class!=TrueColor || im==NULL || im->kind!=MRI_rgb ){
217 #else
218    if( vin==NULL || vin->class!=TrueColor || im==NULL || im->kind!=MRI_rgb ){
219 #endif
220       fprintf(stderr,"\a\n*** ILLEGAL input to rgb_to_XImage\n") ;
221       sleep(1) ; exit(1) ;
222    }
223 
224    /* get color masks and shifts to put high bit of color byte into place */
225 
226    rmask = vin->red_mask   ; rshift = 7 - highbit(rmask) ;
227    gmask = vin->green_mask ; gshift = 7 - highbit(gmask) ;
228    bmask = vin->blue_mask  ; bshift = 7 - highbit(bmask) ;
229 
230    /* input image dimensions */
231 
232    wide = im->nx ;
233    high = im->ny ;
234 
235    /* make output XImage */
236 
237    xim = XCreateImage( dis , vin->visual , vin->depth , ZPixmap, 0, NULL,
238                        wide,  high, 32, 0) ;
239 
240    bperline = xim->bytes_per_line ;
241    bperpix  = xim->bits_per_pixel ;
242    border   = xim->byte_order ;
243 
244    if(bperpix != 8 && bperpix != 16 && bperpix != 24 && bperpix != 32){
245       fprintf(stderr,"\a\n*** rgb_to_XImage: can't use %d-bit TrueColor\n",bperpix) ;
246       sleep(1) ; exit(1) ;
247    }
248 
249    /* make output image array */
250 
251    imagedata = (byte *) XtMalloc((size_t) (high * bperline)) ;
252    xim->data = (char *) imagedata ;
253 
254    lip = imagedata ;       /* pointer to row of output image array */
255    pp  = MRI_RGB_PTR(im) ; /* pointer to input image data */
256 
257    xcol = (int *) malloc(sizeof(int) * wide) ; /* row of output colors */
258 
259    /*-- loop over image --*/
260 
261    for (i=0; i<high; i++, lip+=bperline) {  /* loop over rows */
262 
263       for (j=0, ip=lip; j<wide; j++) {      /* load color for row #i */
264 
265         r = *pp++ ;  g = *pp++ ;  b = *pp++ ;  /* get input RGB byte values */
266 
267         /* shift each component to the correct position, and mask it off */
268 
269         r = (rshift<0) ? (r<<(-rshift)) : (r>>rshift) ; r = r & rmask ;
270         g = (gshift<0) ? (g<<(-gshift)) : (g>>gshift) ; g = g & gmask ;
271         b = (bshift<0) ? (b<<(-bshift)) : (b>>bshift) ; b = b & bmask ;
272 
273         xcol[j] = r | g | b ;  /* assemble color for this pixel */
274       }
275 
276       /* now put all colors for row #i into output image array,
277          allowing for most possible bytes/pixel and byte ordering stupidities */
278 
279       switch( bperpix ){
280            case 32:
281              if (border == MSBFirst)
282                 for( j=0 ; j < wide ; j++ ){
283                    *ip++ = (xcol[j]>>24) & 0xff ;
284                    *ip++ = (xcol[j]>>16) & 0xff ;
285                    *ip++ = (xcol[j]>>8)  & 0xff ;
286                    *ip++ =  xcol[j]      & 0xff ;
287                  }
288              else
289                 for( j=0 ; j < wide ; j++ ){
290                    *ip++ =  xcol[j]      & 0xff ;
291                    *ip++ = (xcol[j]>>8)  & 0xff ;
292                    *ip++ = (xcol[j]>>16) & 0xff ;
293                    *ip++ = (xcol[j]>>24) & 0xff ;
294                  }
295            break ;
296 
297            case 24:
298              if (border == MSBFirst)
299                 for( j=0 ; j < wide ; j++ ){
300                   *ip++ = (xcol[j]>>16) & 0xff ;
301                   *ip++ = (xcol[j]>>8)  & 0xff ;
302                   *ip++ =  xcol[j]      & 0xff ;
303                 }
304              else
305                 for( j=0 ; j < wide ; j++ ){
306                   *ip++ =  xcol[j]      & 0xff ;
307                   *ip++ = (xcol[j]>>8)  & 0xff ;
308                   *ip++ = (xcol[j]>>16) & 0xff ;
309                 }
310            break ;
311 
312            case 16:
313              if (border == MSBFirst)
314                 for( j=0 ; j < wide ; j++ ){
315                   *ip++ = (xcol[j]>>8)  & 0xff ;
316                   *ip++ =  xcol[j]      & 0xff ;
317                 }
318              else
319                 for( j=0 ; j < wide ; j++ ){
320                   *ip++ =  xcol[j]      & 0xff ;
321                   *ip++ = (xcol[j]>>8)  & 0xff ;
322                 }
323            break ;
324 
325            case 8:
326                 for( j=0 ; j < wide ; j++ )
327                    *ip++ = xcol[j] & 0xff ;
328            break ;
329          }
330     } /* end of loop over rows */
331 
332    free(xcol) ;
333    return xim ;
334 }
335 
336 /*------------------------------------------------------------------------
337   Returns position of highest set bit in 'ul' as an integer (0-31),
338   or returns -1 if no bit is set.
339 --------------------------------------------------------------------------*/
340 
341 static int highbit(unsigned long ul)
342 {
343   int i;  unsigned long hb;
344 
345   hb = 0x80;  hb = hb << 24;   /* hb = 0x80000000UL */
346   for (i=31; ((ul & hb) == 0) && i>=0;  i--, ul<<=1);
347   return i;
348 }
349 #endif
350 
351 /*----------  Fix a Linux stupidity  ------------------------------------*/
352 
353 #include "machdep.h"
354 #ifdef NEED_XSETLOCALE
355 #include <locale.h>
356 char * _Xsetlocale( int category, const char * locale)
357 { return setlocale(category,locale) ; }
358 #endif
359