Beispiel #1
0
// [HGM] kibitz: write kibitz line; split window for it if necessary
void
OutputKibitz (int window, char *text)
{
	static int currentLineEnd[2];
	int where = 0;
	if(!EngineOutputIsUp()) return;
	if(!opponentKibitzes) { // on first kibitz of game, clear memos
	    DoClearMemo(1); currentLineEnd[1] = 0;
	    if(gameMode == IcsObserving) { DoClearMemo(0); currentLineEnd[0] = 0; }
	}
	opponentKibitzes = TRUE; // this causes split window DisplayMode in ICS modes.
	VerifyDisplayMode();
	strncpy(text+strlen(text)-1, "\r\n",sizeof(text+strlen(text)-1)); // to not lose line breaks on copying
	if(gameMode == IcsObserving) {
	    DoSetWindowText(0, nLabel, gameInfo.white);
	    SetIcon( 0, nColorIcon,  nColorWhite);
	    SetIcon( 0, nStateIcon,  nClear);
	}
	DoSetWindowText(1, nLabel, gameMode == IcsPlayingBlack ? gameInfo.white : gameInfo.black); // opponent name
	SetIcon( 1, nColorIcon,  gameMode == IcsPlayingBlack ? nColorWhite : nColorBlack);
	SetIcon( 1, nStateIcon,  nClear);
	if(strstr(text, "\\  ") == text) where = currentLineEnd[window-1]; // continuation line
//if(appData.debugMode) fprintf(debugFP, "insert '%s' at %d (end = %d,%d)\n", text, where, currentLineEnd[0], currentLineEnd[1]);
	InsertIntoMemo(window-1, text, where); // [HGM] multivar: always at top
	currentLineEnd[window-1] = where + strlen(text);
}
Beispiel #2
0
void OutputChatMessage(int partner, char *text)
{
	int j, n = strlen(text);

	if(!chatHandle[partner]) return;
	text[n+1] = 0; text[n] = '\n'; text[n-1] = '\r'; // Needs CR to not lose line breaks on copy-paste
	InsertIntoMemo(chatHandle[partner], text);
	if(partner != onTop) for(j=0; j<MAX_CHAT; j++) if(j != partner && chatHandle[j])
	    Button_SetState(GetDlgItem(chatHandle[j], IDC_Focus1+partner-(j<partner)), TRUE);
}
Beispiel #3
0
// This seems pure front end
LRESULT CALLBACK ChatProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
    static SnapData sd;
    char buf[MSG_SIZ], mess[MSG_SIZ];
    int partner = -1, i, x, y;
    static BOOL filterHasFocus[MAX_CHAT];
    WORD wMask;
    HWND hMemo;

    for(i=0; i<MAX_CHAT; i++) if(hDlg == chatHandle[i]) { partner = i; break; }

    switch (message) {
    case WM_INITDIALOG:
        Translate(hDlg, DLG_Chat);
	if(partner<0) {
		for(i=0; i<MAX_CHAT; i++) if(chatHandle[i] == NULL) { partner = i; break; }
	        chatHandle[partner] = hDlg;
		snprintf(buf, MSG_SIZ, T_("Chat Window %s"), ics_handle[0] ? ics_handle : first.tidy);
		SetWindowText(hDlg, buf);
        }
	for(i=0; i<MAX_CHAT; i++) if(chatHandle[i]) {
	    if(i == partner) continue;
	    // set our button in other open chats
	    SetDlgItemText(chatHandle[i], IDC_Focus1+partner-(i<partner), chatPartner[partner]);
	    EnableWindow( GetDlgItem(chatHandle[i], IDC_Focus1+partner-(i<partner)), 1 );
	    // and buttons for other chats in ours
	    SetDlgItemText(hDlg, IDC_Focus1+i-(i>partner), chatPartner[i]);
	} else EnableWindow( GetDlgItem(hDlg, IDC_Focus1+i-(i>partner)), 0 );
	for(i=0; i<MAX_CHAT-1; i++) { Button_SetStyle(GetDlgItem(hDlg, IDC_Focus1+i), BS_PUSHBUTTON|BS_LEFT, TRUE); }
        x = wpConsole.x; y = wpConsole.y; EnsureOnScreen(&x, &y, 0, 0);
        SetWindowPos(hDlg, NULL, x, y, 0, 0, SWP_NOZORDER|SWP_NOSIZE);
	SendMessage( GetDlgItem(hDlg, IDC_ChatPartner), // [HGM] clickbox: initialize with requested handle
			WM_SETTEXT, 0, (LPARAM) chatPartner[partner] );
	filterHasFocus[partner] = TRUE;
	onTop = partner; // a newly opened box becomes top one
	if(chatPartner[partner][0]) {
	    filterHasFocus[partner] = FALSE;
	    SetFocus( GetDlgItem(hDlg, OPT_ChatInput) );
	}
	hMemo = GetDlgItem(hDlg, IDC_ChatMemo);
	wMask = (WORD) SendMessage(hMemo, EM_GETEVENTMASK, 0, 0L);
	SendMessage(hMemo, EM_SETEVENTMASK, 0, wMask | ENM_LINK);
	SendMessage(hMemo, EM_AUTOURLDETECT, TRUE, 0L);
	chatInputWindowProc = (WNDPROC) // cloned from ConsoleWndProc(). Assume they all share same proc.
	      SetWindowLongPtr(GetDlgItem(hDlg, OPT_ChatInput), GWLP_WNDPROC, (LONG_PTR) InterceptArrowKeys);
        return FALSE;

    case WM_NOTIFY:
      if (((NMHDR*)lParam)->code == EN_LINK)
      {
	ENLINK *pLink = (ENLINK*)lParam;
	if (pLink->msg == WM_LBUTTONUP)
	{
	  TEXTRANGE tr;

	  tr.chrg = pLink->chrg;
	  tr.lpstrText = malloc(1+tr.chrg.cpMax-tr.chrg.cpMin);
	  SendMessage( GetDlgItem(hDlg, IDC_ChatMemo), EM_GETTEXTRANGE, 0, (LPARAM)&tr);
	  ShellExecute(NULL, "open", tr.lpstrText, NULL, NULL, SW_SHOW);
	  free(tr.lpstrText);
	}
      }
    break;

    case WM_COMMAND:
      /*
        [AS]
        If <Enter> is pressed while editing the filter, it's better to apply
        the filter rather than selecting the current game.
      */
      if( LOWORD(wParam) == IDC_ChatPartner ) {
          switch( HIWORD(wParam) ) {
          case EN_SETFOCUS:
              filterHasFocus[partner] = TRUE;
              break;
          case EN_KILLFOCUS:
              filterHasFocus[partner] = FALSE;
              break;
          }
      }

      if( filterHasFocus[partner] && (LOWORD(wParam) == IDC_Send) ) {
	  SetFocus(GetDlgItem(hDlg, OPT_ChatInput));
          wParam = IDC_Change;
      }
      /* [AS] End command replacement */

        switch (LOWORD(wParam)) {

	case IDCANCEL: /* let Esc key switch focus back to console */
	    SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleInput));
	    break;

	case IDC_Clear:
	    SendMessage( GetDlgItem(hDlg, IDC_ChatMemo), WM_SETTEXT, 0, (LPARAM) "" );
	    break;

	case IDC_Change:
	    GetDlgItemText(hDlg, IDC_ChatPartner, chatPartner[partner], MSG_SIZ);
	    for(i=0; i<MAX_CHAT; i++) if(chatHandle[i] && i != partner) {
	      // set our button in other open chats
	      SetDlgItemText(chatHandle[i], IDC_Focus1+partner-(i<partner), chatPartner[partner]);
	    }
	    break;

	case IDC_Send:
	    GetDlgItemText(hDlg, OPT_ChatInput, mess, MSG_SIZ);
	    SetDlgItemText(hDlg, OPT_ChatInput, "");
	    // from here on it could be back-end
	    SaveInHistory(mess);
	    if(!strcmp("whispers", chatPartner[partner]))
	      snprintf(buf, MSG_SIZ, "whisper %s\n", mess); // WHISPER box uses "whisper" to send
	    else if(!strcmp("shouts", chatPartner[partner]))
	      snprintf(buf, MSG_SIZ, "shout %s\n", mess); // SHOUT box uses "shout" to send
	    else {
		if(!atoi(chatPartner[partner])) {
		  snprintf(buf, MSG_SIZ, "> %s\r\n", mess); // echo only tells to handle, not channel
		InsertIntoMemo(hDlg, buf);
		snprintf(buf, MSG_SIZ, "xtell %s %s\n", chatPartner[partner], mess);
		} else
		  snprintf(buf, MSG_SIZ, "tell %s %s\n", chatPartner[partner], mess);
	    }
	    SendToICS(buf);
	    break;

	case IDC_Focus1:
	case IDC_Focus2:
	case IDC_Focus3:
	case IDC_Focus4:
	    i = LOWORD(wParam) - IDC_Focus1;
	    if(i >= partner) i++;
	    onTop = i;
	    SetFocus(GetDlgItem(hDlg, IDC_Send));
	    if(chatHandle[i]) {
		int j;
		for(j=0; j<MAX_CHAT; j++) if(i != j && chatHandle[j])
		    Button_SetState(GetDlgItem(chatHandle[j], IDC_Focus1+i-(j<i)), FALSE);
		SetFocus(GetDlgItem(chatHandle[i], OPT_ChatInput));
	    }
	    break;

        default:
          break;
        }

        break;

    case WM_CLOSE:
	chatHandle[partner] = 0;
	chatPartner[partner][0] = 0;
        ChatPopDown();
	for(i=0; i<MAX_CHAT; i++) if(chatHandle[i] && i != partner) {
	    // set our button in other open chats
	    SetDlgItemText(chatHandle[i], IDC_Focus1+partner-(i<partner), "");
	    EnableWindow( GetDlgItem(chatHandle[i], IDC_Focus1+partner-(i<partner)), 0 );
	}
	EndDialog(hDlg, TRUE);
        break;

    case WM_SIZE:
        ResizeWindowControls( hDlg );
        break;

    case WM_ENTERSIZEMOVE:
        return OnEnterSizeMove( &sd, hDlg, wParam, lParam );

    case WM_SIZING:
        return OnSizing( &sd, hDlg, wParam, lParam );

    case WM_MOVING:
        return OnMoving( &sd, hDlg, wParam, lParam );

    case WM_EXITSIZEMOVE:
        return OnExitSizeMove( &sd, hDlg, wParam, lParam );
    }

    return FALSE;
}
Beispiel #4
0
// pure back end, now SetWindowText is called via wrapper DoSetWindowText
static void
UpdateControls (EngineOutputData *ed)
{
//    int isPondering = FALSE;

    char s_label[MAX_NAME_LENGTH + 32];
    int h;
    char * name = ed->name;

    /* Label */
    if( name == 0 || *name == '\0' ) {
        name = "?";
    }

    strncpy( s_label, name, MAX_NAME_LENGTH );
    s_label[ MAX_NAME_LENGTH-1 ] = '\0';

#ifdef SHOW_PONDERING
    if( IsEnginePondering( ed->which ) ) {
        char buf[8];

        buf[0] = '\0';

        if( ed->hint != 0 && *ed->hint != '\0' ) {
            strncpy( buf, ed->hint, sizeof(buf) );
            buf[sizeof(buf)-1] = '\0';
        }
        else if( ed->pv != 0 && *ed->pv != '\0' ) {
            char * sep = strchr( ed->pv, ' ' );
            int buflen = sizeof(buf);

            if( sep != NULL ) {
                buflen = sep - ed->pv + 1;
                if( buflen > sizeof(buf) ) buflen = sizeof(buf);
            }

            strncpy( buf, ed->pv, buflen );
            buf[ buflen-1 ] = '\0';
        }

        SetEngineState( ed->which, STATE_PONDERING, buf );
    }
    else if( gameMode == TwoMachinesPlay ) {
        SetEngineState( ed->which, STATE_THINKING, "" );
    }
    else if( gameMode == AnalyzeMode || gameMode == AnalyzeFile
	  || (gameMode == IcsObserving && appData.icsEngineAnalyze)) { // [HGM] ICS-analyze
        char buf[64];
        int time_secs = ed->time / 100;
        int time_mins = time_secs / 60;

        buf[0] = '\0';

        if( ed->an_move_index != 0 && ed->an_move_count != 0 && *ed->hint != '\0' ) {
            char mov[16];

            strncpy( mov, ed->hint, sizeof(mov) );
            mov[ sizeof(mov)-1 ] = '\0';

            snprintf( buf, sizeof(buf)/sizeof(buf[0]), "[%d] %d/%d: %s [%02d:%02d:%02d]", ed->depth, ed->an_move_index,
			ed->an_move_count, mov, time_mins / 60, time_mins % 60, time_secs % 60 );
        }

        SetEngineState( ed->which, STATE_ANALYZING, buf );
    }
    else {
        SetEngineState( ed->which, STATE_IDLE, "" );
    }
#endif

    DoSetWindowText( ed->which, nLabel, s_label );

    s_label[0] = '\0';

    if( ed->time > 0 && ed->nodes > 0 ) {
        unsigned long nps_100 = ed->nodes / ed->time;

        if( nps_100 < 100000 ) {
	  snprintf( s_label, sizeof(s_label)/sizeof(s_label[0]), "%s: %lu", _("NPS"), nps_100 * 100 );
        }
        else {
	  snprintf( s_label, sizeof(s_label)/sizeof(s_label[0]), "%s: %.1fk", _("NPS"), nps_100 / 10.0 );
        }
    }

    DoSetWindowText( ed->which, nLabelNPS, s_label );

    /* Memo */
    if( ed->pv != 0 && *ed->pv != '\0' ) {
        char s_nodes[24];
        char s_score[16];
        char s_time[24];
        char buf[256];
        int buflen;
        int time_secs = ed->time / 100;
        int time_cent = ed->time % 100;

        /* Nodes */
        if( ed->nodes < 1000000 ) {
            snprintf( s_nodes, sizeof(s_nodes)/sizeof(s_nodes[0]), u64Display, ed->nodes );
        }
        else {
            snprintf( s_nodes, sizeof(s_nodes)/sizeof(s_nodes[0]), "%.1fM", u64ToDouble(ed->nodes) / 1000000.0 );
        }

        /* Score */
        h = ((gameMode == AnalyzeMode && appData.whitePOV || appData.scoreWhite) && !WhiteOnMove(currentMove) ? -1 : 1) * ed->score;
        if( h > 0 ) {
	  snprintf( s_score, sizeof(s_score)/sizeof(s_score[0]), "+%.2f", h / 100.0 );
        }
        else {
	  snprintf( s_score, sizeof(s_score)/sizeof(s_score[0]), "%.2f", h / 100.0 );
        }

        /* Time */
        snprintf( s_time, sizeof(s_time)/sizeof(s_time[0]), "%d:%02d.%02d", time_secs / 60, time_secs % 60, time_cent );

        /* Put all together... */
	if(ed->nodes == 0 && ed->score == 0 && ed->time == 0)
	  snprintf( buf, sizeof(buf)/sizeof(buf[0]), "%3d\t", ed->depth );
	else
	  snprintf( buf, sizeof(buf)/sizeof(buf[0]), "%3d\t%s\t%s\t%s\t", ed->depth, s_score, s_nodes, s_time );

        /* Add PV */
        buflen = strlen(buf);

        strncpy( buf + buflen, ed->pv, sizeof(buf) - buflen );

        buf[ sizeof(buf) - 3 ] = '\0';

        strcat( buf + buflen, "\r\n" );

        /* Update memo */
        InsertIntoMemo( ed->which, buf, InsertionPoint(strlen(buf), ed) );
        strncpy(lastLine[ed->which], buf, MSG_SIZ);
    }

    /* Colors */
    SetEngineColorIcon( ed->which );
}
Beispiel #5
0
// back end, now the front-end wrapper ClearMemo is used, and ed no longer contains handles.
void
SetProgramStats (FrontEndProgramStats * stats) // now directly called by back-end
{
    EngineOutputData ed;
    int clearMemo = FALSE;
    int which, depth, multi;
    ChessMove moveType;
    int ff, ft, rf, rt;
    char pc;

    if( stats == 0 ) {
        SetEngineState( 0, STATE_IDLE, "" );
        SetEngineState( 1, STATE_IDLE, "" );
        return;
    }

    if(gameMode == IcsObserving && !appData.icsEngineAnalyze)
	return; // [HGM] kibitz: shut up engine if we are observing an ICS game

    which = stats->which;
    depth = stats->depth;

    if( which < 0 || which > 1 || depth < 0 || stats->time < 0 || stats->pv == 0 ) {
        return;
    }

    if( !EngineOutputDialogExists() ) {
        return;
    }

    VerifyDisplayMode();

    ed.which = which;
    ed.depth = depth;
    ed.nodes = stats->nodes;
    ed.score = stats->score;
    ed.time = stats->time;
    ed.pv = stats->pv;
    ed.hint = stats->hint;
    ed.an_move_index = stats->an_move_index;
    ed.an_move_count = stats->an_move_count;

    /* Get target control. [HGM] this is moved to front end, which get them from a table */
    if( which == 0 ) {
        ed.name = first.tidy;
    }
    else {
        ed.name = second.tidy;
    }

    if( ed.pv != 0 && ed.pv[0] == ' ' ) {
        if( strncmp( ed.pv, " no PV", 6 ) == 0 ) { /* Hack on hack! :-O */
            ed.pv = "";
        }
    }

    /* Clear memo if needed */
    if( lastDepth[which] > depth || (lastDepth[which] == depth && depth <= 1 && ed.pv[0]) ) { // no reason to clear if we won't add line
        clearMemo = TRUE;
    }

    if( lastForwardMostMove[which] != forwardMostMove ) {
        clearMemo = TRUE;
    }

    if( clearMemo ) {
        DoClearMemo(which); nrVariations[which] = 0;
        header[which][0] = NULLCHAR;
        if(gameMode == AnalyzeMode) {
          ChessProgramState *cps = (which ? &second : &first);
          if((multi = MultiPV(cps)) >= 0) {
            snprintf(header[which], MSG_SIZ, "\t%s viewpoint\t\tfewer / Multi-PV setting = %d / more\n",
                                       appData.whitePOV || appData.scoreWhite ? "white" : "mover", cps->option[multi].value);
	  }
          if(!which) snprintf(header[which]+strlen(header[which]), MSG_SIZ-strlen(header[which]), "%s", exclusionHeader);
          InsertIntoMemo( which, header[which], 0);
        } else
        if(appData.ponderNextMove && lastLine[which][0]) {
            InsertIntoMemo( which, lastLine[which], 0 );
            InsertIntoMemo( which, "\n", 0 );
        }
    }

    if(ed.pv && ed.pv[0] && ParseOneMove(ed.pv, currentMove, &moveType, &ff, &rf, &ft, &rt, &pc))
	ed.moveKey = (ff<<24 | rf << 16 | ft << 8 | rt) ^ pc*87161;
    else ed.moveKey = ed.nodes; // kludge to get unique key unlikely to match any move

    /* Update */
    lastDepth[which] = depth == 1 && ed.nodes == 0 ? 0 : depth; // [HGM] info-line kudge
    lastForwardMostMove[which] = forwardMostMove;

    UpdateControls( &ed );
}