-/* 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;
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);
}