]> git.cworth.org Git - ttt/blobdiff - src/ttt-curses-client.c
Add a dependency of ttt-client.c on ttt-lex.h to fix the build.
[ttt] / src / ttt-curses-client.c
index b6e5981194b90d19380432198511da990eae243a..c8e42c58edee3525c6caaa5499c26ffd8fef7a58 100644 (file)
@@ -1,6 +1,6 @@
-/* ttt-client.c - client handling code for tic-tac-toe game server
+/*ttt-curses-client.c - curses based tic-tac-toe game client
  *
- * Copyright © 2005 Carl Worth
+ * Copyright © 2005 Bryan Worth
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Author: Bryan Worth <bryan@theworths.org> 
  */
 
-
 /* TODO: see /usr/share/doc/ncurses-devel-5.3/test/view.c for example code
  *      to handle window resizing
- *      
- *      add code to read username from config file or prompt user if config
- *      file does not exist. (username is currently hardcoded and needs
- *      changed before compiling)
  *
  */     
 
-
 #include "ttt-socket.h"
 #include <curses.h>
 #include <signal.h>
 
-static void finish(int sig);
+static void
+finish (int sig);
+
+void
+mvprintstr (int     y,
+           int     x,
+           char    *string,
+           chtype  attrs);
+
+void
+mvwprintstr (WINDOW *window,
+            int    y,
+            int    x,
+            char   *string,
+            chtype attrs);
 
-void mvprintstr(int, int, char *, chtype);
-void mvwprintstr(WINDOW *, int, int, char *, chtype);
-void wprint(WINDOW *, char *);
+void
+wprint (WINDOW *window,
+       char   *string);
+
+/*
+ *
+ */
 
-void mvprintstr(int y, int x, char *string, chtype attrs)
+void
+mvprintstr (int    y,
+           int    x,
+           char   *string,
+           chtype attrs)
 {
     int xx = 0;
     int l;
@@ -51,171 +67,355 @@ void mvprintstr(int y, int x, char *string, chtype attrs)
        xx++;
     }
     cline[l] = '\0';
-    mvaddchstr(y, x, cline);
+    mvaddchstr (y, x, cline);
 }
 
-
-void mvwprintstr(WINDOW * window, int y, int x, char *string, chtype attrs)
+void mvwprintstr (WINDOW *window,
+                 int    y,
+                 int    x,
+                 char   *string,
+                 chtype attrs)
 {
     int xx = 0;
     int l;
     chtype cline[1000];
-    l = strlen(string);
+    l = strlen (string);
     while (xx < l) {
        cline[xx] = string[xx] | attrs;
        xx++;
     }
     cline[l] = '\0';
-    mvwaddchstr(window, y, x, cline);
+    mvwaddchstr (window, y, x, cline);
 }
 
-
-void wprint(WINDOW * window, char *string)
+void wprint (WINDOW *window,
+            char   *string)
 {
     int xx = 0;
     int l;
     chtype outc;
-    l = strlen(string);
+    l = strlen (string);
 
     while (xx < l) {
        outc = string[xx];
-       if (string[xx] != '\r')
-           waddch(window, outc);
+       if (string[xx] != '\r') 
+           waddch (window, outc);
        xx++;
     }
 }
 
+void inpprint (WINDOW *window,char *string,int pos,int curx);
+
+void inpprint (WINDOW *window,char *string,int pos,int curx)
+{
+    int mx,my;
+    char tbuf[1024];
+    getmaxyx(window,my,mx);
+    if ( curx > 0 ) {
+       strncpy(tbuf,&string[curx], mx-1);
+       tbuf[mx-1]='\0';
+       wmove(window,0,0);
+       wprint(window,tbuf);
+       wclrtoeol(window);
+       wmove(window,0,pos - curx);
+       
+    }
+    else
+    {
+       strcpy(tbuf,string);
+       if (strlen(string) > mx-1) tbuf[mx-1]='\0';
+       wmove(window,0,0);
+       wprint(window,tbuf);
+       wclrtoeol(window);
+       wmove(window,0,pos);
+    }
+
+
+}
+
+
 
-char *message2;
-int _socket;
-size_t maxread;
 
+FILE *sockin, *sockout;
 
-int main(int argc, char **argv)
+
+int
+main (int argc, char **argv)
 {
-    char *message;
-    char buffer[1000];
-    char *host;
-    char *port;
+    char *host="localhost";
+    char *port="5334";
     chtype c;
-    ssize_t numread;
+    char *username;
+    char *envuser;
+    char *confpath;
+    char *conffile;
+    char *command_string;
+    int _socket;
+    char buffer[BUFSIZ];
+    char tlin[1024];
+    char inplin[1024];
+    ttt_status_t status;
+    int curpos = 0;
+    int curx = 0;
+    int mx, my;
 
     static WINDOW *mainwnd;
     static WINDOW *dispwin;
     static WINDOW *inpwin;
+    static WINDOW *statwin;
+    FILE *conf_file;
 
     mainwnd = initscr();
-    int dlines = LINES - 2, cols = COLS;
-
-    (void) nonl();
-    noecho();
-    cbreak();
-    nodelay(mainwnd, TRUE);
-    curs_set(0);
-    refresh();
-    dispwin = newwin(dlines - 1, cols - 2, 0, 0);
-    inpwin = newwin(1, cols - 2, dlines, 0);
-    keypad(mainwnd, TRUE);     // enable keyboard mapping 
-    keypad(inpwin, TRUE);      // enable keyboard mapping 
-    nodelay(inpwin, TRUE);
-    wrefresh(mainwnd);
-    wrefresh(dispwin);
-    wrefresh(inpwin);
-    (void) scrollok(mainwnd, TRUE);
-    (void) scrollok(dispwin, TRUE);
-    (void) scrollok(inpwin, TRUE);
-    (void) idlok(mainwnd, TRUE);
-    (void) idlok(dispwin, TRUE);
-    (void) idlok(inpwin, TRUE);
-    wsetscrreg(dispwin, 0, dlines - 2);
+    int dlines = LINES, cols = COLS;
+
+    (void) nonl ();
+    (void) nl ();
+    noecho ();
+    cbreak ();
+    nodelay (mainwnd, TRUE);
+    curs_set (0);
+    refresh ();
+    dispwin = newwin (dlines - 6, cols , 0, 0);
+    statwin = newwin (4, cols , dlines -4, 0);
+    inpwin = newwin (1, cols , dlines -1, 0);
+    keypad (mainwnd, TRUE);    // enable keyboard mapping 
+    keypad (inpwin, TRUE);     // enable keyboard mapping 
+    nodelay (inpwin, TRUE);
+    getmaxyx(inpwin,my,mx);
+    wrefresh (mainwnd);
+    wrefresh (dispwin);
+    wrefresh (statwin);
+    wrefresh (inpwin);
+    (void) scrollok (mainwnd, TRUE);
+    (void) scrollok (dispwin, TRUE);
+    (void) scrollok (statwin, TRUE);
+    (void) scrollok (inpwin, TRUE);
+    (void) idlok (mainwnd, TRUE);
+    (void) idlok (dispwin, TRUE);
+    (void) idlok (statwin, TRUE);
+    (void) idlok (inpwin, TRUE);
+    wsetscrreg (dispwin, 0, dlines - 2);
+    wsetscrreg (statwin, 0, 4);
     
-    (void) signal(SIGINT, finish);     /* arrange interrupts to terminate */
-    if (has_colors()) {
-       start_color();
-
-       init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
-       init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
-       init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);
-       init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
-       init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
-       init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
-       init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
-       init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
+    (void) signal (SIGINT, finish);    /* arrange interrupts to terminate */
+    if (has_colors ()) {
+       start_color ();
+
+       init_pair (COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
+       init_pair (COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
+       init_pair (COLOR_RED, COLOR_RED, COLOR_BLACK);
+       init_pair (COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
+       init_pair (COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
+       init_pair (COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
+       init_pair (COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
+       init_pair (COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
     }
-    wbkgd(dispwin, COLOR_PAIR(COLOR_WHITE));
-    wbkgd(inpwin, COLOR_PAIR(COLOR_CYAN));
-    wrefresh(dispwin);
-    wrefresh(inpwin);
-
-    xasprintf(&host, "localhost");
-    xasprintf(&port, "5334");
-    xasprintf(&message, "HELO bryan\r\n");
-
-    ttt_socket_create_client(host, port, &_socket);
-    ttt_socket_write(_socket, message, strlen(message));
-
-    maxread = 100;
-    numread = read(_socket, buffer, maxread);
-    if (numread > 0) {
-       buffer[numread] = '\0';
-       xasprintf(&message, "%s", buffer);
-       wprint(dispwin, message);
-       wrefresh(dispwin);
+    wrefresh (dispwin);
+    wrefresh (inpwin);
+
+    xasprintf(&confpath,"%s/.ttt/",getenv("HOME"));
+    xasprintf(&conffile,"%s/.ttt/client.conf",getenv("HOME"));
+    username="user";
+    if (access (conffile, F_OK) != 0 ) {
+       envuser=getenv("USER");
+       if (envuser != NULL) username=strdup(envuser);
+       if (access (confpath, F_OK) != 0 ) {
+           xasprintf(&command_string,"mkdir %s",confpath);
+           system (command_string);
+       }
+       if ((conf_file = fopen(conffile,"w")) != NULL) {
+           fprintf(conf_file,"username=%s",username);
+           fclose(conf_file);
+       }
     }
-    xasprintf(&message2, "MESSAGE \"");
-    while (1) {
-       curs_set(1);
-       c = wgetch(inpwin);
-       if (c != ERR) {
-           xasprintf(&message2, "%s%c", message2, (int) c);
-           waddch(inpwin, c);
-           wrefresh(inpwin);
+    if ((conf_file = fopen(conffile,"r")) != NULL) {
+        while (fgets(buffer,BUFSIZ,conf_file)) {
+           if (buffer[strlen(buffer)-1] == 10) buffer[strlen(buffer)-1] = '\0';
+           if (strncmp(buffer,"username=",9) == 0) {
+               xasprintf (&username, "%s", &buffer[9]);
+           }
+           if (strncmp(buffer,"port=",5) == 0) {
+               xasprintf (&port, "%s",&buffer[5]);
+           }
        }
+       fclose(conf_file); 
+    }
+    status=ttt_socket_create_client (host, port, &_socket);
+    if (status) {
+       endwin();
+       printf("Unable to connect to server! Connection status: %d\n",status);
+       exit(1);
+    }
+    sockin=fdopen(_socket,"r");
+    sockout=fdopen(_socket,"w");
+
+
 
-       numread = 0;
-       maxread = 100;
-       numread = read(_socket, buffer, maxread);
-       if (numread > 0) {
-           curs_set(0);
-           buffer[numread] = '\0';
-           wprint(dispwin, buffer);
-           wrefresh(dispwin);
-           wrefresh(inpwin);
+    fprintf(sockout, "HELO %s\r\n",username);
+    fflush(sockout);
+    
+    if (fgets(buffer,BUFSIZ,sockin)) {
+       if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
+           wprint (dispwin, buffer);
        }
-       if ((int) c == 13) {
-           curs_set(0);
-           xasprintf(&message2, "%s\"\r\n", message2);
-           ttt_socket_write(_socket, message2, strlen(message2));
-           xasprintf(&message2, "MESSAGE \"");
-           maxread = 100;
-           numread = read(_socket, buffer, maxread);
-           if (numread > 0) {
-               buffer[numread] = '\0';
-               wprint(dispwin, buffer);
-           }
-           wrefresh(dispwin);
-           werase(inpwin);
-           wrefresh(inpwin);
+       else {
+           if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
        }
+       wrefresh (dispwin);
+       wrefresh (statwin);
     }
+    
+    fprintf(sockout, "WHO \r\n");
+    fflush(sockout);
+    
+    inplin[0]='\0';
+    while (1) {
+       curs_set (1);
+       c = wgetch (inpwin);
+       if ((c != ERR) && (strlen(inplin)< 1000)) {
+           switch ((int) c) {
+           case 13:  // CARRIAGE RETURN
+               break;
+           case 10: // LINE FEED
+               break;
+           case 262: // HOME key
+               curpos = 0;
+               curx = 0;
+               inpprint(inpwin,inplin,curpos,curx);
+               wrefresh (inpwin);
+               break;       
+           case 360: // END key
+               curpos = strlen(inplin);
+               if (strlen(inplin) > mx -1) {
+                   curx = strlen(inplin) - mx +1;
+               }
+               else
+               {
+                   curx = 0;
+               }
+               inpprint(inpwin,inplin,curpos,curx);
+               wrefresh (inpwin);
+               break;
+           case 330: // DELETE key
+               if (strlen(inplin) > 0) {
+                   if (curpos == strlen(inplin)) {
+                       inplin[strlen(inplin)-1]='\0';
+                       curpos--;
+                   }
+                   else
+                   {
+                       strncpy(&inplin[curpos],&inplin[curpos+1],strlen(inplin)-curpos+1);
+                   }
 
 
+                   inpprint(inpwin,inplin,curpos,curx);
+                   wrefresh (inpwin);
+               }
+               break;          
+           case 263: //  }
+           case 8:   //   > Various BACKSPACE codes
+           case 127: //  }
+               if (curpos > 0) {
+                   if (curpos == strlen(inplin)) {
+                       inplin[strlen(inplin)-1]='\0';
+                   }
+                   else
+                   {
+                       strncpy(&inplin[curpos-1],&inplin[curpos],strlen(inplin)-curpos);
+                       inplin[strlen(inplin)-1]='\0';
+                   }
+                   if (curpos > 0) curpos--;
+                   if (curx > 0) curx--;
+                   inpprint(inpwin,inplin,curpos,curx);
+                   wrefresh (inpwin);
+               }
+               break;
+           case 260: // LEFT ARROW
+               if (curpos > 0) {
+                   curpos--;
+                   if (curx > curpos) curx = curpos;
+                   inpprint(inpwin,inplin,curpos,curx);
+                   wrefresh (inpwin);
+               }
+               break;
+           case 261: // RIGHT ARROW
+               if (curpos < strlen(inplin)) {
+                   curpos++;
+                   if (curpos - curx > mx-1) curx++;
+                   inpprint(inpwin,inplin,curpos,curx);
+                   wrefresh (inpwin);
+               }
+               break;
+           default: // ALL OTHER KEYS
+               if (curpos == strlen(inplin)) {
+                   sprintf (inplin,"%s%c",inplin,(int) c);
+               }
+               else
+               {
+                   
+                   strncpy(tlin,&inplin[curpos],strlen(inplin)-curpos);
+                   tlin[strlen(inplin)-curpos]='\0';
+                   strcpy(&inplin[curpos+1],tlin);
+                   inplin[curpos] = (int) c;
+               }
+               curpos++;
+               if (curpos - curx > mx-1) curx++;
+               inpprint(inpwin,inplin,curpos,curx);
+               wrefresh (inpwin);
+           }
+       }
 
+       if (fgets(buffer,BUFSIZ,sockin)) {
+           curs_set (0);
+           if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
+               wprint (dispwin, &buffer[15]);
+           }
+           else {
+               if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
+           }
+           wrefresh (dispwin);
+           wrefresh (statwin);
+           wrefresh (inpwin);
+       }
+       if (((int) c == 13) || ((int) c == 10)) {
+           curs_set (0);
+           curpos = 0;
+           curx = 0;
+           if (inplin[0] == '/') {
+               fprintf(sockout,"%s\r\n",&inplin[1]);
+           }
+           else {
+               fprintf(sockout,"MESSAGE \"%s\"\r\n",inplin);
+           }
+           fflush(sockout);
+           inplin[0] = '\0';
+           if (fgets(buffer,BUFSIZ,sockin)) {
+               if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
+                   wprint (dispwin, buffer);
+               }
+               else {
+                   if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
+               }
+           }
+           wrefresh (dispwin);
+           wrefresh (statwin);
+           werase (inpwin);
+           wrefresh (inpwin);
+       }
+    }
 }
 
-
-static void finish(int sig)
+static void
+finish (int sig)
 {
-    char buffer[1024];
-    ssize_t numread;
+    char buffer[BUFSIZ];
+    
     endwin();
 
     /* do your non-curses wrapup here */
-    xasprintf(&message2, "QUIT\r\n");
-    ttt_socket_write(_socket, message2, strlen(message2));
-    maxread = 100;
-    numread = read(_socket, buffer, maxread);
-    buffer[numread] = '\0';
-    xasprintf(&message2, "%s", buffer);
-    exit(0);
+    fprintf(sockout,"QUIT\r\n");
+    fflush(sockout);
+
+    while (fgets(buffer,BUFSIZ,sockin));
+    exit (0);
 }