[The patch is further down.] Bug fixes: - Fixed a bug in the networking read loop (conn.c:newNetData). The loop around the read() breaks when taken more than once. Results were damaged game/player lists and garbage in the terminal window. - Fixed a bug in the bPropW handling in the rc-file. Small windows sizes were not stored. [Note: When starting cgoban (with an old config file) the first time after applying the patch windows will be half the wide that they used to be.] - Fixed a bug when inserting text into a text window. The passed width was wrong so that it forces a line break of the string when it was not neccesary. - Inserted a missing str_clip(cmdBuild,0) into client/game.c. - Fixed a bug in CTRL-D handling of the tbin widget. (SEGV when pressed on last char in last line (not always immediate)) - NNGS guest login sometimes hang. Server sends "#> " (two spaces) which was not recognized as a prompt. Enhancements: - Added cross mark support (on board, in sgf files, in editor). - Added support for "titled games". IGS send a "Game is titled: ...." for each move of a titled game. These were shown in the terminal window. I forward these titles to the goban widget where they will be displayed in the title box. - Added the player names into the timer/score boxes. The rows of black/white stones are reduced to a single stone and the player's name and rank are shown right of that stone. (That was done after I noticed that the names may not be visible in titled games.) - Optional (compile time support) for a fixed width font in the terminal window. IGS output assumes a fixed width font and the ASCII-graphics, tables, and help files will be messed up with proportional fonts. Change the TBIN_FONTNUM define in wmslib/src/but/tbin.h. - Made the game list window a little bit larger so that 3-digit game numbers will fit into the first column. - In the game list window the common values of some fields (board size=19, move number=0, handicap=0, observers=0) are replaced by a single dot. Not only makes this the window cleaner, it's also easier to look for special games (unusual board size, high handycap, etc). - Added a key (XK_Insert) to insert the current selection. - The resource name changed to "CGoban" from "Basicwin". That way the window manager can properly identify the windows. - Added a '-connect ' command line option and changed the '-nngs/igs' option slightly. '-connect' looks for the given name in the setup's server list and uses that server entry to connect to. '-nngs/igs' has become a shortcut for '-connect NNGS/IGS'. (Original -nngs/igs took always the first/second entry of the list whatever server that may be.) (TODO: gmpSetup still has the same problem). - '-connect/-igs/-nngs' does an autologin without putting up the username/password requester. Old behaviour selectable by #if. (I'm not sure if the cliData_decRef(cd) in src/main.c:connect_to is required. It seems to be but even without everything seems to work correct...) - When playing/observing the say/kibitz input box is activated by default. (Pressing RETURN on an empty line still switches back to 'browse-game-mode'. And the input box is empty on start...) - Use the bold font for the remaining time / score. (And added some space too.) - Put Helvetica as the first font in the font lists. The serif fonts are too hard to read with these low resolutions. - I removed all these strange cursor shapes (annoying, especially with the different hotspot locations). - Made the idle cursor look dull (recolored to some shades of gray). - Made the scroll speed faster (8 lines/second instead of 2). Ciao, ET. diff -ru cgoban-1.9.12-orig/src/cgbuts.c cgoban-1.9.12-et1/src/cgbuts.c --- cgoban-1.9.12-orig/src/cgbuts.c Tue Jan 25 05:40:24 2000 +++ cgoban-1.9.12-et1/src/cgbuts.c Mon May 13 22:52:48 2002 @@ -481,7 +481,10 @@ lw = (w + 7) / 15; if (lw < 1) lw = 1; - XSetLineAttributes(dpy, gc, lw, LineSolid, CapButt, JoinMiter); + XSetLineAttributes(dpy, gc, lw, LineSolid, CapProjecting, JoinMiter); + /* all of them require abs coordinates */ + x -= win->xOff; + y -= win->yOff; } if (piece == goStone_black) butEnv_setXFg(env, BUT_WHITE); @@ -490,35 +493,43 @@ switch(markType) { case goMark_none: break; + case goMark_cross: + off = w/3; + XDrawLine(dpy, win->win, gc, x+off, y+off, x+2*off, y+2*off); + XDrawLine(dpy, win->win, gc, x+2*off, y+off, x+off, y+2*off); + break; case goMark_triangle: - points[0].x = x+w/2 - win->xOff; - points[0].y = y+lw - win->yOff; - points[1].x = x+((w*0.9330127)-(lw*0.8660254)+0.5) - win->xOff; - points[1].y = y+((w*0.75)-(lw*0.5)+0.5) - win->yOff; - points[2].x = x+((w*0.0669873)+(lw*0.8660254)+0.5) - win->xOff; + #define SIN60 0.8660254038 + #define COS60 0.5 + points[0].x = x+w/2; + points[0].y = y+lw-1; + points[1].x = x+(w*(0.5+SIN60/2) - lw*SIN60 + 0.5); + points[1].y = y+(w*(0.5+COS60/2) - lw*COS60 + 0.5); + points[2].x = x+(w*(0.5-SIN60/2) + lw*SIN60 - 0.5); points[2].y = points[1].y; points[3] = points[0]; XDrawLines(dpy, win->win, gc, points, 4, CoordModeOrigin); break; case goMark_ko: case goMark_square: - off = (int)(w*0.14644661+lw*0.5+0.5); - XDrawRectangle(dpy, win->win, gc, x + off - win->xOff, y + off - win->yOff, - w-off*2-(lw&1),w-off*2-(lw&1)); + #define SIN45 0.7071067812 + off = w*(1-SIN45) + lw + 1; + XDrawRectangle(dpy, win->win, gc, x + off/2, y + off/2, w-off, w-off); break; case goMark_lastMove: case goMark_circle: off = (w + 1) / 4; - XDrawArc(dpy, win->win, gc, x + off - win->xOff, y + off - win->yOff, + XDrawArc(dpy, win->win, gc, x + off, y + off, w-off*2-1,w-off*2-1, 0,360*64); break; case goMark_smBlack: case goMark_smWhite: + off = (w + 1) / 4; if (markType == goMark_smBlack) - cgbuts_drawp(b, win, goStone_black, FALSE, x+(w+1)/4,y+(w+1)/4, w/2, + cgbuts_drawp(b, win, goStone_black, FALSE, x+off,y+off, w/2, stoneVersion, dx,dy,dw,dh); else - cgbuts_drawp(b, win, goStone_white, FALSE, x+(w+1)/4,y+(w+1)/4, w/2, + cgbuts_drawp(b, win, goStone_white, FALSE, x+off,y+off, w/2, stoneVersion, dx,dy,dw,dh); break; case goMark_letter: @@ -531,7 +542,7 @@ assert(markAux >= 0); if (markAux > 999) markAux = 999; - if ((markAux > 99) && (w < butEnv_fontH(env, 0) * 2)) + if ((markAux > 99) && (w < butEnv_fontH(env, 1) * 2)) sprintf(text, "%02d", markAux % 100); else sprintf(text, "%d", markAux); diff -ru cgoban-1.9.12-orig/src/cgbuts.h cgoban-1.9.12-et1/src/cgbuts.h --- cgoban-1.9.12-orig/src/cgbuts.h Tue Jan 25 05:40:24 2000 +++ cgoban-1.9.12-et1/src/cgbuts.h Sun Apr 21 20:04:13 2002 @@ -75,7 +75,7 @@ typedef enum { goMark_none, goMark_lastMove, goMark_ko, - goMark_triangle, goMark_square, goMark_circle, + goMark_cross, goMark_triangle, goMark_square, goMark_circle, goMark_letter, goMark_number, goMark_smWhite, goMark_smBlack } GoMarkType; #define goMark_max (goMark_ko + 1) diff -ru cgoban-1.9.12-orig/src/cgoban.c cgoban-1.9.12-et1/src/cgoban.c --- cgoban-1.9.12-orig/src/cgoban.c Thu Feb 28 04:34:35 2002 +++ cgoban-1.9.12-et1/src/cgoban.c Mon May 13 14:46:31 2002 @@ -91,6 +91,7 @@ {"board.showCoords", "t", NULL, CLPSETUP_SHOWBOOL|CLPSETUP_BOOL, NULL}, CLPSETUP_MSG(""), {"edit", "", "Edit SGF file", CLPSETUP_NOSAVE, NULL}, + {"connect", "", "Connect to given server", CLPSETUP_NOSAVE, NULL}, {"nngs", "f", "Connect to NNGS", CLPSETUP_BOOL|CLPSETUP_NOSAVE, NULL}, {"igs", "f", "Connect to IGS", CLPSETUP_BOOL|CLPSETUP_NOSAVE, NULL}, {"iconic", "f", NULL, CLPSETUP_BOOL|CLPSETUP_NOSAVE, NULL}, @@ -100,7 +101,7 @@ {"help.y", "", NULL, 0, NULL}, {"help.w", "28.284271", NULL, 0, NULL}, {"help.h", "40.0", NULL, 0, NULL}, - {"game.rules", "0", NULL, 0, checkRules}, + {"game.rules", "1", NULL, 0, checkRules}, {"game.size", "19", NULL, 0, checkSize}, {"game.komi", "5.5", NULL, 0, checkKomi}, {"game.handicap", "0", NULL, 0, checkHandicap}, @@ -109,7 +110,7 @@ {"local.x", "", NULL, 0, NULL}, {"local.y", "", NULL, 0, NULL}, {"local.bProp", "1.0", NULL, 0, checkBProp}, - {"local.bPropW", "1.0", NULL, 0, checkBProp}, + {"local.bPropW", "2.0", NULL, 0, checkBProp}, {"local.sgfName", "game.sgf", NULL, 0, NULL}, {"edit.x", "", NULL, 0, NULL}, {"edit.y", "", NULL, 0, NULL}, @@ -118,13 +119,13 @@ {"edit.toolW", "0.0", NULL, 0, NULL}, {"edit.toolH", "0.0", NULL, 0, NULL}, {"edit.bProp", "1.0", NULL, 0, checkBProp}, - {"edit.bPropW", "1.0", NULL, 0, checkBProp}, + {"edit.bPropW", "2.0", NULL, 0, checkBProp}, {"edit.sgfName", "seigen-minoru.sgf", NULL, 0, NULL}, {"edit.infoX", "", NULL, 0, NULL}, {"edit.infoY", "", NULL, 0, NULL}, {"edit.infoW", "1.0", NULL, 0, NULL}, {"edit.infoH", "1.0", NULL, 0, NULL}, - {"setup.timeType", "2", NULL, 0, checkTimeType}, + {"setup.timeType", "3", NULL, 0, checkTimeType}, {"setup.mainTime", "30:00", NULL, 0, checkTimeValue}, {"setup.igsBYTime", "10:00", NULL, 0, checkTimeValue}, {"setup.igsBYStones", "25", NULL, 0, checkBYStones}, @@ -189,13 +190,13 @@ {"client.x", "", NULL, 0, NULL}, {"client.y", "", NULL, 0, NULL}, {"client.bProp", "1.0", NULL, 0, checkBProp}, - {"client.bPropW", "1.0", NULL, 0, checkBProp}, + {"client.bPropW", "2.0", NULL, 0, checkBProp}, {"client.numberKibitz", "f", NULL, CLPSETUP_BOOL, NULL}, {"client.noTypo", "f", NULL, CLPSETUP_BOOL, NULL}, {"client.look.x", "", NULL, 0, NULL}, {"client.look.y", "", NULL, 0, NULL}, {"client.look.bProp", "1.0", NULL, 0, checkBProp}, - {"client.look.bPropW", "1.0", NULL, 0, checkBProp}, + {"client.look.bPropW", "2.0", NULL, 0, checkBProp}, {"client.saykib", "1", NULL, 0, NULL}, {"client.warnLimit", "30", NULL, 0, NULL}, {"abut.fsel.x", "", NULL, 0, NULL}, @@ -287,6 +288,7 @@ butEnv_setFont(cg->env, 1, msg_labelFonts, (cg->fontH*5+3)/6); butEnv_setFont(cg->env, 2, msg_bFonts, cg->fontH); + butEnv_setFont(cg->env, 3, msg_fFonts, cg->fontH); cgbuts_init(&cg->cgbuts, cg->env, cg->rnd, color, clp_getBool(cg->clp, "client.noTypo"), clp_getBool(cg->clp, "hiContrast"), diff -ru cgoban-1.9.12-orig/src/client/board.c cgoban-1.9.12-et1/src/client/board.c --- cgoban-1.9.12-orig/src/client/board.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/client/board.c Fri Apr 12 10:03:39 2002 @@ -65,7 +65,7 @@ static const ButKey ctrlKeys[] = {{XK_Control_L, 0,0}, {XK_Control_R,0,0}, {0,0,0}}; CliBoard *cli; - Str gameName; + Str gameName, whiteName, blackName; cli = wms_malloc(sizeof(CliBoard)); MAGIC_SET(cli); @@ -99,14 +99,20 @@ cli->game->forcePlay = TRUE; cli->sgf->mode = sgfInsert_variant; str_init(&gameName); + str_init(&whiteName); + str_init(&blackName); + str_print(&whiteName, "%s %s", str_chars(wName), str_chars(wRank)); + str_print(&blackName, "%s %s", str_chars(bName), str_chars(bRank)); str_print(&gameName, msg_cliGameName, gameNum, - str_chars(wName), str_chars(wRank), - str_chars(bName), str_chars(bRank)); + str_chars(&whiteName), str_chars(&blackName)); cli->goban = goban_create(cli->cg, &actions, cli, cli->game, - "client", str_chars(&gameName)); + "client", str_chars(&gameName), + str_chars(&whiteName), str_chars(&blackName)); goban_startTimer(cli->goban, goGame_whoseMove(cli->game)); goban_setHold(cli->goban, TRUE); but_setFlags(cli->goban->save, BUT_NOPRESS); + str_deinit(&blackName); + str_deinit(&whiteName); str_deinit(&gameName); cli->goban->iDec1 = grid_create(&cli->cg->cgbuts, NULL, NULL, cli->goban->iWin, 2, BUT_DRAWABLE, 0); diff -ru cgoban-1.9.12-orig/src/client/conn.c cgoban-1.9.12-et1/src/client/conn.c --- cgoban-1.9.12-orig/src/client/conn.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/client/conn.c Thu May 9 19:45:22 2002 @@ -142,64 +142,70 @@ static ButOut newNetData(void *packet, int fd) { CliConn *cc = packet; - int amtRead, totalAmtRead, readLen, lineStart, lineEnd; + int len; assert(MAGIC(cc)); - totalAmtRead = 0; - do { - if (cc->inLen + totalAmtRead + 1 >= cc->inSize) - expandBuf(&cc->inBuf, &cc->inSize, cc->inLen); - readLen = cc->inSize - (cc->inLen + totalAmtRead + 1); - amtRead = read(cc->fd, cc->inBuf + cc->inLen, readLen); - if (amtRead < 0) { - if (errno == EAGAIN) - amtRead = 0; - else { - cc->newData(cc->packet, NULL, errno); - return(0); - } - } else if (amtRead == 0) { + if (cc->inLen + 1 >= cc->inSize) /* +1 for \0 */ + expandBuf(&cc->inBuf, &cc->inSize, len); + /*FIXME: if server sends a sequence of non-LF chars we run OOM...*/ + + len = read(cc->fd, cc->inBuf + cc->inLen, cc->inSize - cc->inLen - 1); + if (len <= 0) + { + if (len == 0) /* EOF */ + cc->newData(cc->packet, NULL, 0); + else if (errno != EAGAIN) cc->newData(cc->packet, NULL, errno); - return(0); - } - totalAmtRead += amtRead; - } while (amtRead == readLen); - totalAmtRead = telnetMunge(cc, totalAmtRead); - if (totalAmtRead < 0) { + return 0; + } + + len = telnetMunge(cc, len); + if (len < 0) /* a telnet ^C packet */ + { cc->newData(cc->packet, NULL, EPIPE); - return(0); + return 0 ; } - if (totalAmtRead > 0) { - cc->inLen += totalAmtRead; - assert(cc->inLen < cc->inSize); - lineStart = 0; - for (;;) { - lineEnd = lineStart; - while ((lineEnd < cc->inLen) && (cc->inBuf[lineEnd] != '\n')) - ++lineEnd; - if ((lineEnd < cc->inLen) || - (cc->loginMode && - (((lineEnd - lineStart == 7) && - !strncmp(cc->inBuf + lineStart, "Login: ", 7)) || - ((lineEnd - lineStart == 10) && - !strncmp(cc->inBuf + lineStart, "Password: ", 10)) || - ((lineEnd - lineStart == 3) && - !strncmp(cc->inBuf + lineStart, "#> ", 3))))) { - cc->inBuf[lineEnd] = '\0'; -#if TRACELOG - printf("%s\n", cc->inBuf + lineStart); + + if (len > 0) + { + char *s = cc->inBuf; + char *e = s + cc->inLen + len; + char *p; + + *e = '\0'; + /* pass complete lines */ + while (s < e && (p = memchr(s, '\n', e - s))) + { + *p = '\0'; +#if TRACELOG + printf("`%s'\n", s); #endif - cc->newData(cc->packet, cc->inBuf + lineStart, lineEnd - lineStart); - lineStart = lineEnd + 1; - } else - break; + cc->newData(cc->packet, s, p - s); + s = p + 1; } - if (lineStart >= cc->inLen) { - cc->inLen = 0; - } else if (lineStart > 0) { - memmove(cc->inBuf, cc->inBuf + lineStart, cc->inLen - lineStart); - cc->inLen -= lineStart; + /* in login mode we may pass (some) incomplete lines */ + if (s < e && cc->loginMode) + { + /* strip trailing whitespace */ + for (p = e; p > s && isspace(p[-1]); *--p = '\0') + ; + if (!strcmp(s, "Login:") || !strcmp(s, "Password:") || !strcmp(s, "#>")) + { +#if TRACELOG + printf("`%s'\n", s); +#endif + cc->newData(cc->packet, s, p - s); + s = e + 1; + } + } + if (s < e) + { + cc->inLen = e - s; + if (s > cc->inBuf) + memmove(cc->inBuf, s, cc->inLen); } + else + cc->inLen = 0; } return(0); } diff -ru cgoban-1.9.12-orig/src/client/game.c cgoban-1.9.12-et1/src/client/game.c --- cgoban-1.9.12-orig/src/client/game.c Thu Feb 28 04:29:03 2002 +++ cgoban-1.9.12-et1/src/client/game.c Wed Apr 24 16:35:22 2002 @@ -115,7 +115,7 @@ cg = gl->data->cg; physH = butEnv_fontH(gl->data->cg->env, 0); bw = butEnv_stdBw(gl->data->cg->env); - minWinW = physH * 18 + bw * 8; + minWinW = physH * 19 + bw * 8; winW = minWinW + physH * 2 * clp_getInt(cg->clp, "client.games.w"); wHRatio = clp_getDouble(cg->clp, "client.games.h2"); winH = ((double)(minWinW + physH * 12) * wHRatio + 0.5); @@ -165,6 +165,15 @@ } +void cliGameList_gotTitle(CliGameList *gl, const char *buf) { + if (gl->defaultGame >= 0) { + CliBoard *b = gl->games[gl->defaultGame].board; + if (b) + butText_set(b->goban->labelText, buf); + } +} + + void cliGameList_gotMove(CliGameList *gl, const char *buf) { int args; int moveNum, handicap; @@ -351,6 +360,7 @@ cliPlayerList_playerInGame(gl->playerList, bName, gameNum); g->moveNum = move; if (g->board && g->fromMatch && (move < 2)) { + str_clip(&gl->data->cmdBuild, 0); if (g->komi != komi) str_print(&gl->data->cmdBuild, "komi %g\n", g->komi); if (g->board->moveBlack) { @@ -519,7 +529,6 @@ int fontH; int physFontH = butEnv_fontH(butWin_env(win), 0); int slideW = (physFontH * 3)/2; - int centerAdd; assert(MAGIC(gl)); fontH = gl->data->cg->fontH; @@ -535,28 +544,27 @@ slideW, physFontH); butCan_resizeWin(gl->swin->win, 0, butList_len(gl->list) * physFontH + bw * 2, TRUE); - centerAdd = (physFontH * 3 + 1) / 4; - tabs[0] = (physFontH * 2) / 2; - tabs[1] = (physFontH * 3) / 2; - tabs[2] = (physFontH * 17) / 2; - tabs[3] = (physFontH * 20) / 2; - tabs[4] = (physFontH * 37) / 2; - tabs[5] = (physFontH * 41) / 2; - tabs[6] = (physFontH * 45) / 2; - tabs[7] = (physFontH * 49) / 2; - tabs[8] = (physFontH * 53) / 2; - tabs[9] = (physFontH * 57) / 2; - if (w < physFontH * 20 + bw * 8) + tabs[0] = (physFontH * 3) / 2; + tabs[1] = (physFontH * 4) / 2; + tabs[2] = (physFontH * 18) / 2; + tabs[3] = (physFontH * 21) / 2; + tabs[4] = (physFontH * 38) / 2; + tabs[5] = (physFontH * 42) / 2; + tabs[6] = (physFontH * 46) / 2; + tabs[7] = (physFontH * 50) / 2; + tabs[8] = (physFontH * 54) / 2; + tabs[9] = (physFontH * 58) / 2; + if (w < physFontH * 21 + bw * 8) tabs[4] += physFontH * 20; - if (w < physFontH * 22 + bw * 8) + if (w < physFontH * 23 + bw * 8) tabs[5] += physFontH * 20; - if (w < physFontH * 24 + bw * 8) + if (w < physFontH * 25 + bw * 8) tabs[6] += physFontH * 20; - if (w < physFontH * 26 + bw * 8) + if (w < physFontH * 27 + bw * 8) tabs[7] += physFontH * 20; - if (w < physFontH * 28 + bw * 8) + if (w < physFontH * 29 + bw * 8) tabs[8] += physFontH * 20; - if (w < physFontH * 30 + bw * 8) + if (w < physFontH * 31 + bw * 8) tabs[9] += physFontH * 20; butList_setTabs(gl->title, tabs, tabAligns, 10); butList_setTabs(gl->list, tabs, tabAligns, 10); @@ -599,6 +607,19 @@ return(0); } +static const char * +opt_num(int num, int ignore) +{ + static char buf[64]; + static char *p = buf; + + if (num == ignore) + return "·"; + if ((p += 8) >= buf + sizeof(buf)) + p = buf; + sprintf(p, "%d", num); + return p; +} static void getListEl(CliGameList *gl, int gNum, Str *out) { switch(gl->games[gNum].state) { @@ -606,28 +627,30 @@ str_copyCharsLen(out, "", 0); break; case cliGame_over: - str_print(out, "\t-\t%s [%s]\tvs.\t%s [%s]\t%d\t%d\t%d\t%g\t\t%s", + str_print(out, "\t\t%s [%s]\tvs.\t%s [%s]\t%s\t%s\t%s\t%g\t\t%s", str_chars(&gl->games[gNum].wName), str_chars(&gl->games[gNum].wRank), str_chars(&gl->games[gNum].bName), str_chars(&gl->games[gNum].bRank), - gl->games[gNum].moveNum, - gl->games[gNum].size, - gl->games[gNum].handicap, gl->games[gNum].komi, + opt_num(gl->games[gNum].moveNum, 0), + opt_num(gl->games[gNum].size, 19), + opt_num(gl->games[gNum].handicap, 0), + gl->games[gNum].komi, str_chars(&gl->games[gNum].flags)); break; default: - str_print(out, "\t%d\t%s [%s]\tvs.\t%s [%s]\t%d\t%d\t%d\t%g\t%s\t(%d)", + str_print(out, "\t%d\t%s [%s]\tvs.\t%s [%s]\t%s\t%s\t%s\t%g\t%s\t%s", gNum, str_chars(&gl->games[gNum].wName), str_chars(&gl->games[gNum].wRank), str_chars(&gl->games[gNum].bName), str_chars(&gl->games[gNum].bRank), - gl->games[gNum].moveNum, - gl->games[gNum].size, - gl->games[gNum].handicap, gl->games[gNum].komi, + opt_num(gl->games[gNum].moveNum, 0), + opt_num(gl->games[gNum].size, 19), + opt_num(gl->games[gNum].handicap, 0), + gl->games[gNum].komi, str_chars(&gl->games[gNum].flags), - gl->games[gNum].observers); + opt_num(gl->games[gNum].observers, 0)); break; } } diff -ru cgoban-1.9.12-orig/src/client/game.h cgoban-1.9.12-et1/src/client/game.h --- cgoban-1.9.12-orig/src/client/game.h Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/client/game.h Wed Apr 3 23:13:29 2002 @@ -77,5 +77,6 @@ extern void cliGameList_deadStone(CliGameList *gl, const char *buf); extern void cliGameList_gotUndo(CliGameList *gl, const char *buf); extern bool cliGame_tellIsSay(CliGameList *list, Str *tell); +extern void cliGameList_gotTitle(CliGameList *gl, const char *buf); #endif /* _CLIENT_MAIN_H_ */ diff -ru cgoban-1.9.12-orig/src/client/login.c cgoban-1.9.12-et1/src/client/login.c --- cgoban-1.9.12-orig/src/client/login.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/client/login.c Thu May 9 19:36:52 2002 @@ -38,7 +38,7 @@ cl = wms_malloc(sizeof(CliLogin)); MAGIC_SET(cl); cl->cd = cd; - fs = butEnv_fontStr(cd->cg->env, 0); + fs = butEnv_fontStr(cd->cg->env, TBIN_FONTNUM); conn = cliConn_init(&cd->conn, cd->cg, cd->serverNum, cd->server, fs->min_char_or_byte2, fs->max_char_or_byte2, cliLogin_dataIn, cl); @@ -118,7 +118,7 @@ cliMain_log(cl->main, "\n"); switch(cl->state) { case cliLogin_waitForUser: - if (!strcmp(buf, "Login: ")) { + if (!strcmp(buf, "Login:")) { cl->state = cliLogin_waitForPassword; cliConn_send(&cl->cd->conn, str_chars(&cl->user)); cliMain_log(cl->main, str_chars(&cl->user)); @@ -127,7 +127,7 @@ break; case cliLogin_waitForPassword: if (!strcmp(buf, "1 1") || - !strcmp(buf, "Password: ")) { + !strcmp(buf, "Password:")) { cl->state = cliLogin_waitForPrompt; if ((str_len(&cl->pass) == 0) && (cl->cd->server == cliServer_nngs)) { str_init(&errStr); @@ -141,7 +141,7 @@ cliConn_send(&cl->cd->conn, str_chars(&cl->pass)); cliMain_log(cl->main, "******\n"); } - } else if (!strcmp(buf, "#> ")) { + } else if (!strcmp(buf, "#>")) { cliConn_send(&cl->cd->conn, "toggle client 1\n"); cliMain_message(cl->main, msg_guest); cl->state = cliLogin_waitForPrompt; @@ -149,11 +149,11 @@ } break; case cliLogin_waitForPrompt: - if (!strcmp(buf, "Login: ")) { + if (!strcmp(buf, "Login:")) { cliMain_message(cl->main, msg_loginFailed); cliLogin_destroy(cl, TRUE); return; - } else if (!strcmp(buf, "#> ")) { + } else if (!strcmp(buf, "#>")) { cliConn_send(&cl->cd->conn, "toggle client 1\n"); cliMain_log(cl->main, "toggle client 1\n"); } else if (!strcmp(buf, "1 5")) { diff -ru cgoban-1.9.12-orig/src/client/look.c cgoban-1.9.12-et1/src/client/look.c --- cgoban-1.9.12-orig/src/client/look.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/client/look.c Fri Apr 12 09:50:42 2002 @@ -104,7 +104,7 @@ moveOk, moveOk, moveOk, moveOk}; Goban *goban; GoGame *game; - Str title; + Str title, white, black; static const GoTime noTime = {goTime_none, 0, 0, 0}; CliLookChild *child; int i; @@ -124,11 +124,13 @@ child = wms_malloc(sizeof(CliLookChild)); MAGIC_SET(child); str_init(&title); - str_print(&title, msg_cliLookName, - str_chars(&look->name[goStone_white]), - str_chars(&look->rank[goStone_white]), - str_chars(&look->name[goStone_black]), - str_chars(&look->rank[goStone_black])); + str_init(&white); + str_init(&black); + str_print(&white, "%s %s", str_chars(&look->name[goStone_white]), + str_chars(&look->rank[goStone_white])); + str_print(&black, "%s %s", str_chars(&look->name[goStone_black]), + str_chars(&look->rank[goStone_black])); + str_print(&title, msg_cliLookName, str_chars(&white), str_chars(&black)); /* * I pass in a handicap of 0 even though I know the real handicap. Why? * because otherwise when I parse over the board, if I find a white @@ -141,7 +143,7 @@ &noTime, TRUE); makeMoves(game, str_chars(&look->boardData), size); goban = goban_create(look->cg, &actions, child, game, "client.look", - str_chars(&title)); + str_chars(&title), str_chars(&white), str_chars(&black)); goban->pic->allowedMoves = goPicMove_noWhite | goPicMove_noBlack; goban->iDec1 = grid_create(&look->cg->cgbuts, NULL, NULL, goban->iWin, 2, BUT_DRAWABLE, 0); @@ -154,6 +156,8 @@ butText_set(goban->infoText, "Static Game Board"); child->game = game; child->goban = goban; + str_deinit(&black); + str_deinit(&white); str_deinit(&title); } diff -ru cgoban-1.9.12-orig/src/client/main.c cgoban-1.9.12-et1/src/client/main.c --- cgoban-1.9.12-orig/src/client/main.c Sat Feb 26 23:53:49 2000 +++ cgoban-1.9.12-et1/src/client/main.c Mon Apr 29 18:14:51 2002 @@ -296,8 +296,10 @@ ++buf; --bufLen; } - ++buf; - --bufLen; + if (isspace(*buf)) { + ++buf; + --bufLen; + } str_copyCharsLen(&cMain->outStr, buf, bufLen); str_catChar(&cMain->outStr, '\n'); } @@ -347,6 +349,8 @@ cliGameList_deadStone(&cMain->gameList, buf); else if (!strncmp(buf, "You can check ", 14)) cliGameList_selectDead(&cMain->gameList, buf); + else if (!strncmp(buf, "Game is titled: ", 16)) + cliGameList_gotTitle(&cMain->gameList, buf + 16); else if (!strncmp(buf, "Use playerList.match, buf); - else if (strncmp(buf, "Adding game to", 14) && + else if (!strncmp(buf, "Player:", 7)) { + /* it's hard to read... */ + cliMain_log(cMain, "--- Player stats ---\n"); + cliMain_log(cMain, str_chars(&cMain->outStr)); + } else if (strncmp(buf, "Adding game to", 14) && strncmp(buf, "{Game ", 6) && strncmp(buf, "Requesting ", 11) && strncmp(buf, "You decline", 11) && diff -ru cgoban-1.9.12-orig/src/client/match.c cgoban-1.9.12-et1/src/client/match.c --- cgoban-1.9.12-orig/src/client/match.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/client/match.c Mon May 13 23:00:48 2002 @@ -61,6 +61,10 @@ match = cliMatch_create(data, oppName, next, rankDiff); if ((colorChar == 'B') != match->meFirst) swapPressed(match->swap); +#if 0 /* ET: issue an automatic "stats " on game request */ + str_print(&data->cmdBuild, "stats %s\n", oppName); + cliConn_send(&data->conn, str_chars(&data->cmdBuild)); +#endif } else { /* Modify an old one. */ XRaiseWindow(butEnv_dpy(butWin_env(match->win)), butWin_xwin(match->win)); diff -ru cgoban-1.9.12-orig/src/client/player.c cgoban-1.9.12-et1/src/client/player.c --- cgoban-1.9.12-orig/src/client/player.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/client/player.c Mon Apr 29 17:42:29 2002 @@ -305,13 +305,14 @@ void cliPlayerList_whoOutput(CliPlayerList *pl, const char *buf) { + int len = strlen(buf); char onePlayer[36]; - if (buf[1] != 'I') { + if (len > 20 && buf[1] != 'I') { strncpy(onePlayer, buf, 35); onePlayer[35] = '\0'; updatePlayer(pl, onePlayer); - if (strlen(buf) > 50) { + if (len > 50) { strncpy(onePlayer, buf+37, 35); onePlayer[35] = '\0'; updatePlayer(pl, onePlayer); diff -ru cgoban-1.9.12-orig/src/control.c cgoban-1.9.12-et1/src/control.c --- cgoban-1.9.12-orig/src/control.c Tue Jan 25 05:40:24 2000 +++ cgoban-1.9.12-et1/src/control.c Thu May 9 17:27:15 2002 @@ -119,7 +119,10 @@ ctrl->sPics[1] = grid_create(&cg->cgbuts, NULL, NULL, ctrl->win, 2, BUT_DRAWABLE|BUT_PRESSTHRU, 0); grid_setStone(ctrl->sPics[1], goStone_white, FALSE); - grid_setVersion(ctrl->sPics[1], CGBUTS_WORLDEAST(1)); + if (clp_getStrNum(cg->clp, "client.protocol", serverNum)[0] == 'n') + grid_setVersion(ctrl->sPics[1], CGBUTS_WORLDWEST(1)); + else + grid_setVersion(ctrl->sPics[1], CGBUTS_WORLDEAST(1)); grid_setLineGroup(ctrl->sPics[1], gridLines_none); ctrl->lGame = butCt_create(localGoban, ctrl, ctrl->win, 1, diff -ru cgoban-1.9.12-orig/src/editBoard.c cgoban-1.9.12-et1/src/editBoard.c --- cgoban-1.9.12-orig/src/editBoard.c Tue Jan 25 05:40:24 2000 +++ cgoban-1.9.12-et1/src/editBoard.c Sun Apr 21 20:05:37 2002 @@ -214,7 +214,7 @@ } eb->goban = goban_create(cg, &editBoard_actions, eb, eb->game, "edit", - title); + title, white, black); if (tmpTitle) str_destroy(tmpTitle); eb->goban->iDec1 = stoneGroup_create(&cg->cgbuts, eb->goban->iWin, 2, @@ -319,6 +319,18 @@ else result = gobanOut_err; break; + case editTool_cross: + if (butEnv_keyModifiers(env) & ShiftMask) { + if (!markGroup(eb, sgfType_cross, loc)) + result = gobanOut_err; + else { + eb->tools.modified = TRUE; + } + } else { + eb->tools.modified = TRUE; + setMark(eb, sgfType_cross, loc, setMark_toggle); + } + break; case editTool_triangle: if (butEnv_keyModifiers(env) & ShiftMask) { if (!markGroup(eb, sgfType_triangle, loc)) @@ -832,6 +844,7 @@ for (search = eb->sgf->active; search && (search->type != sgfType_node); search = search->parent) { if (((search->type == sgfType_triangle) || + (search->type == sgfType_cross) || (search->type == sgfType_circle) || (search->type == sgfType_square)) && (goBoard_sgf2Loc(eb->game->board, search->lVal) == loc)) { @@ -853,11 +866,13 @@ eb->sgf->mode = sgfInsert_variant; if (sType == sgfType_triangle) { markAdded = goMark_triangle; + } else if (sType == sgfType_circle) { + markAdded = goMark_circle; } else if (sType == sgfType_square) { markAdded = goMark_square; } else { - assert(sType == sgfType_circle); - markAdded = goMark_circle; + assert(sType == sgfType_cross); + markAdded = goMark_cross; } grid_setMark(eb->goban->pic->boardButs[loc], markAdded, 0); } @@ -956,7 +971,7 @@ return(FALSE); oldMark = grid_markType(eb->goban->pic->boardButs[loc]); if ((oldMark == goMark_triangle) || (oldMark == goMark_square) || - (oldMark == goMark_circle)) + (oldMark == goMark_cross) || (oldMark == goMark_circle)) action = setMark_forceOff; else action = setMark_forceOn; @@ -1020,6 +1035,7 @@ pressAllowed = goPicMove_stone | goPicMove_noPass; gameState = goGameState_selectDead; break; + case editTool_cross: case editTool_triangle: case editTool_square: case editTool_circle: diff -ru cgoban-1.9.12-orig/src/editTool.c cgoban-1.9.12-et1/src/editTool.c --- cgoban-1.9.12-orig/src/editTool.c Wed Feb 9 07:50:02 2000 +++ cgoban-1.9.12-et1/src/editTool.c Sun Apr 21 20:05:47 2002 @@ -119,6 +119,13 @@ grid_setLineGroup(b, gridLines_none); grid_setVersion(b, CGBUTS_YINYANG(1)); + etw->selDesc[editTool_cross] = b = + grid_create(&cg->cgbuts, NULL, NULL, etw->toolWin, + 2, BUT_DRAWABLE|BUT_PRESSTHRU, 0); + grid_setStone(b, goStone_black, FALSE); + grid_setLineGroup(b, gridLines_none); + grid_setMark(b, goMark_cross, 0); + etw->selDesc[editTool_triangle] = b = grid_create(&cg->cgbuts, NULL, NULL, etw->toolWin, 2, BUT_DRAWABLE|BUT_PRESSTHRU, 0); diff -ru cgoban-1.9.12-orig/src/editTool.h cgoban-1.9.12-et1/src/editTool.h --- cgoban-1.9.12-orig/src/editTool.h Wed Feb 9 07:50:02 2000 +++ cgoban-1.9.12-et1/src/editTool.h Sun Apr 21 20:05:57 2002 @@ -25,7 +25,7 @@ **********************************************************************/ typedef enum { editTool_play, editTool_changeBoard, editTool_score, - editTool_triangle, editTool_square, editTool_circle, + editTool_cross, editTool_triangle, editTool_square, editTool_circle, editTool_letter, editTool_number } EditTool; #define editTool_min editTool_play diff -ru cgoban-1.9.12-orig/src/gmp/play.c cgoban-1.9.12-et1/src/gmp/play.c --- cgoban-1.9.12-orig/src/gmp/play.c Wed Feb 9 07:50:05 2000 +++ cgoban-1.9.12-et1/src/gmp/play.c Fri Apr 12 09:47:22 2002 @@ -143,7 +143,7 @@ int size, hcap; float komi; GoTime time; - const char *title; + const char *title, *white = NULL, *black = NULL; GoStone s; assert(MAGIC(cg)); @@ -196,9 +196,18 @@ } else { title = msg_noTitle; } + + me = sgf_findFirstType(mc, sgfType_playerName); + while (me) { + if (me->gVal == goStone_white) + white = str_chars(me->sVal); + else + black = str_chars(me->sVal); + me = sgfElem_findFirstType(me, sgfType_playerName); + } l->goban = goban_create(cg, &gmpPlay_actions, l, l->game, "local", - title); + title, white, black); l->goban->pic->allowedMoves |= goPicMove_noWhite | goPicMove_noBlack; goPic_update(l->goban->pic); goban_message(l->goban, msg_waitingForGame); diff -ru cgoban-1.9.12-orig/src/goTime.c cgoban-1.9.12-et1/src/goTime.c --- cgoban-1.9.12-orig/src/goTime.c Tue Jan 25 05:40:24 2000 +++ cgoban-1.9.12-et1/src/goTime.c Fri Apr 12 10:07:29 2002 @@ -185,7 +185,7 @@ break; case(goTime_canadian): goTime_str(tLeft, out); - str_catChar(out, '/'); + str_catChars(out, " / "); if (timer->aux == 0) { str_catChar(out, '-'); } else { @@ -195,7 +195,7 @@ case(goTime_japanese): goTime_str(tLeft, out); if (tLeft <= time->aux * time->by) { - str_catChar(out, '('); + str_catChars(out, " ("); if (tLeft < 0) str_catChar(out, '0'); else diff -ru cgoban-1.9.12-orig/src/goban.c cgoban-1.9.12-et1/src/goban.c --- cgoban-1.9.12-orig/src/goban.c Thu Feb 28 04:34:35 2002 +++ cgoban-1.9.12-et1/src/goban.c Tue May 7 22:19:50 2002 @@ -71,7 +71,8 @@ Goban *goban_create(Cgoban *cg, const GobanActions *actions,void *packet, - GoGame *game, const char *clpName, const char *title) { + GoGame *game, const char *clpName, const char *title, + const char *white, const char *black) { static ButKey rewKeys[] = {{XK_Home, 0,0}, {0,0,0}}; static ButKey backKeys[] = {{XK_Left, 0,0}, {0,0,0}}; static ButKey fwdKeys[] = {{XK_Right, 0,0}, {0,0,0}}; @@ -112,7 +113,7 @@ winSize = WIN_W(cg->fontH, butEnv_stdBw(cg->env)); g->win = butWin_iCreate(g, cg->env, title, - (int)(winSize * clpEntry_getDouble(g->bPropW) + 0.5), + (int)(winSize * clpEntry_getDouble(g->bPropW)/2 + 0.5), (int)(winSize * clpEntry_getDouble(g->bProp) + 0.5), &g->iWin, FALSE, 64,64, NULL, NULL, resize, iResize, destroy); @@ -181,20 +182,25 @@ but_setKeys(g->ff, ffKeys); for (s = goStone_white; s <= goStone_black; ++s) { + const char *name = s == goStone_white ? white : black; + pi = &g->playerInfos[s]; pi->box = butBoxFilled_create(g->win, 1, BUT_DRAWABLE); - for (i = 0; i < 5; ++i) { - assert(i < CGBUTS_NUMWHITE); - pi->stones[i] = grid_create(&g->cg->cgbuts, NULL, NULL, g->win, 2, - BUT_DRAWABLE, 0); - grid_setStone(pi->stones[i], s, FALSE); - grid_setLineGroup(pi->stones[i], gridLines_none); - grid_setVersion(pi->stones[i], i); - } + + pi->stone = grid_create(&g->cg->cgbuts, NULL, NULL, g->win, 2, + BUT_DRAWABLE, 0); + grid_setStone(pi->stone, s, FALSE); + grid_setLineGroup(pi->stone, gridLines_none); + /*grid_setVersion(pi->stones[i], i);*/ + + pi->nameLabel = butText_create(g->win, 2, BUT_DRAWABLE, name, butText_left); + butText_setFont(pi->nameLabel, 2); + pi->capsLabel = butText_create(g->win, 2, BUT_DRAWABLE, msg_score, butText_left); pi->capsOut = butText_create(g->win, 3, BUT_DRAWABLE, "0", butText_right); butText_setColor(pi->capsOut, CGBUTS_COLORREDLED, FALSE); + butText_setFont(pi->capsOut, 2); pi->capsBox = butBoxFilled_create(g->win, 2, BUT_DRAWABLE); butBoxFilled_setColors(pi->capsBox, BUT_SHAD,BUT_LIT,BUT_FG); pi->timeLabel = butText_create(g->win, 2, BUT_DRAWABLE, @@ -202,6 +208,7 @@ pi->timeOut = butText_create(g->win, 3, BUT_DRAWABLE, "", butText_right); butText_setColor(pi->timeOut, CGBUTS_COLORREDLED, FALSE); + butText_setFont(pi->timeOut, 2); pi->timeBox = butBoxFilled_create(g->win, 2, BUT_DRAWABLE); butBoxFilled_setColors(pi->timeBox, BUT_SHAD,BUT_LIT,BUT_FG); } @@ -279,7 +286,7 @@ butW = fontH * 10 + bw*4; boardW = winW - butW - fontH*3 - bw*2; clpEntry_setDouble(g->bProp, (double)winH / (double)butWin_getMinH(win)); - clpEntry_setDouble(g->bPropW, (double)winW / (double)butWin_getMinW(win)/2.0); + clpEntry_setDouble(g->bPropW, (double)winW / (double)butWin_getMinW(win)); butH = fontH * 2; butSpc = fontH * 2 + bw; @@ -326,9 +333,9 @@ for (s = goStone_white; s <= goStone_black; ++s) { pi = &g->playerInfos[s]; but_resize(pi->box, butX,butY, butW,boxH); - for (i = 0; i < 5; ++i) - but_resize(pi->stones[i], butX+bw*2+bigStoneW*2*i + fontH/2, - butY+bw*2 + fontH/2, fontH, fontH); + but_resize(pi->stone, butX+bw*2 + fontH/2, butY+bw*2 + fontH/2,fontH,fontH); + butText_resize(pi->nameLabel, butX+bw*2+bigStoneW*2 + 0*fontH/2, + butY+bw*2 + fontH/2, fontH); butText_resize(pi->capsLabel, butX+bw*2,butY+butSpc+bw*2, butH); but_resize(pi->capsOut, x+bw*2,butY+bw*3+butSpc, w-bw*4,butH-bw*2); but_resize(pi->capsBox, x,butY+bw*2+butSpc, w,butH); @@ -882,7 +889,7 @@ butTbin_setReadOnly(g->comments->tbin, TRUE); butPlain_setColor(g->comments->bg, BUT_BG); g->kibIn = butTextin_create(gotKibitz, g, g->win, 1, - BUT_PRESSABLE|BUT_DRAWABLE, "", 200); + BUT_PRESSABLE|BUT_DRAWABLE|BUT_KEYED, "", 200); g->newKib = newKib; g->kibType = butRadio_create(newKibVal, g, g->win, 1, kibFlags, kibVal, 3); diff -ru cgoban-1.9.12-orig/src/goban.h cgoban-1.9.12-et1/src/goban.h --- cgoban-1.9.12-orig/src/goban.h Thu Feb 28 04:34:35 2002 +++ cgoban-1.9.12-et1/src/goban.h Fri Apr 12 09:21:52 2002 @@ -70,7 +70,7 @@ typedef struct GobanPlayerInfo_struct { - But *box, *stones[5], *capsLabel, *capsOut, *timeLabel, *timeOut; + But *box, *stone, *nameLabel, *capsLabel, *capsOut, *timeLabel, *timeOut; But *capsBox, *timeBox; } GobanPlayerInfo; @@ -129,7 +129,8 @@ **********************************************************************/ extern Goban *goban_create(Cgoban *cg, const GobanActions *actions, void *packet, GoGame *game, const char *bPropName, - const char *title); + const char *title, + const char *white, const char *black); #define goban_setTitle(g, n) butText_set((g)->labelText, (n)) #define goban_getComments(g) abutTerm_get((g)->comments) #define goban_setComments(g, c) abutTerm_set((g)->comments, (c)) diff -ru cgoban-1.9.12-orig/src/local.c cgoban-1.9.12-et1/src/local.c --- cgoban-1.9.12-orig/src/local.c Wed Feb 9 07:50:02 2000 +++ cgoban-1.9.12-et1/src/local.c Fri Apr 12 10:47:42 2002 @@ -143,7 +143,7 @@ int size, hcap; float komi; GoTime time; - const char *title; + const char *title, *white = NULL, *black = NULL; assert(MAGIC(cg)); l = wms_malloc(sizeof(Local)); @@ -176,6 +176,10 @@ } me = sgf_findFirstType(mc, sgfType_playerName); while (me) { + if (me->gVal == goStone_white) + white = str_chars(me->sVal); + else + black = str_chars(me->sVal); me = sgfElem_findFirstType(me, sgfType_playerName); } me = sgf_findFirstType(mc, sgfType_time); @@ -196,7 +200,7 @@ } l->goban = goban_create(cg, &local_actions, l, l->game, "local", - title); + title, white, black); l->goban->iDec1 = grid_create(&cg->cgbuts, NULL, NULL, l->goban->iWin, 2, BUT_DRAWABLE, 0); grid_setStone(l->goban->iDec1, goStone_white, FALSE); diff -ru cgoban-1.9.12-orig/src/main.c cgoban-1.9.12-et1/src/main.c --- cgoban-1.9.12-orig/src/main.c Sun Feb 27 00:03:46 2000 +++ cgoban-1.9.12-et1/src/main.c Mon May 13 14:46:40 2002 @@ -21,6 +21,7 @@ #include "editBoard.h" #include "crwin.h" #include "client/setup.h" +#include "client/login.h" #include "arena.h" @@ -28,6 +29,7 @@ * Forward Declarations **********************************************************************/ static void stealth(int exitVal); +static int connect_to(Cgoban *cg, const char *server); #if !DEBUG static RETSIGTYPE sigHandler(); #endif /* !DEBUG */ @@ -38,7 +40,6 @@ int retVal = 0; Control *ctrl; EditBoard *e; - CliSetup *client; cg = cgoban_create(argc, argv, envp); if (cg == NULL) { @@ -78,22 +79,12 @@ crwin_create(cg, e->goban->win, 4); control_create(cg, TRUE); } + } else if (clp_getStr(cg->clp, "connect")[0]) { + retVal = connect_to(cg, clp_getStr(cg->clp, "connect")); } else if (clp_getBool(cg->clp, "nngs")) { - if ((client = cliSetup_create(cg, cliServer_nngs)) == NULL) { - cg->env->minWindows = 0; - retVal = 1; - } else { - crwin_create(cg, client->login->win, 3); - control_create(cg, TRUE); - } + retVal = connect_to(cg, "NNGS"); } else if (clp_getBool(cg->clp, "igs")) { - if ((client = cliSetup_create(cg, cliServer_igs)) == NULL) { - cg->env->minWindows = 0; - retVal = 1; - } else { - crwin_create(cg, client->login->win, 3); - control_create(cg, TRUE); - } + retVal = connect_to(cg, "IGS"); } else { ctrl = control_create(cg, clp_getBool(cg->clp, "iconic")); crwin_create(cg, ctrl->win, 3); @@ -104,6 +95,45 @@ cgoban_destroy(cg); return(retVal); +} + + +static int connect_to(Cgoban *cg, const char *server) { + ClpEntry *sNames; + int serverNum; + + sNames = clp_lookup(cg->clp, "client.server"); + for (serverNum = 0; serverNum < SETUP_MAXSERVERS; serverNum++) + if (!strcmp(server, clpEntry_getStrNum(sNames, serverNum))) { +#if 1 /* auto-login */ + CliData *cd; + CliLogin *cl; + const char *user = clp_getStrNum(cg->clp, "client.username", serverNum); + const char *pass = clp_getStrNum(cg->clp, "client.password", serverNum); + + cd = cliData_create(cg, serverNum, NULL, NULL); + str_copyChars(&cd->userName, user); + if ((cl = cliLogin_create(cd, user, pass)) != NULL) { + cliData_decRef(cd); /*ET: not sure!?! */ + crwin_create(cg, cl->main->win, 3); + control_create(cg, TRUE); + return 0; + } +#else /* request username/password (old behaviour) */ + CliSetup *client; + + if ((client = cliSetup_create(cg, serverNum)) != NULL) { + crwin_create(cg, client->login->win, 3); + control_create(cg, TRUE); + return 0; + } +#endif + break; + } + if (serverNum >= SETUP_MAXSERVERS) + fprintf(stderr, "cgoban: Cannot find server '%s' in setup.\n", server); + cg->env->minWindows = 0; + return 1; } diff -ru cgoban-1.9.12-orig/src/msg.c cgoban-1.9.12-et1/src/msg.c --- cgoban-1.9.12-orig/src/msg.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/msg.c Mon May 13 23:22:18 2002 @@ -21,15 +21,23 @@ * Globals **********************************************************************/ const char msg_mFonts[] = + "-adobe-helvetica-medium-r-normal--%d-*-*-*-*-*-*-*/" "-adobe-utopia-medium-r-normal--%d-*-*-*-*-*-*-*/" "-adobe-times-medium-r-normal--%d-*-*-*-*-*-*-*/" "-bitstream-charter-medium-r-normal--%d-*-*-*-*-*-*-*"; const char msg_labelFonts[] = "-adobe-helvetica-bold-r-normal--%d-*-*-*-*-*-*-*"; const char msg_bFonts[] = + "-adobe-helvetica-bold-r-normal--%d-*-*-*-*-*-*-*/" "-adobe-utopia-bold-r-normal--%d-*-*-*-*-*-*-*/" "-adobe-times-bold-r-normal--%d-*-*-*-*-*-*-*/" "-bitstream-charter-black-r-normal--%d-*-*-*-*-*-*-*"; +const char msg_fFonts[] = + "-jmk-neep-medium-r-*--*-%d0-*-*-*-*-*-*/" + "-b&h-lucidatypewriter-medium-r-normal-*-%d-*-*-*-*-*-*-*/" + "-adobe-courier-medium-r-normal--%d-*-*-*-*-*-*-*/" + "-bitstream-courier-black-r-normal--%d-*-*-*-*-*-*-*/" + "fixed"; /* * From crwin.c @@ -213,12 +221,13 @@ /* From editTools.c */ const char *msg_toolNames[] = { - "Play Game", "Edit Board", "Compute Score", "Add Triangle", "Add Square", - "Add Circle", "Add Letter", "Number Stones"}; + "Play Game", "Edit Board", "Compute Score", "Add Mark", "Add Triangle", + "Add Square", "Add Circle", "Add Letter", "Number Stones"}; const char *msg_toolDesc1[] = { "Click to play a stone", "Click to add/remove white stones", "Click to mark stones as dead", + "Click to add/remove cross marks", "Click to add/remove triangle marks", "Click to add/remove square marks", "Click to add/remove circle marks", @@ -231,6 +240,7 @@ "Shift-click to mark groups of stones", "Shift-click to mark groups of stones", "Shift-click to mark groups of stones", + "Shift-click to mark groups of stones", "", "Shift-click to add/remove move numbers"}; const char msg_killNode[] = "Delete Moves"; @@ -343,7 +353,7 @@ "Login is in progress."; /* From client/board.c */ -const char msg_cliGameName[] = "Game %d: %s %s (W) vs. %s %s (B)"; +const char msg_cliGameName[] = "Game %d: %s (W) vs. %s (B)"; const char msg_close[] = "Close"; const char msg_adjourn[] = "Adjourn"; const char msg_resign[] = "Resign"; @@ -360,7 +370,7 @@ "return code %d."; /* From client/look.c */ -const char msg_cliLookName[] = "%s %s (W) vs. %s %s (B)"; +const char msg_cliLookName[] = "%s (W) vs. %s (B)"; const char msg_cliLookInfo[] = "Static Game Board"; /* From client/main.c */ diff -ru cgoban-1.9.12-orig/src/msg.h cgoban-1.9.12-et1/src/msg.h --- cgoban-1.9.12-orig/src/msg.h Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/msg.h Wed Apr 3 02:46:45 2002 @@ -11,7 +11,7 @@ /********************************************************************** * Global variables **********************************************************************/ -extern const char msg_mFonts[], msg_labelFonts[], msg_bFonts[]; +extern const char msg_mFonts[], msg_labelFonts[], msg_bFonts[], msg_fFonts[]; /* From "crwin.c" */ extern const char msg_byBillShubert[]; diff -ru cgoban-1.9.12-orig/src/sgf.h cgoban-1.9.12-et1/src/sgf.h --- cgoban-1.9.12-orig/src/sgf.h Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/sgf.h Sun Apr 21 20:07:00 2002 @@ -44,7 +44,7 @@ sgfType_timeLeft, sgfType_stonesLeft, sgfType_setBoard, sgfType_territory, - sgfType_triangle, sgfType_square, sgfType_circle, sgfType_label, + sgfType_cross,sgfType_triangle,sgfType_square,sgfType_circle,sgfType_label, sgfType_comment, sgfType_result } SgfType; @@ -114,6 +114,7 @@ #define sgf_addTerritory(mc, color, loc) \ sgf_addCLElem(mc, sgfType_territory, color, loc) #define sgf_addTriangle(mc, loc) sgf_addLElem(mc, sgfType_triangle, loc) +#define sgf_addCross(mc, loc) sgf_addLElem(mc, sgfType_cross, loc) #define sgf_addCircle(mc, loc) sgf_addLElem(mc, sgfType_circle, loc) #define sgf_addSquare(mc, loc) sgf_addLElem(mc, sgfType_square, loc) #define sgf_label(mc, loc, label) \ diff -ru cgoban-1.9.12-orig/src/sgfIn.c cgoban-1.9.12-et1/src/sgfIn.c --- cgoban-1.9.12-orig/src/sgfIn.c Thu Nov 30 00:45:42 2000 +++ cgoban-1.9.12-et1/src/sgfIn.c Tue Apr 23 21:18:10 2002 @@ -331,12 +331,17 @@ if (err) return(msg_sgfBadLoc); break; - case(TOKEN2('M','A')): /* I draw "MA" (mark) as a square. */ - case(TOKEN1('M')): /* Some games have marks as "M[..]". */ + case(TOKEN2('S','Q')): arg_multi(arg, mc, sgfType_square, goStone_empty, &err); if (err) return(msg_sgfBadLoc); break; + case(TOKEN2('M','A')): + case(TOKEN1('M')): /* Some games have marks as "M[..]". */ + arg_multi(arg, mc, sgfType_cross, goStone_empty, &err); + if (err) + return(msg_sgfBadLoc); + break; case(TOKEN2('L','B')): arg_multiLabel(arg, mc, &err); if (err) @@ -607,7 +612,7 @@ firstTime = FALSE; } state = state_token; - str_copyChars(&buf, ""); + str_clip(&buf, 0); for (;;) { c = getc(f); if (c == '\n') diff -ru cgoban-1.9.12-orig/src/sgfMap.c cgoban-1.9.12-et1/src/sgfMap.c --- cgoban-1.9.12-orig/src/sgfMap.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/sgfMap.c Sun Apr 21 20:31:04 2002 @@ -308,7 +308,8 @@ cgbuts_drawp(map->cgbuts, win, stone, grey, stoneX, stoneY, gridSize, x % CGBUTS_NUMWHITE, dx, dy, dw, dh); - } if (el->flags & SGFMAPFLAGS_MARKED) + } + if (el->flags & SGFMAPFLAGS_MARKED) cgbuts_markPiece(map->cgbuts, win, stone, goMark_triangle, 0, stoneX, stoneY, gridSize, 1, dx, dy, dw, dh); else if (stone != goStone_empty) @@ -426,6 +427,7 @@ } me->moveNum = ++moveNum; break; + case sgfType_cross: case sgfType_triangle: case sgfType_comment: case sgfType_square: @@ -759,6 +761,7 @@ } moveAdd = 1; break; + case sgfType_cross: case sgfType_triangle: case sgfType_comment: case sgfType_square: diff -ru cgoban-1.9.12-orig/src/sgfOut.c cgoban-1.9.12-et1/src/sgfOut.c --- cgoban-1.9.12-orig/src/sgfOut.c Sat Apr 7 01:10:19 2001 +++ cgoban-1.9.12-et1/src/sgfOut.c Sun Apr 21 20:08:57 2002 @@ -184,6 +184,10 @@ me = printPoints(nodeOut, mc, me); break; + case sgfType_cross: + str_copyChars(nodeOut, "MA"); + me = printPoints(nodeOut, mc, me); + break; case sgfType_triangle: str_copyChars(nodeOut, "TR"); me = printPoints(nodeOut, mc, me); @@ -193,7 +197,7 @@ me = printPoints(nodeOut, mc, me); break; case sgfType_square: - str_copyChars(nodeOut, "MA"); + str_copyChars(nodeOut, "SQ"); me = printPoints(nodeOut, mc, me); break; case sgfType_label: diff -ru cgoban-1.9.12-orig/src/sgfPlay.c cgoban-1.9.12-et1/src/sgfPlay.c --- cgoban-1.9.12-orig/src/sgfPlay.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/src/sgfPlay.c Sun Apr 21 20:09:48 2002 @@ -227,6 +227,7 @@ grid_setMark(pic->boardButs[loc], mark, 0); } break; + case sgfType_cross: case sgfType_triangle: case sgfType_circle: case sgfType_square: @@ -234,8 +235,10 @@ mark = goMark_triangle; else if (me->type == sgfType_circle) mark = goMark_circle; - else /* me->type == sgfType_square */ + else if (me->type == sgfType_square) mark = goMark_square; + else /* me->type == sgfType_cross */ + mark = goMark_cross; loc = goBoard_sgf2Loc(game->board, me->lVal); changed[loc] = TRUE; if (grid_grey(pic->boardButs[loc])) { diff -ru cgoban-1.9.12-orig/wmslib/src/abut/term.c cgoban-1.9.12-et1/wmslib/src/abut/term.c --- cgoban-1.9.12-orig/wmslib/src/abut/term.c Tue Jan 25 05:40:25 2000 +++ cgoban-1.9.12-et1/wmslib/src/abut/term.c Sun May 12 23:15:58 2002 @@ -69,18 +69,20 @@ env = term->abut->env; butTbin_set(term->tbin, text); butCan_resizeWin(term->swin->win, 0, butTbin_numLines(term->tbin) * - butEnv_fontH(env, 0) + butEnv_stdBw(env) * 2, TRUE); + butEnv_fontH(env, TBIN_FONTNUM) + butEnv_stdBw(env) * 2, TRUE); } void abutTerm_resize(AbutTerm *term, int x, int y, int w, int h) { - int fontH = butEnv_fontH(term->abut->env, 0); - int bw = butEnv_stdBw(term->abut->env); + ButEnv *env; + int fontH; assert(MAGIC(term)); - abutSwin_resize(term->swin, x, y, w, h, (fontH * 3) / 2, fontH); + env = term->abut->env; + fontH = butEnv_fontH(term->abut->env, TBIN_FONTNUM); + abutSwin_resize(term->swin, x, y, w, h, (butEnv_fontH(env, 0) * 3) / 2, fontH); butCan_resizeWin(term->swin->win, 0, butTbin_numLines(term->tbin) * fontH + - bw * 2, TRUE); + butEnv_stdBw(env) * 2, TRUE); } @@ -132,7 +134,7 @@ term = swin->packet; assert(MAGIC(term)); newState = abutTermState_steady; - h = butEnv_fontH(env, 0); + h = butEnv_fontH(env, TBIN_FONTNUM); y = activeLine * h + bw; if (passiveLine != activeLine) { if (y <= butCan_yOff(win) + bw) { diff -ru cgoban-1.9.12-orig/wmslib/src/but/i_win.c cgoban-1.9.12-et1/wmslib/src/but/i_win.c --- cgoban-1.9.12-orig/wmslib/src/but/i_win.c Sun Feb 27 00:03:49 2000 +++ cgoban-1.9.12-et1/wmslib/src/but/i_win.c Sat May 11 02:58:28 2002 @@ -257,7 +257,7 @@ static Atom protocols[1]; /* Stupid X doesn't call their strings const always. */ char *annoyance; - char annoy2[] = "Basicwin"; + static char annoy2[] = "CGoban"; sizeHints = XAllocSizeHints(); if (win->x != int_max) { @@ -329,8 +329,8 @@ wm_hints.initial_state = NormalState; wm_hints.input = True; - class_hints.res_name = annoyance; - class_hints.res_class = annoy2; + class_hints.res_class = annoyance; + class_hints.res_name = annoy2; XSetWMProperties(dpy, win->win, &windowName, &iconName, dumb_argv, 0, sizeHints, &wm_hints, &class_hints); protocols[0] = but_wmDeleteWindow; diff -ru cgoban-1.9.12-orig/wmslib/src/but/rcur.c cgoban-1.9.12-et1/wmslib/src/but/rcur.c --- cgoban-1.9.12-orig/wmslib/src/but/rcur.c Tue Jan 25 05:40:26 2000 +++ cgoban-1.9.12-et1/wmslib/src/but/rcur.c Wed Apr 24 00:27:19 2002 @@ -102,7 +102,7 @@ for (i = butCur_idle; i < butCur_bogus; ++i) cursors[i].pic = NULL; - cursors[butCur_idle].fontcurnum = XC_left_ptr; + cursors[butCur_idle].fontcurnum = XC_top_left_arrow; cursors[butCur_idle].hotX = 1; cursors[butCur_idle].hotY = 1; cursors[butCur_idle].w = 16; @@ -110,7 +110,7 @@ cursors[butCur_idle].pic = ntp_bits; cursors[butCur_idle].mask = ntm_bits; - cursors[butCur_twitch].fontcurnum = XC_arrow; + cursors[butCur_twitch].fontcurnum = XC_top_left_arrow; cursors[butCur_twitch].hotX = 14; cursors[butCur_twitch].hotY = 1; cursors[butCur_twitch].w = 16; @@ -126,7 +126,7 @@ cursors[butCur_text].pic = txtp_bits; cursors[butCur_text].mask = txtm_bits; - cursors[butCur_up].fontcurnum = XC_sb_up_arrow; + cursors[butCur_up].fontcurnum = XC_top_left_arrow; cursors[butCur_up].hotX = 14; cursors[butCur_up].hotY = 14; cursors[butCur_up].w = 16; @@ -134,7 +134,7 @@ cursors[butCur_up].pic = ntp_bits; cursors[butCur_up].mask = ntm_bits; - cursors[butCur_down].fontcurnum = XC_sb_down_arrow; + cursors[butCur_down].fontcurnum = XC_top_left_arrow; cursors[butCur_down].hotX = 14; cursors[butCur_down].hotY = 14; cursors[butCur_down].w = 16; @@ -142,7 +142,7 @@ cursors[butCur_down].pic = ntp_bits; cursors[butCur_down].mask = ntm_bits; - cursors[butCur_left].fontcurnum = XC_sb_left_arrow; + cursors[butCur_left].fontcurnum = XC_top_left_arrow; cursors[butCur_left].hotX = 14; cursors[butCur_left].hotY = 14; cursors[butCur_left].w = 16; @@ -150,7 +150,7 @@ cursors[butCur_left].pic = ntp_bits; cursors[butCur_left].mask = ntm_bits; - cursors[butCur_right].fontcurnum = XC_sb_right_arrow; + cursors[butCur_right].fontcurnum = XC_top_left_arrow; cursors[butCur_right].hotX = 14; cursors[butCur_right].hotY = 14; cursors[butCur_right].w = 16; @@ -158,7 +158,7 @@ cursors[butCur_right].pic = ntp_bits; cursors[butCur_right].mask = ntm_bits; - cursors[butCur_lr].fontcurnum = XC_sb_h_double_arrow; + cursors[butCur_lr].fontcurnum = XC_top_left_arrow; cursors[butCur_lr].hotX = 14; cursors[butCur_lr].hotY = 14; cursors[butCur_lr].w = 16; @@ -166,7 +166,7 @@ cursors[butCur_lr].pic = ntp_bits; cursors[butCur_lr].mask = ntm_bits; - cursors[butCur_ud].fontcurnum = XC_sb_v_double_arrow; + cursors[butCur_ud].fontcurnum = XC_top_left_arrow; cursors[butCur_ud].hotX = 14; cursors[butCur_ud].hotY = 14; cursors[butCur_ud].w = 16; @@ -174,7 +174,7 @@ cursors[butCur_ud].pic = ntp_bits; cursors[butCur_ud].mask = ntm_bits; - cursors[butCur_grab].fontcurnum = XC_fleur; + cursors[butCur_grab].fontcurnum = XC_top_left_arrow; cursors[butCur_grab].hotX = 14; cursors[butCur_grab].hotY = 14; cursors[butCur_grab].w = 16; @@ -199,6 +199,11 @@ cursors[i].w, cursors[i].h); env->cmask[i] = XCreateBitmapFromData(env->dpy, d, cursors[i].mask, cursors[i].w, cursors[i].h); + } + { /* make the idle cursor dull */ + static XColor gray1 = { 0, 0x8888,0x8888,0x8888, DoRed|DoGreen|DoBlue }; + static XColor gray2 = { 0, 0xcccc,0xcccc,0xcccc, DoRed|DoGreen|DoBlue }; + XRecolorCursor(env->dpy, env->cursors[butCur_idle], &gray1, &gray2); } env->curnum = butCur_idle; env->curwin = None; diff -ru cgoban-1.9.12-orig/wmslib/src/but/slide.c cgoban-1.9.12-et1/wmslib/src/but/slide.c --- cgoban-1.9.12-orig/wmslib/src/but/slide.c Tue Jan 25 05:40:26 2000 +++ cgoban-1.9.12-et1/wmslib/src/but/slide.c Mon May 13 00:32:46 2002 @@ -510,7 +510,7 @@ atj = slide->timer_jump; else atj = -slide->timer_jump; - slide->timer = butTimer_fCreate(NULL, but, delay, atj*2, FALSE, slide_now); + slide->timer = butTimer_fCreate(NULL, but, delay, atj*8, FALSE, slide_now); } } diff -ru cgoban-1.9.12-orig/wmslib/src/but/tbin.c cgoban-1.9.12-et1/wmslib/src/but/tbin.c --- cgoban-1.9.12-orig/wmslib/src/but/tbin.c Tue Jan 25 05:40:26 2000 +++ cgoban-1.9.12-et1/wmslib/src/but/tbin.c Tue May 14 00:13:24 2002 @@ -285,8 +285,8 @@ assert(but->action == &action); assert(MAGIC(tb)); - fontH = butEnv_fontH(env, 0); - XSetFont(env->dpy, env->gc, env->fonts[0]->fid); + fontH = butEnv_fontH(env, TBIN_FONTNUM); + XSetFont(env->dpy, env->gc, env->fonts[TBIN_FONTNUM]->fid); startLine = (y - fontH + 1 - but->y) / fontH; if (startLine < 0) startLine = 0; @@ -305,7 +305,7 @@ ButWin *win = but->win; ButEnv *env = win->env; Tin *ti = &tb->tins[tinNum]; - XFontStruct *fs = env->fonts[0]; + XFontStruct *fs = env->fonts[TBIN_FONTNUM]; int loCur, hiCur; int blockL, blockW; @@ -395,7 +395,7 @@ newMousePress = 0; rightSide = FALSE; } else - newMousePress = locateMouse(env->fonts[0], tb->buf + ti->start, + newMousePress = locateMouse(env->fonts[TBIN_FONTNUM], tb->buf + ti->start, ti->len, x - (but->x+tb->lMargin), &rightSide); if (rightSide && (newMousePress == ti->len) && @@ -521,7 +521,7 @@ tb->locs[tbin_mouse].index = 0; rightSide = FALSE; } else - tb->locs[tbin_mouse].index = locateMouse(env->fonts[0], + tb->locs[tbin_mouse].index = locateMouse(env->fonts[TBIN_FONTNUM], tb->buf + ti->start, ti->len, x - (but->x+tb->lMargin), @@ -654,7 +654,7 @@ tb->locs[tbin_loCur].index); tb->locs[tbin_loCur].tin = tinNum_prev(tb->locs[tbin_loCur].tin, tb); tb->locs[tbin_loCur].index = - locateMouse(env->fonts[0], + locateMouse(env->fonts[TBIN_FONTNUM], tb->buf + tb->tins[tb->locs[tbin_loCur].tin].start, tb->tins[tb->locs[tbin_loCur].tin].len, tb->mouseX, NULL); @@ -676,7 +676,7 @@ tb->locs[tbin_hiCur].index); tb->locs[tbin_hiCur].tin = tinNum_next(tb->locs[tbin_hiCur].tin, tb); tb->locs[tbin_hiCur].index = - locateMouse(env->fonts[0], + locateMouse(env->fonts[TBIN_FONTNUM], tb->buf + tb->tins[tb->locs[tbin_hiCur].tin].start, tb->tins[tb->locs[tbin_hiCur].tin].len, tb->mouseX, NULL); @@ -706,14 +706,14 @@ need_draw = TRUE; } else if (tinNum_next(tb->locs[tbin_loCur].tin, tb) < tb->maxTins) { if (tb->locs[tbin_loCur].index < - tb->tins[tb->locs[tbin_loCur].tin].len) + tb->tins[tb->locs[tbin_loCur].tin].len) { ++tb->locs[tbin_hiCur].index; - else if (tb->buf[tb->loBreak - 1] == '\n') { + } else if (tb->buf[tb->loBreak - 1] == '\n') { tb->locs[tbin_hiCur].tin = tinNum_next(tb->locs[tbin_hiCur].tin, tb); tb->locs[tbin_hiCur].index = 0; } else { tb->locs[tbin_hiCur].tin = tinNum_next(tb->locs[tbin_hiCur].tin, tb); - tb->locs[tbin_hiCur].index = 1; + tb->locs[tbin_hiCur].index = 0; /*ET: was 1*/ } insertResult = insert(env, "", tb, but->w, &changePrev); need_draw = TRUE; @@ -781,6 +781,27 @@ } else if ((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R)) { } else if ((keysym >= XK_F1) && (keysym <= XK_F35)) { insertResult = insert(env, newtext, tb, but->w, &changePrev); +#if 1 /* People don't like my delete. :-( */ + } else if (keysym == XK_Delete) { + if ((tb->locs[tbin_loCur].index != tb->locs[tbin_hiCur].index) || + (tb->locs[tbin_loCur].tin != tb->locs[tbin_hiCur].tin)) { + insertResult = insert(env, "", tb, but->w, &changePrev); + need_draw = TRUE; + } else if (tinNum_next(tb->locs[tbin_loCur].tin, tb) < tb->maxTins) { + if (tb->locs[tbin_loCur].index < tb->tins[tb->locs[tbin_loCur].tin].len) + ++tb->locs[tbin_hiCur].index; + else if (tb->buf[tb->loBreak - 1] == '\n') { + tb->locs[tbin_hiCur].tin = tinNum_next(tb->locs[tbin_hiCur].tin, tb); + tb->locs[tbin_hiCur].index = 0; + } else { + tb->locs[tbin_hiCur].tin = tinNum_next(tb->locs[tbin_hiCur].tin, tb); + tb->locs[tbin_hiCur].index = 0; /*ET: was 1*/ + } + insertResult = insert(env, "", tb, but->w, &changePrev); + need_draw = TRUE; + } else + result |= BUTOUT_ERR; +#endif } else if ((keysym == XK_BackSpace) || (keysym == XK_Delete)) { if ((tb->locs[tbin_loCur].index != tb->locs[tbin_hiCur].index) || (tb->locs[tbin_loCur].tin != tb->locs[tbin_hiCur].tin)) { @@ -807,27 +828,6 @@ } else { result |= BUTOUT_ERR; } -#if 0 /* People don't like my delete. :-( */ - } else if (keysym == XK_Delete) { - if ((tb->locs[tbin_loCur].index != tb->locs[tbin_hiCur].index) || - (tb->locs[tbin_loCur].tin != tb->locs[tbin_hiCur].tin)) { - insertResult = insert(env, "", tb, but->w, &changePrev); - need_draw = TRUE; - } else if (tinNum_next(tb->locs[tbin_loCur].tin, tb) < tb->maxTins) { - if (tb->locs[tbin_loCur].index < tb->tins[tb->locs[tbin_loCur].tin].len) - ++tb->locs[tbin_hiCur].index; - else if (tb->buf[tb->loBreak - 1] == '\n') { - tb->locs[tbin_hiCur].tin = tinNum_next(tb->locs[tbin_hiCur].tin, tb); - tb->locs[tbin_hiCur].index = 0; - } else { - tb->locs[tbin_hiCur].tin = tinNum_next(tb->locs[tbin_hiCur].tin, tb); - tb->locs[tbin_hiCur].index = 1; - } - insertResult = insert(env, "", tb, but->w, &changePrev); - need_draw = TRUE; - } else - result |= BUTOUT_ERR; -#endif } else if (keysym == XK_Left) { need_draw = TRUE; if (!loc_eq(tb->locs[tbin_loCur], tb->locs[tbin_hiCur])) { @@ -866,7 +866,7 @@ setMouseX(but, tb, tb->locs[tbin_loCur].tin, tb->locs[tbin_loCur].index); tb->locs[tbin_loCur].tin = tinNum_prev(tb->locs[tbin_loCur].tin, tb); - tb->locs[tbin_loCur].index = locateMouse(env->fonts[0], + tb->locs[tbin_loCur].index = locateMouse(env->fonts[TBIN_FONTNUM], tb->buf + tb->tins[tb->locs[tbin_loCur]. tin].start, @@ -892,13 +892,16 @@ tb->locs[tbin_hiCur].index); tb->locs[tbin_hiCur].tin = tinNum_next(tb->locs[tbin_hiCur].tin, tb); tb->locs[tbin_hiCur].index = - locateMouse(env->fonts[0], + locateMouse(env->fonts[TBIN_FONTNUM], tb->buf + tb->tins[tb->locs[tbin_hiCur].tin].start, tb->tins[tb->locs[tbin_hiCur].tin].len, tb->mouseX, NULL); tb->locs[tbin_loCur] = tb->locs[tbin_hiCur]; } need_draw = TRUE; + } else if (keysym == XK_Insert) { + tb->locs[tbin_mouse] = tb->locs[tbin_loCur] = tb->locs[tbin_hiCur]; + paste(env, but); } else if ((keysym == XK_Return) || (keysym == XK_Linefeed) || (keysym == XK_KP_Enter)) { insertResult = insert(env, "\n", tb, but->w, &changePrev); @@ -923,12 +926,12 @@ drawLo = tinNum_prev(drawLo, tb); } assert(drawHi >= drawLo); - drawLo = tinNum_line(drawLo, tb) * butEnv_fontH(env, 0); + drawLo = tinNum_line(drawLo, tb) * butEnv_fontH(env, TBIN_FONTNUM); if (insertResult == insert_cr) { drawHi = but->h; } else { assert((drawHi < tb->loTinBreak) || (drawHi >= tb->hiTinBreak)); - drawHi = (tinNum_line(drawHi, tb) + 1) * butEnv_fontH(env, 0); + drawHi = (tinNum_line(drawHi, tb) + 1) * butEnv_fontH(env, TBIN_FONTNUM); } if (drawLo < but->h) { assert(drawHi >= drawLo); @@ -1110,7 +1113,7 @@ static bool tryJoinLines(Tbin *tb, int tinNum, ButEnv *env, int butW) { int prevTinNum, w, curChar; Tin *a, *b; - XFontStruct *fs = env->fonts[0]; + XFontStruct *fs = env->fonts[TBIN_FONTNUM]; TbinLoc loc; if ((tinNum == 0) || (tinNum == tb->maxTins)) @@ -1198,7 +1201,7 @@ static void breakLine(Tbin *tb, int tinNum, ButEnv *env, int butW) { - XFontStruct *fs = env->fonts[0]; + XFontStruct *fs = env->fonts[TBIN_FONTNUM]; int breakPoint, w; TbinLoc loc; @@ -1251,7 +1254,7 @@ tb->tins[tb->hiTinBreak].len += tb->tins[tinNum].len - breakPoint; tb->tins[tb->hiTinBreak].start = tb->tins[tinNum].start + breakPoint; tb->tins[tb->hiTinBreak].width += - XTextWidth(env->fonts[0], tb->buf + tb->tins[tb->hiTinBreak].start, + XTextWidth(env->fonts[TBIN_FONTNUM], tb->buf + tb->tins[tb->hiTinBreak].start, tb->tins[tinNum].len - breakPoint); tb->tins[tb->loTinBreak] = tb->tins[tb->hiTinBreak]; ++tb->loTinBreak; @@ -1284,7 +1287,7 @@ Tin *ti = &tb->tins[tb->locs[tbin_loCur].tin]; ButWin *win = but->win; ButEnv *env = win->env; - XFontStruct *fs = env->fonts[0]; + XFontStruct *fs = env->fonts[TBIN_FONTNUM]; int x, y; int rw, rh; @@ -1318,7 +1321,7 @@ Tin *ti = &tb->tins[tb->locs[tbin_loCur].tin]; ButWin *win = but->win; ButEnv *env = win->env; - XFontStruct *fs = env->fonts[0]; + XFontStruct *fs = env->fonts[TBIN_FONTNUM]; int fontH = fs->ascent + fs->descent; int x, y; int rw; @@ -1620,7 +1623,7 @@ if (y < but->y) return(0); - n = (y - but->y) / butEnv_fontH(but->win->env, 0); + n = (y - but->y) / butEnv_fontH(but->win->env, TBIN_FONTNUM); if (n >= tbin->loTinBreak) n += tbin->hiTinBreak - tbin->loTinBreak; if (n >= tbin->maxTins) @@ -1632,7 +1635,7 @@ static void setMouseX(But *but, Tbin *tbin, int tin, int loc) { assert((tin >= 0) && (tin < tbin->maxTins)); assert((loc >= 0) && (loc <= tbin->tins[tin].len)); - tbin->mouseX = XTextWidth(but->win->env->fonts[0], + tbin->mouseX = XTextWidth(but->win->env->fonts[TBIN_FONTNUM], tbin->buf + tbin->tins[tin].start, loc); } @@ -1662,7 +1665,7 @@ if (tbin->offWinCallback) { y = win->yOff; h = win->h; - ch = butEnv_fontH(win->env, 0); + ch = butEnv_fontH(win->env, TBIN_FONTNUM); if (tbin->clicks) { assert(loc_valid(tbin->locs[tbin_mouse], tbin)); cy = loLineNum = tinNum_line(tbin->locs[tbin_mouse].tin, tbin); @@ -1849,7 +1852,7 @@ textLen = tin->len; while ((textLen > 0) && (buf[tin->start + textLen - 1] == ' ')) --textLen; - tin->width = XTextWidth(env->fonts[0], buf + tin->start, textLen); + tin->width = XTextWidth(env->fonts[TBIN_FONTNUM], buf + tin->start, textLen); return(tin->width); } @@ -1914,8 +1917,7 @@ tb->locs[tbin_loCur].index = tb->tins[tb->locs[tbin_loCur].tin].len; tb->locs[tbin_hiCur] = tb->locs[tbin_loCur]; } - insert(but->win->env, appText, tb, - but->w - (tb->lMargin + tb->rMargin), NULL); + insert(but->win->env, appText, tb, but->w, NULL); checkOffWin(but, 0, TRUE); if (saveOldCurs && !loc_eq(tb->locs[tbin_mouse], tb->locs[tbin_press])) { tb->locs[tbin_loCur] = tb->locs[tbin_mouse]; diff -ru cgoban-1.9.12-orig/wmslib/src/but/tbin.h cgoban-1.9.12-et1/wmslib/src/but/tbin.h --- cgoban-1.9.12-orig/wmslib/src/but/tbin.h Tue Jan 25 05:40:26 2000 +++ cgoban-1.9.12-et1/wmslib/src/but/tbin.h Mon May 13 22:59:32 2002 @@ -9,6 +9,8 @@ #ifndef _BUT_TBIN_H_ #define _BUT_TBIN_H_ 1 +#define TBIN_FONTNUM 0 /* 0 = prop, 3 = fixed width font */ + /********************************************************************** * Functions **********************************************************************/ diff -ru cgoban-1.9.12-orig/wmslib/src/but/text.c cgoban-1.9.12-et1/wmslib/src/but/text.c --- cgoban-1.9.12-orig/wmslib/src/but/text.c Tue Jan 25 05:40:26 2000 +++ cgoban-1.9.12-et1/wmslib/src/but/text.c Wed Apr 3 23:48:18 2002 @@ -86,8 +86,10 @@ assert(but->action == &action); if (text == NULL) text = ""; - str_copyChars(&t->text, text); - but_draw(but); + if (strcmp(str_chars(&t->text), text)) { + str_copyChars(&t->text, text); + but_draw(but); + } } diff -ru cgoban-1.9.12-orig/wmslib/src/but/textin.c cgoban-1.9.12-et1/wmslib/src/but/textin.c --- cgoban-1.9.12-orig/wmslib/src/but/textin.c Tue Jan 25 05:40:26 2000 +++ cgoban-1.9.12-et1/wmslib/src/but/textin.c Tue May 7 22:05:41 2002 @@ -549,29 +549,29 @@ } else if ((keysym >= XK_F1) && (keysym <= XK_F35)) { if (!(need_draw = insert(env, newtext, ti))) result |= BUTOUT_ERR | BUTOUT_CAUGHT; - } else if ((keysym == XK_BackSpace) || (keysym == XK_Delete)) { +#if 1 /* People don't like it when delete works the way I like it. :-( */ + } else if (keysym == XK_Delete) { if (ti->loc != ti->cutend) need_draw = insert(env, "", ti); - else if (ti->loc > 0) { - for (i = ti->cutend = --ti->loc; ti->str[i]; ++i) + else if (ti->loc < ti->len) { + for (i = ti->loc; ti->str[i]; ++i) ti->str[i] = ti->str[i+1]; --ti->len; need_draw = TRUE; } else result |= BUTOUT_ERR | BUTOUT_CAUGHT; -#if 0 /* People don't like it when delete works the way I like it. :-( */ - } else if (keysym == XK_Delete) { +#endif + } else if ((keysym == XK_BackSpace) || (keysym == XK_Delete)) { if (ti->loc != ti->cutend) need_draw = insert(env, "", ti); - else if (ti->loc < ti->len) { - for (i = ti->loc; ti->str[i]; ++i) + else if (ti->loc > 0) { + for (i = ti->cutend = --ti->loc; ti->str[i]; ++i) ti->str[i] = ti->str[i+1]; --ti->len; need_draw = TRUE; } else result |= BUTOUT_ERR | BUTOUT_CAUGHT; -#endif - } else if (keysym == XK_Left) { + } else if (keysym == XK_Left) { if (ti->loc != ti->cutend) { if (ti->loc < ti->cutend) ti->cutend = ti->loc; @@ -601,6 +601,8 @@ } else if (keysym == XK_Down) { ti->loc = ti->cutend = ti->len; need_draw = TRUE; + } else if (keysym == XK_Insert) { + paste(env, but); } else if ((keysym == XK_Return) || (keysym == XK_Linefeed) || (keysym == XK_KP_Enter)) { result |= BUTOUT_CAUGHT; @@ -839,7 +841,7 @@ wms_free(pb2); } else XBell(env->dpy, 0); - } + } env->sNotify = NULL; return(0); } diff -ru cgoban-1.9.12-orig/wmslib/src/but/timer.c cgoban-1.9.12-et1/wmslib/src/but/timer.c --- cgoban-1.9.12-orig/wmslib/src/but/timer.c Tue Jan 25 05:40:26 2000 +++ cgoban-1.9.12-et1/wmslib/src/but/timer.c Mon May 13 00:33:18 2002 @@ -180,7 +180,6 @@ for (bt = but_timerList; bt != NULL; bt = bt->next) { if (bt->state == butTimer_on) { if (timercmp(&bt->nextFiring, ¤t_time, <)) { - take_timer = TRUE; ticks = but_timerDiv(but_timerSub(current_time, bt->nextFiring), bt->period, &timerem) + 1 + bt->ticksLeft; take_timer = TRUE; diff -ru cgoban-1.9.12-orig/wmslib/src/wms/str.c cgoban-1.9.12-et1/wmslib/src/wms/str.c --- cgoban-1.9.12-orig/wmslib/src/wms/str.c Tue Jan 25 05:40:26 2000 +++ cgoban-1.9.12-et1/wmslib/src/wms/str.c Tue Apr 23 21:18:27 2002 @@ -293,7 +293,7 @@ const char *sVal; assert(MAGIC(dest)); - str_copyChars(dest, ""); + str_clip(dest, 0); va_start(ap, fmt); while (*fmt) { if (*fmt != '%')