home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / educatio / xcoral16.zip / INIT_MEN.C < prev    next >
C/C++ Source or Header  |  1993-01-15  |  14KB  |  544 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <X11/Xlib.h>
  17. #include <X11/Xutil.h>
  18. #include <malloc.h>
  19.  
  20. #include "menus.h"
  21.  
  22. XContext        SwContext;
  23. XContext        TiContext;
  24. static ResourcesMenu    rm;
  25.  
  26. static int getnbstr ();
  27. static char *getmaxstr ();
  28. static void show_bar ();
  29. static VMenu *Vmenu ();
  30.  
  31. extern void Display3D ();
  32.  
  33. /*
  34. **    Function name : InitMenuRes
  35. **
  36. **    Description :  Initialisations des ressources pour les menus.
  37. **        La fonte, le foregreound, le background ainsi que
  38. **        les couleurs utilisees pour le 3D. 
  39. **        Plusieurs contextes graphiques sont mis en oeuvre.
  40. **    
  41. **    Input :  Le display, font, foreground, background, top_shadow et bottom_shadow.
  42. **    Ouput :
  43. */
  44. void InitMenusRes ( display, font, fg, bg, ts, bs )
  45.     Display        *display;
  46.     XFontStruct    *font;
  47.     unsigned long     fg, bg, ts, bs;
  48. {
  49.     GC gc;
  50.     XGCValues gcv;
  51.     unsigned long gcm;
  52.     
  53.     gc = DefaultGC ( display, DefaultScreen (display ));
  54.  
  55.     rm.ngc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
  56.     rm.bgc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );  /* Ne sert plus == ngc */
  57.     rm.ugc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
  58.     rm.igc = XCreateGC ( display, DefaultRootWindow ( display ), 0, &gcv );
  59.  
  60.     rm.top_shadow = ts;
  61.     rm.bot_shadow = bs;
  62.     rm.font = font;
  63.     rm.fg = fg;
  64.     rm.bg = bg;
  65.  
  66.     XCopyGC ( display, gc, (~0), rm.ngc );
  67.     XCopyGC ( display, gc, (~0), rm.igc );
  68.     
  69.     gcm = 0;
  70.     gcm |= GCFunction;    gcv.function = GXxor;
  71.     gcm |= GCPlaneMask;    gcv.plane_mask = fg ^ bg;
  72.     gcm |= GCForeground;    gcv.foreground = fg ^ bg;
  73.     gcm |= GCBackground;    gcv.background = bg;
  74.  
  75.     XChangeGC ( display, rm.igc, gcm, &gcv );
  76.     
  77.     gcv.line_width = 0; gcv.font = font -> fid;
  78.     gcv.background = bg; gcv.foreground = fg;
  79.     
  80.     XChangeGC ( display, rm.ngc, GCLineWidth | GCFont | GCForeground |
  81.         GCBackground, &gcv );
  82.  
  83.     XCopyGC ( display, rm.ngc, (~0), rm.bgc );
  84.     XCopyGC ( display, rm.ngc, (~0), rm.ugc );
  85.     
  86.     rm.height_bar = font -> ascent + font -> descent + BAR_SPACE;
  87.  
  88.     TiContext  = XUniqueContext ();
  89.     SwContext = XUniqueContext ();
  90. }
  91.  
  92.  
  93. /*
  94. **    Function name : MakeMenus
  95. **
  96. **    Description : Fabrication des menus pour chacun des titres.
  97. **
  98. **    Input :  Le display, la fenetre parent, les titres, les items et la
  99. **        table des callbacks.
  100. **    Ouput : XYMenu *
  101. */
  102. XYMenu *MakeMenus ( display, w, title, item, fnt ) 
  103.     Display        *display;
  104.     Window        w;
  105.     char        **title;
  106.     char        ***item;
  107.     void        (**fnt []) ();
  108. {
  109.     XYMenu        *menu;
  110.     SWindow        *sw;
  111.     XWindowAttributes att;
  112.     register     int i = 0;
  113.     register     int x = 0, width;
  114.     VMenu        *Vmenu ();
  115. /*    char    *malloc (); */
  116.  
  117.     XGetWindowAttributes ( display, w, &att );
  118.     menu = ( XYMenu * ) malloc ( sizeof ( XYMenu ));
  119.        bzero ( menu, sizeof ( XYMenu ));
  120.    
  121.     menu -> width_relief = DEPTH_WIDTH;
  122.     menu -> font = rm.font;
  123.     menu -> bar_height = rm.height_bar;
  124.     menu -> bar_width     = att.width + ( menu -> width_relief * 2 );
  125.     menu -> h_item = rm.font->ascent + rm.font->descent + 2 + ( 2 * menu -> width_relief );
  126.     menu -> y_menu = menu -> bar_height + 2;        
  127.     menu -> titlename     = title;
  128.     menu -> itemname     = item;
  129.     menu -> y_title = rm.font -> ascent +  1;
  130.     menu -> parent = w;
  131.     menu -> n_last_unmapped = -1;
  132.     menu -> hmax_menu = 0;
  133.     menu -> w_under = w;
  134.     menu -> Ngc = rm.ngc;
  135.     menu -> Igc = rm.igc;
  136.     menu -> Bgc = rm.bgc;
  137.     menu -> Ugc = rm.ugc;
  138.     menu -> top_sh = rm.top_shadow;
  139.     menu -> bot_sh = rm.bot_shadow;
  140.  
  141.     menu -> fg_bar = menu -> fg_menu = rm.fg;
  142.     menu -> bg_bar = menu -> bg_menu = rm.bg;
  143.  
  144.     menu -> w_bar = XCreateSimpleWindow ( display, w, 0, 0, menu -> bar_width,
  145.         menu -> bar_height, 0, rm.bg, rm.bg );
  146.     XSelectInput ( display, menu->w_bar, ExposureMask | StructureNotifyMask
  147.         | VisibilityChangeMask );
  148.  
  149.     menu->mapped = 0;
  150.     menu -> save = 0;
  151.     x = 2;
  152.     while ( *title != 0 ) {
  153.         width = XTextWidth ( rm.font, *title, strlen ( *title )) + 20;
  154.         *title++;    
  155.         menu->w_title [i] =
  156.             XCreateSimpleWindow ( display, menu->w_bar, x, 2,
  157.                 width,
  158.                 menu -> h_item,
  159.                 0, rm.bg, rm.bg );
  160.         menu->title_width [i] = width;
  161.         /*
  162.          * Ne sert que pour savoir si on est dans la barre des titres.
  163.          * le choix de width n'a pas d'importance.
  164.          */
  165.         XSaveContext ( display, menu->w_title [i], TiContext, (caddr_t) width ) ;
  166.  
  167.         XSelectInput ( display, menu->w_title [i], ExposureMask |
  168.             EnterWindowMask | ButtonPressMask );
  169.         menu -> no_menu = i;        
  170.         sw = ( SWindow * ) malloc ( sizeof ( SWindow ));
  171.         sw -> w = menu -> w_title [i];
  172.         sw -> type = MENU;
  173.         sw -> no_m = i;
  174.         sw -> no_i = 0;
  175.         if ( XSaveContext ( display, sw -> w, SwContext, (caddr_t) sw ) != 0 )
  176.             (void) fprintf ( stderr, "make_xymenus XSaveContext Error\n" );
  177.         menu->vmenu [i] = Vmenu ( display, w, menu, *item, x, *fnt, rm.bg ); 
  178.         if ( menu -> vmenu [i] -> height > menu -> hmax_menu )
  179.             menu -> hmax_menu = menu -> vmenu [i] -> height;
  180.         x += width;
  181.         i++;
  182.         *item++;
  183.         *fnt++;
  184.         if ( i > 10 )
  185.             break;
  186.     }
  187.     menu->nb_menus = i;
  188.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) != True )
  189.         SetMenuPixmap ( display, menu, menu -> bar_width );
  190.     show_bar ( display, menu -> parent, menu );
  191.     return menu;
  192. }
  193.  
  194.  
  195. /*
  196. **    Function name : MouseInMenuBar
  197. **
  198. **    Description :  Comme son nom l'indique.
  199. **
  200. **    Input : Le Display, la fenetre
  201. **    Ouput : Vrai ou Faux.
  202. */
  203. int MouseInMenuBar ( display, w )
  204.     Display *display;
  205.     Window w;
  206. {
  207.     int m;
  208.  
  209.     if ( XFindContext ( display, w, TiContext, (caddr_t *) &m ) != XCNOENT )
  210.         return True;
  211.     else
  212.         return False;
  213. }
  214.  
  215.  
  216. /*
  217. **    Function name : SetMenuPixmap
  218. **
  219. **    Description : Fabrication d'un pixmap pour sauvegarder
  220. **        les parties cachees.
  221. **    Input : Le display, le menu, largeur de la fenetre parent.
  222. **    Ouput :
  223. */
  224. void SetMenuPixmap ( display, menu, width )
  225.     Display *display;
  226.     XYMenu *menu;
  227.     register int width;
  228. {
  229.  
  230.     if ( menu -> save != 0 ) {
  231. #ifdef DEBUG
  232.         fprintf ( stderr, "Pixmap ms = %d\n", menu -> save );
  233. #endif DEBUG
  234.             XFreePixmap ( display, menu -> save );
  235.     }
  236.  
  237. #ifdef SHADOW
  238.     menu -> save = XCreatePixmap ( display,
  239.         menu -> w_under , width,
  240.         menu -> hmax_menu + SHAD + 10,
  241.         DefaultDepth ( display, DefaultScreen ( display )));
  242. #else
  243.     menu -> save = XCreatePixmap ( display,
  244.         menu -> w_under , width,
  245.         menu -> hmax_menu + 10,
  246.         DefaultDepth ( display, DefaultScreen ( display )));
  247. #endif
  248.     menu -> save_ok = 0;        /* Ya rien  dans la pixmap */
  249.     menu -> pix_width = width;
  250. }
  251.  
  252.  
  253. /*
  254. **    Function name : Vmenu
  255. **
  256. **    Description : Fabrication des menus associes a chaque titre
  257. **        principal.
  258. **
  259. **    Input :  Le Display, la fenetre parent, menu, table des items,
  260. **        la fonte, le background.
  261. **    Ouput :
  262. */
  263. static VMenu *Vmenu ( display, window, menu, item, x_title, fnt, bg )
  264.     Display    *display;
  265.     Window    window;
  266.     XYMenu    *menu;
  267.     register char **item;
  268.     register int x_title;
  269.     void (**fnt) ();
  270.     unsigned long bg;
  271. {
  272.     VMenu    *vm;
  273.     SWindow    *sw;
  274.     char    *getmaxstr ();
  275.     XSetWindowAttributes att, att_io;
  276.     register int x_menu, n;
  277.     register char *maxstr;
  278.     register int nb_item;
  279.  
  280.     vm = ( VMenu * ) malloc ( sizeof ( VMenu ));
  281.        bzero ( vm, sizeof ( VMenu ));
  282.     maxstr = getmaxstr ( item );
  283.     nb_item = getnbstr ( item );
  284.  
  285.     vm -> height = ( nb_item * menu -> h_item ) + 6;
  286.     vm -> width = XTextWidth ( menu->font, maxstr, strlen ( maxstr )) + 26
  287.         + ( 2 * menu -> width_relief );
  288.  
  289.     x_menu = x_title;    
  290.     vm -> x = x_menu;
  291. #ifdef SHADOW
  292.     att_io.win_gravity = NorthWestGravity;
  293.     att_io.event_mask = 0;
  294.     att_io.override_redirect = False;
  295.     att_io.do_not_propagate_mask = NoEventMask;
  296.     att_io.cursor = None;
  297.     vm -> trans = XCreateWindow ( display, window, x_menu, menu -> y_menu,
  298.         vm -> width + SHAD, vm -> height + SHAD, 0, 0,
  299.         InputOutput, CopyFromParent,
  300.         CWWinGravity | CWEventMask | CWOverrideRedirect | 
  301.         CWDontPropagate | CWCursor, 
  302.         &att_io );
  303.     vm -> shadow = XCreateSimpleWindow ( display, vm -> trans, SHAD,
  304.             SHAD, vm->width, vm->height, 0, 
  305.             BlackPixel ( display, DefaultScreen ( display )),
  306.             BlackPixel ( display, DefaultScreen ( display )));
  307.     vm -> v_frame = XCreateSimpleWindow ( display, vm -> trans, 0,
  308.             0, vm->width, vm->height, 0, bg, bg );
  309.     XSelectInput ( display, vm->v_frame, ExposureMask | LeaveWindowMask );
  310.     XSelectInput ( display, vm -> trans, ExposureMask | LeaveWindowMask );
  311. #else
  312.     vm->v_frame = XCreateSimpleWindow ( display, window, x_menu,
  313.             menu->y_menu, vm->width, vm->height, 0, bg, bg );
  314.     XSelectInput ( display, vm->v_frame, ExposureMask | LeaveWindowMask );
  315. #endif
  316.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) == True )
  317.         att.save_under = True;
  318.     else
  319.         att.save_under = False;
  320. #ifdef SHADOW
  321.     XChangeWindowAttributes ( display, vm -> trans, CWSaveUnder, &att );
  322. #else
  323.     XChangeWindowAttributes ( display, vm->v_frame, CWSaveUnder, &att );
  324. #endif
  325.     n = 0;
  326.     vm -> iname = item;
  327.     while ( *item != 0 ) {
  328.         vm->w_item [n] = XCreateSimpleWindow ( display, vm->v_frame,
  329.             3, (n * menu -> h_item) + 3,
  330.             vm->width - 6, menu -> h_item, 0,
  331.             bg, bg );
  332.         XSelectInput ( display, vm->w_item [n], ExposureMask
  333.             | EnterWindowMask );
  334.         sw = ( SWindow * ) malloc ( sizeof ( SWindow ));
  335.         sw -> w = vm->w_item [n];
  336.         sw -> type = ITEM;
  337.         sw -> no_i = n;
  338.         sw -> no_m = menu -> no_menu;
  339.         if ( XSaveContext ( display, sw -> w, SwContext, (caddr_t) sw ) != 0 )
  340.             (void) fprintf ( stderr,  "make_vertical_menus XSaveContext Error\n" );
  341.         vm -> func [n] = *fnt;
  342.         n++;
  343.         *item++;
  344.         *fnt++;
  345.     }
  346. #ifdef SHADOW
  347.     XMapSubwindows ( display, vm -> trans );
  348.     XMapSubwindows ( display, vm -> v_frame );
  349. #else
  350.     XMapSubwindows ( display, vm -> v_frame );
  351. #endif
  352.     vm->nb_items = n;
  353.     return ( vm );
  354. }
  355.  
  356.  
  357. /*
  358. **    Function name : SetHiddenWindow
  359. **
  360. **    Description : Initialise les parametres de la fenetre cachee.
  361. **
  362. **    Input : Le menu, la fenetre cachee, le contexte graphique.
  363. **    Ouput :
  364. */
  365. void SetHiddenWindow ( menu, w, gc )
  366.     XYMenu    *menu;
  367.     Window    w;
  368.     GC    gc;
  369. {
  370.     menu -> w_under = w;
  371.     menu -> Ugc = gc;
  372. }
  373.  
  374.  
  375. /*
  376. **    Function name : getnbstr
  377. **
  378. **    Description : Pour avoir la taille d'un tableau de pointeurs
  379. **
  380. **    Input : La tableau.
  381. **    Ouput : le nombre d'entree non vide dans le tableau.
  382. */
  383. static int getnbstr ( tstr )
  384.     register char **tstr;
  385. {
  386.     register int i = 0;
  387.     while ( *tstr != 0 ) {
  388.         i++;
  389.         *tstr++;
  390.         if ( i > 100 ) return ( 0 );
  391.     }
  392.     return ( i );
  393. }
  394.  
  395.  
  396. /*
  397. **    Function name : getmaxstr
  398. **
  399. **    Description : Donne la plus longue chaine dans un tableau,
  400. **        en fonction de la fonte utilisee.
  401. **
  402. **    Input : Le tableau
  403. **    Ouput : La plus grande chaine.
  404. */
  405. static char *getmaxstr ( tstr )
  406.     register char **tstr;
  407. {
  408.     register char *s;
  409.     register int i, j;
  410.  
  411.     i = j = 0;
  412.     while ( *tstr != 0 ) {
  413.         j = strlen ( *tstr );
  414.            if ( (j=XTextWidth ( rm.font, *tstr, strlen ( *tstr ))) > i ) {
  415.             s = *tstr;
  416.             i = j;
  417.         }
  418.         tstr ++;
  419.     }
  420.     return ( s );
  421. }
  422.  
  423.  
  424. /*
  425. **    Function name : RefreshMenuBar
  426. **
  427. **    Description : Redessine la barre des titres.
  428. **
  429. **    Input : Le display, le menu.
  430. **    Ouput :
  431. */
  432. void RefreshMenuBar ( display, menu )
  433.     Display     *display;
  434.     XYMenu    *menu;
  435. {
  436.     register int i;
  437.     register char     **str = menu->titlename;
  438.  
  439.     XResizeWindow ( display, menu -> w_bar, menu -> bar_width,
  440.         menu -> bar_height );
  441.  
  442.     Display3D ( display, menu -> w_bar,
  443.             menu -> top_sh, menu -> bot_sh,
  444.             menu -> width_relief , DEPTH_UP );
  445.  
  446.     for ( i=0; i < menu->nb_menus; i++ ) {
  447.         XDrawString ( display, menu->w_title [i], menu -> Bgc, 10,
  448.             menu -> y_title + menu -> width_relief + 1,
  449.             *str, strlen ( *str ));
  450.         str++;
  451.     }
  452. }
  453.  
  454.  
  455. /*
  456. **    Function name : show_bar
  457. **
  458. **    Description : Affichage de la barre des titres.
  459. **
  460. **    Input : Le display, la fenetre mere, le menu.
  461. **    Ouput :
  462. */
  463. static void show_bar ( display, w, menu )
  464.     Display    *display;
  465.     Window    w;
  466.     XYMenu    *menu;
  467. {
  468.     XEvent    event;
  469.  
  470.     XMapSubwindows ( display, menu->w_bar ); 
  471.     XMapWindow ( display, menu->w_bar ); 
  472.     XMapWindow ( display, w );
  473.     XFlush ( display );
  474.     XWindowEvent ( display, w, ExposureMask, &event );
  475.     XWindowEvent ( display, menu -> w_bar, ExposureMask, &event );
  476.     RefreshMenuBar ( display, menu );
  477. }
  478.  
  479.  
  480. /*
  481. **    Function name : ButtonPressInMenu
  482. **
  483. **    Description : Comme son nom l'indique.
  484. **
  485. **    Input : La fenetre de l'evenement, le menu.
  486. **    Ouput : Le numero du menu, sinon -1;
  487. */
  488. int ButtonPressInMenu ( w, menu )
  489.     Window    w;
  490.     XYMenu    *menu;
  491. {
  492.     register int i, n = -1;
  493.  
  494.     for ( i=0; i < menu -> nb_menus; i++) 
  495.         if ( w == menu -> w_title [i] ) {
  496.             n = i;
  497.             break;
  498.         }
  499.     return ( n );
  500. }
  501.  
  502.  
  503. /*
  504. **    Function name : DeleteMenu
  505. **
  506. **    Description : Comme son nom l'indique.
  507. **
  508. **    Input : Le display, le menu.
  509. **    Ouput :
  510. */
  511. void DeleteMenu ( display, menu )
  512. Display    *display;
  513. XYMenu    *menu;
  514. {
  515.     register int i, j;
  516.     SWindow    *sw;
  517.  
  518.     for ( i = 0; i < menu -> nb_menus; i++ ) {
  519.         for ( j=0; j < menu -> vmenu [i] -> nb_items; j++ ) {
  520.             XFindContext ( display, menu -> vmenu [i] -> w_item [j], SwContext, (caddr_t *) &sw );
  521.                      if ( sw != 0 )
  522.                 (void) free (( char * ) sw );
  523.             XDeleteContext ( display, menu -> vmenu [i] -> w_item [j], SwContext );
  524.             XDestroyWindow ( display, menu -> vmenu [i] -> w_item [j] ); 
  525.         }
  526. #ifdef SHADOW
  527.         XDestroyWindow ( display, menu -> vmenu [i] -> trans );
  528. #else
  529.         XDestroyWindow ( display, menu -> vmenu [i] -> v_frame );
  530. #endif
  531.         XFindContext ( display, menu -> w_title [i], SwContext, (caddr_t *) &sw );
  532.         if ( sw != 0 )
  533.             (void) free ( ( char * ) sw );
  534.         XDeleteContext ( display, menu -> w_title [i], SwContext );
  535.         if ( menu -> vmenu [i] != 0 )
  536.             free ( ( char * ) menu -> vmenu [i] );
  537.     }
  538.     XDestroyWindow ( display,menu -> w_bar );
  539.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display ) ) != True )
  540.         XFreePixmap ( display, menu -> save );
  541.     if ( menu != 0 )
  542.         (void) free ( ( char * ) menu ); 
  543. }
  544.