Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

curs_cio.c 27 KB
Newer Older
1
/* $Id: curs_cio.c,v 1.60 2020/06/27 00:04:45 deuce Exp $ */
deuce's avatar
deuce committed
2 3 4 5 6

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
7
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
deuce's avatar
deuce committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 *																			*
 * This library is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU Lesser General Public License		*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU Lesser General Public License for more details: lgpl.txt or	*
 * http://www.fsf.org/copyleft/lesser.html									*
 *																			*
 * Anonymous FTP access to the most recent released source is available at	*
 * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
 *																			*
 * Anonymous CVS access to the development source and modification history	*
 * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
 *     (just hit return, no password is necessary)							*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * You are encouraged to submit any modifications (preferably in Unix diff	*
 * format) via e-mail to mods@synchro.net									*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

34 35
#include <langinfo.h>
#include <locale.h>
36
#include <sys/time.h>
37
#include <stdarg.h>
38 39
#include <stdio.h>
#include <stdlib.h>
40 41
#include <unistd.h>

42 43
#include "gen_defs.h"	/* xpdev, for BOOL/TRUE/FALSE */

44 45 46 47 48 49 50
#if (defined CIOLIB_IMPORTS)
 #undef CIOLIB_IMPORTS
#endif
#if (defined CIOLIB_EXPORTS)
 #undef CIOLIB_EXPORTS
#endif

51
#include "ciolib.h"
52
#include "curs_cio.h"
deuce's avatar
deuce committed
53
#include "vidmodes.h"
54
#include "utf8_codepages.h"
55

56
static unsigned char curs_nextgetch=0;
57

58 59
static int lastattr=0;
static long mode;
60
static int vflags=0;
61
static int suspended = 0;
deuce's avatar
deuce committed
62
static int mpress = 0;
63
void curs_resume(void);
64

65 66 67
static int default_font=0;
static int current_font[4]={0, 0, 0, 0};

68
static short curses_color(short color)
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
{
	switch(color)
	{
		case 0 :
			return(COLOR_BLACK);
		case 1 :
			return(COLOR_BLUE);
		case 2 :
			return(COLOR_GREEN);
		case 3 :
			return(COLOR_CYAN);
		case 4 :
			return(COLOR_RED);
		case 5 :
			return(COLOR_MAGENTA);
		case 6 :
			return(COLOR_YELLOW);
		case 7 :
			return(COLOR_WHITE);
		case 8 :
89
			return(COLOR_BLACK+8);
90
		case 9 :
91
			return(COLOR_BLUE+8);
92
		case 10 :
93
			return(COLOR_GREEN+8);
94
		case 11 :
95
			return(COLOR_CYAN+8);
96
		case 12 :
97
			return(COLOR_RED+8);
98
		case 13 :
99
			return(COLOR_MAGENTA+8);
100
		case 14 :
101
			return(COLOR_YELLOW+8);
102
		case 15 :
103
			return(COLOR_WHITE+8);
104 105 106 107
	}
	return(0);
}

108
static int _putch(unsigned char ch, BOOL refresh_now, int cp)
109
{
110 111
	int	ret;
	cchar_t	cha;
112
	wchar_t wch[2] = {0};
113
	attr_t	attr = 0;
Deucе's avatar
Deucе committed
114
	short	cpair = 0;
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317

	attr_get(&attr, &cpair, NULL);
	attr &= ~A_COLOR;
	switch (mode) {
		case CIOLIB_MODE_CURSES_ASCII:
			switch(ch)
			{
				case 30:
					wch[0]=ACS_UARROW & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 31:
					wch[0]=ACS_DARROW & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 176:
					wch[0]=ACS_CKBOARD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 177:
					wch[0]=ACS_BOARD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 178:
					wch[0]=ACS_BOARD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 179:
					wch[0]=ACS_SBSB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 180:
					wch[0]=ACS_SBSS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 181:
					wch[0]=ACS_SBSD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 182:
					wch[0]=ACS_DBDS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 183:
					wch[0]=ACS_BBDS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 184:
					wch[0]=ACS_BBSD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 185:
					wch[0]=ACS_DBDD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 186:
					wch[0]=ACS_DBDB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 187:
					wch[0]=ACS_BBDD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 188:
					wch[0]=ACS_DBBD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 189:
					wch[0]=ACS_DBBS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 190:
					wch[0]=ACS_SBBD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 191:
					wch[0]=ACS_BBSS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 192:
					wch[0]=ACS_SSBB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 193:
					wch[0]=ACS_SSBS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 194:
					wch[0]=ACS_BSSS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 195:
					wch[0]=ACS_SSSB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 196:
					wch[0]=ACS_BSBS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 197:
					wch[0]=ACS_SSSS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 198:
					wch[0]=ACS_SDSB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 199:
					wch[0]=ACS_DSDB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 200:
					wch[0]=ACS_DDBB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 201:
					wch[0]=ACS_BDDB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 202:
					wch[0]=ACS_DDBD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 203:
					wch[0]=ACS_BDDD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 204:
					wch[0]=ACS_DDDB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 205:
					wch[0]=ACS_BDBD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 206:
					wch[0]=ACS_DDDD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 207:
					wch[0]=ACS_SDBD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 208:
					wch[0]=ACS_DSBS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 209:
					wch[0]=ACS_BDSD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 210:
					wch[0]=ACS_BSDS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 211:
					wch[0]=ACS_DSBB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 212:
					wch[0]=ACS_SDBB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 213:
					wch[0]=ACS_BDSB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 214:
					wch[0]=ACS_BSDB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 215:
					wch[0]=ACS_DSDS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 216:
					wch[0]=ACS_SDSD & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 217:
					wch[0]=ACS_SBBS & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 218:
					wch[0]=ACS_BSSB & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 219:
					wch[0]=ACS_BLOCK & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				case 254:
					wch[0]=ACS_BULLET & A_CHARTEXT;
					attr |= WA_ALTCHARSET;
					break;
				default:
					wch[0]=ch;
			}
			break;
		case CIOLIB_MODE_CURSES_IBM:
			wch[0]=ch;
			break;
		case CIOLIB_MODE_CURSES:
318
			wch[0] = cpoint_from_cpchar_ext(cp, ch);
319
			break;
320 321
	}

322 323 324 325 326 327 328
	if(!wch[0]) {
		wch[0]=' ';
		attr |= WA_BOLD;
	}
	else {
		attr &= ~WA_BOLD;
	}
329
	curs_resume();
330 331 332
	if (wch[0] < ' ') {
		attr |= WA_REVERSE;
		wch[0] = wch[0] + 'A' - 1;
333
	}
334 335 336

	setcchar(&cha, wch, attr, cpair, NULL);
	ret = add_wch(&cha);
337 338 339 340 341 342 343 344 345

	if(!hold_update) {
		if(refresh_now)
			refresh();
	}

	return(ret);
}

346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
int curs_vmem_puttext(int sx, int sy, int ex, int ey, struct vmem_cell *fill)
{
	int x,y;
	int fillpos=0;
	unsigned char attr;
	unsigned char fill_char;
	unsigned char orig_attr;
	int oldx, oldy;

	if(		   sx < 1
			|| sy < 1
			|| ex < 1
			|| ey < 1
			|| sx > cio_textinfo.screenwidth
			|| sy > cio_textinfo.screenheight
			|| sx > ex
			|| sy > ey
			|| ex > cio_textinfo.screenwidth
			|| ey > cio_textinfo.screenheight
			|| fill==NULL)
		return(0);

	curs_resume();
	getyx(stdscr,oldy,oldx);
	orig_attr=lastattr;
	for(y=sy-1;y<ey;y++)
	{
		for(x=sx-1;x<ex;x++)
		{
			fill_char=fill[fillpos].ch;
			attr=fill[fillpos].legacy_attr;
			textattr(attr);
			move(y, x);
			_putch(fill_char,FALSE,conio_fontdata[fill[fillpos].font].cp);
			fillpos++;
		}
	}
	textattr(orig_attr);
	move(oldy, oldx);
	if(!hold_update)
		refresh();
	return(1);
}

deuce's avatar
deuce committed
390
int curs_puttext(int sx, int sy, int ex, int ey, void *fillbuf)
391 392 393 394 395 396 397
{
	int x,y;
	int fillpos=0;
	unsigned char attr;
	unsigned char fill_char;
	unsigned char orig_attr;
	int oldx, oldy;
deuce's avatar
deuce committed
398
	unsigned char *fill;
399

400
	fill = fillbuf;
401 402 403 404 405

	if(		   sx < 1
			|| sy < 1
			|| ex < 1
			|| ey < 1
406 407
			|| sx > cio_textinfo.screenwidth
			|| sy > cio_textinfo.screenheight
408 409
			|| sx > ex
			|| sy > ey
410 411
			|| ex > cio_textinfo.screenwidth
			|| ey > cio_textinfo.screenheight
412 413
			|| fill==NULL)
		return(0);
414

415
	curs_resume();
416 417
	getyx(stdscr,oldy,oldx);
	orig_attr=lastattr;
418
	for(y=sy-1;y<ey;y++)
419
	{
420
		for(x=sx-1;x<ex;x++)
421 422 423
		{
			fill_char=fill[fillpos++];
			attr=fill[fillpos++];
424
			textattr(attr);
425
			move(y, x);
426
			_putch(fill_char,FALSE,getcodepage());
427 428
		}
	}
429
	textattr(orig_attr);
430
	move(oldy, oldx);
431
	if(!hold_update)
432
		refresh();
433 434 435
	return(1);
}

436
int curs_vmem_gettext(int sx, int sy, int ex, int ey, struct vmem_cell *fill)
437 438 439 440 441 442 443 444
{
	int x,y;
	int fillpos=0;
	unsigned char attrib;
	unsigned char colour;
	int oldx, oldy;
	unsigned char thischar;
	int	ext_char;
445
	struct text_info	ti;
446 447
	attr_t attr;
	cchar_t cchar;
448 449 450
	int fnt = current_font[0];
	int cp;
	fd_set cp_checked;
451

452
	curs_resume();
453
	gettextinfo(&ti);
454

455 456 457 458 459 460 461 462 463 464 465 466 467 468
	if(		   sx < 1
			|| sy < 1
			|| ex < 1
			|| ey < 1
			|| sx > ti.screenwidth
			|| sy > ti.screenheight
			|| sx > ex
			|| sy > ey
			|| ex > ti.screenwidth
			|| ey > ti.screenheight
			|| fill==NULL)
		return(0);

	getyx(stdscr,oldy,oldx);
469 470 471 472
	for(y=sy-1;y<=ey-1;y++)
	{
		for(x=sx-1;x<=ex-1;x++)
		{
473 474 475 476
			mvin_wch(y, x, &cchar);
			attr = cchar.attr;
			thischar = ext_char = cchar.chars[0];
			if(attr&WA_REVERSE) {
deuce's avatar
deuce committed
477
				thischar=(thischar)-'A'+1;
478
			}
479 480 481 482 483
			else {
				switch (mode) {
					case CIOLIB_MODE_CURSES_ASCII:
						/* likely ones */
						if (attr & WA_ALTCHARSET) {
deuce's avatar
deuce committed
484
							if (ext_char == (ACS_CKBOARD & A_CHARTEXT))
485 486 487
							{
								thischar=176;
							}
deuce's avatar
deuce committed
488
							else if (ext_char == (ACS_BOARD & A_CHARTEXT))
489 490 491
							{
								thischar=177;
							}
deuce's avatar
deuce committed
492
							else if (ext_char == (ACS_BSSB & A_CHARTEXT))
493 494 495
							{
								thischar=218;
							}
deuce's avatar
deuce committed
496
							else if (ext_char == (ACS_SSBB & A_CHARTEXT))
497 498 499
							{
								thischar=192;
							}
deuce's avatar
deuce committed
500
							else if (ext_char == (ACS_BBSS & A_CHARTEXT))
501 502 503
							{
								thischar=191;
							}
deuce's avatar
deuce committed
504
							else if (ext_char == (ACS_SBBS & A_CHARTEXT))
505 506 507
							{
								thischar=217;
							}
deuce's avatar
deuce committed
508
							else if (ext_char == (ACS_SBSS & A_CHARTEXT))
509 510 511
							{
								thischar=180;
							}
deuce's avatar
deuce committed
512
							else if (ext_char == (ACS_SSSB & A_CHARTEXT))
513 514 515
							{
								thischar=195;
							}
deuce's avatar
deuce committed
516
							else if (ext_char == (ACS_SSBS & A_CHARTEXT))
517 518 519
							{
								thischar=193;
							}
deuce's avatar
deuce committed
520
							else if (ext_char == (ACS_BSSS & A_CHARTEXT))
521 522 523
							{
								thischar=194;
							}
deuce's avatar
deuce committed
524
							else if (ext_char == (ACS_BSBS & A_CHARTEXT))
525 526 527
							{
								thischar=196;
							}
deuce's avatar
deuce committed
528
							else if (ext_char == (ACS_SBSB & A_CHARTEXT))
529 530 531
							{
								thischar=179;
							}
deuce's avatar
deuce committed
532
							else if (ext_char == (ACS_SSSS & A_CHARTEXT))
533 534 535
							{
								thischar=197;
							}
deuce's avatar
deuce committed
536
							else if (ext_char == (ACS_BLOCK & A_CHARTEXT))
537 538 539
							{
								thischar=219;
							}
deuce's avatar
deuce committed
540
							else if (ext_char == (ACS_UARROW & A_CHARTEXT))
541 542 543
							{
								thischar=30;
							}
deuce's avatar
deuce committed
544
							else if (ext_char == (ACS_DARROW & A_CHARTEXT))
545 546 547 548 549
							{
								thischar=31;
							}

							/* unlikely (Not in ncurses) */
deuce's avatar
deuce committed
550
							else if (ext_char == (ACS_SBSD & A_CHARTEXT))
551 552 553
							{
								thischar=181;
							}
deuce's avatar
deuce committed
554
							else if (ext_char == (ACS_DBDS & A_CHARTEXT))
555 556 557
							{
								thischar=182;
							}
deuce's avatar
deuce committed
558
							else if (ext_char == (ACS_BBDS & A_CHARTEXT))
559 560 561
							{
								thischar=183;
							}
deuce's avatar
deuce committed
562
							else if (ext_char == (ACS_BBSD & A_CHARTEXT))
563 564 565
							{
								thischar=184;
							}
deuce's avatar
deuce committed
566
							else if (ext_char == (ACS_DBDD & A_CHARTEXT))
567 568 569
							{
								thischar=185;
							}
deuce's avatar
deuce committed
570
							else if (ext_char == (ACS_DBDB & A_CHARTEXT))
571 572 573
							{
								thischar=186;
							}
deuce's avatar
deuce committed
574
							else if (ext_char == (ACS_BBDD & A_CHARTEXT))
575 576 577
							{
								thischar=187;
							}
deuce's avatar
deuce committed
578
							else if (ext_char == (ACS_DBBD & A_CHARTEXT))
579 580 581
							{
								thischar=188;
							}
deuce's avatar
deuce committed
582
							else if (ext_char == (ACS_DBBS & A_CHARTEXT))
583 584 585
							{
								thischar=189;
							}
deuce's avatar
deuce committed
586
							else if (ext_char == (ACS_SBBD & A_CHARTEXT))
587 588 589
							{
								thischar=190;
							}
deuce's avatar
deuce committed
590
							else if (ext_char == (ACS_SDSB & A_CHARTEXT))
591 592 593
							{
								thischar=198;
							}
deuce's avatar
deuce committed
594
							else if (ext_char == (ACS_DSDB & A_CHARTEXT))
595 596 597
							{
								thischar=199;
							}
deuce's avatar
deuce committed
598
							else if (ext_char == (ACS_DDBB & A_CHARTEXT))
599 600 601
							{
								thischar=200;
							}
deuce's avatar
deuce committed
602
							else if (ext_char == (ACS_BDDB & A_CHARTEXT))
603 604 605
							{
								thischar=201;
							}
deuce's avatar
deuce committed
606
							else if (ext_char == (ACS_DDBD & A_CHARTEXT))
607 608 609
							{
								thischar=202;
							}
deuce's avatar
deuce committed
610
							else if (ext_char == (ACS_BDDD & A_CHARTEXT))
611 612 613
							{
								thischar=203;
							}
deuce's avatar
deuce committed
614
							else if (ext_char == (ACS_DDDB & A_CHARTEXT))
615 616 617
							{
								thischar=204;
							}
deuce's avatar
deuce committed
618
							else if (ext_char == (ACS_BDBD & A_CHARTEXT))
619 620 621
							{
								thischar=205;
							}
deuce's avatar
deuce committed
622
							else if (ext_char == (ACS_DDDD & A_CHARTEXT))
623 624 625
							{
								thischar=206;
							}
deuce's avatar
deuce committed
626
							else if (ext_char == (ACS_SDBD & A_CHARTEXT))
627 628 629
							{
								thischar=207;
							}
deuce's avatar
deuce committed
630
							else if (ext_char == (ACS_DSBS & A_CHARTEXT))
631 632 633
							{
								thischar=208;
							}
deuce's avatar
deuce committed
634
							else if (ext_char == (ACS_BDSD & A_CHARTEXT))
635 636 637
							{
								thischar=209;
							}
deuce's avatar
deuce committed
638
							else if (ext_char == (ACS_BSDS & A_CHARTEXT))
639 640 641
							{
								thischar=210;
							}
deuce's avatar
deuce committed
642
							else if (ext_char == (ACS_DSBB & A_CHARTEXT))
643 644 645
							{
								thischar=211;
							}
deuce's avatar
deuce committed
646
							else if (ext_char == (ACS_SDBB & A_CHARTEXT))
647 648 649
							{
								thischar=212;
							}
deuce's avatar
deuce committed
650
							else if (ext_char == (ACS_BDSB & A_CHARTEXT))
651 652 653
							{
								thischar=213;
							}
deuce's avatar
deuce committed
654
							else if (ext_char == (ACS_BSDB & A_CHARTEXT))
655 656 657
							{
								thischar=214;
							}
deuce's avatar
deuce committed
658
							else if (ext_char == (ACS_DSDS & A_CHARTEXT))
659 660 661
							{
								thischar=215;
							}
deuce's avatar
deuce committed
662
							else if (ext_char == (ACS_SDSD & A_CHARTEXT))
663 664 665 666
							{
								thischar=216;
							}
						}
667
						fnt = 0;
668 669
						break;
					case CIOLIB_MODE_CURSES_IBM:
deuce's avatar
deuce committed
670
						if (ext_char == (ACS_UARROW & A_CHARTEXT))
671 672 673
						{
							thischar=30;
						}
deuce's avatar
deuce committed
674
						else if (ext_char == (ACS_DARROW & A_CHARTEXT))
675 676 677
						{
							thischar=31;
						}
678
						fnt = 0;
679 680
						break;
					case CIOLIB_MODE_CURSES:
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
						thischar = cpchar_from_unicode_cpoint(getcodepage(), ext_char, 0);
						if (thischar == 0 && ext_char != 0) {
							FD_ZERO(&cp_checked);
							for (fnt = 0; fnt < 256; fnt++) {
								cp = conio_fontdata[fnt].cp;
								if (!FD_ISSET(cp, &cp_checked)) {
									FD_SET(cp, &cp_checked);
									thischar = cpchar_from_unicode_cpoint(cp, ext_char, 0);
									if (thischar)
										break;
								}
							}
							if (fnt == 256) {
								fnt = current_font[0];
								thischar = '?';
							}
						}
698
						break;
699 700
				}
			}
701
			fill[fillpos].ch=(unsigned char)(thischar);
702
			attrib=0;
703 704 705 706 707
			if (attr & WA_BOLD) {
				if (thischar == ' ')
					thischar = 0;
				else
					attrib |= 8;
708
			}
709
			if (attr & WA_BLINK)
710 711 712 713
			{
				attrib |= 128;
			}
			colour=PAIR_NUMBER(attr&A_COLOR)-1;
deuce's avatar
deuce committed
714 715 716 717
			if (COLORS >= 16)
				colour=colour&0x7f;
			else
				colour=((colour&56)<<1)|(colour&7);
718 719 720 721
			fill[fillpos].legacy_attr = colour|attrib;
			attr2palette(attrib, &fill[fillpos].fg, &fill[fillpos].bg);
			fill[fillpos].font = fnt;
			fillpos++;
722 723 724 725 726 727
		}
	}
	move(oldy, oldx);
	return(1);
}

deuce's avatar
deuce committed
728
void curs_textattr(int attr)
729
{
730
	chtype   attrs=WA_NORMAL;
731
	int	colour;
732
	int	fg,bg;
733 734 735 736 737

	if (lastattr==attr)
		return;

	lastattr=attr;
738 739 740 741 742 743 744 745 746 747

	fg = attr & 0x0f;
	bg = attr & 0xf0;

	if (vflags & CIOLIB_VIDEO_NOBRIGHT)
		fg &= 0x07;

	if (!(vflags & CIOLIB_VIDEO_BGBRIGHT))
		bg &= 0x70;

748 749
	if (attr & 128)
	{
750
		if (!(vflags & CIOLIB_VIDEO_NOBLINK))
751
			attrs |= WA_BLINK;
752 753 754 755 756 757 758
	}

	if (COLORS >= 16) {
		colour = COLOR_PAIR( ((fg|bg)+1) );
	}
	else {
		if (fg & 8)  {
759
			attrs |= WA_BOLD;
760
		}
deuce's avatar
deuce committed
761
		colour = COLOR_PAIR( ((fg&7)|((bg&0x70)>>1))+1 );
762
	}
763
	curs_resume();
deuce's avatar
deuce committed
764
#ifdef NCURSES_VERSION_MAJOR
765
	attrset(attrs);
766
	color_set(colour, NULL);
deuce's avatar
deuce committed
767
#else
768
	attrset(attrs|colour);
deuce's avatar
deuce committed
769
#endif
770 771
	/* bkgdset(colour); */
	bkgdset(colour);
772 773

	cio_textinfo.attribute=attr;
774 775 776 777 778 779 780
}

int curs_kbhit(void)
{
	struct timeval timeout;
	fd_set	rfds;

781 782
	if(curs_nextgetch)
		return(1);
deuce's avatar
deuce committed
783 784
	if(mpress || mouse_trywait()) {
		mpress = 1;
deuce's avatar
deuce committed
785
		return(1);
deuce's avatar
deuce committed
786
	}
787 788 789 790 791 792 793 794 795 796
	timeout.tv_sec=0;
	timeout.tv_usec=0;
	FD_ZERO(&rfds);
	FD_SET(fileno(stdin),&rfds);

	return(select(fileno(stdin)+1,&rfds,NULL,NULL,&timeout));
}

void curs_gotoxy(int x, int y)
{
797 798 799 800
	int absx,absy;
	absx=x+cio_textinfo.winleft-1;
	absy=y+cio_textinfo.wintop-1;

801
	curs_resume();
802
	move(absy-1,absx-1);
803
	if(!hold_update)
804
		refresh();
805 806 807

	cio_textinfo.curx=x;
	cio_textinfo.cury=y;
808 809
}

810 811
void curs_suspend(void)
{
812 813 814 815 816
	if (!suspended) {
		noraw();
		endwin();
	}
	suspended = 1;
817 818 819 820
}

void curs_resume(void)
{
821 822 823 824 825 826
	if (suspended) {
		raw();
		timeout(10);
		refresh();
		getch();
	}
827
	suspended = 0;
828 829
}

rswindell's avatar
rswindell committed
830
int curs_initciolib(long inmode)
831 832
{
	short	fg, bg, pair=0;
833 834
	char *p;

835
	setlocale(LC_ALL, "");
836 837
	if (inmode == CIOLIB_MODE_AUTO)
		inmode = CIOLIB_MODE_CURSES;
838 839 840 841 842 843 844 845 846 847
	if (inmode == CIOLIB_MODE_CURSES) {
		p = nl_langinfo(CODESET);
		if (p == NULL)
			inmode = CIOLIB_MODE_CURSES_ASCII;
		else if (!strcasestr(p, "UTF"))
			if (!strcasestr(p, "UCS2"))
				if (!strcasestr(p, "Unicode"))
					if (!strcasestr(p, "GB18030"))
						inmode = CIOLIB_MODE_CURSES_ASCII;
	}
848 849

#ifdef XCURSES
rswindell's avatar
rswindell committed
850
	char	*argv[2]={"ciolib",NULL};
851 852 853

	Xinitscr(1,argv);
#else
854 855 856
	char *term;
	SCREEN *tst;

857 858
	cio_api.options = 0;

859 860 861 862 863 864 865
	term=getenv("TERM");
	if(term==NULL)
		return(0);
	tst=newterm(term,stdout,stdin);
	if(tst==NULL)
		return(0);
	endwin();
866 867 868 869 870 871 872 873
	initscr();
#endif
	start_color();
	cbreak();
	noecho();
	nonl();
	keypad(stdscr, TRUE);
	scrollok(stdscr,FALSE);
deuce's avatar
deuce committed
874
	halfdelay(1);
875 876
	raw();
	timeout(10);
877
	atexit(curs_suspend);
878
	suspended = 0;
879 880

	/* Set up color pairs */
881 882 883 884 885 886 887 888 889 890 891 892
	if (COLORS >= 16) {
		for(bg=0;bg<16;bg++)  {
			for(fg=0;fg<16;fg++) {
				init_pair(++pair,curses_color(fg),curses_color(bg));
			}
		}
	}
	else {
		for(bg=0;bg<8;bg++)  {
			for(fg=0;fg<8;fg++) {
				init_pair(++pair,curses_color(fg),curses_color(bg));
			}
893 894 895
		}
	}
	mode = inmode;
deuce's avatar
deuce committed
896
#ifdef NCURSES_VERSION_MAJOR
897 898 899 900 901 902
	{
		mmask_t msk = BUTTON1_PRESSED|BUTTON1_RELEASED|BUTTON2_PRESSED|BUTTON2_RELEASED|BUTTON3_PRESSED|BUTTON3_RELEASED|REPORT_MOUSE_POSITION;
#ifdef BUTTON5_PRESSED
		msk |= BUTTON4_PRESSED|BUTTON5_PRESSED;
#endif
		if (mousemask(msk, NULL) == msk) {
deuce's avatar
deuce committed
903
			mouseinterval(0);
deuce's avatar
deuce committed
904
			cio_api.mouse=1;
deuce's avatar
deuce committed
905
		}
deuce's avatar
deuce committed
906
		else {
deuce's avatar
deuce committed
907
			mousemask(0,NULL);
deuce's avatar
deuce committed
908
		}
909
	}
deuce's avatar
deuce committed
910
#endif
911

912 913
	if (COLORS >= 16)
		cio_api.options = CONIO_OPT_BRIGHT_BACKGROUND;
914 915
	if (can_change_color())
		cio_api.options |= CONIO_OPT_PALETTE_SETTING;
916 917
	curs_textmode(0);
	return(1);
918 919 920
}

void curs_setcursortype(int type) {
921
	curs_resume();
922 923 924 925
	switch(type) {
		case _NOCURSOR:
			curs_set(0);
			break;
926

927 928 929
		case _SOLIDCURSOR:
			curs_set(2);
			break;
930

931 932 933 934 935
		default:	/* Normal cursor */
			curs_set(1);
			break;

	}
936
	if(!hold_update)
937
		refresh();
938 939
}

940 941
int curs_getch(void)
{
942
	wint_t ch;
deuce's avatar
deuce committed
943
#ifdef NCURSES_VERSION_MAJOR
deuce's avatar
deuce committed
944
	MEVENT mevnt;
deuce's avatar
deuce committed
945
#endif
946 947 948 949 950 951

	if(curs_nextgetch) {
		ch=curs_nextgetch;
		curs_nextgetch=0;
	}
	else {
952
		curs_resume();
953
		while(get_wch(&ch)==ERR) {
deuce's avatar
deuce committed
954 955
			if(mpress || mouse_trywait()) {
				mpress = 0;
956 957 958
				curs_nextgetch=CIO_KEY_MOUSE>>8;
				return(CIO_KEY_MOUSE & 0xff);
			}
959
		}
960 961 962 963 964
		switch(ch) {
			case KEY_DOWN:            /* Down-arrow */
				curs_nextgetch=0x50;
				ch=0;
				break;
965

966 967 968 969
			case KEY_UP:		/* Up-arrow */
				curs_nextgetch=0x48;
				ch=0;
				break;
970

971 972 973 974
			case KEY_LEFT:		/* Left-arrow */
				curs_nextgetch=0x4b;
				ch=0;
				break;
975

976 977 978 979
			case KEY_RIGHT:            /* Right-arrow */
				curs_nextgetch=0x4d;
				ch=0;
				break;
980

981 982 983 984
			case KEY_HOME:            /* Home key (upward+left arrow) */
				curs_nextgetch=0x47;
				ch=0;
				break;
985

986 987 988
			case KEY_BACKSPACE:            /* Backspace (unreliable) */
				ch=8;
				break;
989

990 991 992 993
			case KEY_F(1):			/* Function Key */
				curs_nextgetch=0x3b;
				ch=0;
				break;
994

995 996 997 998
			case KEY_F(2):			/* Function Key */
				curs_nextgetch=0x3c;
				ch=0;
				break;
999

1000 1001 1002 1003
			case KEY_F(3):			/* Function Key */
				curs_nextgetch=0x3d;
				ch=0;
				break;
1004

1005 1006 1007 1008
			case KEY_F(4):			/* Function Key */
				curs_nextgetch=0x3e;
				ch=0;
				break;
1009

1010 1011 1012 1013
			case KEY_F(5):			/* Function Key */
				curs_nextgetch=0x3f;
				ch=0;
				break;
1014

1015 1016 1017 1018
			case KEY_F(6):			/* Function Key */
				curs_nextgetch=0x40;
				ch=0;
				break;
1019

1020 1021 1022 1023
			case KEY_F(7):			/* Function Key */
				curs_nextgetch=0x41;
				ch=0;
				break;
1024

1025 1026 1027 1028
			case KEY_F(8):			/* Function Key */
				curs_nextgetch=0x42;
				ch=0;
				break;
1029

1030 1031 1032 1033
			case KEY_F(9):			/* Function Key */
				curs_nextgetch=0x43;
				ch=0;
				break;
1034

1035 1036 1037 1038
			case KEY_F(10):			/* Function Key */
				curs_nextgetch=0x44;
				ch=0;
				break;
1039

1040 1041 1042 1043
			case KEY_F(11):			/* Function Key */
				curs_nextgetch=0x57;
				ch=0;
				break;
1044

1045 1046 1047 1048
			case KEY_F(12):			/* Function Key */
				curs_nextgetch=0x58;
				ch=0;
				break;
1049

1050 1051 1052 1053
			case KEY_DC:            /* Delete character */
				curs_nextgetch=0x53;
				ch=0;
				break;
1054

1055 1056 1057 1058
			case KEY_IC:            /* Insert char or enter insert mode */
				curs_nextgetch=0x52;
				ch=0;
				break;
1059

1060 1061 1062 1063
			case KEY_EIC:            /* Exit insert char mode */
				curs_nextgetch=0x52;
				ch=0;
				break;
1064

1065 1066 1067