aboutsummaryrefslogtreecommitdiff
path: root/draw.c
blob: 1497e65ede89f99a47da688d31a83afba68e4a3c (plain)
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
132
133
/* Copyright 1998 DJ Delorie <dj@delorie.com>
   Distributed under the terms of the GNU GPL
   http://www.delorie.com/store/hcalc/
   Revisions copyright 2007, 
   Theodore Kilgore <kilgota@auburn.edu>
	More revisions copyright 2023, B. Watson <urchlay@slackware.uk>
*/
#include "hcalc.h"
#include <string.h>

static unsigned int shown_offsets[15];
static int shown_bitmask;
static int show_bits;
int scale_factor;

#define BASE_CHARS_LEFT 6
#define BASE_CHARS_TOP 6
#define BASE_CHAR_WIDTH 5
#define BASE_CHAR_HEIGHT 7
#define BASE_BITS_LEFT_X 92
#define BASE_BITS_TOP_1 6
#define BASE_BITS_BOT_1 10
#define BASE_BITS_TOP_0 10
#define BASE_BITS_BOT_0 12

#define CHARS_LEFT (BASE_CHARS_LEFT * scale_factor)
#define CHARS_TOP (BASE_CHARS_TOP * scale_factor)
#define CHAR_WIDTH (BASE_CHAR_WIDTH * scale_factor)
#define CHAR_HEIGHT (BASE_CHAR_HEIGHT * scale_factor)
#define BITS_LEFT_X (BASE_BITS_LEFT_X * scale_factor)
#define BITS_TOP_1 (BASE_BITS_TOP_1 * scale_factor)
#define BITS_BOT_1 (BASE_BITS_BOT_1 * scale_factor)
#define BITS_TOP_0 (BASE_BITS_TOP_0 * scale_factor)
#define BITS_BOT_0 (BASE_BITS_BOT_0 * scale_factor)

void redraw_chars() {
	int i;
	for(i = 0; i < 15; i++) {
		XCopyArea(display, chars, window, gc,
				  shown_offsets[i], 0, CHAR_WIDTH, CHAR_HEIGHT,
				  CHARS_LEFT + BITS_TOP_1 * i, CHARS_TOP);
	}
}

void redraw(void) {
	XCopyArea(display, face, window, gc, 0, 0, widths[winsize],
			  heights[winsize], 0, 0);

	if(show_bits) {
		int i, x;
		XSetForeground(display, gc, bit_off);
		for(i = 0; i < 32; i++) {
			x = BITS_LEFT_X - (BITS_TOP_1 / 3) * i -
				(BITS_TOP_1) / 2 * (i / 4);
			if(!(shown_bitmask & (1 << i)))
				XDrawLine(display, window, gc, x, BITS_TOP_0, x,
						  BITS_BOT_0);
		}
		XSetForeground(display, gc, bit_on);
		for(i = 0; i < 32; i++) {
			x = BITS_LEFT_X - scale_factor * 2 * i -
				scale_factor * 3 * (i / 4);
			if(shown_bitmask & (1 << i))
				XDrawLine(display, window, gc, x, BITS_TOP_1, x,
						  BITS_BOT_1);
		}
	} else
		redraw_chars();
}

void set_bits(int b) {
	shown_bitmask = b;
	show_bits = 1;
	redraw();
}

void set_string(char *s) {
	char tmp[16];
	int i;
	sprintf(tmp, "%15.15s", s);
	for(i = 0; i < 15; i++)
		shown_offsets[i] = char_to_x[(int)tmp[i]];
	if(show_bits == 0)
		redraw_chars();
	else {
		show_bits = 0;
		redraw();
	}
}

void send_current_display(void) {
	char tmp[40], *tp = tmp;
	int i;
	XEvent e;

	if(show_bits) {
		for(i = 31; i > 0; i--)
			if(shown_bitmask & (1 << i))
				break;
		for(; i >= 0; i--) {
			if(shown_bitmask & (1 << i))
				*tp++ = '1';
			else
				*tp++ = '0';
		}
	} else {
		for(i = 0; i < 15; i++) {
			char c = charmap[shown_offsets[i] / BITS_TOP_1];
			if(c != ' ' && c != ',')
				*tp++ = c;
		}
	}

	*tp = 0;

	e.type = SelectionNotify;
	e.xselection.display = display;
	e.xselection.requestor = event.xselectionrequest.requestor;
	e.xselection.selection = event.xselectionrequest.selection;
	e.xselection.target = event.xselectionrequest.target;
	e.xselection.property = event.xselectionrequest.property;
	e.xselection.time = event.xselectionrequest.time;

	if(event.xselectionrequest.target != XA_STRING) {
		e.xselection.property = None;
	} else {
		XChangeProperty(display, e.xselection.requestor,
						e.xselection.property, XA_STRING, 8,
						PropModeReplace, (unsigned char *)tmp,
						strlen(tmp));
	}
	XSendEvent(display, e.xselection.requestor, False, 0, &e);
}