The R Project SVN R

Rev

Rev 28991 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 28991 Rev 31702
1
/*
1
/*
2
 * GraphApp - Cross-Platform Graphics Programming Library.
2
 * GraphApp - Cross-Platform Graphics Programming Library.
3
 *
3
 *
4
 * File: controls.c -- manipulating scrollbars, buttons, etc.
4
 * File: controls.c -- manipulating scrollbars, buttons, etc.
5
 * Platform: Windows  Version: 2.40  Date: 1998/04/04
5
 * Platform: Windows  Version: 2.40  Date: 1998/04/04
6
 *
6
 *
7
 * Version: 1.00  Changes: Original version by Lachlan Patrick.
7
 * Version: 1.00  Changes: Original version by Lachlan Patrick.
8
 * Version: 1.60  Changes: Added clear(), draw(), flashcontrol().
8
 * Version: 1.60  Changes: Added clear(), draw(), flashcontrol().
9
 * Version: 2.00  Changes: New object class system.
9
 * Version: 2.00  Changes: New object class system.
10
 * Version: 2.15  Changes: Transparent backgrounds added.
10
 * Version: 2.15  Changes: Transparent backgrounds added.
11
 * Version: 2.20  Changes: Non-native buttons supported.
11
 * Version: 2.20  Changes: Non-native buttons supported.
12
 * Version: 2.35  Changes: New reference count technique.
12
 * Version: 2.35  Changes: New reference count technique.
13
 * Version: 2.40  Changes: Support for new controls.
13
 * Version: 2.40  Changes: Support for new controls.
14
 */
14
 */
15
 
15
 
16
/* Copyright (C) 1993-1998 Lachlan Patrick
16
/* Copyright (C) 1993-1998 Lachlan Patrick
17
 
17
 
18
   This file is part of GraphApp, a cross-platform C graphics library.
18
   This file is part of GraphApp, a cross-platform C graphics library.
19
 
19
 
20
   GraphApp is free software; you can redistribute it and/or modify it
20
   GraphApp is free software; you can redistribute it and/or modify it
21
   under the terms of the GNU Library General Public License.
21
   under the terms of the GNU Library General Public License.
22
   GraphApp is distributed in the hope that it will be useful, but
22
   GraphApp is distributed in the hope that it will be useful, but
23
   WITHOUT ANY WARRANTY.
23
   WITHOUT ANY WARRANTY.
24
 
24
 
25
   See the file COPYLIB.TXT for details.
25
   See the file COPYLIB.TXT for details.
26
*/
26
*/
27
 
27
 
28
/*  Copyright (C) 2004 	The R Foundation
28
/*  Copyright (C) 2004 	The R Foundation
29
 
29
 
30
    Changes for R:
30
    Changes for R:
31
 
31
 
32
    sort out resize (confused screen and client coords)
32
    sort out resize (confused screen and client coords)
33
    add printer and metafile handling
33
    add printer and metafile handling
-
 
34
    Remove assumption of current->dest being non-NULL
34
 
35
 
35
 */
36
 */
36
 
37
 
37
#include "internal.h"
38
#include "internal.h"
38
 
39
 
39
/*
40
/*
40
 *  Setting control call-backs.
41
 *  Setting control call-backs.
41
 */
42
 */
42
void setaction(control obj, actionfn fn)
43
void setaction(control obj, actionfn fn)
43
{
44
{
44
	if (obj)
45
	if (obj)
45
		obj->action = fn;
46
		obj->action = fn;
46
}
47
}
47
 
48
 
48
void sethit(control obj, intfn fn)
49
void sethit(control obj, intfn fn)
49
{
50
{
50
	if (obj)
51
	if (obj)
51
		obj->hit = fn;
52
		obj->hit = fn;
52
}
53
}
53
 
54
 
54
void setdel(control obj, actionfn fn)
55
void setdel(control obj, actionfn fn)
55
{
56
{
56
	if (obj)
57
	if (obj)
57
		if (obj->call)
58
		if (obj->call)
58
			obj->call->die = fn;
59
			obj->call->die = fn;
59
}
60
}
60
 
61
 
61
void setclose(control obj, actionfn fn)
62
void setclose(control obj, actionfn fn)
62
{
63
{
63
	if (obj)
64
	if (obj)
64
		if (obj->call)
65
		if (obj->call)
65
			obj->call->close = fn;
66
			obj->call->close = fn;
66
}
67
}
67
 
68
 
68
void setredraw(control obj, drawfn fn)
69
void setredraw(control obj, drawfn fn)
69
{
70
{
70
	if (obj)
71
	if (obj)
71
		if (obj->call)
72
		if (obj->call)
72
			obj->call->redraw = fn;
73
			obj->call->redraw = fn;
73
}
74
}
74
 
75
 
75
void setresize(control obj, drawfn fn)
76
void setresize(control obj, drawfn fn)
76
{
77
{
77
	if (obj)
78
	if (obj)
78
		if (obj->call)
79
		if (obj->call)
79
			obj->call->resize = fn;
80
			obj->call->resize = fn;
80
}
81
}
81
 
82
 
82
void setkeydown(control obj, keyfn fn)
83
void setkeydown(control obj, keyfn fn)
83
{
84
{
84
	if (obj)
85
	if (obj)
85
		if (obj->call)
86
		if (obj->call)
86
			obj->call->keydown = fn;
87
			obj->call->keydown = fn;
87
}
88
}
88
 
89
 
89
void setkeyaction(control obj, keyfn fn)
90
void setkeyaction(control obj, keyfn fn)
90
{
91
{
91
	if (obj)
92
	if (obj)
92
		if (obj->call)
93
		if (obj->call)
93
			obj->call->keyaction = fn;
94
			obj->call->keyaction = fn;
94
}
95
}
95
 
96
 
96
void setmousedown(control obj, mousefn fn)
97
void setmousedown(control obj, mousefn fn)
97
{
98
{
98
	if (obj)
99
	if (obj)
99
		if (obj->call)
100
		if (obj->call)
100
			obj->call->mousedown = fn;
101
			obj->call->mousedown = fn;
101
}
102
}
102
 
103
 
103
void setmouseup(control obj, mousefn fn)
104
void setmouseup(control obj, mousefn fn)
104
{
105
{
105
	if (obj)
106
	if (obj)
106
		if (obj->call)
107
		if (obj->call)
107
			obj->call->mouseup = fn;
108
			obj->call->mouseup = fn;
108
}
109
}
109
 
110
 
110
void setmousemove(control obj, mousefn fn)
111
void setmousemove(control obj, mousefn fn)
111
{
112
{
112
	if (obj)
113
	if (obj)
113
		if (obj->call)
114
		if (obj->call)
114
			obj->call->mousemove = fn;
115
			obj->call->mousemove = fn;
115
}
116
}
116
 
117
 
117
void setmousedrag(control obj, mousefn fn)
118
void setmousedrag(control obj, mousefn fn)
118
{
119
{
119
	if (obj)
120
	if (obj)
120
		if (obj->call)
121
		if (obj->call)
121
			obj->call->mousedrag = fn;
122
			obj->call->mousedrag = fn;
122
}
123
}
123
 
124
 
124
void setmouserepeat(control obj, mousefn fn)
125
void setmouserepeat(control obj, mousefn fn)
125
{
126
{
126
	if (obj)
127
	if (obj)
127
		if (obj->call)
128
		if (obj->call)
128
			obj->call->mouserepeat = fn;
129
			obj->call->mouserepeat = fn;
129
}
130
}
130
 
131
 
131
void setdrop(control obj, dropfn fn)
132
void setdrop(control obj, dropfn fn)
132
{
133
{
133
	if (obj)
134
	if (obj)
134
	    if (obj->call) {
135
	    if (obj->call) {
135
		DragAcceptFiles(obj->handle, TRUE);
136
		DragAcceptFiles(obj->handle, TRUE);
136
		obj->call->drop = fn;
137
		obj->call->drop = fn;
137
	    }
138
	    }
138
}
139
}
139
 
140
 
140
void setonfocus(control obj, actionfn fn)
141
void setonfocus(control obj, actionfn fn)
141
{
142
{
142
	if (obj)
143
	if (obj)
143
		obj->call->focus = fn;
144
		obj->call->focus = fn;
144
}
145
}
145
 
146
 
146
 
147
 
147
/*
148
/*
148
 *  Drawing controls and windows.
149
 *  Drawing controls and windows.
149
 */
150
 */
150
void clear(control obj)
151
void clear(control obj)
151
{
152
{
152
	drawing prev;
153
	drawing prev;
153
	rgb old;
154
	rgb old;
154
 
155
 
155
	if (! obj)
156
	if (! obj)
156
		return;
157
		return;
157
	if (! isvisible(obj))
158
	if (! isvisible(obj))
158
		return;
159
		return;
159
	if (! isvisible(parentwindow(obj)))
160
	if (! isvisible(parentwindow(obj)))
160
		return;
161
		return;
161
	if (obj->bg == Transparent)
162
	if (obj->bg == Transparent)
162
		return;
163
		return;
163
	prev = current->dest;
164
	prev = current->dest;
164
	drawto(obj);
165
	drawto(obj);
165
	old = currentrgb();
166
	old = currentrgb();
166
	setrgb(obj->bg);
167
	setrgb(obj->bg);
167
	fillrect(getrect(obj));
168
	fillrect(getrect(obj));
-
 
169
	if (prev) {
168
	setrgb(old);
170
		setrgb(old);
169
	drawto(prev);
171
		drawto(prev);
-
 
172
    	}
170
}
173
}
171
 
174
 
172
void draw(control obj)
175
void draw(control obj)
173
{
176
{
174
	drawing prev;
177
	drawing prev;
175
	drawstate old;
178
	drawstate old;
176
 
179
 
177
	if (! obj)
180
	if (! obj)
178
		return;
181
		return;
179
	if (obj->kind == MenubarObject) {
182
	if (obj->kind == MenubarObject) {
180
		DrawMenuBar(obj->parent->handle);
183
		DrawMenuBar(obj->parent->handle);
181
		return;
184
		return;
182
	}
185
	}
183
 
186
 
184
	if (! isvisible(obj))
187
	if (! isvisible(obj))
185
		return;
188
		return;
186
	if (! isvisible(parentwindow(obj)))
189
	if (! isvisible(parentwindow(obj)))
187
		return;
190
		return;
188
	if ((obj->call == NULL) || (obj->call->redraw == NULL))
191
	if ((obj->call == NULL) || (obj->call->redraw == NULL))
189
		return;
192
		return;
190
	prev = current->dest;
193
	prev = current->dest;
191
	drawto(obj);
194
	drawto(obj);
192
	old = copydrawstate();
195
	if (prev) old = copydrawstate();
193
	moveto(pt(0,0));
196
	moveto(pt(0,0));
194
	obj->call->redraw(obj, getrect(obj));
197
	obj->call->redraw(obj, getrect(obj));
-
 
198
	if (prev) {
195
	restoredrawstate(old);
199
		restoredrawstate(old);
196
	drawto(prev);
200
		drawto(prev);
-
 
201
    	}
197
}
202
}
198
 
203
 
199
void redraw(control obj)
204
void redraw(control obj)
200
{
205
{
201
	clear(obj);
206
	clear(obj);
202
	draw(obj);
207
	draw(obj);
203
}
208
}
204
 
209
 
205
/*  void getscreenrect(control obj, rect *r) */
210
/*  void getscreenrect(control obj, rect *r) */
206
/*  { */
211
/*  { */
207
/*      RECT W; */
212
/*      RECT W; */
208
/*      GetWindowRect(obj->handle, &W); */
213
/*      GetWindowRect(obj->handle, &W); */
209
/*      r->x = W.left; */
214
/*      r->x = W.left; */
210
/*      r->y = W.top; */
215
/*      r->y = W.top; */
211
/*      r->width = W.right - W.left; */
216
/*      r->width = W.right - W.left; */
212
/*      r->height = W.bottom - W.top; */
217
/*      r->height = W.bottom - W.top; */
213
/*  } */
218
/*  } */
214
 
219
 
215
 
220
 
216
/* The original here used GetWindowRect (which used screen coordinates)
221
/* The original here used GetWindowRect (which used screen coordinates)
217
   and MoveWindow (which uses client coordinates) so got the positioning
222
   and MoveWindow (which uses client coordinates) so got the positioning
218
   hopelessly wrong.  This version works for WindowObjects, but I would be
223
   hopelessly wrong.  This version works for WindowObjects, but I would be
219
   suspicious of it for other cases.  BDR 2000/04/05
224
   suspicious of it for other cases.  BDR 2000/04/05
220
*/
225
*/
221
void resize(control obj, rect r)
226
void resize(control obj, rect r)
222
{
227
{
223
        RECT R;
228
        RECT R;
224
	WINDOWPLACEMENT W;
229
	WINDOWPLACEMENT W;
225
	int dw, dh, dx, dy;
230
	int dw, dh, dx, dy;
226
 
231
 
227
	if (! obj)
232
	if (! obj)
228
		return;
233
		return;
229
	r = rcanon(r);
234
	r = rcanon(r);
230
	if (obj->kind == WindowObject) {
235
	if (obj->kind == WindowObject) {
231
	        W.length = sizeof(WINDOWPLACEMENT);
236
	        W.length = sizeof(WINDOWPLACEMENT);
232
		r.x = obj->rect.x;
237
		r.x = obj->rect.x;
233
		r.y = obj->rect.y;
238
		r.y = obj->rect.y;
234
		if (!equalr(r, obj->rect)) {
239
		if (!equalr(r, obj->rect)) {
235
			GetWindowPlacement(obj->handle, &W);
240
			GetWindowPlacement(obj->handle, &W);
236
			if (!isvisible(obj)) W.showCmd = SW_HIDE;  /* stops the resize from revealing the window */
241
			if (!isvisible(obj)) W.showCmd = SW_HIDE;  /* stops the resize from revealing the window */
237
			dx = r.x - obj->rect.x;
242
			dx = r.x - obj->rect.x;
238
			dy = r.y - obj->rect.y;
243
			dy = r.y - obj->rect.y;
239
			/* don't believe current sizes!
244
			/* don't believe current sizes!
240
			dw = r.width - obj->rect.width;
245
			dw = r.width - obj->rect.width;
241
			dh = r.height - obj->rect.height;
246
			dh = r.height - obj->rect.height;
242
			Rprintf("dw %d dh %d\n", dw, dh); */
247
			Rprintf("dw %d dh %d\n", dw, dh); */
243
			GetClientRect(obj->handle, &R);
248
			GetClientRect(obj->handle, &R);
244
			dw = r.width - (R.right - R.left);
249
			dw = r.width - (R.right - R.left);
245
			dh = r.height - (R.bottom - R.top);
250
			dh = r.height - (R.bottom - R.top);
246
			W.rcNormalPosition.left += dx;
251
			W.rcNormalPosition.left += dx;
247
			W.rcNormalPosition.top += dy;
252
			W.rcNormalPosition.top += dy;
248
			W.rcNormalPosition.right += dx + dw;
253
			W.rcNormalPosition.right += dx + dw;
249
			W.rcNormalPosition.bottom += dy + dh;
254
			W.rcNormalPosition.bottom += dy + dh;
250
			SetWindowPlacement(obj->handle, &W);
255
			SetWindowPlacement(obj->handle, &W);
251
		}
256
		}
252
	}
257
	}
253
	else {
258
	else {
254
		if (! equalr(r, obj->rect))
259
		if (! equalr(r, obj->rect))
255
			MoveWindow(obj->handle, r.x, r.y, r.width, r.height, 1);
260
			MoveWindow(obj->handle, r.x, r.y, r.width, r.height, 1);
256
		obj->rect.x = r.x;
261
		obj->rect.x = r.x;
257
		obj->rect.y = r.y;
262
		obj->rect.y = r.y;
258
	}
263
	}
259
	obj->rect.width = r.width;
264
	obj->rect.width = r.width;
260
	obj->rect.height = r.height;
265
	obj->rect.height = r.height;
261
}
266
}
262
 
267
 
263
/*
268
/*
264
 *  Showing and hiding controls and windows.
269
 *  Showing and hiding controls and windows.
265
 */
270
 */
266
void show(control obj)
271
void show(control obj)
267
{
272
{
268
	if (! obj)
273
	if (! obj)
269
		return;
274
		return;
270
	switch (obj->kind)
275
	switch (obj->kind)
271
	{
276
	{
272
	case CursorObject: case FontObject: case BitmapObject:
277
	case CursorObject: case FontObject: case BitmapObject:
273
	case MenubarObject: case MenuObject: case MenuitemObject:
278
	case MenubarObject: case MenuObject: case MenuitemObject:
274
		break;
279
		break;
275
	case WindowObject:
280
	case WindowObject:
276
		obj->state |= Visible;
281
		obj->state |= Visible;
277
		show_window(obj);
282
		show_window(obj);
278
		break;
283
		break;
279
	default:
284
	default:
280
		ShowWindow(obj->handle, SW_SHOWNORMAL);
285
		ShowWindow(obj->handle, SW_SHOWNORMAL);
281
		SetFocus(obj->handle);
286
		SetFocus(obj->handle);
282
		UpdateWindow(obj->handle);
287
		UpdateWindow(obj->handle);
283
	}
288
	}
284
	obj->state |= Visible;
289
	obj->state |= Visible;
285
}
290
}
286
 
291
 
287
void hide(control obj)
292
void hide(control obj)
288
{
293
{
289
	if (! obj)
294
	if (! obj)
290
		return;
295
		return;
291
	switch (obj->kind)
296
	switch (obj->kind)
292
	{
297
	{
293
	case CursorObject: case FontObject: case BitmapObject:
298
	case CursorObject: case FontObject: case BitmapObject:
294
	case MenubarObject: case MenuObject: case MenuitemObject:
299
	case MenubarObject: case MenuObject: case MenuitemObject:
295
		break;
300
		break;
296
	case WindowObject:
301
	case WindowObject:
297
		hide_window(obj);
302
		hide_window(obj);
298
		break;
303
		break;
299
	default:
304
	default:
300
		ShowWindow(obj->handle, SW_HIDE);
305
		ShowWindow(obj->handle, SW_HIDE);
301
	}
306
	}
302
	obj->state &= ~Visible;
307
	obj->state &= ~Visible;
303
}
308
}
304
 
309
 
305
int isvisible(control obj)
310
int isvisible(control obj)
306
{
311
{
307
	if (! obj)
312
	if (! obj)
308
		return 0;
313
		return 0;
309
	return (obj->state & Visible) ? 1 : 0;
314
	return (obj->state & Visible) ? 1 : 0;
310
}
315
}
311
 
316
 
312
/*
317
/*
313
 *  Enabling and disabling controls and windows.
318
 *  Enabling and disabling controls and windows.
314
 */
319
 */
315
void enable(control obj)
320
void enable(control obj)
316
{
321
{
317
	if (! obj)
322
	if (! obj)
318
		return;
323
		return;
319
	switch (obj->kind)
324
	switch (obj->kind)
320
	{
325
	{
321
	case CursorObject: case FontObject: case BitmapObject:
326
	case CursorObject: case FontObject: case BitmapObject:
322
	case MenubarObject:
327
	case MenubarObject:
323
		break;
328
		break;
324
	case MenuObject: case MenuitemObject:
329
	case MenuObject: case MenuitemObject:
325
		EnableMenuItem(obj->parent->handle,
330
		EnableMenuItem(obj->parent->handle,
326
			obj->id, MF_ENABLED | MF_BYCOMMAND);
331
			obj->id, MF_ENABLED | MF_BYCOMMAND);
327
		break;
332
		break;
328
	case FieldObject: case TextboxObject:
333
	case FieldObject: case TextboxObject:
329
		sendmessage(obj->handle, EM_SETREADONLY, FALSE, 0L);
334
		sendmessage(obj->handle, EM_SETREADONLY, FALSE, 0L);
330
		break;
335
		break;
331
	default:
336
	default:
332
		if (! isenabled(obj)) {
337
		if (! isenabled(obj)) {
333
			EnableWindow(obj->handle, 1);
338
			EnableWindow(obj->handle, 1);
334
			obj->state |= Enabled;
339
			obj->state |= Enabled;
335
			draw(obj);
340
			draw(obj);
336
		}
341
		}
337
	}
342
	}
338
	obj->state |= Enabled;
343
	obj->state |= Enabled;
339
}
344
}
340
 
345
 
341
void disable(control obj)
346
void disable(control obj)
342
{
347
{
343
	if (! obj)
348
	if (! obj)
344
		return;
349
		return;
345
	switch (obj->kind)
350
	switch (obj->kind)
346
	{
351
	{
347
	case CursorObject: case FontObject: case BitmapObject:
352
	case CursorObject: case FontObject: case BitmapObject:
348
	case MenubarObject: case MenuObject:
353
	case MenubarObject: case MenuObject:
349
		break;
354
		break;
350
	case MenuitemObject:
355
	case MenuitemObject:
351
		EnableMenuItem(obj->parent->handle,
356
		EnableMenuItem(obj->parent->handle,
352
			obj->id, MF_GRAYED | MF_BYCOMMAND);
357
			obj->id, MF_GRAYED | MF_BYCOMMAND);
353
		break;
358
		break;
354
	case FieldObject: case TextboxObject:
359
	case FieldObject: case TextboxObject:
355
		sendmessage(obj->handle, EM_SETREADONLY, TRUE, 0L);
360
		sendmessage(obj->handle, EM_SETREADONLY, TRUE, 0L);
356
		break;
361
		break;
357
	default:
362
	default:
358
		if (isenabled(obj)) {
363
		if (isenabled(obj)) {
359
			EnableWindow(obj->handle, 0);
364
			EnableWindow(obj->handle, 0);
360
			obj->state &= ~Enabled;
365
			obj->state &= ~Enabled;
361
			draw(obj);
366
			draw(obj);
362
		}
367
		}
363
	}
368
	}
364
	obj->state &= ~Enabled;
369
	obj->state &= ~Enabled;
365
}
370
}
366
 
371
 
367
int isenabled(control obj)
372
int isenabled(control obj)
368
{
373
{
369
	if (! obj)
374
	if (! obj)
370
		return 0;
375
		return 0;
371
	return (obj->state & Enabled) ? 1 : 0;
376
	return (obj->state & Enabled) ? 1 : 0;
372
}
377
}
373
 
378
 
374
/*
379
/*
375
 *  Checking and unchecking controls.
380
 *  Checking and unchecking controls.
376
 */
381
 */
377
void check(control obj)
382
void check(control obj)
378
{
383
{
379
	if (! obj)
384
	if (! obj)
380
		return;
385
		return;
381
	switch (obj->kind)
386
	switch (obj->kind)
382
	{
387
	{
383
	case CursorObject: case FontObject: case BitmapObject:
388
	case CursorObject: case FontObject: case BitmapObject:
384
	case MenubarObject: case MenuObject:
389
	case MenubarObject: case MenuObject:
385
		break;
390
		break;
386
	case MenuitemObject:
391
	case MenuitemObject:
387
		CheckMenuItem(obj->parent->handle, obj->id,
392
		CheckMenuItem(obj->parent->handle, obj->id,
388
			MF_CHECKED | MF_BYCOMMAND);
393
			MF_CHECKED | MF_BYCOMMAND);
389
		break;
394
		break;
390
#if USE_NATIVE_BUTTONS
395
#if USE_NATIVE_BUTTONS
391
	case ButtonObject:
396
	case ButtonObject:
392
		sendmessage(obj->handle, BM_SETCHECK, 1, 0L);
397
		sendmessage(obj->handle, BM_SETCHECK, 1, 0L);
393
		break;
398
		break;
394
#endif
399
#endif
395
#if USE_NATIVE_TOGGLES
400
#if USE_NATIVE_TOGGLES
396
	case CheckboxObject: case RadioObject:
401
	case CheckboxObject: case RadioObject:
397
		sendmessage(obj->handle, BM_SETCHECK, 1, 0L);
402
		sendmessage(obj->handle, BM_SETCHECK, 1, 0L);
398
		break;
403
		break;
399
#endif
404
#endif
400
	default:
405
	default:
401
		if (! ischecked(obj)) {
406
		if (! ischecked(obj)) {
402
			obj->state |= Checked;
407
			obj->state |= Checked;
403
			draw(obj);
408
			draw(obj);
404
		}
409
		}
405
	}
410
	}
406
	obj->state |= Checked;
411
	obj->state |= Checked;
407
}
412
}
408
 
413
 
409
void uncheck(control obj)
414
void uncheck(control obj)
410
{
415
{
411
	if (! obj)
416
	if (! obj)
412
		return;
417
		return;
413
	switch (obj->kind)
418
	switch (obj->kind)
414
	{
419
	{
415
	case CursorObject: case FontObject: case BitmapObject:
420
	case CursorObject: case FontObject: case BitmapObject:
416
	case MenubarObject: case MenuObject:
421
	case MenubarObject: case MenuObject:
417
		break;
422
		break;
418
	case MenuitemObject:
423
	case MenuitemObject:
419
		CheckMenuItem(obj->parent->handle, obj->id,
424
		CheckMenuItem(obj->parent->handle, obj->id,
420
			MF_UNCHECKED | MF_BYCOMMAND);
425
			MF_UNCHECKED | MF_BYCOMMAND);
421
		break;
426
		break;
422
#if USE_NATIVE_BUTTONS
427
#if USE_NATIVE_BUTTONS
423
	case ButtonObject:
428
	case ButtonObject:
424
		sendmessage(obj->handle, BM_SETCHECK, 0, 0L);
429
		sendmessage(obj->handle, BM_SETCHECK, 0, 0L);
425
		break;
430
		break;
426
#endif
431
#endif
427
#if USE_NATIVE_TOGGLES
432
#if USE_NATIVE_TOGGLES
428
	case CheckboxObject: case RadioObject:
433
	case CheckboxObject: case RadioObject:
429
		sendmessage(obj->handle, BM_SETCHECK, 0, 0L);
434
		sendmessage(obj->handle, BM_SETCHECK, 0, 0L);
430
		break;
435
		break;
431
#endif
436
#endif
432
	default:
437
	default:
433
		if (ischecked(obj)) {
438
		if (ischecked(obj)) {
434
			obj->state &= ~Checked;
439
			obj->state &= ~Checked;
435
			draw(obj);
440
			draw(obj);
436
		}
441
		}
437
	}
442
	}
438
	obj->state &= ~Checked;
443
	obj->state &= ~Checked;
439
}
444
}
440
 
445
 
441
int ischecked(control obj)
446
int ischecked(control obj)
442
{
447
{
443
	if (! obj)
448
	if (! obj)
444
		return 0;
449
		return 0;
445
	return (obj->state & Checked) ? 1 : 0;
450
	return (obj->state & Checked) ? 1 : 0;
446
}
451
}
447
 
452
 
448
/*
453
/*
449
 *  Highlighting and unhighlighting controls.
454
 *  Highlighting and unhighlighting controls.
450
 */
455
 */
451
void highlight(control obj)
456
void highlight(control obj)
452
{
457
{
453
	if (! obj)
458
	if (! obj)
454
		return;
459
		return;
455
	switch (obj->kind)
460
	switch (obj->kind)
456
	{
461
	{
457
	case CursorObject: case FontObject: case BitmapObject:
462
	case CursorObject: case FontObject: case BitmapObject:
458
	case MenubarObject: case MenuObject: case MenuitemObject:
463
	case MenubarObject: case MenuObject: case MenuitemObject:
459
		break;
464
		break;
460
#if USE_NATIVE_BUTTONS
465
#if USE_NATIVE_BUTTONS
461
	case ButtonObject:
466
	case ButtonObject:
462
		sendmessage(obj->handle, BM_SETSTATE, 1, 0L);
467
		sendmessage(obj->handle, BM_SETSTATE, 1, 0L);
463
		break;
468
		break;
464
#endif
469
#endif
465
#if USE_NATIVE_TOGGLES
470
#if USE_NATIVE_TOGGLES
466
	case CheckboxObject: case RadioObject:
471
	case CheckboxObject: case RadioObject:
467
		sendmessage(obj->handle, BM_SETSTATE, 1, 0L);
472
		sendmessage(obj->handle, BM_SETSTATE, 1, 0L);
468
		break;
473
		break;
469
#endif
474
#endif
470
	case FieldObject: case TextboxObject:
475
	case FieldObject: case TextboxObject:
471
		sendmessage(obj->handle, EM_SETSEL, 0, MAKELONG(0,-1));
476
		sendmessage(obj->handle, EM_SETSEL, 0, MAKELONG(0,-1));
472
		break;
477
		break;
473
	default:
478
	default:
474
		if (! ishighlighted(obj)) {
479
		if (! ishighlighted(obj)) {
475
			obj->state |= Highlighted;
480
			obj->state |= Highlighted;
476
			draw(obj);
481
			draw(obj);
477
		}
482
		}
478
	}
483
	}
479
	obj->state |= Highlighted;
484
	obj->state |= Highlighted;
480
}
485
}
481
 
486
 
482
void unhighlight(control obj)
487
void unhighlight(control obj)
483
{
488
{
484
	if (! obj)
489
	if (! obj)
485
		return;
490
		return;
486
	switch (obj->kind)
491
	switch (obj->kind)
487
	{
492
	{
488
	case CursorObject: case FontObject: case BitmapObject:
493
	case CursorObject: case FontObject: case BitmapObject:
489
	case MenubarObject: case MenuObject: case MenuitemObject:
494
	case MenubarObject: case MenuObject: case MenuitemObject:
490
		break;
495
		break;
491
#if USE_NATIVE_BUTTONS
496
#if USE_NATIVE_BUTTONS
492
	case ButtonObject:
497
	case ButtonObject:
493
		sendmessage(obj->handle, BM_SETSTATE, 0, 0L);
498
		sendmessage(obj->handle, BM_SETSTATE, 0, 0L);
494
		break;
499
		break;
495
#endif
500
#endif
496
#if USE_NATIVE_TOGGLES
501
#if USE_NATIVE_TOGGLES
497
	case CheckboxObject: case RadioObject:
502
	case CheckboxObject: case RadioObject:
498
		sendmessage(obj->handle, BM_SETSTATE, 0, 0L);
503
		sendmessage(obj->handle, BM_SETSTATE, 0, 0L);
499
		break;
504
		break;
500
#endif
505
#endif
501
	case FieldObject: case TextboxObject:
506
	case FieldObject: case TextboxObject:
502
		sendmessage(obj->handle, EM_SETSEL, 0, MAKELONG(0,0));
507
		sendmessage(obj->handle, EM_SETSEL, 0, MAKELONG(0,0));
503
		break;
508
		break;
504
	default:
509
	default:
505
		if (ishighlighted(obj)) {
510
		if (ishighlighted(obj)) {
506
			obj->state &= ~Highlighted;
511
			obj->state &= ~Highlighted;
507
			draw(obj);
512
			draw(obj);
508
		}
513
		}
509
	}
514
	}
510
	obj->state &= ~Highlighted;
515
	obj->state &= ~Highlighted;
511
}
516
}
512
 
517
 
513
int ishighlighted(control obj)
518
int ishighlighted(control obj)
514
{
519
{
515
	if (! obj)
520
	if (! obj)
516
		return 0;
521
		return 0;
517
	return (obj->state & Highlighted) ? 1 : 0;
522
	return (obj->state & Highlighted) ? 1 : 0;
518
}
523
}
519
 
524
 
520
/*
525
/*
521
 *  The flashcontrol function highlights a control as if the user
526
 *  The flashcontrol function highlights a control as if the user
522
 *  just used it, e.g. a button will become pressed down for a
527
 *  just used it, e.g. a button will become pressed down for a
523
 *  moment. Used in conjunction with activatecontrol() below,
528
 *  moment. Used in conjunction with activatecontrol() below,
524
 *  it can simulate a mouse-click on a button.
529
 *  it can simulate a mouse-click on a button.
525
 */
530
 */
526
void flashcontrol(control obj)
531
void flashcontrol(control obj)
527
{
532
{
528
	highlight(obj);
533
	highlight(obj);
529
	delay(150);
534
	delay(150);
530
	unhighlight(obj);
535
	unhighlight(obj);
531
}
536
}
532
 
537
 
533
/*
538
/*
534
 *  The activatecontrol function is really useful. It causes
539
 *  The activatecontrol function is really useful. It causes
535
 *  a variety of controls to call their 'action functions.'
540
 *  a variety of controls to call their 'action functions.'
536
 *
541
 *
537
 *  There are two types of action functions which a control can use.
542
 *  There are two types of action functions which a control can use.
538
 *  The first (obj->action) takes one argument, the control itself,
543
 *  The first (obj->action) takes one argument, the control itself,
539
 *  and is used in buttons, checkboxes and the like as a response
544
 *  and is used in buttons, checkboxes and the like as a response
540
 *  to a user clicking on these controls. The second function,
545
 *  to a user clicking on these controls. The second function,
541
 *  (obj->hit) function, takes two arguments: the control and its
546
 *  (obj->hit) function, takes two arguments: the control and its
542
 *  current 'value'. A scrollbar's value changes as the user scrolls,
547
 *  current 'value'. A scrollbar's value changes as the user scrolls,
543
 *  and so its hit function is called whenever that happens.
548
 *  and so its hit function is called whenever that happens.
544
 *
549
 *
545
 *  The activatecontrol function tries to call the action function,
550
 *  The activatecontrol function tries to call the action function,
546
 *  and if that doesn't exist, calls the hit function, passing the
551
 *  and if that doesn't exist, calls the hit function, passing the
547
 *  object's value to it.
552
 *  object's value to it.
548
 */
553
 */
549
void activatecontrol(control obj)
554
void activatecontrol(control obj)
550
{
555
{
551
	if (! obj)
556
	if (! obj)
552
		return;
557
		return;
553
	drawto(obj);
558
	drawto(obj);
554
	if (obj->action != NULL)
559
	if (obj->action != NULL)
555
		obj->action(obj);
560
		obj->action(obj);
556
	else if (obj->hit != NULL)
561
	else if (obj->hit != NULL)
557
		obj->hit(obj, obj->value);
562
		obj->hit(obj, obj->value);
558
}
563
}
559
 
564
 
560
/*
565
/*
561
 *  Changing and determining the state of an object.
566
 *  Changing and determining the state of an object.
562
 *  These functions do not automatically redraw the object.
567
 *  These functions do not automatically redraw the object.
563
 */
568
 */
564
#if 0
569
#if 0
565
void setstate(control obj, long state)
570
void setstate(control obj, long state)
566
{
571
{
567
	if (obj)
572
	if (obj)
568
		obj->state = state;
573
		obj->state = state;
569
}
574
}
570
 
575
 
571
long getstate(control obj)
576
long getstate(control obj)
572
{
577
{
573
	if (obj)
578
	if (obj)
574
		return obj->state;
579
		return obj->state;
575
	else
580
	else
576
		return 0;
581
		return 0;
577
}
582
}
578
#endif
583
#endif
579
 
584
 
580
void setvalue(control obj, int value)
585
void setvalue(control obj, int value)
581
{
586
{
582
	if (obj)
587
	if (obj)
583
		obj->value = value;
588
		obj->value = value;
584
}
589
}
585
 
590
 
586
int getvalue(control obj)
591
int getvalue(control obj)
587
{
592
{
588
	if (obj)
593
	if (obj)
589
		return obj->value;
594
		return obj->value;
590
	else
595
	else
591
		return 0;
596
		return 0;
592
}
597
}
593
 
598
 
594
void setforeground(control obj, rgb fg)
599
void setforeground(control obj, rgb fg)
595
{
600
{
596
	if (! obj)
601
	if (! obj)
597
		return;
602
		return;
598
	obj->fg = fg;
603
	obj->fg = fg;
599
	InvalidateRect(obj->handle, NULL, TRUE);
604
	InvalidateRect(obj->handle, NULL, TRUE);
600
	redraw(obj);
605
	redraw(obj);
601
}
606
}
602
 
607
 
603
rgb getforeground(control obj)
608
rgb getforeground(control obj)
604
{
609
{
605
	if (obj)
610
	if (obj)
606
		return obj->fg;
611
		return obj->fg;
607
	else
612
	else
608
		return Black;
613
		return Black;
609
}
614
}
610
 
615
 
611
void setbackground(control obj, rgb bg)
616
void setbackground(control obj, rgb bg)
612
{
617
{
613
#if USE_NATIVE_CONTROLS
618
#if USE_NATIVE_CONTROLS
614
	COLORREF wincolour;
619
	COLORREF wincolour;
615
 
620
 
616
	wincolour = RGB((bg&gaRed)>>16,(bg&gaGreen)>>8,(bg&gaBlue));
621
	wincolour = RGB((bg&gaRed)>>16,(bg&gaGreen)>>8,(bg&gaBlue));
617
 
622
 
618
	if (! obj)
623
	if (! obj)
619
		return;
624
		return;
620
	if (obj->bgbrush)
625
	if (obj->bgbrush)
621
		DeleteObject(obj->bgbrush);
626
		DeleteObject(obj->bgbrush);
622
	obj->bgbrush = CreateSolidBrush(wincolour);
627
	obj->bgbrush = CreateSolidBrush(wincolour);
623
#endif
628
#endif
624
	if (! obj)
629
	if (! obj)
625
		return;
630
		return;
626
	obj->bg = bg;
631
	obj->bg = bg;
627
	InvalidateRect(obj->handle, NULL, TRUE);
632
	InvalidateRect(obj->handle, NULL, TRUE);
628
	redraw(obj);
633
	redraw(obj);
629
}
634
}
630
 
635
 
631
rgb getbackground(control obj)
636
rgb getbackground(control obj)
632
{
637
{
633
	if (obj)
638
	if (obj)
634
		return obj->bg;
639
		return obj->bg;
635
	else
640
	else
636
		return Transparent;
641
		return Transparent;
637
}
642
}
638
 
643
 
639
void setdata(control obj, void *data)
644
void setdata(control obj, void *data)
640
{
645
{
641
	if (obj)
646
	if (obj)
642
		obj->data = data;
647
		obj->data = data;
643
}
648
}
644
 
649
 
645
void *getdata(control obj)
650
void *getdata(control obj)
646
{
651
{
647
	if (obj)
652
	if (obj)
648
		return obj->data;
653
		return obj->data;
649
	else
654
	else
650
		return NULL;
655
		return NULL;
651
}
656
}
652
 
657
 
653
void _setextradata(control obj, void *data)
658
void _setextradata(control obj, void *data)
654
{
659
{
655
	if (obj)
660
	if (obj)
656
		obj->extra = data;
661
		obj->extra = data;
657
}
662
}
658
 
663
 
659
void *_getextradata(control obj)
664
void *_getextradata(control obj)
660
{
665
{
661
	if (obj)
666
	if (obj)
662
		return obj->extra;
667
		return obj->extra;
663
	else
668
	else
664
		return NULL;
669
		return NULL;
665
}
670
}
666
 
671
 
667
/*
672
/*
668
 *  Set the text of an object. This will set the names appearing
673
 *  Set the text of an object. This will set the names appearing
669
 *  in a window's title bar, a button, checkbox or radio button,
674
 *  in a window's title bar, a button, checkbox or radio button,
670
 *  or the value in a textbox or a text field.
675
 *  or the value in a textbox or a text field.
671
 */
676
 */
672
void settext(control obj, char *text)
677
void settext(control obj, char *text)
673
{
678
{
674
	if (! obj)
679
	if (! obj)
675
		return;
680
		return;
676
	if (! text)
681
	if (! text)
677
		text = "";
682
		text = "";
678
	if (strcmp(gettext(obj), text) == 0)
683
	if (strcmp(gettext(obj), text) == 0)
679
		return; /* no changes to be made */
684
		return; /* no changes to be made */
680
	if (obj->text) {
685
	if (obj->text) {
681
		/* discard prior information */
686
		/* discard prior information */
682
		discard(obj->text);
687
		discard(obj->text);
683
		obj->text = NULL;
688
		obj->text = NULL;
684
	}
689
	}
685
	/* Set the new text. */
690
	/* Set the new text. */
686
	obj->text = new_string(text);
691
	obj->text = new_string(text);
687
	if (text) {
692
	if (text) {
688
		if (obj->kind & ControlObject) {
693
		if (obj->kind & ControlObject) {
689
			text = to_dos_string(text);
694
			text = to_dos_string(text);
690
			SetWindowText(obj->handle, text);
695
			SetWindowText(obj->handle, text);
691
			discard(text);
696
			discard(text);
692
		}
697
		}
693
                if (obj->kind==MenuitemObject) {
698
                if (obj->kind==MenuitemObject) {
694
                        ModifyMenu(obj->parent->handle, obj->id,
699
                        ModifyMenu(obj->parent->handle, obj->id,
695
                                   MF_BYCOMMAND|MF_STRING,obj->id,
700
                                   MF_BYCOMMAND|MF_STRING,obj->id,
696
                                   text);
701
                                   text);
697
                }
702
                }
698
 
703
 
699
	}
704
	}
700
	/* Redraw it if it's a redrawable object. */
705
	/* Redraw it if it's a redrawable object. */
701
	if (obj->call && obj->call->redraw)
706
	if (obj->call && obj->call->redraw)
702
		redraw(obj);
707
		redraw(obj);
703
}
708
}
704
 
709
 
705
/*
710
/*
706
 *  Get the text string from a window's title bar or from a
711
 *  Get the text string from a window's title bar or from a
707
 *  control. This may be a button's name, for example, or
712
 *  control. This may be a button's name, for example, or
708
 *  the value inside a text field.
713
 *  the value inside a text field.
709
 */
714
 */
710
char *gettext(control obj)
715
char *gettext(control obj)
711
{
716
{
712
	static char *empty = "";
717
	static char *empty = "";
713
	char *text;
718
	char *text;
714
	int length, index;
719
	int length, index;
715
	HWND hwnd;
720
	HWND hwnd;
716
	UINT len_msg, gettext_msg;
721
	UINT len_msg, gettext_msg;
717
	WPARAM arg1, arg2;
722
	WPARAM arg1, arg2;
718
 
723
 
719
	if (! obj)
724
	if (! obj)
720
		return empty;
725
		return empty;
721
	if ((obj->kind & ControlObject) == 0)
726
	if ((obj->kind & ControlObject) == 0)
722
		return obj->text ? obj->text : empty;
727
		return obj->text ? obj->text : empty;
723
 
728
 
724
	hwnd = obj->handle;
729
	hwnd = obj->handle;
725
 
730
 
726
	switch (obj->kind) {
731
	switch (obj->kind) {
727
	  case ListboxObject:
732
	  case ListboxObject:
728
	  case MultilistObject:
733
	  case MultilistObject:
729
		len_msg = LB_GETTEXTLEN;
734
		len_msg = LB_GETTEXTLEN;
730
		gettext_msg = LB_GETTEXT;
735
		gettext_msg = LB_GETTEXT;
731
		index = getlistitem(obj);
736
		index = getlistitem(obj);
732
		if (index < 0) return empty;
737
		if (index < 0) return empty;
733
		arg1 = arg2 = index;
738
		arg1 = arg2 = index;
734
		break;
739
		break;
735
	  case DroplistObject:
740
	  case DroplistObject:
736
		len_msg = CB_GETLBTEXTLEN;
741
		len_msg = CB_GETLBTEXTLEN;
737
		gettext_msg = CB_GETLBTEXT;
742
		gettext_msg = CB_GETLBTEXT;
738
		index = getlistitem(obj);
743
		index = getlistitem(obj);
739
		if (index < 0) return empty;
744
		if (index < 0) return empty;
740
		arg1 = arg2 = index;
745
		arg1 = arg2 = index;
741
		break;
746
		break;
742
	  case DropfieldObject:
747
	  case DropfieldObject:
743
		// use default mechanism
748
		// use default mechanism
744
	  default:
749
	  default:
745
		len_msg = WM_GETTEXTLENGTH;
750
		len_msg = WM_GETTEXTLENGTH;
746
		gettext_msg = WM_GETTEXT;
751
		gettext_msg = WM_GETTEXT;
747
		arg1 = 0;
752
		arg1 = 0;
748
		arg2 = sendmessage(hwnd, len_msg, 0, 0L)+1;
753
		arg2 = sendmessage(hwnd, len_msg, 0, 0L)+1;
749
		break;
754
		break;
750
	}
755
	}
751
 
756
 
752
	/* Free any previous information. */
757
	/* Free any previous information. */
753
	if (obj->text)
758
	if (obj->text)
754
	    discard(obj->text);
759
	    discard(obj->text);
755
	/* Find the length of the string. */
760
	/* Find the length of the string. */
756
	length = sendmessage(obj->handle, len_msg, arg1, 0L);
761
	length = sendmessage(obj->handle, len_msg, arg1, 0L);
757
	if (length == 0)
762
	if (length == 0)
758
		return (obj->text = new_string(NULL));
763
		return (obj->text = new_string(NULL));
759
	/* Copy the text from the object. */
764
	/* Copy the text from the object. */
760
	text = array(length+2, char);
765
	text = array(length+2, char);
761
	sendmessage(obj->handle, gettext_msg, arg2, (LPCSTR) text);
766
	sendmessage(obj->handle, gettext_msg, arg2, (LPCSTR) text);
762
	obj->text = to_c_string(text);
767
	obj->text = to_c_string(text);
763
	discard(text);
768
	discard(text);
764
	/* Return the resultant string. */
769
	/* Return the resultant string. */
765
	if (! obj->text)
770
	if (! obj->text)
766
		obj->text = new_string(NULL);
771
		obj->text = new_string(NULL);
767
	return obj->text;
772
	return obj->text;
768
}
773
}
769
 
774
 
770
/*
775
/*
771
 *  Set the font used by a control.
776
 *  Set the font used by a control.
772
 */
777
 */
773
void settextfont(object obj, font f)
778
void settextfont(object obj, font f)
774
{
779
{
775
	if (! obj)
780
	if (! obj)
776
		return;
781
		return;
777
	if (! f)
782
	if (! f)
778
		f = SystemFont;
783
		f = SystemFont;
779
	if (obj->drawstate) {
784
	if (obj->drawstate) {
780
		decrease_refcount(obj->drawstate->fnt);
785
		decrease_refcount(obj->drawstate->fnt);
781
		obj->drawstate->fnt = f;
786
		obj->drawstate->fnt = f;
782
		increase_refcount(f);
787
		increase_refcount(f);
783
	}
788
	}
784
	else {
789
	else {
785
		sendmessage(obj->handle, WM_SETFONT, f->handle, 0L);
790
		sendmessage(obj->handle, WM_SETFONT, f->handle, 0L);
786
	}
791
	}
787
}
792
}
788
 
793
 
789
/*
794
/*
790
 *  Get the font used by a control.
795
 *  Get the font used by a control.
791
 */
796
 */
792
font gettextfont(object obj)
797
font gettextfont(object obj)
793
{
798
{
794
	font f = NULL;
799
	font f = NULL;
795
	if (obj) {
800
	if (obj) {
796
		if (obj->drawstate)
801
		if (obj->drawstate)
797
			f = obj->drawstate->fnt;
802
			f = obj->drawstate->fnt;
798
	}
803
	}
799
	if (! f)
804
	if (! f)
800
		f = SystemFont;
805
		f = SystemFont;
801
	return f;
806
	return f;
802
}
807
}
803
 
808
 
804
/*
809
/*
805
 *  Control and window functions.
810
 *  Control and window functions.
806
 *  Parentwindow of a window is itself.
811
 *  Parentwindow of a window is itself.
807
 */
812
 */
808
window parentwindow(control obj)
813
window parentwindow(control obj)
809
{
814
{
810
	while (obj) {
815
	while (obj) {
811
		if (obj->kind == WindowObject)
816
		if (obj->kind == WindowObject)
812
			break;
817
			break;
813
		obj = obj->parent;
818
		obj = obj->parent;
814
	}
819
	}
815
	return (window) obj;
820
	return (window) obj;
816
}
821
}
817
 
822
 
818
/*
823
/*
819
 *  Polymorphic functions:
824
 *  Polymorphic functions:
820
 */
825
 */
821
rect objrect(object obj)
826
rect objrect(object obj)
822
{
827
{
823
	rect r;
828
	rect r;
824
	image img;
829
	image img;
825
 
830
 
826
	if (! obj)
831
	if (! obj)
827
		return rect(0,0,0,0);
832
		return rect(0,0,0,0);
828
 
833
 
829
	switch (obj->kind)
834
	switch (obj->kind)
830
	{
835
	{
831
	  case Image8: case Image32:
836
	  case Image8: case Image32:
832
		img = (image) obj;
837
		img = (image) obj;
833
		r = rect(0,0,img->width,img->height);
838
		r = rect(0,0,img->width,img->height);
834
		break;
839
		break;
835
	  case BitmapObject:
840
	  case BitmapObject:
836
	  case FontObject: case CursorObject:
841
	  case FontObject: case CursorObject:
837
	 case PrinterObject:
842
	 case PrinterObject:
838
		r = obj->rect;
843
		r = obj->rect;
839
		break;
844
		break;
840
	 case MetafileObject:
845
	 case MetafileObject:
841
		r = obj->rect;
846
		r = obj->rect;
842
		break;
847
		break;
843
	  default:
848
	  default:
844
		GetClientRect(obj->handle, (RECT *) &r);
849
		GetClientRect(obj->handle, (RECT *) &r);
845
		break;
850
		break;
846
	}
851
	}
847
	return r;
852
	return r;
848
}
853
}
849
 
854
 
850
int objwidth(object obj)
855
int objwidth(object obj)
851
{
856
{
852
	rect r = objrect(obj);
857
	rect r = objrect(obj);
853
	return r.width;
858
	return r.width;
854
}
859
}
855
 
860
 
856
int objheight(object obj)
861
int objheight(object obj)
857
{
862
{
858
	rect r = objrect(obj);
863
	rect r = objrect(obj);
859
	return r.height;
864
	return r.height;
860
}
865
}
861
 
866
 
862
int objdepth(object obj)
867
int objdepth(object obj)
863
{
868
{
864
	HDC screendc;
869
	HDC screendc;
865
	int depth;
870
	int depth;
866
 
871
 
867
	if (! obj)
872
	if (! obj)
868
		return 0;
873
		return 0;
869
 
874
 
870
	switch (obj->kind)
875
	switch (obj->kind)
871
	{
876
	{
872
	  case Image8: case Image32:
877
	  case Image8: case Image32:
873
		depth = ((image)obj)->depth;
878
		depth = ((image)obj)->depth;
874
		break;
879
		break;
875
	  case BitmapObject:
880
	  case BitmapObject:
876
	  case FontObject: case CursorObject:
881
	  case FontObject: case CursorObject:
877
		depth = obj->depth;
882
		depth = obj->depth;
878
		break;
883
		break;
879
	  default:
884
	  default:
880
		screendc = GetDC(NULL);
885
		screendc = GetDC(NULL);
881
		depth = GetDeviceCaps(screendc, BITSPIXEL) *
886
		depth = GetDeviceCaps(screendc, BITSPIXEL) *
882
			GetDeviceCaps(screendc, PLANES);
887
			GetDeviceCaps(screendc, PLANES);
883
		ReleaseDC(NULL, screendc);
888
		ReleaseDC(NULL, screendc);
884
		break;
889
		break;
885
	}
890
	}
886
 
891
 
887
	return depth;
892
	return depth;
888
}
893
}
889
 
894
 
890
void delobj(object obj)
895
void delobj(object obj)
891
{
896
{
892
	if (! obj)
897
	if (! obj)
893
		return;
898
		return;
894
	switch (obj->kind)
899
	switch (obj->kind)
895
	{
900
	{
896
	  case Image8:
901
	  case Image8:
897
	  case Image32:
902
	  case Image32:
898
		delimage((image)obj);
903
		delimage((image)obj);
899
		break;
904
		break;
900
	  default:
905
	  default:
901
		/* if (obj->refcount == 1)   why would this test be here?? */
906
		/* if (obj->refcount == 1)   why would this test be here?? */
902
			decrease_refcount(obj);
907
			decrease_refcount(obj);
903
		break;
908
		break;
904
	}
909
	}
905
}
910
}