ciolib.c 18.1 KB
Newer Older
deuce's avatar
deuce committed
1
2
3
4
5
6
7
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
/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
 * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html		*
 *																			*
 * 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
#include <stdarg.h>
35
#include <stdlib.h>	/* malloc */
36
37
#include <stdio.h>

deuce's avatar
deuce committed
38
39
#include <threadwrap.h>

40
41
42
#define CIOLIB_NO_MACROS
#include "ciolib.h"

deuce's avatar
deuce committed
43
44
45
#ifdef _WIN32
 #include "win32cio.h"
#else
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 #ifndef NO_X
  #include "x_cio.h"
 #endif
 #include "curs_cio.h"
 #undef getch
#endif

#include "ansi_cio.h"

cioapi_t	cio_api;

static int ungotch;
static struct text_info cio_textinfo;
static int lastmode=3;
int _wscroll=1;
int directvideo=0;
62
int hold_update=0;
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
static int initialized=0;

int ciolib_movetext(int sx, int sy, int ex, int ey, int dx, int dy);
char *ciolib_cgets(char *str);
int ciolib_cscanf (char *format , ...);
int ciolib_kbhit(void);
int ciolib_getch(void);
int ciolib_getche(void);
int ciolib_ungetch(int ch);
void ciolib_gettextinfo(struct text_info *info);
int ciolib_wherex(void);
int ciolib_wherey(void);
void ciolib_wscroll(void);
void ciolib_gotoxy(int x, int y);
void ciolib_clreol(void);
void ciolib_clrscr(void);
int ciolib_cputs(char *str);
int	ciolib_cprintf(char *fmat, ...);
void ciolib_textbackground(int colour);
void ciolib_textcolor(int colour);
void ciolib_highvideo(void);
void ciolib_lowvideo(void);
void ciolib_normvideo(void);
int ciolib_puttext(int a,int b,int c,int d,unsigned char *e);
int ciolib_gettext(int a,int b,int c,int d,unsigned char *e);
88
void ciolib_textattr(int a);
89
void ciolib_delay(long a);
90
int ciolib_putch(int a);
91
92
93
94
95
96
void ciolib_setcursortype(int a);
void ciolib_textmode(int mode);
void ciolib_window(int sx, int sy, int ex, int ey);
void ciolib_delline(void);
void ciolib_insline(void);
char *ciolib_getpass(const char *prompt);
deuce's avatar
deuce committed
97
98
void ciolib_copytext(const char *text, size_t buflen);
char *ciolib_getcliptext(void);
99

100
101
#define CIOLIB_INIT()		{ if(!initialized) initciolib(CIOLIB_MODE_AUTO); }

102
103
104
105
106
#ifndef _WIN32
 #ifndef NO_X
int try_x_init(int mode)
{
	if(!console_init()) {
107
		cio_api.mode=CIOLIB_MODE_X;
deuce's avatar
deuce committed
108
		cio_api.mouse=1;
109
110
111
112
113
114
115
116
117
118
119
120
121
122
		cio_api.puttext=x_puttext;
		cio_api.gettext=x_gettext;
		cio_api.textattr=x_textattr;
		cio_api.kbhit=x_kbhit;
		cio_api.delay=x_delay;
		cio_api.wherey=x_wherey;
		cio_api.wherex=x_wherex;
		cio_api.putch=x_putch;
		cio_api.gotoxy=x_gotoxy;
		cio_api.gettextinfo=x_gettextinfo;
		cio_api.setcursortype=x_setcursortype;
		cio_api.getch=x_getch;
		cio_api.getche=x_getche;
		cio_api.textmode=x_textmode;
deuce's avatar
deuce committed
123
124
		cio_api.showmouse=NULL;
		cio_api.hidemouse=NULL;
125
		cio_api.settitle=x_settitle;
deuce's avatar
deuce committed
126
127
		cio_api.copytext=x_copytext;
		cio_api.getcliptext=x_getcliptext;
128
129
130
131
132
133
134
135
136
		return(1);
	}
	return(0);
}
 #endif

int try_curses_init(int mode)
{
	if(curs_initciolib(mode)) {
137
		cio_api.mode=CIOLIB_MODE_CURSES_IBM;
138
139
140
141
142
143
144
145
146
147
148
149
150
151
		cio_api.puttext=curs_puttext;
		cio_api.gettext=curs_gettext;
		cio_api.textattr=curs_textattr;
		cio_api.kbhit=curs_kbhit;
		cio_api.delay=curs_delay;
		cio_api.wherey=curs_wherey;
		cio_api.wherex=curs_wherex;
		cio_api.putch=curs_putch;
		cio_api.gotoxy=curs_gotoxy;
		cio_api.gettextinfo=curs_gettextinfo;
		cio_api.setcursortype=curs_setcursortype;
		cio_api.getch=curs_getch;
		cio_api.getche=curs_getche;
		cio_api.textmode=curs_textmode;
deuce's avatar
deuce committed
152
153
		cio_api.showmouse=curs_showmouse;
		cio_api.hidemouse=curs_hidemouse;
154
		cio_api.settitle=NULL;
deuce's avatar
deuce committed
155
156
		cio_api.copytext=NULL;
		cio_api.getcliptext=NULL;
157
158
159
160
161
162
163
164
165
		return(1);
	}
	return(0);
}
#endif

int try_ansi_init(int mode)
{
	if(ansi_initciolib(mode)) {
166
		cio_api.mode=CIOLIB_MODE_ANSI;
deuce's avatar
deuce committed
167
		cio_api.mouse=0;
168
169
170
171
172
173
174
175
176
177
178
179
180
181
		cio_api.puttext=ansi_puttext;
		cio_api.gettext=ansi_gettext;
		cio_api.textattr=ansi_textattr;
		cio_api.kbhit=ansi_kbhit;
		cio_api.delay=ansi_delay;
		cio_api.wherey=ansi_wherey;
		cio_api.wherex=ansi_wherex;
		cio_api.putch=ansi_putch;
		cio_api.gotoxy=ansi_gotoxy;
		cio_api.gettextinfo=ansi_gettextinfo;
		cio_api.setcursortype=ansi_setcursortype;
		cio_api.getch=ansi_getch;
		cio_api.getche=ansi_getche;
		cio_api.textmode=ansi_textmode;
deuce's avatar
deuce committed
182
183
		cio_api.showmouse=NULL;
		cio_api.hidemouse=NULL;
184
		cio_api.settitle=NULL;
deuce's avatar
deuce committed
185
186
		cio_api.copytext=NULL;
		cio_api.getcliptext=NULL;
187
188
189
190
191
192
		return(1);
	}
	return(0);
}

#ifdef _WIN32
193
194
195
#if defined(__BORLANDC__)
        #pragma argsused
#endif
196
int try_conio_init(int mode)
197
198
{
	/* This should test for something or other */
199
	if(win32_initciolib(mode)) {
200
		cio_api.mode=CIOLIB_MODE_CONIO;
deuce's avatar
deuce committed
201
		cio_api.mouse=1;
202
203
204
		cio_api.puttext=win32_puttext;
		cio_api.gettext=win32_gettext;
		cio_api.textattr=win32_textattr;
deuce's avatar
deuce committed
205
		cio_api.kbhit=win32_kbhit;
206
207
208
209
210
211
		cio_api.wherey=win32_wherey;
		cio_api.wherex=win32_wherex;
		cio_api.putch=win32_putch;
		cio_api.gotoxy=win32_gotoxy;
		cio_api.gettextinfo=win32_gettextinfo;
		cio_api.setcursortype=win32_setcursortype;
deuce's avatar
deuce committed
212
213
		cio_api.getch=win32_getch;
		cio_api.getche=win32_getche;
214
		cio_api.textmode=win32_textmode;
deuce's avatar
deuce committed
215
216
		cio_api.showmouse=win32_showmouse;
		cio_api.hidemouse=win32_hidemouse;
217
		cio_api.settitle=win32_settitle;
deuce's avatar
deuce committed
218
219
		cio_api.copytext=win32_copytext;
		cio_api.getcliptext=win32_getcliptext;
220
221
222
223
224
225
226
227
228
		return(1);
	}
	return(0);
}
#endif

int initciolib(int mode)
{
	switch(mode) {
229
		case CIOLIB_MODE_AUTO:
230
#ifdef _WIN32
231
			if(!try_conio_init(mode))
232
#else
233
#ifndef NO_X
234
			if(!try_x_init(mode))
235
#endif
236
237
238
239
240
				if(!try_curses_init(mode))
#endif
					try_ansi_init(mode);
			break;
#ifdef _WIN32
241
		case CIOLIB_MODE_CONIO:
242
			try_conio_init(mode);
243
244
			break;
#else
245
246
		case CIOLIB_MODE_CURSES:
		case CIOLIB_MODE_CURSES_IBM:
247
248
			try_curses_init(mode);
			break;
249

250
		case CIOLIB_MODE_X:
251
#ifndef NO_X
252
			try_x_init(mode);
253
#endif
254
255
			break;
#endif
256
		case CIOLIB_MODE_ANSI:
257
258
259
			try_ansi_init(mode);
			break;
	}
260
	if(cio_api.mode==CIOLIB_MODE_AUTO) {
deuce's avatar
deuce committed
261
		fprintf(stderr,"CIOLIB initialization failed!\n");
262
263
264
265
266
267
268
269
270
271
		return(-1);
	}

	initialized=1;
	ciolib_gettextinfo(&cio_textinfo);
	cio_textinfo.winleft=1;
	cio_textinfo.wintop=1;
	cio_textinfo.winright=cio_textinfo.screenwidth;
	cio_textinfo.winbottom=cio_textinfo.screenheight;
	cio_textinfo.normattr=7;
deuce's avatar
deuce committed
272
	_beginthread(ciolib_mouse_thread,0,NULL);
273
274
275
276
277
	return(0);
}

int ciolib_kbhit(void)
{
278
	CIOLIB_INIT();
279
280
	if(ungotch)
		return(1);
deuce's avatar
deuce committed
281
282
	if(mouse_pending())
		return(1);
283
284
285
286
287
288
289
	return(cio_api.kbhit());
}

int ciolib_getch(void)
{
	int ch;

290
291
	CIOLIB_INIT();

292
293
294
295
296
297
298
299
300
301
302
303
	if(ungotch) {
		ch=ungotch;
		ungotch=0;
		return(ch);
	}
	return(cio_api.getch());
}

int ciolib_getche(void)
{
	int ch;

304
305
	CIOLIB_INIT();

306
307
308
309
310
311
312
313
314
315
316
	if(ungotch) {
		ch=ungotch;
		ungotch=0;
		ciolib_putch(ch);
		return(ch);
	}
	return(cio_api.getche());
}

int ciolib_ungetch(int ch)
{
317
318
	CIOLIB_INIT();
	
319
320
321
322
323
324
325
326
327
328
	if(ungotch)
		return(EOF);
	ungotch=ch;
	return(ch);
}

int ciolib_movetext(int sx, int sy, int ex, int ey, int dx, int dy)
{
	int width;
	int height;
329
	unsigned char *buf;
330

331
332
	CIOLIB_INIT();
	
333
334
	width=ex-sx;
	height=ey-sy;
335
	buf=(unsigned char *)malloc((width+1)*(height+1)*2);
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
	if(buf==NULL)
		return(0);
	if(!ciolib_gettext(sx,sy,ex,ey,buf)) {
		free(buf);
		return(0);
	}
	if(!ciolib_puttext(dx,dy,dx+width,dy+height,buf)) {
		free(buf);
		return(0);
	}
	free(buf);
	return(1);
}

char *ciolib_cgets(char *str)
{
	int	maxlen;
	int len=0;
	int ch;

356
357
	CIOLIB_INIT();
	
358
	maxlen=*(unsigned char *)str;
deuce's avatar
deuce committed
359
	while((ch=ciolib_getche())!='\n' && ch !='\r') {
360
361
		switch(ch) {
			case 0:	/* Skip extended keys */
362
				ciolib_getche();
363
				break;
deuce's avatar
deuce committed
364
			case '\r':	/* Skip \r (ToDo: Should this be treated as a \n? */
365
366
367
				break;
			case '\b':
				if(len==0) {
368
					ciolib_putch(7);
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
					break;
				}
				ciolib_putch('\b');
				len--;
				break;
			default:
				str[(len++)+2]=ch;
				if(len==maxlen) {
					str[len+2]=0;
					*((unsigned char *)(str+1))=(unsigned char)len;
					return(&str[2]);
				}
				break;
		}
	}
384
385
386
	str[len+2]=0;
	*((unsigned char *)(str+1))=(unsigned char)len;
	return(&str[2]);
387
388
}

389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
#ifdef _MSC_VER	/* Use lame vsscanf() implementation */
/* This is a way to do _vsscanf without using fancy stack tricks or using the
 * "_input" method provided by Microsoft, which is no longer exported as of .NET.
 * The function has a limit of 25 arguments (or less if you run out of stack space),
 *  but how many arguments do you need?
 */
/* From "krabsheva" - http://www.codeguru.com/Cpp/Cpp/string/comments.php/c5631/?thread=1051 */
int vsscanf( const char *buffer, const char *format, va_list arg_ptr )
{
	int i, ret;
	void *arg_arr[25];

	// Do exception handling in case we go too far //
	__try
	{
		for ( i = 0; i < 25; i++ )
			arg_arr[i] = va_arg( arg_ptr, void * );
	}
	__except( EXCEPTION_EXECUTE_HANDLER )
	{
	}

	/* This is lame, but the extra arguments won't be used by sscanf */
	ret = sscanf( buffer, format, arg_arr[0], arg_arr[1], arg_arr[2], arg_arr[3],
		arg_arr[4], arg_arr[5], arg_arr[6], arg_arr[7], arg_arr[8], arg_arr[9],
		arg_arr[10], arg_arr[11], arg_arr[12], arg_arr[13], arg_arr[14],
		arg_arr[15], arg_arr[16], arg_arr[17], arg_arr[18], arg_arr[19],
		arg_arr[20], arg_arr[21], arg_arr[22], arg_arr[23], arg_arr[24] );

	return ret;
}
#endif

422
423
424
425
426
427
int ciolib_cscanf (char *format , ...)
{
	char str[255];
    va_list argptr;
	int ret;

428
429
	CIOLIB_INIT();
	
430
431
432
433
434
435
436
437
438
439
440
441
442
	str[0]=-1;
	va_start(argptr,format);
	ret=vsscanf(ciolib_cgets(str),format,argptr);
	va_end(argptr);
	return(ret);
}

char *ciolib_getpass(const char *prompt)
{
	static char pass[9];
	int len=0;
	int ch;

443
444
	CIOLIB_INIT();
	
445
	ciolib_cputs((char *)prompt);
deuce's avatar
deuce committed
446
	while((ch=ciolib_getch())!='\n') {
447
448
		switch(ch) {
			case 0:	/* Skip extended keys */
deuce's avatar
deuce committed
449
				ciolib_getch();
450
451
452
453
454
				break;
			case '\r':	/* Skip \r (ToDo: Should this be treeated as a \n? */
				break;
			case '\b':
				if(len==0) {
455
					ciolib_putch(7);
456
457
458
459
460
461
					break;
				}
				len--;
				break;
			default:
				if(len==8)
462
					ciolib_putch(7);
463
464
465
466
467
				else
					pass[len++]=ch;
				break;
		}
	}
468
469
	pass[len]=0;
	return(pass);
470
471
472
473
474
}

void ciolib_gettextinfo(struct text_info *info)
{
	if(!initialized)
475
		initciolib(CIOLIB_MODE_AUTO);
476
477
478
479
480
481
482
483
484
485
486
487
488
489
	else {
		cio_api.gettextinfo(&cio_textinfo);
	}
	if(info!=&cio_textinfo) {
		info->winleft=cio_textinfo.winleft;        /* left window coordinate */
		info->wintop=cio_textinfo.wintop;         /* top window coordinate */
		info->winright=cio_textinfo.winright;       /* right window coordinate */
		info->winbottom=cio_textinfo.winbottom;      /* bottom window coordinate */
		info->attribute=cio_textinfo.attribute;      /* text attribute */
		info->normattr=cio_textinfo.normattr;       /* normal attribute */
		info->currmode=cio_textinfo.currmode;       /* current video mode:
                               			 BW40, BW80, C40, C80, or C4350 */
		info->screenheight=cio_textinfo.screenheight;   /* text screen's height */
		info->screenwidth=cio_textinfo.screenwidth;    /* text screen's width */
490
491
		info->curx=cio_textinfo.curx-cio_textinfo.winleft+1;           /* x-coordinate in current window */
		info->cury=cio_textinfo.cury-cio_textinfo.wintop+1;           /* y-coordinate in current window */
492
493
494
495
496
497
498
499
	}
}

void ciolib_wscroll(void)
{
	int os;
	struct text_info ti;

500
501
	CIOLIB_INIT();
	
502
503
504
505
	ciolib_gettextinfo(&ti);
	if(!_wscroll)
		return;
	ciolib_movetext(ti.winleft,ti.wintop+1,ti.winright,ti.winbottom,ti.winleft,ti.wintop);
506
	ciolib_gotoxy(1,ti.winbottom-ti.wintop+1);
507
508
	os=_wscroll;
	_wscroll=0;
509
510
	/* ciolib_cprintf("%*s",ti.winright-ti.winleft+1,""); */
	ciolib_clreol();
511
512
513
514
515
516
517
518
	_wscroll=os;
	ciolib_gotoxy(ti.curx,ti.cury);
}

int ciolib_wherex(void)
{
	int x;

519
520
	CIOLIB_INIT();
	
521
522
523
524
525
526
527
528
529
	x=cio_api.wherex();
	x=x-cio_textinfo.winleft+1;
	return(x);
}

int ciolib_wherey(void)
{
	int y;

530
531
	CIOLIB_INIT();
	
532
533
534
535
536
537
538
539
540
541
542
	y=cio_api.wherey();
	y=y-cio_textinfo.wintop+1;
	return(y);
}

void ciolib_gotoxy(int x, int y)
{
	int nx;
	int ny;
	struct text_info ti;

543
544
	CIOLIB_INIT();
	
545
546
547
548
549
550
551
552
553
554
555
	ciolib_gettextinfo(&ti);
	if(		x < 1
			|| x > ti.winright-ti.winleft+1
			|| y < 1
			|| y > ti.winbottom-ti.wintop+1)
		return;
	nx=x+ti.winleft-1;
	ny=y+ti.wintop-1;
	cio_api.gotoxy(nx,ny);
}

deuce's avatar
deuce committed
556
void ciolib_textmode(int mode)
557
{
558
559
	CIOLIB_INIT();
	
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
	if(mode==-1) {
		ciolib_gettextinfo(&cio_textinfo);
		cio_api.textmode(lastmode);
		lastmode=cio_textinfo.currmode;
	}
	else {
		ciolib_gettextinfo(&cio_textinfo);
		lastmode=cio_textinfo.currmode;
		cio_api.textmode(mode);
	}
	ciolib_gettextinfo(&cio_textinfo);
	cio_textinfo.winleft=1;
	cio_textinfo.wintop=1;
	cio_textinfo.winright=cio_textinfo.screenwidth;
	cio_textinfo.winbottom=cio_textinfo.screenheight;
}

void ciolib_window(int sx, int sy, int ex, int ey)
{
579
580
	CIOLIB_INIT();
	
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
	ciolib_gettextinfo(&cio_textinfo);
	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)
		return;
	cio_textinfo.winleft=sx;
	cio_textinfo.wintop=sy;
	cio_textinfo.winright=ex;
	cio_textinfo.winbottom=ey;
	ciolib_gotoxy(1,1);
}

void ciolib_clreol(void)
{
602
603
604
605
	unsigned char *buf;
	int i;
	int width,height;
	struct text_info ti;
606

607
608
	CIOLIB_INIT();
	
609
	ciolib_gettextinfo(&ti);
610
611
612
613
614
615
616
617
618
619

	width=ti.winright-ti.curx+1;
	height=1;
	buf=(unsigned char *)malloc(width*height*2);
	for(i=0;i<width*height*2;) {
		buf[i++]=' ';
		buf[i++]=ti.attribute;
	}
	ciolib_puttext(ti.curx+ti.winleft-1,ti.cury+ti.wintop-1,ti.winright,ti.cury+ti.wintop-1,buf);
	free(buf);
620
621
622
623
}

void ciolib_clrscr(void)
{
624
	unsigned char *buf;
625
626
627
628
	int i;
	int width,height;
	struct text_info ti;

629
630
	CIOLIB_INIT();
	
631
632
633
634
	ciolib_gettextinfo(&ti);

	width=ti.winright-ti.winleft+1;
	height=ti.winbottom-ti.wintop+1;
635
	buf=(unsigned char *)malloc(width*height*2);
636
637
638
639
640
641
642
643
644
645
646
647
	for(i=0;i<width*height*2;) {
		buf[i++]=' ';
		buf[i++]=ti.attribute;
	}
	ciolib_puttext(ti.winleft,ti.wintop,ti.winright,ti.winbottom,buf);
	free(buf);
}

void ciolib_delline(void)
{
	struct text_info ti;

648
649
	CIOLIB_INIT();
	
650
651
652
653
654
655
656
657
658
659
660
661
	ciolib_gettextinfo(&ti);

	ciolib_movetext(ti.winleft,ti.cury+1,ti.winright,ti.winbottom,ti.winleft,ti.cury);
	ciolib_gotoxy(1,ti.winbottom-ti.wintop+1);
	ciolib_clreol();
	ciolib_gotoxy(ti.curx,ti.cury);
}

void ciolib_insline(void)
{
	struct text_info ti;

662
663
	CIOLIB_INIT();
	
664
665
666
667
668
669
670
671
672
673
674
675
	ciolib_gettextinfo(&ti);

	ciolib_movetext(ti.winleft,ti.cury,ti.winright,ti.winbottom,ti.winleft,ti.cury+1);
	ciolib_gotoxy(1,ti.cury);
	ciolib_clreol();
	ciolib_gotoxy(ti.curx,ti.cury);
}

int ciolib_cprintf(char *fmat, ...)
{
    va_list argptr;
	int		ret;
676
#ifdef _MSC_VER		/* Can't figure out a way to allocate a "big enough" buffer for Win32. */
677
678
679
680
681
	char	str[16384];
#else
	char	*str;
#endif

682
	CIOLIB_INIT();
683

684
    va_start(argptr,fmat);
685
#ifdef _MSC_VER
rswindell's avatar
rswindell committed
686
	ret=_vsnprintf(str,sizeof(str)-1,fmat,argptr);
687
688
#else
    ret=vsnprintf(NULL,0,fmat,argptr);
deuce's avatar
deuce committed
689
690
	if(ret<0)
		return(EOF);
691
692
693
694
695
696
697
698
699
700
	str=(char *)malloc(ret+1);
	if(str==NULL)
		return(EOF);
	ret=vsprintf(str,fmat,argptr);
#endif
    va_end(argptr);
	if(ret>=0)
		ciolib_cputs(str);
	else
		ret=EOF;
701
#ifndef _MSC_VER
702
703
704
705
706
707
708
709
710
	free(str);
#endif
    return(ret);
}

int ciolib_cputs(char *str)
{
	int		pos;
	int		ret=0;
711
	int		olddmc;
712

713
	CIOLIB_INIT();
714

715
716
	olddmc=hold_update;
	hold_update=1;
717
718
719
720
721
722
723
	for(pos=0;str[pos];pos++)
	{
		ret=str[pos];
		if(str[pos]=='\n')
			ciolib_putch('\r');
		ciolib_putch(str[pos]);
	}
724
	hold_update=olddmc;
deuce's avatar
deuce committed
725
	ciolib_gotoxy(ciolib_wherex(),ciolib_wherey());
726
727
728
729
730
731
	return(ret);
}

void ciolib_textbackground(int colour)
{
	unsigned char attr;
732
	unsigned char col;
733

734
735
	CIOLIB_INIT();
	
736
737
738
	ciolib_gettextinfo(&cio_textinfo);
	attr=cio_textinfo.attribute;
	attr&=143;
739
740
	col=(colour & 0x07);
	attr|=(col<<4);
741
742
743
744
745
746
	ciolib_textattr(attr);
}

void ciolib_textcolor(int colour)
{
	unsigned char attr;
747
	unsigned char col;
748

749
750
	CIOLIB_INIT();
	
751
752
753
	ciolib_gettextinfo(&cio_textinfo);
	attr=cio_textinfo.attribute;
	attr&=240;
754
755
	col=colour&0x0f;
	attr|=col;
756
757
758
759
760
761
762
	ciolib_textattr(attr);
}

void ciolib_highvideo(void)
{
	int attr;

763
764
	CIOLIB_INIT();
	
765
766
767
768
769
770
771
772
773
774
	ciolib_gettextinfo(&cio_textinfo);
	attr=cio_textinfo.attribute;
	attr |= 8;
	ciolib_textattr(attr);
}

void ciolib_lowvideo(void)
{
	int attr;

775
776
	CIOLIB_INIT();
	
777
778
779
780
781
782
783
784
	ciolib_gettextinfo(&cio_textinfo);
	attr=cio_textinfo.attribute;
	attr &= 0xf7;
	ciolib_textattr(attr);
}

void ciolib_normvideo(void)
{
785
786
	CIOLIB_INIT();
	
787
788
789
790
791
	ciolib_textattr(0x07);
}

int ciolib_puttext(int a,int b,int c,int d,unsigned char *e)
{
792
793
	CIOLIB_INIT();
	
794
795
796
797
798
	return(cio_api.puttext(a,b,c,d,e));
}

int ciolib_gettext(int a,int b,int c,int d,unsigned char *e)
{
799
800
	CIOLIB_INIT();
	
801
802
803
	return(cio_api.gettext(a,b,c,d,e));
}

804
void ciolib_textattr(int a)
805
{
806
807
	CIOLIB_INIT();
	
808
809
810
811
812
	cio_api.textattr(a);
}

void ciolib_delay(long a)
{
813
814
	CIOLIB_INIT();
	
815
816
817
	cio_api.delay(a);
}

818
int ciolib_putch(int a)
819
{
820
	unsigned char a1=a;
821
	CIOLIB_INIT();
822

823
	return(cio_api.putch(a1));
824
825
826
827
}

void ciolib_setcursortype(int a)
{
828
829
	CIOLIB_INIT();
	
830
831
	cio_api.setcursortype(a);
}
deuce's avatar
deuce committed
832
833
834
835
836
837

int ciolib_showmouse(void) {
	CIOLIB_INIT();

	if(cio_api.showmouse!=NULL)
		return(cio_api.showmouse());
838
	return(-1);
deuce's avatar
deuce committed
839
840
841
842
843
844
845
}

int ciolib_hidemouse(void) {
	CIOLIB_INIT();

	if(cio_api.hidemouse!=NULL)
		return(cio_api.hidemouse());
846
	return(-1);
deuce's avatar
deuce committed
847
}
848
849
850
851
852
853
854

void ciolib_settitle(const char *title) {
	CIOLIB_INIT();

	if(cio_api.settitle!=NULL)
		cio_api.settitle(title);
}
deuce's avatar
deuce committed
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872

void ciolib_copytext(const char *text, size_t buflen)
{
	CIOLIB_INIT();

	if(cio_api.copytext!=NULL)
		cio_api.copytext(text,buflen);
}

char *ciolib_getcliptext(void)
{
	CIOLIB_INIT();

	if(cio_api.getcliptext!=NULL)
		return(cio_api.getcliptext());
	else
		return(NULL);
}