The R Project SVN R

Rev

Rev 81507 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 81507 Rev 83796
Line 1... Line 1...
1
/*
1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  file console.c
3
 *  file console.c
4
 *  Copyright (C) 1998--2003  Guido Masarotto and Brian Ripley
4
 *  Copyright (C) 1998--2003  Guido Masarotto and Brian Ripley
5
 *  Copyright (C) 2004-8      The R Foundation
5
 *  Copyright (C) 2004-8      The R Foundation
6
 *  Copyright (C) 2004-2021   The R Core Team
6
 *  Copyright (C) 2004-2022   The R Core Team
7
 *
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
11
 *  (at your option) any later version.
Line 347... Line 347...
347
    } else {
347
    } else {
348
	p->lbuf = NULL;
348
	p->lbuf = NULL;
349
	p->kbuf = NULL;
349
	p->kbuf = NULL;
350
    }
350
    }
351
    BM = NULL;
351
    BM = NULL;
352
    p->rows = rows;
352
    p->rows = rows; /* ROWS */
353
    p->cols = cols;
353
    p->cols = cols; /* COLS */
354
    for (int i=0; i<numGuiColors; i++)
354
    for (int i=0; i<numGuiColors; i++)
355
	p->guiColors[i] = guiColors[i];
355
	p->guiColors[i] = guiColors[i];
356
    p->f = f;
356
    p->f = f;
357
    FH = fontheight(f);
357
    FH = fontheight(f);
358
    FW = fontwidth(f);
358
    FW = fontwidth(f);
Line 423... Line 423...
423
    return(1);
423
    return(1);
424
}
424
}
425
 
425
 
426
/* Here fch and lch are columns, and we have to cope with both MBCS
426
/* Here fch and lch are columns, and we have to cope with both MBCS
427
   and double-width chars. */
427
   and double-width chars. */
428
 
-
 
-
 
428
/* caller must manage R_alloc stack */
429
static void writelineHelper(ConsoleData p, int fch, int lch,
429
static void writelineHelper(ConsoleData p, int fch, int lch,
430
			    rgb fgr, rgb bgr, int j, int len, wchar_t *s)
430
			    rgb fgr, rgb bgr, int j, int len, wchar_t *s)
431
{
431
{
432
    rect  r;
432
    rect  r;
433
 
433
 
Line 495... Line 495...
495
    wchar_t *s, *stmp, *p0;
495
    wchar_t *s, *stmp, *p0;
496
    int   insel, len, col1, d;
496
    int   insel, len, col1, d;
497
    int   c1, c2, c3, x0, y0, x1, y1;
497
    int   c1, c2, c3, x0, y0, x1, y1;
498
    rect r;
498
    rect r;
499
    int   bg, fg, highlight, base;
499
    int   bg, fg, highlight, base;
-
 
500
    const void *vmax = NULL;
500
 
501
 
-
 
502
    vmax = vmaxget();
501
    if (p->kind == CONSOLE) base = consolebg;
503
    if (p->kind == CONSOLE) base = consolebg;
502
    else if (p->kind == PAGER) base = pagerbg;
504
    else if (p->kind == PAGER) base = pagerbg;
503
    else base = dataeditbg;
505
    else base = dataeditbg;
504
 
506
 
505
    bg = p->guiColors[base];
507
    bg = p->guiColors[base];
506
    fg = p->guiColors[base+1];
508
    fg = p->guiColors[base+1];
507
    highlight = p->guiColors[base+2];
509
    highlight = p->guiColors[base+2];
508
 
510
 
509
    if ((i < 0) || (i >= NUMLINES)) return 0;
511
    if ((i < 0) || (i >= NUMLINES)) {
-
 
512
	vmaxset(vmax);
-
 
513
	return 0;
-
 
514
    }
510
    stmp = s = LINE(i);
515
    stmp = s = LINE(i);
511
    len = wcswidth(stmp);
516
    len = wcswidth(stmp);
512
    /* If there is a \r in the line, we need to preprocess it */
517
    /* If there is a \r in the line, we need to preprocess it */
513
    if((p0 = wcschr(s, L'\r'))) {
518
    if((p0 = wcschr(s, L'\r'))) {
514
	int l, l1;
519
	int l, l1;
515
	stmp = LINE(i);
520
	stmp = LINE(i);
-
 
521
	/* stmp may be large particularly when using txtProgressBar */
516
	s = (wchar_t *) alloca((wcslen(stmp) + 1) * sizeof(wchar_t));
522
	s = (wchar_t *) R_alloc(wcslen(stmp) + 1, sizeof(wchar_t));
517
	l = p0 - stmp;
523
	l = p0 - stmp;
518
	wcsncpy(s, stmp, l);
524
	wcsncpy(s, stmp, l);
519
	stmp = p0 + 1;
525
	stmp = p0 + 1;
520
	while((p0 = wcschr(stmp, L'\r'))) {
526
	while((p0 = wcschr(stmp, L'\r'))) {
521
	    l1 = p0 - stmp;
527
	    l1 = p0 - stmp;
Line 538... Line 544...
538
    }
544
    }
539
    col1 = COLS - 1;
545
    col1 = COLS - 1;
540
    insel = p->sel ? ((i - p->my0) * (i - p->my1)) : 1;
546
    insel = p->sel ? ((i - p->my0) * (i - p->my1)) : 1;
541
    if (insel < 0) {
547
    if (insel < 0) {
542
	WLHELPER(0, col1, bg, fg);
548
	WLHELPER(0, col1, bg, fg);
-
 
549
	vmaxset(vmax);
543
	return len;
550
	return len;
544
    }
551
    }
545
    if ((USER(i) >= 0) && (USER(i) < FC + COLS)) {
552
    if ((USER(i) >= 0) && (USER(i) < FC + COLS)) {
546
	if (USER(i) <= FC)
553
	if (USER(i) <= FC)
547
	    WLHELPER(0, col1, highlight, bg);
554
	    WLHELPER(0, col1, highlight, bg);
Line 556... Line 563...
556
	WLHELPER(0, col1, fg, bg);
563
	WLHELPER(0, col1, fg, bg);
557
    /* This is the cursor, and it may need to be variable-width */
564
    /* This is the cursor, and it may need to be variable-width */
558
    if ((CURROW >= 0) && (CURCOL >= FC) && (CURCOL < FC + COLS) &&
565
    if ((CURROW >= 0) && (CURCOL >= FC) && (CURCOL < FC + COLS) &&
559
	(i == NUMLINES - 1) && (p->sel == 0 || !intersect_input(p, 0))) {
566
	(i == NUMLINES - 1) && (p->sel == 0 || !intersect_input(p, 0))) {
560
	if (!p->overwrite) {
567
	if (!p->overwrite) {
561
	    if (p->cursor_blink) {
568
	    if (p->cursor_blink) 
562
	    	setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
569
	    	setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
563
	    	            p->cursor_blink == 1 ? 1 : FW/4, FH);
570
	    	            p->cursor_blink == 1 ? 1 : FW/4, FH);
564
	    	showcaret(c, 1);
-
 
565
	    } else showcaret(c, 0);
-
 
566
	    
571
	    
567
	    if (p->cursor_blink < 2) {
572
	    if (p->cursor_blink < 2) {
568
	    	r = rect(BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, FW/4, FH);
573
	    	r = rect(BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, FW/4, FH);
569
	    	gfillrect(BM, highlight, r);
574
	    	gfillrect(BM, highlight, r);
570
	    }
575
	    }
Line 577... Line 582...
577
		w0 += Ri18n_wcwidth(wc);
582
		w0 += Ri18n_wcwidth(wc);
578
	    }
583
	    }
579
	    /* term string '\0' box width = 1 fix */
584
	    /* term string '\0' box width = 1 fix */
580
	    w0 = wc ? Ri18n_wcwidth(wc) : 1;
585
	    w0 = wc ? Ri18n_wcwidth(wc) : 1;
581
	    nn[0] = wc;
586
	    nn[0] = wc;
582
	    if (p->cursor_blink) {
587
	    if (p->cursor_blink) 
583
	    	setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
588
	    	setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
584
	    		    p->cursor_blink == 1 ? 1 : FW/4, FH);
589
	    		    p->cursor_blink == 1 ? 1 : FW/4, FH);
585
	    	showcaret(c, 1);
-
 
586
	    } else showcaret(c, 0);
-
 
587
	    if (p->cursor_blink < 2) {
590
	    if (p->cursor_blink < 2) {
588
	    	r = rect(BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH,
591
	    	r = rect(BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH,
589
		         w0 * FW, FH);
592
		         w0 * FW, FH);
590
	    	gfillrect(BM, highlight, r);
593
	    	gfillrect(BM, highlight, r);
591
	    	gdrawwcs(BM, p->f, bg, pt(r.x, r.y), nn);
594
	    	gdrawwcs(BM, p->f, bg, pt(r.x, r.y), nn);
592
	    }
595
	    }
593
	} else {
596
	} else {
594
	    if (p->cursor_blink) {
597
	    if (p->cursor_blink) 
595
		setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
598
		setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
596
		            p->cursor_blink == 1 ? 1 : FW, FH);
599
		            p->cursor_blink == 1 ? 1 : FW, FH);
597
	    	showcaret(c, 1);
-
 
598
	    } else showcaret(c, 0);
-
 
599
	    if (p->cursor_blink < 2) 
600
	    if (p->cursor_blink < 2) 
600
	    	WLHELPER(CURCOL - FC, CURCOL - FC, bg, highlight); 
601
	    	WLHELPER(CURCOL - FC, CURCOL - FC, bg, highlight); 
601
	}
602
	}
602
    }
603
    }
603
    if (insel != 0) return len;
604
    if (insel != 0) {
-
 
605
	vmaxset(vmax);
-
 
606
	return len;
-
 
607
    }
604
    c1 = (p->my0 < p->my1);
608
    c1 = (p->my0 < p->my1);
605
    c2 = (p->my0 == p->my1);
609
    c2 = (p->my0 == p->my1);
606
    c3 = (p->mx0 < p->mx1);
610
    c3 = (p->mx0 < p->mx1);
607
    if (c1 || (c2 && c3)) {
611
    if (c1 || (c2 && c3)) {
608
	x0 = p->mx0; y0 = p->my0;
612
	x0 = p->mx0; y0 = p->my0;
Line 610... Line 614...
610
    } else {
614
    } else {
611
	x0 = p->mx1; y0 = p->my1;
615
	x0 = p->mx1; y0 = p->my1;
612
	x1 = p->mx0; y1 = p->my0;
616
	x1 = p->mx0; y1 = p->my0;
613
    }
617
    }
614
    if (i == y0) {
618
    if (i == y0) {
615
	if (FC + COLS < x0) return len;
619
	if (FC + COLS < x0) {
-
 
620
	    vmaxset(vmax);
-
 
621
	    return len;
-
 
622
	}
616
	if(mbcslocale) {
623
	if(mbcslocale) {
617
	    int w0, w1 = 1;
624
	    int w0, w1 = 1;
618
	    wchar_t *P = s;
625
	    wchar_t *P = s;
619
	    for (w0 = 0; w0 < x0; P++) {
626
	    for (w0 = 0; w0 < x0; P++) {
620
		if(!*P) break;
627
		if(!*P) break;
Line 625... Line 632...
625
	}
632
	}
626
	c1 = (x0 > FC) ? (x0 - FC) : 0;
633
	c1 = (x0 > FC) ? (x0 - FC) : 0;
627
    } else
634
    } else
628
	c1 = 0;
635
	c1 = 0;
629
    if (i == y1) {
636
    if (i == y1) {
-
 
637
	if (FC > x1) {
-
 
638
	    vmaxset(vmax);
630
	if (FC > x1) return len;
639
	    return len;
-
 
640
	}
631
	if(mbcslocale) {
641
	if(mbcslocale) {
632
	    int w0;
642
	    int w0;
633
	    wchar_t *P = s;
643
	    wchar_t *P = s;
634
	    for (w0 = 0; w0 <= x1; P++) {
644
	    for (w0 = 0; w0 <= x1; P++) {
635
		if(!*P) break;
645
		if(!*P) break;
Line 639... Line 649...
639
	}
649
	}
640
	c2 = (x1 > FC + COLS) ? (COLS - 1) : (x1 - FC);
650
	c2 = (x1 > FC + COLS) ? (COLS - 1) : (x1 - FC);
641
    } else
651
    } else
642
	c2 = COLS - 1;
652
	c2 = COLS - 1;
643
    WLHELPER(c1, c2, bg, fg);
653
    WLHELPER(c1, c2, bg, fg);
-
 
654
    vmaxset(vmax);
644
    return len;
655
    return len;
645
}
656
}
646
 
657
 
647
void drawconsole(control c, rect r) /* r is unused here */
658
void drawconsole(control c, rect r) /* r is unused here */
648
{
659
{
Line 691... Line 702...
691
	return;;
702
	return;;
692
    }
703
    }
693
    if (p->needredraw) {
704
    if (p->needredraw) {
694
	ww = min(NUMLINES, ROWS) - 1;
705
	ww = min(NUMLINES, ROWS) - 1;
695
	rw = FV + ww;
706
	rw = FV + ww;
696
	writeline(c, p, rw, ww);
707
	WRITELINE(rw, ww);
697
	if (ds == 0) {
708
	if (ds == 0) {
698
	    RSHOW(RLINE(ww));
709
	    RSHOW(RLINE(ww));
699
	    return;;
710
	    return;;
700
	}
711
	}
701
    }
712
    }
Line 888... Line 899...
888
    }
899
    }
889
    p->kbuf[(p->firstkey + p->numkeys) % NKEYS] = k;
900
    p->kbuf[(p->firstkey + p->numkeys) % NKEYS] = k;
890
    p->numkeys++;
901
    p->numkeys++;
891
}
902
}
892
 
903
 
-
 
904
static void storekeys(control c, const char *str)
-
 
905
{
-
 
906
    if (strlen(str) == 0) return; 
-
 
907
    if(isUnicodeWindow(c)) {
-
 
908
	size_t sz = (strlen(str) + 1) * sizeof(wchar_t);
-
 
909
	const void *vmax = NULL;
-
 
910
	vmax = vmaxget();
-
 
911
	wchar_t *wcs = (wchar_t*) R_alloc(strlen(str) + 1, sizeof(wchar_t));
-
 
912
	memset(wcs, 0, sz);
-
 
913
	mbstowcs(wcs, str, sz-1);
-
 
914
	int i;
-
 
915
	for(i = 0; wcs[i]; i++) storekey(c, wcs[i]);
-
 
916
	vmaxset(vmax);
-
 
917
    } else {
-
 
918
	const char *ch;
-
 
919
	for (ch = str; *ch; ch++) storekey(c, (unsigned char) *ch);
-
 
920
    }
-
 
921
}
-
 
922
 
893
static void storetab(control c)
923
static void storetab(control c)
894
{
924
{
895
    ConsoleData p = getdata(c);
925
    ConsoleData p = getdata(c);
896
    p->kbuf[(p->firstkey + p->numkeys) % NKEYS] = L' ';
926
    p->kbuf[(p->firstkey + p->numkeys) % NKEYS] = L' ';
897
    p->numkeys++;
927
    p->numkeys++;
Line 910... Line 940...
910
 
940
 
911
 
941
 
912
static void performCompletion(control c)
942
static void performCompletion(control c)
913
{
943
{
914
    ConsoleData p = getdata(c);
944
    ConsoleData p = getdata(c);
915
    int i, alen, alen2, max_show = 10, cursor_position = CURCOL - prompt_wid;
945
    int i, alen, max_show = 10, cursor_position = CURCOL - prompt_wid;
916
    wchar_t *partial_line = LINE(NUMLINES - 1) + prompt_wid;
946
    wchar_t *partial_line = LINE(NUMLINES - 1) + prompt_wid;
917
    const char *additional_text;
947
    const char *additional_text;
918
    SEXP cmdSexp, cmdexpr, ans = R_NilValue;
948
    SEXP cmdSexp, cmdexpr, ans = R_NilValue;
919
    ParseStatus status;
949
    ParseStatus status;
-
 
950
    const void *vmax = NULL;
920
 
951
 
921
    if(!completion_available) {
952
    if(!completion_available) {
922
	storetab(c);
953
	storetab(c);
923
	return;
954
	return;
924
    }
955
    }
Line 976... Line 1007...
976
    }
1007
    }
977
    /* Loop is needed here as EXPSEXP will be of length > 1 */
1008
    /* Loop is needed here as EXPSEXP will be of length > 1 */
978
    for(i = 0; i < length(cmdexpr); i++)
1009
    for(i = 0; i < length(cmdexpr); i++)
979
	ans = eval(VECTOR_ELT(cmdexpr, i), R_GlobalEnv);
1010
	ans = eval(VECTOR_ELT(cmdexpr, i), R_GlobalEnv);
980
    UNPROTECT(2);
1011
    UNPROTECT(2);
-
 
1012
    PROTECT(ans);
981
 
1013
 
982
    /* ans has the form list(addition, possible), where 'addition' is
1014
    /* ans has the form list(addition, possible), where 'addition' is
983
       unique additional text if any, and 'possible' is a character
1015
       unique additional text if any, and 'possible' is a character
984
       vector holding possible completions if any (already formatted
1016
       vector holding possible completions if any (already formatted
985
       for linewise printing in the current implementation).  If
1017
       for linewise printing in the current implementation).  If
Line 988... Line 1020...
988
       at the cursor */
1020
       at the cursor */
989
 
1021
 
990
#define ADDITION 0
1022
#define ADDITION 0
991
#define POSSIBLE 1
1023
#define POSSIBLE 1
992
 
1024
 
-
 
1025
    vmax = vmaxget();
993
    alen = length(VECTOR_ELT(ans, POSSIBLE));
1026
    alen = length(VECTOR_ELT(ans, POSSIBLE));
-
 
1027
    /* could translate directly to wchar_t */
994
    additional_text = CHAR(STRING_ELT( VECTOR_ELT(ans, ADDITION), 0 ));
1028
    additional_text = translateChar(STRING_ELT( VECTOR_ELT(ans, ADDITION), 0 ));
995
    alen2 = strlen(additional_text);
-
 
996
    if (alen) {
1029
    if (alen) {
997
	/* make a copy of the current string first */
1030
	/* make a copy of the current string first */
998
	wchar_t p1[wcslen(LINE(NUMLINES - 1)) + 1];
1031
	wchar_t p1[wcslen(LINE(NUMLINES - 1)) + 1];
999
	wcscpy(p1, LINE(NUMLINES - 1));
1032
	wcscpy(p1, LINE(NUMLINES - 1));
1000
	checkpointpos(p->lbuf, 1);
1033
	checkpointpos(p->lbuf, 1);
Line 1003... Line 1036...
1003
	snprintf(buf1, len+1, "%ls\n", p1);
1036
	snprintf(buf1, len+1, "%ls\n", p1);
1004
	consolewrites(c, buf1);
1037
	consolewrites(c, buf1);
1005
 
1038
 
1006
	for (i = 0; i < min(alen, max_show); i++) {
1039
	for (i = 0; i < min(alen, max_show); i++) {
1007
            consolewrites(c, "\n");
1040
            consolewrites(c, "\n");
1008
	    consolewrites(c, CHAR(STRING_ELT(VECTOR_ELT(ans, POSSIBLE), i)));
1041
	    consolewrites(c, translateChar(STRING_ELT(VECTOR_ELT(ans, POSSIBLE), i)));
1009
	}
1042
	}
1010
	if (alen > max_show)
1043
	if (alen > max_show)
1011
	    consolewrites(c, "\n[...truncated]");
1044
	    consolewrites(c, "\n[...truncated]");
1012
	consolewrites(c, "\n");
1045
	consolewrites(c, "\n");
1013
	p->wipe_completion = 1;
1046
	p->wipe_completion = 1;
1014
    }
1047
    }
1015
 
-
 
1016
    if (alen2)
1048
    vmaxset(vmax);
-
 
1049
    UNPROTECT(1); /* ans */
1017
	for (i = 0; i < alen2; i++) storekey(c, additional_text[i]);
1050
    storekeys(c, additional_text);
1018
    return;
1051
    return;
1019
}
1052
}
1020
 
1053
 
1021
/* deletes that part of the selection which is on the input line */
1054
/* deletes that part of the selection which is on the input line */
1022
static void deleteselected(ConsoleData p)
1055
static void deleteselected(ConsoleData p)
Line 1053... Line 1086...
1053
	p->needredraw = 1;
1086
	p->needredraw = 1;
1054
	REDRAW;
1087
	REDRAW;
1055
    }
1088
    }
1056
    storekey(c, BEGINLINE);
1089
    storekey(c, BEGINLINE);
1057
    storekey(c, KILLRESTOFLINE);
1090
    storekey(c, KILLRESTOFLINE);
1058
    if(isUnicodeWindow(c)) {
-
 
1059
	size_t sz = (strlen(cmd) + 1) * sizeof(wchar_t);
-
 
1060
	wchar_t *wcs = (wchar_t*) R_alloc(strlen(cmd) + 1, sizeof(wchar_t));
-
 
1061
	memset(wcs, 0, sz);
-
 
1062
	mbstowcs(wcs, cmd, sz-1);
1091
    storekeys(c, cmd);
1063
	for(i = 0; wcs[i]; i++) storekey(c, wcs[i]);
-
 
1064
    } else {
-
 
1065
	const char *ch;
-
 
1066
	for (ch = cmd; *ch; ch++) storekey(c, (unsigned char) *ch);
-
 
1067
    }
-
 
1068
    storekey(c, '\n');
1092
    storekey(c, '\n');
1069
/* if we are editing we save the actual line
1093
/* if we are editing we save the actual line
1070
   FIXME: not right if Unicode */
1094
   FIXME: not right if Unicode */
1071
    if (CURROW > -1) {
1095
    if (CURROW > -1) {
1072
	char buf[2000], *cp; /* maximum 2 bytes/char */
1096
	char buf[2000], *cp; /* maximum 2 bytes/char */
Line 1724... Line 1748...
1724
int consolereads(control c, const char *prompt, char *buf, int len,
1748
int consolereads(control c, const char *prompt, char *buf, int len,
1725
		 int addtohistory)
1749
		 int addtohistory)
1726
{
1750
{
1727
    ConsoleData p = getdata(c);
1751
    ConsoleData p = getdata(c);
1728
 
1752
 
-
 
1753
    if (p->cursor_blink == 2)
-
 
1754
	/* The caret may be visible via SetUpCaret flag (see newconsole) for
-
 
1755
	   startup. It needs to be hidden now to be protected agains redraw. */
-
 
1756
	showcaret(c, 0);
1729
    wchar_t *cur_line, *P;
1757
    wchar_t *cur_line, *P;
1730
    wchar_t *aLine;
1758
    wchar_t *aLine;
1731
    int ns0 = NUMLINES, w0 = 0, pre_prompt_len;
1759
    int ns0 = NUMLINES, w0 = 0, pre_prompt_len;
1732
 
1760
 
1733
    pre_prompt_len = wcslen(LINE(NUMLINES - 1));
1761
    pre_prompt_len = wcslen(LINE(NUMLINES - 1));
Line 1752... Line 1780...
1752
    FC = 0;
1780
    FC = 0;
1753
    cur_pos = 0;
1781
    cur_pos = 0;
1754
    max_pos = 0;
1782
    max_pos = 0;
1755
    cur_line = &aLine[prompt_len];
1783
    cur_line = &aLine[prompt_len];
1756
    cur_line[0] = L'\0';
1784
    cur_line[0] = L'\0';
1757
    showcaret(c, 1);
-
 
1758
    REDRAW;
1785
    REDRAW;
1759
    for(;;) {
1786
    for(;;) {
1760
	wchar_t cur_char;
1787
	wchar_t cur_char;
1761
	char chtype; /* boolean */
1788
	char chtype; /* boolean */
1762
	p->input = 1;
1789
	p->input = 1;
-
 
1790
	/* The caret must not be shown when drawing, because it would
-
 
1791
	   be erased by redraws. We thus only show it when waiting for the
-
 
1792
	   keyboard input. REDRAW is also called when processing events,
-
 
1793
	   e.g. while the console window is loosing focus, so changing the
-
 
1794
	   caret visibility there was error prone. */
-
 
1795
	if (p->cursor_blink)
-
 
1796
	   showcaret(c, 1);
1763
	cur_char = consolegetc(c);
1797
	cur_char = consolegetc(c);
-
 
1798
	showcaret(c, 0);
1764
	p->input = 0;
1799
	p->input = 0;
1765
	chtype = ((unsigned int) cur_char > 0x1f);
1800
	chtype = ((unsigned int) cur_char > 0x1f);
1766
	if(NUMLINES != ns0) { /* we scrolled, e.g. cleared screen */
1801
	if(NUMLINES != ns0) { /* we scrolled, e.g. cleared screen */
1767
	    cur_line = LINE(NUMLINES - 1) + prompt_len;
1802
	    cur_line = LINE(NUMLINES - 1) + prompt_len;
1768
	    ns0 = NUMLINES;
1803
	    ns0 = NUMLINES;
Line 1869... Line 1904...
1869
		    CURROW = -1;
1904
		    CURROW = -1;
1870
		    cur_line[max_pos] = L'\0';
1905
		    cur_line[max_pos] = L'\0';
1871
		    if (max_pos && addtohistory) wgl_histadd(cur_line);
1906
		    if (max_pos && addtohistory) wgl_histadd(cur_line);
1872
		    xbuffixl(p->lbuf);
1907
		    xbuffixl(p->lbuf);
1873
		    consolewrites(c, "\n");
1908
		    consolewrites(c, "\n");
1874
		    showcaret(c, 0);
-
 
1875
		    REDRAW;
1909
		    REDRAW;
1876
		    return cur_char == EOFKEY;
1910
		    return cur_char == EOFKEY;
1877
		}
1911
		}
1878
		break;
1912
		break;
1879
	    }
1913
	    }
Line 1988... Line 2022...
1988
    fontname[LF_FACESIZE] = L'\0';
2022
    fontname[LF_FACESIZE] = L'\0';
1989
    fontsty =   fnsty;
2023
    fontsty =   fnsty;
1990
    pointsize = fnpoints;
2024
    pointsize = fnpoints;
1991
    if (consolefn) del(consolefn);
2025
    if (consolefn) del(consolefn);
1992
    consolefn = NULL;
2026
    consolefn = NULL;
-
 
2027
    /* keep in step with applyGUI() in preferences.c */
1993
    if (strcmp(fontname, "FixedFont")) {
2028
    if (strcmp(fontname, "FixedFont")) {
1994
	consolefn = gnewfont(NULL, fnname, fnsty | FixedWidth, fnpoints, 0.0, 1);
2029
	consolefn = gnewfont(NULL, fnname, fnsty | FixedWidth, fnpoints, 0.0, 1);
1995
	if (!consolefn) {
2030
	if (!consolefn) {
1996
	    /* This is unlikely to happen: it will find some match */
2031
	    /* This is unlikely to happen: it will find some match */
1997
	    snprintf(msg, LF_FACESIZE + 128,
2032
	    snprintf(msg, LF_FACESIZE + 128,
Line 2217... Line 2252...
2217
    p = newconsoledata((consolefn) ? consolefn : FixedFont,
2252
    p = newconsoledata((consolefn) ? consolefn : FixedFont,
2218
		       consoler, consolec, consolebufb, consolebufl,
2253
		       consoler, consolec, consolebufb, consolebufl,
2219
		       guiColors,
2254
		       guiColors,
2220
		       CONSOLE, consolebuffered, consoleblink);
2255
		       CONSOLE, consolebuffered, consoleblink);
2221
    if (!p) return NULL;
2256
    if (!p) return NULL;
-
 
2257
    if (p->cursor_blink == 2)
-
 
2258
	/* Arrange for a dummy caret to be created when the new window
-
 
2259
	   gets focus. This is to help NVDA (screen reader) to choose
-
 
2260
	   a correct display model and correctly detect characters
-
 
2261
	   under the caret. After the first redraw, which will happen
-
 
2262
	   right away in consolereads, a correct caret will be set up
-
 
2263
	   and destroyed/restored when loosing/gaining focus. */
-
 
2264
	flags |= SetUpCaret;
2222
    c = (console) newwindow(name, rect(consolex, consoley, WIDTH, HEIGHT),
2265
    c = (console) newwindow(name, rect(consolex, consoley, WIDTH, HEIGHT),
2223
			    flags | TrackMouse | VScrollbar | HScrollbar);
2266
			    flags | TrackMouse | VScrollbar | HScrollbar);
2224
    HEIGHT = getheight(c);
2267
    HEIGHT = getheight(c);
2225
    WIDTH  = getwidth(c);
2268
    WIDTH  = getwidth(c);
2226
    COLS = WIDTH / FW - 1;
2269
    COLS = WIDTH / FW - 1;