home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / opndor / ex_chat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-26  |  15.3 KB  |  347 lines

  1. /* EX_CHAT.C - Example of a multi-window full-screen chat program written    */
  2. /*             with OpenDoors. See manual for instructions on how to compile */
  3. /*             a program using OpenDoors.                                    */
  4. /*                                                                           */
  5. /*             This program shows how to do the following:                   */
  6. /*                                                                           */
  7. /*                - Replace the standard OpenDoors chat mode with your own   */
  8. /*                  chat mode implementation. See instructions below.        */
  9. /*                - How to scroll a portion of the screen, leaving the rest  */
  10. /*                  of the screen unaltered.                                 */
  11. /*                - How to determine whether input came from the local or    */
  12. /*                  remote keyboard.                                         */
  13. /*                - How to display a popup window with a message in it when  */
  14. /*                  the sysop shells to DOS. (DOS version only.)             */
  15. /*                - How to save and restore the entire contents of the       */
  16. /*                  screen.                                                  */
  17. /*                                                                           */
  18. /*             Conditional compilation directives allow this program to      */
  19. /*             be compiled as a stand-alone chat door, or as a               */
  20. /*             replacement chat mode to be integrated into any OpenDoors     */
  21. /*             program. If STANDALONE is #defined, ex_chat.c will be         */
  22. /*             compiled as a split-screen chat door that can be run like     */
  23. /*             any door program. If STANDALONE is not #defined, the chat     */
  24. /*             mode function will be compiled as a replacement chat mode     */
  25. /*             for the chat mode built into OpenDoors. In this case,  the    */
  26. /*             demo mainline function simply displays a prompt, and will     */
  27. /*             exit the door as soon as you press the [ENTER] key. While     */
  28. /*             the program is running, if you invoke chat mode (press        */
  29. /*             [ALT]-[C]), the current screen will be saved and the          */
  30. /*             split-screen chat mode will be activated. When you press      */
  31. /*             [ESC] the split-screen chat mode will end, and the            */
  32. /*             original screen will be restored. To integrate this chat      */
  33. /*             mode into your own program, you should simply set             */
  34. /*             od_control.od_cbefore_chat to point to the                    */
  35. /*             fullscreen_chat function, as shown, and remove the mainline   */
  36. /*             (main()/WinMain()) function from this file. The compile this  */
  37. /*             file into your program after removing the #define STANDALONE  */
  38. /*             line.                                                         */
  39.  
  40. /* Include required header files. */
  41. #include "opendoor.h"
  42. #include <string.h>
  43.  
  44.  
  45. /* The following #define forces this code to compile as a stand-alone door */
  46. /* program. If you wish to use this code to replace the standard OpenDoors */
  47. /* chat mode in your own program, remove this #define.                     */
  48. #define STANDALONE
  49.  
  50.  
  51. /* Full-screen chat function prototypes. */
  52. void fullscreen_chat(void);
  53. void chat_new_line(void);
  54. void display_shell_window(void);
  55. void remove_shell_window(void);
  56.  
  57.  
  58.  
  59. /* The main() or WinMain() function: program execution begins here. */
  60. #ifdef ODPLAT_WIN32
  61. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  62.    LPSTR lpszCmdLine, int nCmdShow)
  63. #else
  64. int main(int argc, char *argv[])
  65. #endif
  66. {
  67.    /* Handle standard command-line options and perform other needed setup. */
  68. #ifdef ODPLAT_WIN32
  69.    od_control.od_cmd_show = nCmdShow;
  70.    od_parse_cmd_line(lpszCmdLine);
  71. #else
  72.    od_parse_cmd_line(argc, argv);
  73. #endif
  74.  
  75. #ifdef STANDALONE               /* If compiled as a stand-alone chat program */
  76.    od_init();                                        /* Initialize OpenDoors */
  77.  
  78.    fullscreen_chat();                    /* Invoke full-screen chat function */
  79.  
  80. #else                  /* If compiled as replacement for OpenDoors chat mode */
  81.                       /* Setup OpenDoors to use our custom chat mode instead */
  82.    od_control.od_cbefore_chat=fullscreen_chat;
  83.  
  84.    od_printf("Press [Enter] to exit door, or invoke chat mode.\n\r");
  85.    od_get_answer("\n\r");
  86. #endif
  87.  
  88.    od_exit(0, FALSE);                                       /* Exit program. */
  89.    return(0);                                                   
  90. }
  91.  
  92.  
  93.  
  94.  
  95.  
  96.                                    /* FULL-SCREEN CHAT CUSTOMIZATION OPTIONS */
  97.  
  98. char window_colour[2]={0x0b,0x0c};       /* Text colour used for each person */
  99. char bar_colour=0x70;                     /* Colour of window seperation bar */
  100. char top_line[2]={13,1};      /* Specifies location of each window on screen */
  101. char bottom_line[2]={23,11};         /* Line number of bottom of each window */
  102. char bar_line=12;                    /* Line number of window seperation bar */
  103. char scroll_distance=2;           /* Distance to scroll window when required */
  104. char shell_window_title=0x1a;  /* Colour of title of DOS shell notice window */
  105. char shell_window_boarder=0x1f;        /* Colour of DOS shell window boarder */
  106. char shell_window_text=0x1b;           /* Colour of text in DOS shell window */
  107.  
  108.  
  109.  
  110. char cursor_window;                   /* FULL-SCREEN CHAT INTERNAL VARIABLES */
  111. char current_word[2][81];
  112. int word_length[2];
  113. int cursor_col[2];
  114. int cursor_line[2];
  115. unsigned char key;
  116. int old_chat_key;
  117. void *shell_window;
  118. char *before_shell_text;
  119. char *after_shell_text;
  120. #ifndef STANDALONE     /* If compiled as replacement for OpenDoors chat mode */
  121. char screen_buffer[4004];
  122. #endif
  123.  
  124.                                                 /* FULL-SCREEN CHAT FUNCTION */
  125. void fullscreen_chat(void)
  126. {
  127.    cursor_window=0;                               /* Reset working variables */
  128.    word_length[0]=word_length[1]=0;
  129.    cursor_col[0]=cursor_col[1]=1;
  130.    cursor_line[0]=top_line[0];
  131.    cursor_line[1]=top_line[1];
  132.  
  133.  
  134.                          /* If ANSI or AVATAR graphics mode is not available */
  135.    if(!od_control.user_ansi && !od_control.user_avatar)
  136.    {                           /* Then use OpenDoor's line chat mode instead */
  137. #ifdef STANDALONE               /* If compiled as a stand-alone chat program */
  138.       od_chat();
  139. #endif
  140.       return;
  141.    }
  142.  
  143.    od_control.od_cbefore_shell=display_shell_window;   /* Set shell settings */
  144.    od_control.od_cafter_shell=remove_shell_window;
  145.    before_shell_text=od_control.od_before_shell;
  146.    after_shell_text=od_control.od_after_shell;
  147.    od_control.od_before_shell=NULL;
  148.    od_control.od_after_shell=NULL;
  149.    od_control.od_chat_active=TRUE;
  150.  
  151. #ifdef STANDALONE               /* If compiled as a stand-alone chat program */
  152.    old_chat_key=od_control.key_chat;      /* Prevent internal chat mode from */
  153.    od_control.key_chat=0;                                   /* being invoked */
  154.  
  155. #else                  /* If compiled as replacement for OpenDoors chat mode */
  156.    od_save_screen(screen_buffer);           /* Save current screen contents. */
  157. #endif
  158.  
  159.                                                      /* DRAW THE CHAT SCREEN */
  160.    od_set_attrib(window_colour[0]);
  161.    od_clr_scr();                                         /* Clear the screen */
  162.  
  163.    od_set_cursor(bar_line,1);                  /* Draw window separation bar */
  164.    od_set_attrib(bar_colour);
  165.    od_clr_line();
  166.    od_set_cursor(bar_line,67);
  167.    od_printf("Ctrl-A: Clear");
  168.    od_set_cursor(bar_line,1);
  169.    od_printf(" Top : %-.28s    Bottom : %-.28s    ",
  170.       od_control.sysop_name, od_control.user_name);
  171.  
  172.    od_set_cursor(top_line[0],1);    /* Locate cursor where typing will begin */
  173.    od_set_attrib(window_colour[0]);           /* Set appropriate text colour */
  174.  
  175.                                                            /* MAIN CHAT LOOP */
  176.    for(;;)                             /* (Repeats for each character typed) */
  177.    {
  178.       do
  179.       {
  180.          key=(char)od_get_key(FALSE);    /* Get next keystroke from keyboard */
  181.  
  182.                                                     /* CHECK FOR SYSOP ABORT */
  183.          if((key==27 && od_control.od_last_input==1) /* If sysop pressed ESC */
  184.             || !od_control.od_chat_active)
  185.          {
  186.             od_set_attrib(0x07);                     /* Reset display colour */
  187.             od_clr_scr();                                /* Clear the screen */
  188.  
  189.             od_control.od_cbefore_shell=NULL;  /* Restore DOS shell settings */
  190.             od_control.od_cafter_shell=NULL;
  191.             od_control.od_before_shell=before_shell_text;
  192.             od_control.od_after_shell=after_shell_text;
  193. #ifdef STANDALONE               /* If compiled as a stand-alone chat program */
  194.             od_control.key_chat=old_chat_key;/* Re-enable internal chat mode */
  195.  
  196. #else                  /* If compiled as replacement for OpenDoors chat mode */
  197.             od_control.od_chat_active=FALSE;           /* Turn off chat mode */
  198.             od_restore_screen(screen_buffer);      /* Restore orignal screen */
  199. #endif
  200.             return;                                 /* Exit full-screen chat */
  201.  
  202.          }
  203.       } while(key==0);
  204.  
  205.                                                      /* CHECK FOR NEW TYPIST */
  206.       if(od_control.od_last_input!=cursor_window)/* If new person typing now */
  207.       {                               /* Switch cursor to appropriate window */
  208.          cursor_window=od_control.od_last_input;       /* Set current typist */
  209.  
  210.                                                 /* Move cursor to new window */
  211.          od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
  212.  
  213.          od_set_attrib(window_colour[cursor_window]);  /* Change text colour */
  214.       }
  215.  
  216.  
  217.       if(key==13 || key==10)           /* IF USER PRESSED [ENTER] / [RETURN] */
  218.       {
  219.          word_length[cursor_window]=0;      /* Enter constitutes end of word */
  220.  
  221.          chat_new_line();                               /* Move to next line */
  222.       }
  223.  
  224.  
  225.       else if(key==8)                           /* IF USER PRESS [BACKSPACE] */
  226.       {
  227.          if(cursor_col[cursor_window] > 1)       /* If not at left of screen */
  228.          {
  229.             --cursor_col[cursor_window];    /* Move cursor back on character */
  230.             if(word_length[cursor_window] > 0) --word_length[cursor_window];
  231.             od_printf("\b \b");          /* Erase last character from screen */
  232.          }
  233.       }
  234.  
  235.  
  236.       else if(key==32)                            /* IF USER PRESSED [SPACE] */
  237.       {
  238.          word_length[cursor_window]=0;    /* [Space] constitutes end of word */
  239.  
  240.          if(cursor_col[cursor_window]==79)              /* If at end of line */
  241.             chat_new_line();                     /* Move cursor to next line */
  242.          else                                       /* If not at end of line */
  243.          {
  244.             ++cursor_col[cursor_window];        /* Increment cursor position */
  245.             od_putch(32);                                 /* Display a space */
  246.          }
  247.       }
  248.  
  249.  
  250.       else if(key==1)                    /* IF USER PRESSED CLEAR WINDOW KEY */
  251.       {                                               /* Clear user's window */
  252.          od_scroll(1,top_line[cursor_window],79,bottom_line[cursor_window],
  253.             bottom_line[cursor_window]-top_line[cursor_window]+1,0);
  254.  
  255.          word_length[cursor_window]=0;  /* We are no longer composing a word */
  256.  
  257.          cursor_col[cursor_window]=1;               /* Reset cursor position */
  258.          cursor_line[cursor_window]=top_line[cursor_window];
  259.          od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
  260.       }
  261.  
  262.  
  263.       else if(key>32)                 /* IF USER TYPED A PRINTABLE CHARACTER */
  264.       {                                    /* PERFORM WORD WRAP IF NECESSARY */
  265.          if(cursor_col[cursor_window]==79)    /* If cursor is at end of line */
  266.          {
  267.                                                /* If there is a word to wrap */
  268.             if(word_length[cursor_window]>0 && word_length[cursor_window]<78)
  269.             {
  270.                                          /* Move cursor to beginning of word */
  271.                od_set_cursor(cursor_line[cursor_window],
  272.                           cursor_col[cursor_window]-word_length[cursor_window]);
  273.  
  274.                od_clr_line();                /* Erase word from current line */
  275.  
  276.                chat_new_line();                  /* Move cursor to next line */
  277.  
  278.                                                            /* Redisplay word */
  279.                od_disp(current_word[cursor_window],word_length[cursor_window],
  280.                                                                           TRUE);
  281.                cursor_col[cursor_window]+=word_length[cursor_window];
  282.             }
  283.  
  284.             else                            /* If there is no word to "wrap" */
  285.             {
  286.                chat_new_line();                  /* Move cursor to next line */
  287.                word_length[cursor_window]=0;             /* Start a new word */
  288.             }
  289.          }
  290.  
  291.                                             /* ADD CHARACTER TO CURRENT WORD */
  292.                               /* If there is room for more character in word */
  293.          if(strlen(current_word[cursor_window])<79)     /* Add new character */
  294.             current_word[cursor_window][word_length[cursor_window]++]=key;
  295.  
  296.                                             /* DISPLAY NEWLY TYPED CHARACTER */
  297.          ++cursor_col[cursor_window];
  298.          od_putch(key);
  299.       }
  300.    }
  301. }
  302.  
  303.  
  304.  
  305.               /* FUNCTION USED BY FULL-SCREEN CHAT TO START A NEW INPUT LINE */
  306. void chat_new_line(void)
  307. {                                        /* If cursor is at bottom of window */
  308.    if(cursor_line[cursor_window]==bottom_line[cursor_window])
  309.    {                                  /* Scroll window up one line on screen */
  310.       od_scroll(1,top_line[cursor_window],79, bottom_line[cursor_window],
  311.                 scroll_distance, 0);
  312.       cursor_line[cursor_window]-=(scroll_distance - 1);
  313.    }
  314.  
  315.    else                              /* If cursor is not at bottom of window */
  316.    {
  317.       ++cursor_line[cursor_window];             /* Move cursor down one line */
  318.    }
  319.  
  320.                                          /* Move cursor's position on screen */
  321.    od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]=1);
  322.  
  323.    od_set_attrib(window_colour[cursor_window]);        /* Change text colour */
  324. }
  325.  
  326.  
  327. void display_shell_window(void)
  328. {
  329.    if((shell_window=od_window_create(17,9,63,15,"DOS Shell",
  330.                                      shell_window_boarder, shell_window_title, 
  331.                                      shell_window_text, 0))==NULL) return;
  332.  
  333.    od_set_attrib(shell_window_text);
  334.    od_set_cursor(11,26);
  335.    od_printf("The Sysop has shelled to DOS");
  336.    od_set_cursor(13,21);
  337.    od_printf("He/She will return in a few moments...");
  338. }
  339.  
  340.  
  341. void remove_shell_window(void)
  342. {
  343.    od_window_remove(shell_window);
  344.    od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
  345.    od_set_attrib(window_colour[cursor_window]);
  346. }
  347.