]> git.cworth.org Git - ttt/blob - src/ttt-curses-client.c
* src/ttt-curses-client.c Fixed backspace implementation
[ttt] / src / ttt-curses-client.c
1 /*ttt-curses-client.c - curses based tic-tac-toe game client
2  *
3  * Copyright © 2005 Bryan Worth
4  *
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)
8  * any later version.
9  *
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.
14  *
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.
18  *
19  * Author: Bryan Worth <bryan@theworths.org> 
20  */
21
22 /* TODO: see /usr/share/doc/ncurses-devel-5.3/test/view.c for example code
23  *       to handle window resizing
24  *
25  */      
26
27 #include "ttt-socket.h"
28 #include <curses.h>
29 #include <signal.h>
30
31 static void
32 finish (int sig);
33
34 void
35 mvprintstr (int     y,
36             int     x,
37             char    *string,
38             chtype  attrs);
39
40 void
41 mvwprintstr (WINDOW *window,
42              int    y,
43              int    x,
44              char   *string,
45              chtype attrs);
46
47 void
48 wprint (WINDOW *window,
49         char   *string);
50
51 /*
52  *
53  */
54
55 void
56 mvprintstr (int    y,
57             int    x,
58             char   *string,
59             chtype attrs)
60 {
61     int xx = 0;
62     int l;
63     chtype cline[1000];
64     l = strlen(string);
65     while (xx < l) {
66         cline[xx] = string[xx] | attrs;
67         xx++;
68     }
69     cline[l] = '\0';
70     mvaddchstr (y, x, cline);
71 }
72
73 void mvwprintstr (WINDOW *window,
74                   int    y,
75                   int    x,
76                   char   *string,
77                   chtype attrs)
78 {
79     int xx = 0;
80     int l;
81     chtype cline[1000];
82     l = strlen (string);
83     while (xx < l) {
84         cline[xx] = string[xx] | attrs;
85         xx++;
86     }
87     cline[l] = '\0';
88     mvwaddchstr (window, y, x, cline);
89 }
90
91 void wprint (WINDOW *window,
92              char   *string)
93 {
94     int xx = 0;
95     int l;
96     chtype outc;
97     l = strlen (string);
98
99     while (xx < l) {
100         outc = string[xx];
101         if (string[xx] != '\r') 
102             waddch (window, outc);
103         xx++;
104     }
105 }
106
107 FILE *sockin, *sockout;
108
109 int
110 main (int argc, char **argv)
111 {
112     char *host="localhost";
113     char *port="5334";
114     chtype c;
115     char *username;
116     char *envuser;
117     char *confpath;
118     char *conffile;
119     char *command_string;
120     int _socket;
121     char buffer[BUFSIZ];
122     char inplin[1024];
123
124
125     static WINDOW *mainwnd;
126     static WINDOW *dispwin;
127     static WINDOW *statwin;
128     static WINDOW *inpwin;
129     FILE *conf_file;
130
131     mainwnd = initscr();
132     int dlines = LINES - 2, cols = COLS;
133
134     (void) nonl ();
135     (void) nl ();
136     noecho ();
137     cbreak ();
138     nodelay (mainwnd, TRUE);
139     curs_set (0);
140     refresh ();
141     dispwin = newwin (dlines - 5, cols - 2, 0, 0);
142     statwin = newwin (4, cols - 2, dlines -3, 0);
143     inpwin = newwin (1, cols - 2, dlines, 0);
144     keypad (mainwnd, TRUE);     // enable keyboard mapping 
145     keypad (inpwin, TRUE);      // enable keyboard mapping 
146     nodelay (inpwin, TRUE);
147     wrefresh (mainwnd);
148     wrefresh (dispwin);
149     wrefresh (statwin);
150     wrefresh (inpwin);
151     (void) scrollok (mainwnd, TRUE);
152     (void) scrollok (dispwin, TRUE);
153     (void) scrollok (statwin, TRUE);
154     (void) scrollok (inpwin, TRUE);
155     (void) idlok (mainwnd, TRUE);
156     (void) idlok (dispwin, TRUE);
157     (void) idlok (statwin, TRUE);
158     (void) idlok (inpwin, TRUE);
159     wsetscrreg (dispwin, 0, dlines - 2);
160     wsetscrreg (statwin, 0, 4);
161     
162     (void) signal (SIGINT, finish);     /* arrange interrupts to terminate */
163     if (has_colors ()) {
164         start_color ();
165
166         init_pair (COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);
167         init_pair (COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);
168         init_pair (COLOR_RED, COLOR_RED, COLOR_BLACK);
169         init_pair (COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);
170         init_pair (COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);
171         init_pair (COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
172         init_pair (COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);
173         init_pair (COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);
174     }
175     //wbkgd (dispwin, COLOR_PAIR (COLOR_WHITE));
176     //wbkgd (inpwin, COLOR_PAIR (COLOR_CYAN));
177     wrefresh (dispwin);
178     wrefresh (inpwin);
179
180
181     ttt_socket_create_client (host, port, &_socket);
182     sockin=fdopen(_socket,"r");
183     sockout=fdopen(_socket,"w");
184
185
186     xasprintf(&confpath,"%s/.ttt/",getenv("HOME"));
187     xasprintf(&conffile,"%s/.ttt/client.conf",getenv("HOME"));
188     username="user";
189     if (access (conffile, F_OK) != 0 ) {
190         envuser=getenv("USER");
191         if (envuser != NULL) username=strdup(envuser);
192         if (access (confpath, F_OK) != 0 ) {
193             xasprintf(&command_string,"mkdir %s",confpath);
194             system (command_string);
195         }
196         if ((conf_file = fopen(conffile,"w")) != NULL) {
197                 fprintf(conf_file,"username=%s",username);
198                 fclose(conf_file);
199         }
200     }
201     if ((conf_file = fopen(conffile,"r")) != NULL) {
202         while (fgets(buffer,BUFSIZ,conf_file)) {
203             if (strncmp(buffer,"username=",9) == 0) {
204                 xasprintf (&username, "%s", &buffer[9]);
205                 break;
206             }
207         }
208     fclose(conf_file); 
209     }
210
211     fprintf(sockout, "HELO %s\r\n",username);
212     fflush(sockout);
213
214     if (fgets(buffer,BUFSIZ,sockin)) {
215         if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
216                 wprint (dispwin, buffer);
217         }
218         else {
219             if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
220         }
221         wrefresh (dispwin);
222         wrefresh (statwin);
223     }
224     inplin[0]='\0';
225     while (1) {
226         curs_set (1);
227         c = wgetch (inpwin);
228         if ((c != ERR) && (strlen(inplin)< 1000)) {
229             switch ((int) c) {
230                 case 13: 
231                     break;
232                 case 10:
233                     break;
234                 case 8:
235                     inplin[strlen(inplin)-1]='\0';
236                     wmove (inpwin,0,strlen(inplin));
237                     wclrtoeol( inpwin);
238                     wrefresh (inpwin);
239                     break;
240                 case 127:
241                     inplin[strlen(inplin)-1]='\0';
242                     wmove (inpwin,0,strlen(inplin));
243                     wclrtoeol (inpwin);
244                     wrefresh (inpwin);
245                     break;
246                 case 263:
247                     inplin[strlen(inplin)-1]='\0';
248                     wmove (inpwin,0,strlen(inplin));
249                     wclrtoeol (inpwin);
250                     wrefresh (inpwin);
251                     break;
252                 default: 
253                     sprintf (inplin,"%s%c",inplin,(int) c);
254                     waddch (inpwin, c);
255                     wrefresh (inpwin);
256             }
257         }
258
259         if (fgets(buffer,BUFSIZ,sockin)) {
260             curs_set (0);
261             if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
262                 wprint (dispwin, &buffer[15]);
263             }
264             else {
265                 if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
266             }
267             wrefresh (dispwin);
268             wrefresh (statwin);
269             wrefresh (inpwin);
270         }
271         if (((int) c == 13) || ((int) c == 10)) {
272             curs_set (0);
273             fprintf(sockout,"MESSAGE \"%s\"\r\n",inplin);
274             fflush(sockout);
275             inplin[0] = '\0';
276             if (fgets(buffer,BUFSIZ,sockin)) {
277                 if ((strncmp(buffer,"NOTICE MESSAGE ",15) == 0) && (strlen(buffer) > 15)) {
278                     wprint (dispwin, buffer);
279                 }
280                 else {
281                     if (strncmp(buffer,"MESSAGE",7) != 0) wprint (statwin, buffer);
282                 }
283             }
284             wrefresh (dispwin);
285             wrefresh (statwin);
286             werase (inpwin);
287             wrefresh (inpwin);
288         }
289     }
290 }
291
292 static void
293 finish (int sig)
294 {
295     char buffer[BUFSIZ];
296     
297     endwin();
298
299     /* do your non-curses wrapup here */
300     fprintf(sockout,"QUIT\r\n");
301     fflush(sockout);
302
303     while (fgets(buffer,BUFSIZ,sockin));
304     exit (0);
305 }