File: gettext_settext_demo.c

package info (click to toggle)
svgatextmode 1.9-21
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 2,120 kB
  • ctags: 3,455
  • sloc: ansic: 15,544; makefile: 354; sh: 345; yacc: 341; lex: 226; sed: 15; asm: 12
file content (131 lines) | stat: -rw-r--r-- 2,858 bytes parent folder | download | duplicates (6)
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
Unlike "vcs", reading "vcsa" from offset 0 returns a buffer with a 4-byte
header containing (as I recall) rows, cols, cur_col, cur_row, in that order.
When placing new data in the buffer, offset 4 should be treated as 0, but
the whole buffer, header included, should be written back from 0.
*/
/*
Here's my "port" of Borland C's gettext() and puttext(), using /dev/vcsa0.
They read/write rectangular areas of the screen.

written by Bob McCracken
*/

#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <stdlib.h>
#include <fcntl.h>

#define DEV	"/dev/vcsa0"

#ifndef uchar
#define uchar unsigned char
#endif

int GetText (uchar *buf, int y1, int x1, int y2, int x2)
{
  int Bpr, p, h, v, x, y;
  uchar *M, *Mem;
  struct winsize W;

  ioctl (0, TIOCGWINSZ, &W);

/*
Borland's version defaults to the real full-screen size if the
parms are invalid. Not liking that, I return an error, instead.
*/  
  if (x1 < 0 || y1 < 0 || x2 >= W.ws_col || y2 >= W.ws_row ||

	x1 > x2 || y1 > y2) return -1;
	  
  if ((y = open (DEV, 0)) < 0) return -1;
  
  Bpr = (W.ws_col << 1);	/* bytes-per-row */
  
  x = (Bpr * W.ws_row) + 4;	/* Include 4-byte header in buffer size */
  
  Mem = (uchar *) malloc (x);	/* Ought to check for failure here! */
  
  M = Mem + 4;		/* Point M to start of actual screen data */
  
  read (y, Mem, x); close (y);

/*
"Rectangularize" the screen data and copy to caller's buffer ..
*/  
  v = y2-y1+1; h = (x2-x1+1) << 1; p = (y1 * Bpr) + (x1 << 1);

  for (x = y = 0; y < v; y++, p += Bpr, x += h) memcpy (buf+x, M+p, h);

  free (Mem); return 0;
}

/* Same as above, in reverse ... */

int PutText (uchar *buf, int y1, int x1, int y2, int x2)
{
  int fd, ss, Bpr, p, h, v, x, y;
  uchar *M, *Mem;
  struct winsize W;

  ioctl (0, TIOCGWINSZ, &W);
  
  if (x1 < 0 || y1 < 0 || x2 >= W.ws_col || y2 >= W.ws_row ||
  
  	x1 > x2 || y1 > y2) return -1;
  	
  if ((fd = open (DEV, 2)) < 0) return -1;
  
  Bpr = (W.ws_col << 1);
  
  ss = (Bpr * W.ws_row) + 4;
  
  Mem = (uchar *) malloc (ss);
  
  M = Mem + 4;

/* Get current screen contents and update with caller's "rectangle" */

  read (fd, Mem, ss); lseek (fd, 0, 0);
  
  v = y2-y1+1; h = (x2-x1+1) << 1; p = (y1 * Bpr) + (x1 << 1);

  for (x = y = 0; y < v; y++, p += Bpr, x += h) memcpy (M+p, buf+x, h);

  write (fd, Mem, ss); close (fd);
  
  free (Mem); return 0;
}

/* Usage example: Change background color of a small area. */

#ifdef TEST_GETPUT

#define BGND	0x4F	/* white on red */

#define Y1	6
#define	X1	10
#define	Y2	12
#define X2	39

#define XLEN	(X2-X1+1)
#define YLEN	(Y2-Y1+1)

#define BSIZE	((XLEN<<1)*YLEN)

uchar scrn [BSIZE];

void main()
{
  int x;
  
  if (GetText (scrn, Y1,X1, Y2,X2) < 0) printf ("oops"); else
    {  
	for (x = 1; x < BSIZE; x += 2) scrn[x] = BGND;

	PutText (scrn, Y1,X1, Y2,X2);
    }	
}
#endif