home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / sys / mac / mactopl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-24  |  8.7 KB  |  468 lines

  1. /*    SCCS Id: @(#)mactopl.c    3.1    91/07/23
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include <Dialogs.h>
  7. #include <OSUtils.h>
  8. #include <Packages.h>
  9.  
  10. // int NDECL(mac_doprev_message);
  11. // char FDECL(yn_function,(const char *, const char *, CHAR_P));
  12.  
  13. int FDECL ( try_key_queue , ( char * ) ) ;
  14.  
  15. extern void SetFrameItem ( DialogPtr , short , short ) ;
  16. extern void FlashButton ( DialogPtr , short ) ;
  17.  
  18. extern char * PtoCstr ( unsigned char * ) ;
  19. extern unsigned char * CtoPstr ( char * ) ;
  20.  
  21. void FDECL ( enter_topl_mode , ( char * ) ) ;
  22. void FDECL ( leave_topl_mode , ( char * ) ) ;
  23. void FDECL ( topl_set_resp , ( char * , char ) ) ;
  24.  
  25. extern winid inSelect ;
  26. extern short frame_corner ;
  27.  
  28. int
  29. mac_doprev_message(void)
  30. {
  31.     NhWindow * aWin = & theWindows [ WIN_MESSAGE ] ;
  32.     char * start , * stop ;
  33.  
  34.     if ( ! WIN_MESSAGE )
  35.         return 0 ;
  36.  
  37.     stop = * aWin -> windowText ;
  38.     start = * aWin -> windowText + aWin -> textBase - 2 ;
  39.  
  40.     while ( start > stop && * start != 10 && * start != 13 )
  41.         start -- ;
  42.  
  43.     if ( start <= stop )
  44.         aWin -> textBase = 0L ;
  45.     else
  46.         aWin -> textBase = start - stop + 1 ;
  47.     if ( aWin -> textBase > aWin -> windowTextLen )
  48.         aWin -> textBase = aWin -> windowTextLen ;
  49.  
  50.     display_nhwindow ( WIN_MESSAGE , FALSE ) ;
  51.     InvalRect ( & ( aWin -> theWindow -> portRect ) ) ;
  52.  
  53.     return 0 ;
  54. }
  55.  
  56.  
  57. char
  58. queued_resp(char *resp)
  59. {
  60.     char buf[30];
  61.     if (try_key_queue(&buf)) {
  62.         if (!resp || strchr(resp, buf[0]))
  63.             return buf[0];
  64.         if (digit(buf[0]) && strchr(resp, '#')) {
  65.             yn_number = atoi(buf);
  66.             return '#';
  67.         }
  68.     }
  69.     return '\0';
  70. }
  71.  
  72.  
  73. #define YN_DLOG 133
  74. #define YNQ_DLOG 134
  75. #define YNAQ_DLOG 135
  76. #define YNNAQ_DLOG 136
  77.  
  78. static int yn_user_item [ ] = { 5 , 6 , 7 , 8 } ;
  79. static short gEnterItem , gEscItem ;
  80. static const char * gRespStr = NULL ;
  81. static char gDef = 0 ;
  82. static short dlogID ;
  83.  
  84.  
  85. static void
  86. SetEnterItem ( DialogPtr dp , const short newEnterItem )
  87. {
  88.     short kind ;
  89.     Handle item ;
  90.     Rect r , r2 ;
  91.  
  92.     if ( gEnterItem != newEnterItem ) {
  93.  
  94.         GetDItem ( dp , gEnterItem , & kind , & item , & r2 ) ;
  95.         InsetRect ( & r2 , - 4 , - 4 ) ;
  96.         EraseRect ( & r2 ) ;
  97.         InvalRect ( & r2 ) ;
  98.  
  99.         gEnterItem = newEnterItem ;
  100.  
  101.         GetDItem ( dp , newEnterItem , & kind , & item , & r2 ) ;
  102.         frame_corner = kind == ctrlItem + btnCtrl ? 16 : 0 ;
  103.         InsetRect ( & r2 , - 4 , - 4 ) ;
  104.         InvalRect ( & r2 ) ;
  105.         r = r2 ;
  106.         GetDItem ( dp , yn_user_item [ dlogID - YN_DLOG ] , & kind , & item , & r2 ) ;
  107.         SetDItem ( dp , yn_user_item [ dlogID - YN_DLOG ] , kind , item , & r ) ;
  108.     }
  109. }
  110.  
  111.  
  112. static void
  113. do_tabbing ( DialogPtr dp )
  114. {
  115.     SetEnterItem(dp, gEnterItem == 1 ? strlen(gRespStr) : gEnterItem - 1);
  116. }
  117.  
  118.  
  119. static void
  120. set_yn_number(DialogPtr dp)
  121. {
  122.     if (gRespStr && gRespStr[gEnterItem-1] == '#') {
  123.         short k;
  124.         Handle h;
  125.         Rect r;
  126.         Str255 s;
  127.         GetDItem(dp, gEnterItem, &k, &h, &r);
  128.         GetIText(h, s);
  129.         if (s[0])
  130.             StringToNum(s, &yn_number);
  131.     }
  132. }
  133.  
  134.  
  135. pascal Boolean
  136. YNAQFilter ( DialogPtr dp , EventRecord * ev , short * itemHit )
  137. {
  138.     unsigned char code ;
  139.     char ch ;
  140.     char * re = gRespStr ;
  141.  
  142.     if ( ev -> what != keyDown ) {
  143.  
  144.         return 0 ;
  145.     }
  146.     code = ( ev -> message & 0xff00 ) >> 8 ;
  147.     ch = ev -> message & 0xff ;
  148.  
  149.     switch ( code ) {
  150.  
  151.     case 0x24 :
  152.     case 0x4c :
  153.         set_yn_number ( dp ) ;
  154.         * itemHit = gEnterItem ;
  155.         FlashButton ( dp , * itemHit ) ;
  156.         return 1 ;
  157.  
  158.     case 0x35 :
  159.     case 0x47 :
  160.         * itemHit = gEscItem ;
  161.         FlashButton ( dp , * itemHit ) ;
  162.         return 1 ;
  163.  
  164.     case 0x30 :
  165.         do_tabbing ( dp ) ;
  166.         return 0 ;
  167.     }
  168.     switch ( ch ) {
  169.  
  170.     case '\r' :
  171.     case '\n' :
  172.     case ' ' :
  173.     case 3 :
  174.         set_yn_number ( dp ) ;
  175.         * itemHit = gEnterItem ;
  176.         FlashButton ( dp , * itemHit ) ;
  177.         return 1 ;
  178.  
  179.     case 9 :
  180.         do_tabbing ( dp ) ;
  181.         return 0 ;
  182.  
  183.     case 27 :
  184.         * itemHit = gEscItem ;
  185.         FlashButton ( dp , * itemHit ) ;
  186.         return 1 ;
  187.  
  188.     case CHAR_BS :
  189.     case 28 : case 29 : case 30 : case 31 : /* the four arrow keys */
  190.     case '0' : case '1' : case '2' : case '3' : case '4' :
  191.     case '5' : case '6' : case '7' : case '8' : case '9' :
  192.     {    char * loc = strchr ( gRespStr , '#' ) ;
  193.         if ( loc ) {
  194.             SetEnterItem( dp , loc - gRespStr + 1 ) ;
  195.             return 0; /* Dialog Manager will then put this key into the text field. */
  196.         }
  197.     }
  198.     }
  199.  
  200.     while ( * re ) {
  201.  
  202.         if ( * re == ch ) {
  203.  
  204.             * itemHit = ( re - gRespStr ) + 1 ;
  205.             FlashButton ( dp , * itemHit ) ;
  206.             return 1 ;
  207.         }
  208.         re ++ ;
  209.     }
  210.  
  211.     nhbell ( ) ;
  212.     ev -> what = nullEvent ;
  213.     return 0 ;
  214. }
  215.  
  216.  
  217. static char
  218. do_question_dialog ( char * query , int dlog , int defbut , char * resp )
  219. {
  220.     Str255 p ;
  221.     DialogPtr dp ;
  222.     short item ;
  223.  
  224.     char c = queued_resp ( resp ) ;
  225.     if ( c )
  226.         return c ;
  227.  
  228.     dlogID = dlog ;
  229.     strcpy ( p , query ) ;
  230.     ParamText ( CtoPstr ( p ) , NULL , NULL , NULL ) ;
  231.     dp = mv_get_new_dialog ( dlog ) ;
  232.     if ( ! dp ) {
  233.  
  234.         return 0 ;
  235.     }
  236.     SetPort ( dp ) ;
  237.     ShowWindow ( dp ) ;
  238.  
  239.     gEscItem = strlen ( resp ) ;
  240.     gEnterItem = defbut ;
  241.     gRespStr = resp ;
  242.  
  243.     SetFrameItem ( dp , yn_user_item [ dlogID - YN_DLOG ] , gEnterItem ) ;
  244.  
  245.     InitCursor ( ) ;
  246.     mv_modal_dialog ( YNAQFilter , & item ) ;
  247.     mv_close_dialog ( dp ) ;
  248.     return resp [ item - 1 ] ;
  249. }
  250.  
  251.  
  252. pascal Boolean
  253. OneCharDLOGFilter ( DialogPtr dp , EventRecord * ev , short * item )
  254. {
  255.     char ch ;
  256.     short k ;
  257.     Handle h ;
  258.     Rect r ;
  259.     unsigned char com [ 2 ] ;
  260.  
  261.     if ( ev -> what != keyDown ) {
  262.  
  263.         return 0 ;
  264.     }
  265.     ch = ev -> message & 0xff ;
  266.  
  267.     com [ 0 ] = 1 ;
  268.     com [ 1 ] = ch ;
  269.  
  270.     if ( ch == 27 ) {
  271.  
  272.         GetDItem ( dp , 4 , & k , & h , & r ) ;
  273.         SetIText ( h , com ) ;
  274.         * item = 2 ;
  275.         FlashButton ( dp , 2 ) ;
  276.         return 1 ;
  277.     }
  278.     if ( ! gRespStr || strchr ( gRespStr , ch ) ) {
  279.  
  280.         GetDItem ( dp , 4 , & k , & h , & r ) ;
  281.         SetIText ( h , com ) ;
  282.         * item = 1 ;
  283.         FlashButton ( dp , 1 ) ;
  284.         return 1 ;
  285.     }
  286.     if ( ch == 10 || ch == 13 || ch == 3 || ch == 32 ) {
  287.  
  288.         com [ 1 ] = gDef ;
  289.         GetDItem ( dp , 4 , & k , & h , & r ) ;
  290.         SetIText ( h , com ) ;
  291.         * item = 1 ;
  292.         FlashButton ( dp , 1 ) ;
  293.         return 1 ;
  294.     }
  295.     if ( ch > 32 && ch < 127 ) {
  296.  
  297.         GetDItem ( dp , 4 , & k , & h , & r ) ;
  298.         SetIText ( h , com ) ;
  299.         * item = 1 ;
  300.         FlashButton ( dp , 1 ) ;
  301.         return 1 ;
  302.     }
  303.     nhbell ( ) ;
  304.     ev -> what = nullEvent ;
  305.     return 1 ;
  306. }
  307.  
  308.  
  309. static char
  310. generic_yn_function ( query , resp , def )
  311. const char * query , * resp ;
  312. char def ;
  313. {
  314.     DialogPtr dp ;
  315.     short k , item ;
  316.     Handle h ;
  317.     Rect r ;
  318.     unsigned char com [ 32 ] = { 1 , 27 } ; // margin for getitext
  319.     Str255 pQuery ;
  320.  
  321.     char c = queued_resp ( resp ) ;
  322.     if ( c )
  323.         return c ;
  324.  
  325.     dp = mv_get_new_dialog ( 137 ) ;
  326.     if ( ! dp ) {
  327.  
  328.         return 0 ;
  329.     }
  330.     SetPort ( dp ) ;
  331.     ShowWindow ( dp ) ;
  332.     InitCursor ( ) ;
  333.     SetFrameItem ( dp , 6 , 1 ) ;
  334.     if ( def ) {
  335.  
  336.         com [ 1 ] = def ;
  337.     }
  338.     strcpy ( ( char * ) pQuery , query ) ;
  339.     if ( resp && * resp ) {
  340.  
  341.         strcat ( ( char * ) pQuery , " (" ) ;
  342.         strcat ( ( char * ) pQuery , resp ) ;
  343.         strcat ( ( char * ) pQuery , ")" ) ;
  344.     }
  345.     ParamText ( CtoPstr ( pQuery ) , NULL , NULL , NULL ) ;
  346.     GetDItem ( dp , 4 , & k , & h , & r ) ;
  347.     SetIText ( h , com ) ;
  348.     SelIText ( dp , 4 , 0 , 0x7fff ) ;
  349.     InitCursor ( ) ;
  350.     SetFrameItem ( dp , 6 , 1 ) ;
  351.     gRespStr = resp ;
  352.     gDef = def ;
  353.     do {
  354.  
  355.         mv_modal_dialog ( OneCharDLOGFilter , & item ) ;
  356.  
  357.     } while ( item != 1 && item != 2 ) ;
  358.     GetIText ( h , com ) ;
  359.  
  360.     mv_close_dialog ( dp ) ;
  361.     if ( item == 2 || ! com [ 0 ] ) {
  362.  
  363.         return 27 ; // escape
  364.     }
  365.     return com [ 1 ] ;
  366. }
  367.  
  368.  
  369. static char
  370. ynaq_dialog ( query , resp , def )
  371. const char * query , * resp ;
  372. char def ;
  373. {
  374.     int dia = 0 ;
  375.  
  376.     if ( resp ) {
  377.  
  378.         if ( ! strcmp ( resp , ynchars ) ) {
  379.  
  380.             dia = YN_DLOG ;
  381.         }
  382.         if ( ! strcmp ( resp , ynqchars ) ) {
  383.  
  384.             dia = YNQ_DLOG ;
  385.         }
  386.         if ( ! strcmp ( resp , ynaqchars ) ) {
  387.  
  388.             dia = YNAQ_DLOG ;
  389.         }
  390.         if ( ! strcmp ( resp , ynNaqchars ) ) {
  391.  
  392.             dia = YNNAQ_DLOG ;
  393.         }
  394.     }
  395.     if ( ! dia ) {
  396.  
  397.         return generic_yn_function ( query , resp , def ) ;
  398.     }
  399.  
  400.     return do_question_dialog ( query , dia ,
  401.         ( strchr ( resp , def ) - resp ) + 1 , resp ) ;
  402. }
  403.  
  404.  
  405. char
  406. topl_yn_function(query,resp, def)
  407. const char *query,*resp;
  408. char def;
  409. {
  410.     char buf[30];
  411.     char c = queued_resp(resp);
  412.     if (!c) {
  413.         enter_topl_mode(query);
  414.         topl_set_resp(resp, def);
  415.  
  416.         do {
  417.             c = nhgetch();
  418.             if (c && resp && !strchr(resp, c)) {
  419.                 nhbell();
  420.                 c = '\0';
  421.             }
  422.         } while (!c);
  423.  
  424.         topl_set_resp("", '\0');
  425.         leave_topl_mode(&buf);
  426.         if (c == '#')
  427.             yn_number = atoi(buf);
  428.     }
  429.     return c;
  430. }
  431.  
  432.  
  433. char
  434. popup_yn_function(query,resp, def)
  435. const char *query,*resp;
  436. char def;
  437. {
  438.     char ch [ 2 ] ;
  439.  
  440.     if ( ch [ 0 ] = ynaq_dialog ( query , resp , def ) ) {
  441.  
  442.         return ch [ 0 ] ;
  443.     }
  444.  
  445.     return topl_yn_function(query, resp, def);
  446. }
  447.  
  448.  
  449. char
  450. mac_yn_function(query,resp, def)
  451. const char *query,*resp;
  452. char def;
  453. /*
  454.  *   Generic yes/no function. 'def' is the default (returned by space or
  455.  *   return; 'esc' returns 'q', or 'n', or the default, depending on
  456.  *   what's in the string. The 'query' string is printed before the user
  457.  *   is asked about the string.
  458.  *   If resp is NULL, any single character is accepted and returned.
  459.  */
  460. {
  461.     if (flags.popup_dialog)
  462.         return popup_yn_function(query, resp, def);
  463.     else
  464.         return topl_yn_function(query, resp, def);
  465. }
  466.  
  467. /*topl.c*/
  468.