1 /* 2 3 eboard - chess client 4 http://www.bergo.eng.br/eboard 5 https://github.com/fbergo/eboard 6 Copyright (C) 2000-2016 Felipe Bergo 7 fbergo/at/gmail/dot/com 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 23 */ 24 25 #include "config.h" 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 31 #ifdef HAVE_STRINGS_H 32 #include <strings.h> 33 #endif 34 35 #include <sys/stat.h> 36 #include <sys/types.h> 37 #include <unistd.h> 38 #include <errno.h> 39 #include <time.h> 40 41 #include "util.h" 42 #include "tstring.h" 43 #include "global.h" 44 #include "help.h" 45 #include "mainwindow.h" 46 #include "eboard.h" 47 #include "widgetproxy.h" 48 49 #include "xpm/gnupiece.xpm" 50 51 namespace Help { 52 AboutDialog()53 AboutDialog::AboutDialog() : ModalDialog(N_("About eboard")) { 54 GtkWidget *v,*hb,*label,*bhb,*hs,*ok,*gnup; 55 GtkStyle *style; 56 GdkPixmap *gnud; 57 GdkBitmap *gnub; 58 char z[1024]; 59 60 v=gtk_vbox_new(FALSE,4); 61 gtk_container_add(GTK_CONTAINER(widget),v); 62 63 hb=gtk_hbox_new(FALSE,4); 64 gtk_box_pack_start(GTK_BOX(v),hb,TRUE,TRUE,0); 65 66 style=gtk_widget_get_style(widget); 67 gnud=gdk_pixmap_create_from_xpm_d(widget->window,&gnub, 68 &style->bg[GTK_STATE_NORMAL], 69 (gchar **)gnupiece_xpm); 70 gnup=gtk_pixmap_new(gnud,gnub); 71 72 gtk_box_pack_start(GTK_BOX(hb),gnup,FALSE,TRUE,4); 73 74 snprintf(z,1024, 75 _("eboard version %s\n"\ 76 "(c) 2000-%d Felipe Bergo\n"\ 77 "<fbergo@gmail.com>\n"\ 78 "https://github.com/fbergo/eboard\n\n"\ 79 "This program is free software; you can redistribute\n"\ 80 "it and/or modify it under the terms of the GNU General\n"\ 81 "Public License as published by the Free Software\n"\ 82 "Foundation; either version 2 of the License, or\n"\ 83 "(at your option) any later version.\n"), 84 global.Version, 2016); 85 86 label=gtk_label_new(z); 87 gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_LEFT); 88 gtk_box_pack_start(GTK_BOX(hb),label,TRUE,TRUE,4); 89 90 hs=gtk_hseparator_new(); 91 gtk_box_pack_start(GTK_BOX(v),hs,FALSE,FALSE,4); 92 93 bhb=gtk_hbutton_box_new(); 94 gtk_button_box_set_layout(GTK_BUTTON_BOX(bhb), GTK_BUTTONBOX_END); 95 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bhb), 5); 96 97 gtk_box_pack_start(GTK_BOX(v),bhb,FALSE,FALSE,4); 98 99 ok=gtk_button_new_with_label(_("Close")); 100 GTK_WIDGET_SET_FLAGS(ok,GTK_CAN_DEFAULT); 101 gtk_box_pack_start(GTK_BOX(bhb),ok,TRUE,TRUE,0); 102 103 gtk_widget_grab_default(ok); 104 Gtk::show(ok,bhb,hs,label,gnup,hb,v,NULL); 105 setDismiss(GTK_OBJECT(ok),"clicked"); 106 } 107 KeysDialog()108 KeysDialog::KeysDialog() : ModalDialog(N_("Help: Keys")) { 109 GtkWidget *v,*label,*lbs,*bhb,*hs,*ok; 110 char z[1024]; 111 int i; 112 list<string> s[3]; 113 list<string>::iterator lsi; 114 vector<string> t; 115 116 v=gtk_vbox_new(FALSE,4); 117 gtk_container_add(GTK_CONTAINER(widget),v); 118 119 // changed this code to allow new commands to be added without losing 120 // the translations of the existing ones (1.1.2) -- Felipe 121 t.push_back(_("Anywhere:")); 122 123 s[0].push_back(_("F3: Go to previous pane.")); 124 s[0].push_back(_("F4: Go to next pane.")); 125 s[0].push_back(_("F5: Go to the main board pane.")); 126 s[0].push_back(_("F6: Go to the console pane.")); 127 s[0].push_back(_("F7: Go to the seek graph pane (if available).")); 128 s[0].push_back(_("F8: Toggle shortcut bar visibility.")); 129 s[0].push_back(_("Page Up/Page Down: Scroll the text console.")); 130 s[0].push_back(_("Ctrl+Left: Backward 1 halfmove.")); 131 s[0].push_back(_("Ctrl+Right: Forward 1 halfmove.")); 132 s[0].push_back(_("Ctrl+F: Find upwards (main console buffer).")); 133 s[0].push_back(_("Ctrl+G: Find previous.")); 134 s[0].push_back(_("Ctrl+T: Toggle timestamps.")); 135 136 t.push_back(_("Input Box:")); 137 138 s[1].push_back(_("Up/Down: move thru input history.")); 139 s[1].push_back(_("Enter: send text line.")); 140 s[1].push_back(_("ESC: switch chat/command mode.")); 141 142 t.push_back(_("Syntaxisms:")); 143 144 s[2].push_back(_(".. entering %prefix text will set a chat prefix.")); 145 s[2].push_back(_(".. entering %do scriptname runs scriptname.")); 146 147 z[0] = 0; 148 for(i=0;i<3;i++) { 149 strcat(z, t[i].c_str()); 150 strcat(z, "\n"); 151 for(lsi=s[i].begin();lsi!=s[i].end();lsi++) { 152 strcat(z, (*lsi).c_str()); 153 strcat(z, "\n"); 154 } 155 strcat(z, "\n"); 156 } 157 158 label=gtk_label_new(z); 159 gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_LEFT); 160 lbs = scrollBox(label); 161 gtk_box_pack_start(GTK_BOX(v),lbs,TRUE,TRUE,4); 162 163 hs=gtk_hseparator_new(); 164 gtk_box_pack_start(GTK_BOX(v),hs,FALSE,FALSE,4); 165 166 bhb=gtk_hbutton_box_new(); 167 gtk_button_box_set_layout(GTK_BUTTON_BOX(bhb), GTK_BUTTONBOX_END); 168 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bhb), 5); 169 170 gtk_box_pack_start(GTK_BOX(v),bhb,FALSE,FALSE,4); 171 172 ok=gtk_button_new_with_label(_("Close")); 173 GTK_WIDGET_SET_FLAGS(ok,GTK_CAN_DEFAULT); 174 gtk_box_pack_start(GTK_BOX(bhb),ok,TRUE,TRUE,0); 175 176 gtk_widget_grab_default(ok); 177 gtk_window_set_default_size(GTK_WINDOW(widget),450, 500); 178 Gtk::show(ok,bhb,hs,label,v,NULL); 179 setDismiss(GTK_OBJECT(ok),"clicked"); 180 } 181 DebugDialog()182 DebugDialog::DebugDialog() : ModalDialog(N_("Help: Debug Info")) { 183 GtkWidget *v,*label,*hs,*bhb,*ok,*txt; 184 char z[2048],y[256],x[256],w[256]; 185 struct stat s; 186 EboardFileFinder eff; 187 188 v=gtk_vbox_new(FALSE,4); 189 gtk_container_add(GTK_CONTAINER(widget),v); 190 191 z[0]=0; 192 193 // gtk 194 snprintf(y,256,"GTK+ version %d.%d.%d\n", 195 gtk_major_version, 196 gtk_minor_version, 197 gtk_micro_version); 198 g_strlcat(z,y,2048); 199 200 // gcc (c++) if any 201 snprintf(y,256,"GCC says: %s\n", 202 grabOutput("c++ --version 2>&1")); 203 g_strlcat(z,y,2048); 204 205 // perl 206 snprintf(y,256,"Perl says: %s\n", 207 grabOutput("perl -v | grep ^This")); 208 g_strlcat(z,y,2048); 209 210 // expect 211 snprintf(y,256,"expect says: %s\n", 212 grabOutput("expect -d -c exit 2>&1")); 213 g_strlcat(z,y,2048); 214 215 // kernel 216 snprintf(y,256,"kernel info: %s\n", 217 grabOutput("uname -srm")); 218 g_strlcat(z,y,2048); 219 220 // timeseal 221 snprintf(x,256,"timeseal.%s",global.SystemType); 222 if (!eff.find(x,y)) strcpy(y,x); 223 224 if (lstat(y,&s)==0) { 225 snprintf(w,256,"Found %s\n",y); strcpy(x,w); 226 snprintf(w,256,"Size %lu bytes, Last Modified %s", 227 s.st_size, ctime(&(s.st_mtime)) ); 228 g_strlcat(x,w,256); 229 snprintf(w,256,"Mode %.4o. (seems it i%s enough to be run by eboard)\n", 230 s.st_mode, 231 ( S_ISREG(s.st_mode) 232 && 233 ( 234 ( S_IXUSR&s.st_mode && s.st_uid==getuid() ) 235 || 236 ( S_IXGRP&s.st_mode && s.st_gid==getgid() ) 237 || 238 ( S_IXOTH&s.st_mode ) 239 ) 240 ) ? "s" : "s NOT" 241 ); 242 g_strlcat(x,w,256); 243 244 } else { 245 snprintf(x,256,"%s Not Found (errno %d)",y,errno); 246 } 247 248 snprintf(y,256,"\nFICS timeseal:\n%s\n",x); 249 g_strlcat(z,y,2048); 250 251 label=gtk_label_new(z); 252 gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_LEFT); 253 gtk_box_pack_start(GTK_BOX(v),label,TRUE,TRUE,4); 254 255 hs=gtk_hseparator_new(); 256 gtk_box_pack_start(GTK_BOX(v),hs,FALSE,FALSE,4); 257 258 bhb=gtk_hbutton_box_new(); 259 gtk_button_box_set_layout(GTK_BUTTON_BOX(bhb), GTK_BUTTONBOX_END); 260 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bhb), 5); 261 262 gtk_box_pack_start(GTK_BOX(v),bhb,FALSE,FALSE,4); 263 264 ok=gtk_button_new_with_label(_("Close")); 265 txt=gtk_button_new_with_label(_("Write to Console")); 266 GTK_WIDGET_SET_FLAGS(ok,GTK_CAN_DEFAULT); 267 GTK_WIDGET_SET_FLAGS(txt,GTK_CAN_DEFAULT); 268 gtk_box_pack_start(GTK_BOX(bhb),txt,TRUE,TRUE,0); 269 gtk_box_pack_start(GTK_BOX(bhb),ok,TRUE,TRUE,0); 270 271 gtk_widget_grab_default(ok); 272 273 Gtk::show(ok,txt,bhb,hs,label,v,NULL); 274 setDismiss(GTK_OBJECT(ok),"clicked"); 275 276 gtk_signal_connect(GTK_OBJECT(txt),"clicked", 277 GTK_SIGNAL_FUNC(debugdlg_writecons), 278 (gpointer) this); 279 280 strcpy(pipedata,z); 281 } 282 grabOutput(const char * cmdline)283 char * DebugDialog::grabOutput(const char *cmdline) { 284 FILE *f; 285 bool ok = false; 286 char *c; 287 f=popen(cmdline,"r"); 288 if (f) { 289 if (fgets(pipedata,127,f)) 290 ok=true; 291 pclose(f); 292 } 293 if (!ok) 294 strcpy(pipedata,"unable to retrieve"); 295 else 296 while( (c=strchr(pipedata,'\n'))!=NULL) 297 *c=0; 298 return pipedata; 299 } 300 debugdlg_writecons(GtkWidget * w,gpointer data)301 void debugdlg_writecons(GtkWidget *w, gpointer data) { 302 DebugDialog *me; 303 tstring t; 304 string *c; 305 char z[512]; 306 307 me = (DebugDialog *) data; 308 t.set(me->pipedata); 309 global.output->append("=== START DEBUG INFO ===",0xc0ff00); 310 while( (c=t.token("\n")) != 0) { 311 memset(z,0,512); 312 c->copy(z,511); 313 global.output->append(z, global.Colors.TextBright); 314 } 315 global.output->append("=== END DEBUG INFO ===",0xc0ff00); 316 } 317 318 GettingStarted()319 GettingStarted::GettingStarted() : NonModalDialog(N_("Help: Getting Started ")) { 320 GtkWidget *v, *ts, *bhb, *ok, *fr; 321 322 gtk_window_set_default_size(GTK_WINDOW(widget),620,560); 323 v=gtk_vbox_new(FALSE,4); 324 gtk_container_add(GTK_CONTAINER(widget),v); 325 326 fr = gtk_frame_new(NULL); 327 gtk_frame_set_shadow_type(GTK_FRAME(fr),GTK_SHADOW_ETCHED_IN); 328 gtk_box_pack_start(GTK_BOX(v),fr,TRUE,TRUE,0); 329 330 331 text=gtk_text_view_new(); 332 g_object_set(G_OBJECT(text),"cursor-visible",FALSE,NULL); 333 ts = scrollBox(text); 334 gtk_container_add(GTK_CONTAINER(fr),ts); 335 336 bhb=gtk_hbutton_box_new(); 337 gtk_button_box_set_layout(GTK_BUTTON_BOX(bhb), GTK_BUTTONBOX_END); 338 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bhb), 5); 339 340 gtk_box_pack_start(GTK_BOX(v),bhb,FALSE,FALSE,4); 341 342 ok=gtk_button_new_with_label(_("Close")); 343 GTK_WIDGET_SET_FLAGS(ok,GTK_CAN_DEFAULT); 344 gtk_box_pack_start(GTK_BOX(bhb),ok,TRUE,TRUE,0); 345 346 gtk_widget_grab_default(ok); 347 348 Gtk::show(ok,bhb,text,fr,v,NULL); 349 setDismiss(GTK_OBJECT(ok),"clicked"); 350 351 compose(); 352 gtk_text_view_set_editable(GTK_TEXT_VIEW(text),FALSE); 353 } 354 compose()355 void GettingStarted::compose() { 356 char *T,*p,*q; 357 GtkTextBuffer *tb; 358 GtkTextIter iter; 359 GtkTextTag *tag[6]; 360 361 // codes: #L# large #M# medium #S# small #B# blue #K# black 362 363 T=_("#L#Getting Started\n"\ 364 "#M#Common Tasks in eboard\n\n"\ 365 "Playing against the computer\n"\ 366 "#S#eboard does not \"play chess\" itself, but rather is works as interface to programs that do,\n"\ 367 "called \"engines\", which don't have a graphical interface themselves. You need an engine to\n"\ 368 "play against the computer. GNU Chess, Crafty and Sjeng are chess engines that are available at\n"\ 369 "no cost.\n"\ 370 "Once you have one of them installed, open the #B#Peer#K# menu, then the #B#Play against\n"\ 371 "engine#K# submenu, and select the appropriate option depending on which engine you have\n"\ 372 "installed.\n\n"\ 373 "#M#Playing Chess on the Internet\n"\ 374 "#S#Eboard supports the FICS protocol. FICS runs at freechess.org, but other servers, such as\n"\ 375 "US Chess Live, use FICS's software and should work with eboard too. ICC is not supported.\n"\ 376 "To connect to FICS, open the #B#Peer#K# menu, click #B#Connect to FICS#K#. To connect to\n"\ 377 "other servers, open the #B#Peer#K# menu, click #B#Connect to Other Server...#K#.\n"\ 378 "While you can login as guest on FICS, you'll enjoy it better as a registered user. Registration\n"\ 379 "is done through FICS's site at #B#http://www.freechess.org#K#, and it's free.\n\n"\ 380 "#M#Browsing PGN Games\n"\ 381 "#S#PGN is the most common file format to store chess games. It can store moves and comments\n"\ 382 "(annotations). To open this kind of file within eboard, open the #B#Windows#K# menu, click\n"\ 383 "#B#Games on Client#K#. In the Local Game List dialog, click #B#Load PGN...#K#. To browse a\n"\ 384 "game, #B#select it#K# and click #B#Display#K#. A new tab will be created in the main window\n"\ 385 "with the game."\ 386 "#L#"); 387 388 tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); 389 tag[0] = gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(tb),"tag0", 390 "font","Sans 10", 391 "foreground","#000000", 392 "justification",GTK_JUSTIFY_LEFT, 393 "editable",FALSE, 394 "weight",PANGO_WEIGHT_NORMAL, 395 "wrap-mode",GTK_WRAP_WORD, 396 NULL); 397 tag[1] = gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(tb),"tag1", 398 "font","Sans 12", 399 "foreground","#000000", 400 "justification",GTK_JUSTIFY_LEFT, 401 "editable",FALSE, 402 "weight",PANGO_WEIGHT_BOLD, 403 "wrap-mode",GTK_WRAP_WORD, 404 NULL); 405 tag[2] = gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(tb),"tag2", 406 "font","Sans 16", 407 "foreground","#000000", 408 "justification",GTK_JUSTIFY_LEFT, 409 "editable",FALSE, 410 "weight",PANGO_WEIGHT_BOLD, 411 "wrap-mode",GTK_WRAP_WORD, 412 NULL); 413 tag[3] = gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(tb),"tag3", 414 "font","Sans 10", 415 "foreground","#0000ff", 416 "justification",GTK_JUSTIFY_LEFT, 417 "editable",FALSE, 418 "weight",PANGO_WEIGHT_NORMAL, 419 "wrap-mode",GTK_WRAP_WORD, 420 NULL); 421 tag[4] = gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(tb),"tag4", 422 "font","Sans 12", 423 "foreground","#0000ff", 424 "justification",GTK_JUSTIFY_LEFT, 425 "editable",FALSE, 426 "weight",PANGO_WEIGHT_BOLD, 427 "wrap-mode",GTK_WRAP_WORD, 428 NULL); 429 tag[5] = gtk_text_buffer_create_tag(GTK_TEXT_BUFFER(tb),"tag5", 430 "font","Sans 16", 431 "foreground","#0000ff", 432 "justification",GTK_JUSTIFY_LEFT, 433 "editable",FALSE, 434 "weight",PANGO_WEIGHT_BOLD, 435 "wrap-mode",GTK_WRAP_WORD, 436 NULL); 437 438 439 int ctag = 0, tval[2] = {0,0}; 440 q = T; 441 for(p=T;*p;p++) { 442 443 if (*p=='#') { 444 if (p-q) { 445 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(tb),&iter); 446 gtk_text_buffer_insert_with_tags(GTK_TEXT_BUFFER(tb),&iter,q,p-q,tag[ctag],NULL); 447 } 448 q = p + 3; 449 450 switch(p[1]) { 451 case 'L': tval[0]=2; break; 452 case 'M': tval[0]=1; break; 453 case 'S': tval[0]=0; break; 454 case 'B': tval[1]=1; break; 455 case 'K': tval[1]=0; break; 456 } 457 ctag = 3*tval[1] + tval[0]; 458 p += 3; 459 } 460 461 } 462 463 } 464 465 } // namespace Help 466 467