1 /*ttt-curses-client.c - curses based tic-tac-toe game client
3 * Copyright © 2005 Bryan Worth
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Author: Bryan Worth <bryan@theworths.org>
22 /* TODO: see /usr/share/doc/ncurses-devel-5.3/test/view.c for example code
23 * to handle window resizing
27 #include "ttt-socket.h"
41 mvwprintstr (WINDOW *window,
48 wprint (WINDOW *window,
66 cline[xx] = string[xx] | attrs;
70 mvaddchstr (y, x, cline);
73 void mvwprintstr (WINDOW *window,
84 cline[xx] = string[xx] | attrs;
88 mvwaddchstr (window, y, x, cline);
91 void wprint (WINDOW *window,
101 if (string[xx] != '\r')
102 waddch (window, outc);
107 void inpprint (WINDOW *window,char *string,int pos,int curx);
109 void inpprint (WINDOW *window,char *string,int pos,int curx)
113 getmaxyx(window,my,mx);
115 strncpy(tbuf,&string[curx], mx-1);
120 wmove(window,0,pos - curx);
126 if (strlen(string) > mx-1) tbuf[mx-1]='\0';
139 FILE *sockin, *sockout;
143 main (int argc, char **argv)
145 char *host="localhost";
152 char *command_string;
162 static WINDOW *mainwnd;
163 static WINDOW *dispwin;
164 static WINDOW *inpwin;
165 static WINDOW *statwin;
169 int dlines = LINES, cols = COLS;
175 nodelay (mainwnd, TRUE);
178 dispwin = newwin (dlines - 6, cols , 0, 0);
179 statwin = newwin (4, cols , dlines -4, 0);
180 inpwin = newwin (1, cols , dlines -1, 0);
181 keypad (mainwnd, TRUE); // enable keyboard mapping
182 keypad (inpwin, TRUE); // enable keyboard mapping
183 nodelay (inpwin, TRUE);
184 getmaxyx(inpwin,my,mx);
189 (void) scrollok (mainwnd, TRUE);
190 (void) scrollok (dispwin, TRUE);
191 (void) scrollok (statwin, TRUE);
192 (void) scrollok (inpwin, TRUE);
193 (void) idlok (mainwnd, TRUE);
194 (void) idlok (dispwin, TRUE);
195 (void) idlok (statwin, TRUE);
196 (void) idlok (inpwin, TRUE);
197 wsetscrreg (dispwin, 0, dlines - 2);
198 wsetscrreg (statwin, 0, 4);
200 (void) signal (SIGINT, finish); /* arrange interrupts to terminate */
204 init_pair (COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
205 init_pair (COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
206 init_pair (COLOR_RED, COLOR_RED, COLOR_BLACK);
207 init_pair (COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
208 init_pair (COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
209 init_pair (COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
210 init_pair (COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
211 init_pair (COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
216 xasprintf(&confpath,"%s/.ttt/",getenv("HOME"));
217 xasprintf(&conffile,"%s/.ttt/client.conf",getenv("HOME"));
219 if (access (conffile, F_OK) != 0 ) {
220 envuser=getenv("USER");
221 if (envuser != NULL) username=strdup(envuser);
222 if (access (confpath, F_OK) != 0 ) {
223 xasprintf(&command_string,"mkdir %s",confpath);
224 system (command_string);
226 if ((conf_file = fopen(conffile,"w")) != NULL) {
227 fprintf(conf_file,"username=%s",username);
231 if ((conf_file = fopen(conffile,"r")) != NULL) {
232 while (fgets(buffer,BUFSIZ,conf_file)) {
233 if (buffer[strlen(buffer)-1] == 10) buffer[strlen(buffer)-1] = '\0';
234 if (strncmp(buffer,"username=",9) == 0) {
235 xasprintf (&username, "%s", &buffer[9]);
237 if (strncmp(buffer,"port=",5) == 0) {
238 xasprintf (&port, "%s",&buffer[5]);
243 status=ttt_socket_create_client (host, port, &_socket);
246 printf("Unable to connect to server! Connection status: %d\n",status);
249 sockin=fdopen(_socket,"r");
250 sockout=fdopen(_socket,"w");
254 fprintf(sockout, "HELO %s\r\n",username);
257 if (fgets(buffer,BUFSIZ,sockin)) {
258 if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
259 wprint (dispwin, buffer);
262 if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
268 fprintf(sockout, "WHO \r\n");
275 if ((c != ERR) && (strlen(inplin)< 1000)) {
277 case 13: // CARRIAGE RETURN
279 case 10: // LINE FEED
281 case 262: // HOME key
284 inpprint(inpwin,inplin,curpos,curx);
288 curpos = strlen(inplin);
289 if (strlen(inplin) > mx -1) {
290 curx = strlen(inplin) - mx +1;
296 inpprint(inpwin,inplin,curpos,curx);
299 case 330: // DELETE key
300 if (strlen(inplin) > 0) {
301 if (curpos == strlen(inplin)) {
302 inplin[strlen(inplin)-1]='\0';
307 strncpy(&inplin[curpos],&inplin[curpos+1],strlen(inplin)-curpos+1);
311 inpprint(inpwin,inplin,curpos,curx);
316 case 8: // > Various BACKSPACE codes
319 if (curpos == strlen(inplin)) {
320 inplin[strlen(inplin)-1]='\0';
324 strncpy(&inplin[curpos-1],&inplin[curpos],strlen(inplin)-curpos);
325 inplin[strlen(inplin)-1]='\0';
327 if (curpos > 0) curpos--;
328 if (curx > 0) curx--;
329 inpprint(inpwin,inplin,curpos,curx);
333 case 260: // LEFT ARROW
336 if (curx > curpos) curx = curpos;
337 inpprint(inpwin,inplin,curpos,curx);
341 case 261: // RIGHT ARROW
342 if (curpos < strlen(inplin)) {
344 if (curpos - curx > mx-1) curx++;
345 inpprint(inpwin,inplin,curpos,curx);
349 default: // ALL OTHER KEYS
350 if (curpos == strlen(inplin)) {
351 sprintf (inplin,"%s%c",inplin,(int) c);
356 strncpy(tlin,&inplin[curpos],strlen(inplin)-curpos);
357 tlin[strlen(inplin)-curpos]='\0';
358 strcpy(&inplin[curpos+1],tlin);
359 inplin[curpos] = (int) c;
362 if (curpos - curx > mx-1) curx++;
363 inpprint(inpwin,inplin,curpos,curx);
368 if (fgets(buffer,BUFSIZ,sockin)) {
370 if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
371 wprint (dispwin, &buffer[15]);
374 if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
380 if (((int) c == 13) || ((int) c == 10)) {
384 if (inplin[0] == '/') {
385 fprintf(sockout,"%s\r\n",&inplin[1]);
388 fprintf(sockout,"MESSAGE \"%s\"\r\n",inplin);
392 if (fgets(buffer,BUFSIZ,sockin)) {
393 if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
394 wprint (dispwin, buffer);
397 if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
415 /* do your non-curses wrapup here */
416 fprintf(sockout,"QUIT\r\n");
419 while (fgets(buffer,BUFSIZ,sockin));