home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / educatio / xcoral16.zip / HANDLE_M.C < prev    next >
C/C++ Source or Header  |  1993-01-15  |  13KB  |  500 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.  
  19. #include "menus.h"
  20.  
  21. extern XContext    SwContext;
  22. static     int     button_press;
  23.  
  24. static Window HandleButtonReleaseMenu ();
  25. static void HandleExposeMenu (), HandleLeaveMenu (), HandleEnterMenu ();
  26. static void clear_item (), show_item (), clear_menu (), show_menu ();
  27.  
  28. extern void Display3D ();
  29.  
  30. /*
  31. **    Function name : HandleMenu
  32. **
  33. **    Description : Point d'entree dans la gestion des menus apres un ButtonPress
  34. **
  35. **    Input : Le display, structure event, la fenetre parent, le menu courant,
  36. **        le numero du menu,     les infos pour  la callback.
  37. **    Ouput : La fenetre du ButtonRelease.
  38. */
  39. Window HandleMenu ( display, ev, frame, menu, n, vm, item )
  40.     Display    *display;
  41.     XButtonPressedEvent *ev;
  42.     Window frame;
  43.     XYMenu    *menu;
  44.     register int n;
  45.     register int *vm, *item;    /* RETURN */
  46. {
  47.     XEvent     event;
  48.     SWindow    *sw;
  49.     int pointer_in, last;
  50.  
  51.     button_press = ev -> button;
  52.     
  53.     XGrabPointer ( display, frame, True, ButtonPressMask
  54.         | ButtonReleaseMask, GrabModeAsync,
  55.         GrabModeAsync, frame, None , CurrentTime);
  56.  
  57.     show_menu ( display, menu, n );
  58.     menu -> w_last_item = NULL;
  59.     menu -> n_last_item = -1;
  60.     pointer_in = True;
  61.  
  62.     for (;;) {
  63.                        XNextEvent ( display, &event );
  64.         switch ( event.type ) {
  65.             case EnterNotify:
  66.                 HandleEnterMenu ( display,
  67.                     (XEnterWindowEvent *) &event,
  68.                     menu, (SWindow *) &sw, &pointer_in );
  69.                 break;
  70.             case LeaveNotify:
  71.                 HandleLeaveMenu ( display,
  72.                     (XLeaveWindowEvent *) &event,
  73.                     menu, &pointer_in );
  74.                 break;
  75.  
  76.             case Expose:
  77.                 HandleExposeMenu ( display,
  78.                     (XExposeEvent *) &event,
  79.                     menu, &last );
  80.                 break;
  81.  
  82.             case ButtonRelease:
  83.                 if ( button_press != event.xbutton.button )
  84.                     break;
  85.                 XUngrabPointer ( display, CurrentTime );
  86.                 if ( HandleButtonReleaseMenu ( display,
  87.                     (XButtonReleasedEvent *) &event,
  88.                     menu, frame, vm, item ) ) {
  89.                         return ( event.xany.window );
  90.                 }
  91.                 else {
  92.                     return NULL;
  93.                 }
  94.                 }
  95.         }
  96. }
  97.  
  98.  
  99. /*
  100. **    Function name : HandleButtonReleaseMenu
  101. **
  102. **    Description : Traitement de l'evennement ButtonRelease
  103. **
  104. **    Input :  Le display, button event, le menu, la fenetre parent
  105. **        les infos sur la callback.
  106. **    Ouput : La fenetre de l'evennement,
  107. */
  108. static Window HandleButtonReleaseMenu ( display, ev, menu, frame, vm, it )
  109.     Display    *display;
  110.     XButtonReleasedEvent *ev;
  111.     XYMenu    *menu;
  112.     Window     frame;
  113.     register int *vm, *it;     /* RETURN */
  114. {
  115.     register int last = menu -> n_last_mapped;
  116.     register int item =  menu -> n_last_item;
  117. #ifdef DEBUG
  118.     ( void ) fprintf ( stderr, "HandleButtonRelease w = %d\n",
  119.             ev -> window );
  120. #endif
  121.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display )) != True )
  122.         menu -> save_ok = NULL; /* Pour reinitialiser */
  123.     if ( menu -> mapped != NULL ) {
  124.         clear_menu ( display, menu, last );
  125.         XSync ( display, True );
  126.         if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display )) != True )
  127.             XCopyArea ( display, menu -> save, menu -> w_under,
  128.                 menu -> Ugc, 0, 0, menu -> pix_width,
  129. #ifdef SHADOW
  130.                 menu -> hmax_menu + SHAD + 10,
  131. #else
  132.                 menu -> hmax_menu + 10,
  133. #endif
  134.                 0, 0 );
  135.         if ( item != -1 ) {
  136.             *vm = last;
  137.             *it = item;
  138.         }
  139.         else {
  140.                 *vm = *it = -1;
  141.         }
  142.     }
  143.     if ( ev -> window != frame
  144.         && ev -> window != menu -> mapped 
  145.         && ev -> window != menu -> w_title [last] ) {
  146. #ifdef DEBUG
  147.         ( void ) fprintf ( stderr, "\tNot Parent\n" );
  148. #endif
  149.         return ( ev -> window );
  150.     }
  151.     else
  152.         return NULL;
  153. }
  154.  
  155. /*
  156. **    Function name : HandleExposeMenu
  157. **
  158. **    Description : Traite les evenements d'exposition pendant
  159. **        le ButtonPress et gere l'affichage des menus.    
  160. **
  161. **    Input : Le display, l'expose event, le menu, dernier menu expose
  162. **    Ouput :
  163. */
  164. static void HandleExposeMenu ( display, ev, menu, last )
  165.     Display    *display;
  166.     XExposeEvent    *ev;
  167.     XYMenu    *menu;
  168.     int    *last;
  169. {
  170.     register char **str;
  171.     register int i;
  172.     XRectangle rec [2];
  173. #ifdef DEBUG
  174.     ( void ) fprintf ( stderr, "HandleExpose w = %d\n",
  175.             ev -> window );
  176. #endif
  177.     *last = menu -> n_last_mapped;
  178.     str = menu -> vmenu [*last] -> iname;
  179. /*
  180.     if ( ev -> window == menu -> vmenu [*last] -> v_frame ) {
  181.     }
  182. */
  183.     for ( i=0; i < menu->vmenu [*last]->nb_items; i++ ) {
  184.         if ( ev -> window == menu -> vmenu [*last] -> w_item [i] ) {
  185.             XDrawString ( display,
  186.                 menu -> vmenu [*last] -> w_item [i],
  187.                 menu->Ngc, 10,
  188.                 menu -> y_title + menu -> width_relief,
  189.                 *str,strlen ( *str ));
  190.  
  191.             Display3D ( display, 
  192.                 menu -> vmenu [*last] -> w_item [i],
  193.                 menu -> top_sh, menu -> bot_sh, 
  194.                 menu -> width_relief,
  195.                 DEPTH_UP );
  196.             return;
  197.         }
  198.         str++;
  199.     }
  200.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display )) == True )
  201.             return;
  202.     if ( ev -> window == menu -> w_under ) {
  203.         rec [0].x = ev -> x;
  204.         rec [0].y = ev -> y;
  205.         rec [0].width = ev -> width;
  206.         rec [0].height = ev -> height;
  207.         XSetClipRectangles ( display, menu -> Ugc, 0,0,
  208.             rec, 1, Unsorted );
  209.         XCopyArea ( display, menu -> save, menu -> w_under,
  210.             menu -> Ugc, 0, 0, menu -> pix_width,
  211. #ifdef SHADOW
  212.             menu -> hmax_menu + SHAD + 10,
  213. #else
  214.             menu -> hmax_menu,
  215. #endif
  216.             0, 0 );
  217.         XSetClipMask ( display, menu -> Ugc, None );
  218.     }
  219. }
  220.  
  221.  
  222. /*
  223. **    Function name : HandleLeaveMenu
  224. **
  225. **    Description : Traite les evenements LeaveNotify pendant
  226. **        le ButtonPress et gere l'affichage des menus.
  227. **
  228. **    Input : Le Display, l'evenement, le menu et nn flag qui indique
  229. **        si on est ou non dans la fenetre courante.
  230. **    Ouput :
  231. */
  232. static void HandleLeaveMenu ( display, ev, menu, p_in )
  233.     Display    *display;
  234.     XLeaveWindowEvent *ev;
  235.     XYMenu    *menu;
  236.     int *p_in;
  237. {
  238.     XWindowAttributes att;
  239. #ifdef DEBUG
  240.     (void) fprintf ( stderr, "HandleLeave w = %d\n", ev -> window );
  241. #endif
  242.     if ( ev -> mode == NotifyGrab ) return;
  243.     if ( (ev -> window == menu -> mapped) || 
  244.         (ev -> window == menu -> vmenu [ menu -> n_last_mapped ] -> v_frame) ) {
  245.         clear_item ( display, menu,
  246.                 menu -> n_last_mapped );
  247.     }
  248.     if ( ev -> window == menu -> parent ) {
  249. #ifdef DEBUG
  250.         ( void ) fprintf ( stderr, "\t Leave environnement... pas sur.\n" );
  251.         ( void ) fprintf ( stderr, "x = %d y = %d", ev -> x, ev -> y );
  252. #endif
  253.         XGetWindowAttributes ( display, menu -> parent, &att );
  254. #ifdef DEBUG
  255.     ( void ) fprintf ( stderr, "width = %d height = %d",  att.width, att.height );
  256. #endif
  257.         if ( ev -> x < NULL || ev -> y < NULL
  258.             || ev -> x > att.width || ev -> y > att.height )
  259.                 *p_in = False;
  260.     }
  261. }
  262.  
  263.  
  264. /*
  265. **    Function name : HandleEnterMenu
  266. **
  267. **    Description : Traite les evenements EnterNotify pendant
  268. **        le ButtonPress et gere l'affichage des menus.
  269. **
  270. **    Input : Le display, l'evenement, le menu courant, 
  271. **        le contexte courant ( quel menu et quel item sont mappes ),
  272. **        un flag qui indique si on est ou non dans la fenetre courante.
  273. **    Ouput :
  274. */
  275. static void HandleEnterMenu ( display, ev, menu, sw, p_in )
  276.     Display *display;
  277.     XEnterWindowEvent  *ev;
  278.     XYMenu    *menu;
  279.     SWindow    *sw;
  280.     int *p_in;
  281. {
  282.     register int i;
  283. #ifdef DEBUG
  284.     (void) fprintf ( stderr, "HandleEnter w = %d\n", ev -> window );
  285. #endif
  286.     /*
  287.      * On verifie que le pointer est sur les menus courants.
  288.      */
  289.     *p_in = False;
  290.     for ( i=0;i<MAX_MENUS;i++ ) {
  291.            if ( ev -> window == menu -> w_title [i] ) {
  292.                   *p_in = True;
  293.               break;
  294.            }
  295.     }
  296.     for ( i=0;i<MAX_ITEMS;i++ ) {
  297.            if ( *p_in == True ) break;
  298.            if ( ev -> window ==
  299.                   menu -> vmenu [ menu -> n_last_mapped ] -> w_item [i] ) {
  300.                   *p_in = True;
  301.               break;
  302.            }
  303.     }           
  304.     if ( ev -> mode == NotifyGrab || *p_in == False )
  305.             return;
  306.     if ( XFindContext ( display, ev -> window, SwContext, (caddr_t *) &sw ) != NULL ) {
  307. #ifdef DEBUG
  308.         ( void ) fprintf ( stderr, "HandleEnter XFind default\n" );
  309. #endif
  310.     }
  311.     switch ( sw -> type ) {
  312.         case MENU :
  313.             if ( menu -> n_last_mapped != sw -> no_m ) 
  314.                 show_menu ( display, menu, sw -> no_m );
  315.                 break;
  316.         case ITEM :
  317.             show_item ( display, menu, sw -> no_i, sw -> no_m );
  318.             break;
  319.         default:
  320. #ifdef DEBUG
  321.             (void ) fprintf ( stderr,"HandleEnter CaseDefault\n" );
  322. #endif
  323.             break;
  324.     }
  325.     return;
  326. }
  327.  
  328.  
  329. /*
  330. **    Function name : clear_item
  331. **
  332. **    Description : Efface l'item allume du menu n.
  333. **
  334. **    Input : Le display, le menu courant et son numero.
  335. **    Ouput :
  336. */
  337. static void clear_item ( display, menu, n )
  338.     Display    *display;
  339.     XYMenu    *menu;
  340.     register int n;
  341. {
  342.     if  ( menu -> w_last_item == NULL ) return;
  343.     if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
  344.         XFillRectangle ( display,
  345.             menu -> w_last_item,
  346.             menu -> Igc,
  347.             0 + menu -> width_relief,
  348.             0 + menu -> width_relief,
  349.             menu -> vmenu [n] -> width - ( 2 * menu -> width_relief ) - 6,
  350.             menu -> h_item - ( 2 * menu -> width_relief ));
  351.     else
  352.         Display3D ( display, menu -> w_last_item,
  353.             menu -> top_sh, menu -> bot_sh,
  354.             menu -> width_relief,
  355.             DEPTH_UP );
  356.  
  357.     menu -> w_last_item = NULL;
  358.     menu -> n_last_item = -1;
  359. }
  360.  
  361.  
  362. /*
  363. **    Function name : show_item
  364. **
  365. **    Description : Affiche l' item i du menu n.
  366. **
  367. **    Input : Le display, le menu courant, l'item et le no du menu.
  368. **    Ouput :
  369. */
  370. static void show_item ( display, menu, i, n )
  371.     Display    *display;
  372.     XYMenu    *menu;
  373.     register int i, n;
  374. {
  375.      if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
  376.         XFillRectangle ( display,
  377.             menu -> vmenu [n] -> w_item [i],
  378.             menu -> Igc,
  379.             0 + menu -> width_relief,
  380.             0 + menu -> width_relief,
  381.             menu -> vmenu [n] -> width - ( 2 * menu -> width_relief ) - 6,
  382.             menu -> h_item - ( 2 * menu -> width_relief )) ;
  383.     else
  384.         Display3D ( display, menu -> vmenu [n] -> w_item [i],
  385.             menu -> top_sh, menu -> bot_sh,
  386.             menu -> width_relief,
  387.             DEPTH_DOWN );
  388.  
  389.     if ( menu -> w_last_item != NULL )
  390.         if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
  391.             XFillRectangle ( display,
  392.                 menu -> w_last_item,
  393.                 menu -> Igc,
  394.                 0 + menu -> width_relief,
  395.                 0 + menu -> width_relief,
  396.                 menu -> vmenu [n] -> width - ( 2 * menu -> width_relief ) - 6,
  397.                 menu -> h_item - ( 2 * menu -> width_relief ));
  398.       else
  399.         Display3D ( display, menu -> w_last_item,
  400.             menu -> top_sh, menu -> bot_sh,
  401.             menu -> width_relief,
  402.             DEPTH_UP );
  403.  
  404.     menu -> w_last_item = menu -> vmenu [n] -> w_item [i];
  405.     menu -> n_last_item = i;
  406. }
  407.  
  408.  
  409. /*
  410. **    Function name : clear_menu
  411. **
  412. **    Description : Efface le menu n.
  413. **
  414. **    Input : Le display, le menu courant, son numero.
  415. **    Ouput :
  416. */
  417. static void clear_menu ( display, menu, n )
  418.     Display    *display;
  419.     XYMenu    *menu;
  420.     register int n;
  421. {
  422.      if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
  423.         XFillRectangle ( display, menu->w_title [n], menu->Igc,
  424.             0 + menu -> width_relief,
  425.             0 + menu -> width_relief,
  426.             menu->title_width [n] - ( 2 * menu -> width_relief ),
  427.             menu -> h_item - ( 2 * menu -> width_relief ));
  428. #ifdef SHADOW
  429.     XUnmapWindow  ( display, menu->vmenu [n] -> trans );
  430. #else
  431.     XUnmapWindow  ( display, menu->vmenu [n]->v_frame );
  432. #endif
  433.     menu -> mapped = NULL;
  434.     menu -> w_last_item = NULL;
  435.     menu -> n_last_item = -1;
  436.     menu -> n_last_unmapped = n;
  437.     XFlush ( display );
  438. }
  439.  
  440. /*
  441. **    Function name : show_menu
  442. **
  443. **    Description : Affiche le menu n.
  444. **
  445. **    Input : Le Dispaly, le contexte de menu et le numero du menu.
  446. **    Ouput :
  447. */
  448. static void show_menu ( display, menu, n )
  449.     Display    *display;
  450.     XYMenu    *menu;
  451.     register int n;
  452. {
  453.     register int last = menu -> n_last_mapped;
  454.  
  455.     if ( menu -> mapped != NULL ) {
  456.         clear_menu ( display, menu, last );
  457.         menu -> w_last_item = NULL;
  458.         menu -> n_last_item = -1;
  459.     }
  460. #ifdef DEBUG
  461.     (void) fprintf ( stderr, "Show_menu : Menu : %d, width = %d\n",
  462.         n, menu -> title_width [n] );
  463. #endif
  464.     if ( DefaultDepth ( display, DefaultScreen ( display )) == 1 )
  465.         XFillRectangle ( display, menu -> w_title [n],
  466.             menu -> Igc,
  467.             0 + menu -> width_relief,
  468.             0 + menu -> width_relief,
  469.             menu -> title_width [n] - ( 2 * menu -> width_relief ),
  470.             menu -> h_item - ( 2 * menu -> width_relief ));
  471.  
  472.     if ( DoesSaveUnders ( DefaultScreenOfDisplay ( display )) != True ) {
  473.         if ( menu -> save_ok == NULL ) {
  474.             XCopyArea ( display, menu -> w_under,
  475.                 menu -> save, menu -> Ugc,
  476.                 0, 0,menu -> pix_width,
  477. #ifdef SHADOW
  478.                 menu -> hmax_menu + SHAD + 10,
  479. #else
  480.                 menu -> hmax_menu + 10,
  481. #endif
  482.                 0, 0 );
  483.             menu -> save_ok = 1; /* La pixmap est pleine */
  484.         }
  485.     }
  486. #ifdef SHADOW
  487.     XMapRaised ( display, menu->vmenu [n] -> trans );
  488. #else
  489.     XMapRaised ( display, menu->vmenu [n]->v_frame );
  490. #endif
  491. #ifdef SHADOW
  492.     menu->mapped = menu->vmenu [n] -> trans;
  493. #else
  494.     menu->mapped = menu->vmenu [n] -> v_frame;
  495. #endif
  496.     menu -> n_last_mapped = n;
  497. }
  498.  
  499.  
  500.