1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2006-2012, Haiku. All rights reserved.
3bf215546Sopenharmony_ci * Distributed under the terms of the MIT License.
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Authors:
6bf215546Sopenharmony_ci *		Jérôme Duval, korli@users.berlios.de
7bf215546Sopenharmony_ci *		Philippe Houdoin, philippe.houdoin@free.fr
8bf215546Sopenharmony_ci *		Stefano Ceccherini, burton666@libero.it
9bf215546Sopenharmony_ci */
10bf215546Sopenharmony_ci
11bf215546Sopenharmony_ci#include <kernel/image.h>
12bf215546Sopenharmony_ci
13bf215546Sopenharmony_ci#include <GLView.h>
14bf215546Sopenharmony_ci
15bf215546Sopenharmony_ci#include <assert.h>
16bf215546Sopenharmony_ci#include <stdio.h>
17bf215546Sopenharmony_ci#include <stdlib.h>
18bf215546Sopenharmony_ci#include <string.h>
19bf215546Sopenharmony_ci
20bf215546Sopenharmony_ci#include <DirectWindow.h>
21bf215546Sopenharmony_ci#include "GLRenderer.h"
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_ci#include <private/interface/DirectWindowPrivate.h>
24bf215546Sopenharmony_ci#include "GLRendererRoster.h"
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "glapi/glapi.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_cistruct glview_direct_info {
29bf215546Sopenharmony_ci	direct_buffer_info* direct_info;
30bf215546Sopenharmony_ci	bool direct_connected;
31bf215546Sopenharmony_ci	bool enable_direct_mode;
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci	glview_direct_info();
34bf215546Sopenharmony_ci	~glview_direct_info();
35bf215546Sopenharmony_ci};
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ciBGLView::BGLView(BRect rect, const char* name, ulong resizingMode, ulong mode,
39bf215546Sopenharmony_ci	ulong options)
40bf215546Sopenharmony_ci	:
41bf215546Sopenharmony_ci	BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS),
42bf215546Sopenharmony_ci	fGc(NULL),
43bf215546Sopenharmony_ci	fOptions(options),
44bf215546Sopenharmony_ci	fDitherCount(0),
45bf215546Sopenharmony_ci	fDrawLock("BGLView draw lock"),
46bf215546Sopenharmony_ci	fDisplayLock("BGLView display lock"),
47bf215546Sopenharmony_ci	fClipInfo(NULL),
48bf215546Sopenharmony_ci	fRenderer(NULL),
49bf215546Sopenharmony_ci	fDitherMap(NULL)
50bf215546Sopenharmony_ci{
51bf215546Sopenharmony_ci	fRenderer = GLRendererRoster::Roster()->GetRenderer(this, options);
52bf215546Sopenharmony_ci}
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ciBGLView::~BGLView()
56bf215546Sopenharmony_ci{
57bf215546Sopenharmony_ci	delete fClipInfo;
58bf215546Sopenharmony_ci	if (fRenderer)
59bf215546Sopenharmony_ci		fRenderer->Release();
60bf215546Sopenharmony_ci}
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_civoid
64bf215546Sopenharmony_ciBGLView::LockGL()
65bf215546Sopenharmony_ci{
66bf215546Sopenharmony_ci	// TODO: acquire the OpenGL API lock it on this glview
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci	fDisplayLock.Lock();
69bf215546Sopenharmony_ci	if (fRenderer != NULL && fDisplayLock.CountLocks() == 1)
70bf215546Sopenharmony_ci		fRenderer->LockGL();
71bf215546Sopenharmony_ci}
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_civoid
75bf215546Sopenharmony_ciBGLView::UnlockGL()
76bf215546Sopenharmony_ci{
77bf215546Sopenharmony_ci	thread_id lockerThread = fDisplayLock.LockingThread();
78bf215546Sopenharmony_ci	thread_id callerThread = find_thread(NULL);
79bf215546Sopenharmony_ci
80bf215546Sopenharmony_ci	if (lockerThread != B_ERROR && lockerThread != callerThread) {
81bf215546Sopenharmony_ci		printf("UnlockGL is called from wrong thread, lockerThread: %d, callerThread: %d\n",
82bf215546Sopenharmony_ci			(int)lockerThread, (int)callerThread);
83bf215546Sopenharmony_ci		debugger("[!]");
84bf215546Sopenharmony_ci	}
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci	if (fRenderer != NULL && fDisplayLock.CountLocks() == 1)
87bf215546Sopenharmony_ci		fRenderer->UnlockGL();
88bf215546Sopenharmony_ci	fDisplayLock.Unlock();
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci	// TODO: release the GL API lock to others glviews
91bf215546Sopenharmony_ci}
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_civoid
95bf215546Sopenharmony_ciBGLView::SwapBuffers()
96bf215546Sopenharmony_ci{
97bf215546Sopenharmony_ci	SwapBuffers(false);
98bf215546Sopenharmony_ci}
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_civoid
102bf215546Sopenharmony_ciBGLView::SwapBuffers(bool vSync)
103bf215546Sopenharmony_ci{
104bf215546Sopenharmony_ci	if (fRenderer) {
105bf215546Sopenharmony_ci		_LockDraw();
106bf215546Sopenharmony_ci		fRenderer->SwapBuffers(vSync);
107bf215546Sopenharmony_ci		_UnlockDraw();
108bf215546Sopenharmony_ci	}
109bf215546Sopenharmony_ci}
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ciBView*
113bf215546Sopenharmony_ciBGLView::EmbeddedView()
114bf215546Sopenharmony_ci{
115bf215546Sopenharmony_ci	return NULL;
116bf215546Sopenharmony_ci}
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_civoid*
120bf215546Sopenharmony_ciBGLView::GetGLProcAddress(const char* procName)
121bf215546Sopenharmony_ci{
122bf215546Sopenharmony_ci	return (void*)_glapi_get_proc_address(procName);
123bf215546Sopenharmony_ci}
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_cistatus_t
127bf215546Sopenharmony_ciBGLView::CopyPixelsOut(BPoint source, BBitmap* dest)
128bf215546Sopenharmony_ci{
129bf215546Sopenharmony_ci	if (!fRenderer)
130bf215546Sopenharmony_ci		return B_ERROR;
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ci	if (!dest || !dest->Bounds().IsValid())
133bf215546Sopenharmony_ci		return B_BAD_VALUE;
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci	return fRenderer->CopyPixelsOut(source, dest);
136bf215546Sopenharmony_ci}
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_cistatus_t
140bf215546Sopenharmony_ciBGLView::CopyPixelsIn(BBitmap* source, BPoint dest)
141bf215546Sopenharmony_ci{
142bf215546Sopenharmony_ci	if (!fRenderer)
143bf215546Sopenharmony_ci		return B_ERROR;
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci	if (!source || !source->Bounds().IsValid())
146bf215546Sopenharmony_ci		return B_BAD_VALUE;
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci	return fRenderer->CopyPixelsIn(source, dest);
149bf215546Sopenharmony_ci}
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci/*!	Mesa's GLenum is not ulong but uint, so we can't use GLenum
153bf215546Sopenharmony_ci	without breaking this method signature.
154bf215546Sopenharmony_ci	Instead, we have to use the effective BeOS's SGI OpenGL GLenum type:
155bf215546Sopenharmony_ci	unsigned long.
156bf215546Sopenharmony_ci */
157bf215546Sopenharmony_civoid
158bf215546Sopenharmony_ciBGLView::ErrorCallback(unsigned long errorCode)
159bf215546Sopenharmony_ci{
160bf215546Sopenharmony_ci	char msg[32];
161bf215546Sopenharmony_ci	sprintf(msg, "GL: Error code $%04lx.", errorCode);
162bf215546Sopenharmony_ci	// TODO: under BeOS R5, it call debugger(msg);
163bf215546Sopenharmony_ci	fprintf(stderr, "%s\n", msg);
164bf215546Sopenharmony_ci}
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_civoid
168bf215546Sopenharmony_ciBGLView::Draw(BRect updateRect)
169bf215546Sopenharmony_ci{
170bf215546Sopenharmony_ci	if (fRenderer) {
171bf215546Sopenharmony_ci		if (!fClipInfo || !fClipInfo->enable_direct_mode)
172bf215546Sopenharmony_ci			fRenderer->Draw(updateRect);
173bf215546Sopenharmony_ci		return;
174bf215546Sopenharmony_ci	}
175bf215546Sopenharmony_ci	// TODO: auto-size and center the string
176bf215546Sopenharmony_ci	MovePenTo(8, 32);
177bf215546Sopenharmony_ci	DrawString("No OpenGL renderer available!");
178bf215546Sopenharmony_ci}
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_civoid
182bf215546Sopenharmony_ciBGLView::AttachedToWindow()
183bf215546Sopenharmony_ci{
184bf215546Sopenharmony_ci	BView::AttachedToWindow();
185bf215546Sopenharmony_ci
186bf215546Sopenharmony_ci	fBounds = Bounds();
187bf215546Sopenharmony_ci	for (BView* view = this; view != NULL; view = view->Parent())
188bf215546Sopenharmony_ci		view->ConvertToParent(&fBounds);
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci	if (fRenderer != NULL) {
191bf215546Sopenharmony_ci		// Jackburton: The following code was commented because it doesn't look
192bf215546Sopenharmony_ci		// good in "direct" mode:
193bf215546Sopenharmony_ci		// when the window is moved, the app_server doesn't paint the view's
194bf215546Sopenharmony_ci		// background, and the stuff behind the window itself shows up.
195bf215546Sopenharmony_ci		// Setting the view color to black, instead, looks a bit more elegant.
196bf215546Sopenharmony_ci#if 0
197bf215546Sopenharmony_ci		// Don't paint white window background when resized
198bf215546Sopenharmony_ci		SetViewColor(B_TRANSPARENT_32_BIT);
199bf215546Sopenharmony_ci#else
200bf215546Sopenharmony_ci		SetViewColor(0, 0, 0);
201bf215546Sopenharmony_ci#endif
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_ci		// Set default OpenGL viewport:
204bf215546Sopenharmony_ci		LockGL();
205bf215546Sopenharmony_ci		glViewport(0, 0, Bounds().IntegerWidth(), Bounds().IntegerHeight());
206bf215546Sopenharmony_ci		UnlockGL();
207bf215546Sopenharmony_ci		fRenderer->FrameResized(Bounds().IntegerWidth(),
208bf215546Sopenharmony_ci			Bounds().IntegerHeight());
209bf215546Sopenharmony_ci
210bf215546Sopenharmony_ci		if (fClipInfo) {
211bf215546Sopenharmony_ci			fRenderer->DirectConnected(fClipInfo->direct_info);
212bf215546Sopenharmony_ci			fRenderer->EnableDirectMode(fClipInfo->enable_direct_mode);
213bf215546Sopenharmony_ci		}
214bf215546Sopenharmony_ci
215bf215546Sopenharmony_ci		return;
216bf215546Sopenharmony_ci	}
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ci	fprintf(stderr, "no renderer found! \n");
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci	// No Renderer, no rendering. Setup a minimal "No Renderer" string drawing
221bf215546Sopenharmony_ci	// context
222bf215546Sopenharmony_ci	SetFont(be_bold_font);
223bf215546Sopenharmony_ci	// SetFontSize(16);
224bf215546Sopenharmony_ci}
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_civoid
228bf215546Sopenharmony_ciBGLView::AllAttached()
229bf215546Sopenharmony_ci{
230bf215546Sopenharmony_ci	BView::AllAttached();
231bf215546Sopenharmony_ci}
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ci
234bf215546Sopenharmony_civoid
235bf215546Sopenharmony_ciBGLView::DetachedFromWindow()
236bf215546Sopenharmony_ci{
237bf215546Sopenharmony_ci	BView::DetachedFromWindow();
238bf215546Sopenharmony_ci}
239bf215546Sopenharmony_ci
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_civoid
242bf215546Sopenharmony_ciBGLView::AllDetached()
243bf215546Sopenharmony_ci{
244bf215546Sopenharmony_ci	BView::AllDetached();
245bf215546Sopenharmony_ci}
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_civoid
249bf215546Sopenharmony_ciBGLView::FrameResized(float width, float height)
250bf215546Sopenharmony_ci{
251bf215546Sopenharmony_ci	fBounds = Bounds();
252bf215546Sopenharmony_ci	for (BView* v = this; v; v = v->Parent())
253bf215546Sopenharmony_ci		v->ConvertToParent(&fBounds);
254bf215546Sopenharmony_ci
255bf215546Sopenharmony_ci	if (fRenderer) {
256bf215546Sopenharmony_ci		//_LockDraw();
257bf215546Sopenharmony_ci		fRenderer->FrameResized(width, height);
258bf215546Sopenharmony_ci		//_UnlockDraw();
259bf215546Sopenharmony_ci	}
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci	BView::FrameResized(width, height);
262bf215546Sopenharmony_ci}
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci
265bf215546Sopenharmony_cistatus_t
266bf215546Sopenharmony_ciBGLView::Perform(perform_code d, void* arg)
267bf215546Sopenharmony_ci{
268bf215546Sopenharmony_ci	return BView::Perform(d, arg);
269bf215546Sopenharmony_ci}
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_cistatus_t
273bf215546Sopenharmony_ciBGLView::Archive(BMessage* data, bool deep) const
274bf215546Sopenharmony_ci{
275bf215546Sopenharmony_ci	return BView::Archive(data, deep);
276bf215546Sopenharmony_ci}
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_civoid
280bf215546Sopenharmony_ciBGLView::MessageReceived(BMessage* msg)
281bf215546Sopenharmony_ci{
282bf215546Sopenharmony_ci	BView::MessageReceived(msg);
283bf215546Sopenharmony_ci}
284bf215546Sopenharmony_ci
285bf215546Sopenharmony_ci
286bf215546Sopenharmony_civoid
287bf215546Sopenharmony_ciBGLView::SetResizingMode(uint32 mode)
288bf215546Sopenharmony_ci{
289bf215546Sopenharmony_ci	BView::SetResizingMode(mode);
290bf215546Sopenharmony_ci}
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_civoid
294bf215546Sopenharmony_ciBGLView::GetPreferredSize(float* _width, float* _height)
295bf215546Sopenharmony_ci{
296bf215546Sopenharmony_ci	if (_width)
297bf215546Sopenharmony_ci		*_width = 0;
298bf215546Sopenharmony_ci	if (_height)
299bf215546Sopenharmony_ci		*_height = 0;
300bf215546Sopenharmony_ci}
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_civoid
304bf215546Sopenharmony_ciBGLView::Show()
305bf215546Sopenharmony_ci{
306bf215546Sopenharmony_ci	BView::Show();
307bf215546Sopenharmony_ci}
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_civoid
311bf215546Sopenharmony_ciBGLView::Hide()
312bf215546Sopenharmony_ci{
313bf215546Sopenharmony_ci	BView::Hide();
314bf215546Sopenharmony_ci}
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ciBHandler*
318bf215546Sopenharmony_ciBGLView::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier,
319bf215546Sopenharmony_ci	int32 form, const char* property)
320bf215546Sopenharmony_ci{
321bf215546Sopenharmony_ci	return BView::ResolveSpecifier(msg, index, specifier, form, property);
322bf215546Sopenharmony_ci}
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_cistatus_t
326bf215546Sopenharmony_ciBGLView::GetSupportedSuites(BMessage* data)
327bf215546Sopenharmony_ci{
328bf215546Sopenharmony_ci	return BView::GetSupportedSuites(data);
329bf215546Sopenharmony_ci}
330bf215546Sopenharmony_ci
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_civoid
333bf215546Sopenharmony_ciBGLView::DirectConnected(direct_buffer_info* info)
334bf215546Sopenharmony_ci{
335bf215546Sopenharmony_ci	printf("BGLView::DirectConnected\n");
336bf215546Sopenharmony_ci	if (fClipInfo == NULL) {
337bf215546Sopenharmony_ci		fClipInfo = new (std::nothrow) glview_direct_info();
338bf215546Sopenharmony_ci		if (fClipInfo == NULL)
339bf215546Sopenharmony_ci			return;
340bf215546Sopenharmony_ci	}
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_ci	direct_buffer_info* localInfo = fClipInfo->direct_info;
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci	_LockDraw();
345bf215546Sopenharmony_ci	switch (info->buffer_state & B_DIRECT_MODE_MASK) {
346bf215546Sopenharmony_ci		case B_DIRECT_START:
347bf215546Sopenharmony_ci			fClipInfo->direct_connected = true;
348bf215546Sopenharmony_ci			memcpy(localInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE);
349bf215546Sopenharmony_ci			break;
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci		case B_DIRECT_MODIFY:
352bf215546Sopenharmony_ci			memcpy(localInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE);
353bf215546Sopenharmony_ci			break;
354bf215546Sopenharmony_ci
355bf215546Sopenharmony_ci		case B_DIRECT_STOP:
356bf215546Sopenharmony_ci			fClipInfo->direct_connected = false;
357bf215546Sopenharmony_ci			break;
358bf215546Sopenharmony_ci	}
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci	if (fRenderer)
361bf215546Sopenharmony_ci		_CallDirectConnected();
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci	_UnlockDraw();
364bf215546Sopenharmony_ci}
365bf215546Sopenharmony_ci
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_civoid
368bf215546Sopenharmony_ciBGLView::EnableDirectMode(bool enabled)
369bf215546Sopenharmony_ci{
370bf215546Sopenharmony_ci	printf("BGLView::EnableDirectMode: %d\n", (int)enabled);
371bf215546Sopenharmony_ci	if (fRenderer)
372bf215546Sopenharmony_ci		fRenderer->EnableDirectMode(enabled);
373bf215546Sopenharmony_ci	if (fClipInfo == NULL) {
374bf215546Sopenharmony_ci		fClipInfo = new (std::nothrow) glview_direct_info();
375bf215546Sopenharmony_ci		if (fClipInfo == NULL)
376bf215546Sopenharmony_ci			return;
377bf215546Sopenharmony_ci	}
378bf215546Sopenharmony_ci
379bf215546Sopenharmony_ci	fClipInfo->enable_direct_mode = enabled;
380bf215546Sopenharmony_ci}
381bf215546Sopenharmony_ci
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_civoid
384bf215546Sopenharmony_ciBGLView::_LockDraw()
385bf215546Sopenharmony_ci{
386bf215546Sopenharmony_ci	if (!fClipInfo || !fClipInfo->enable_direct_mode)
387bf215546Sopenharmony_ci		return;
388bf215546Sopenharmony_ci
389bf215546Sopenharmony_ci	fDrawLock.Lock();
390bf215546Sopenharmony_ci}
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_civoid
394bf215546Sopenharmony_ciBGLView::_UnlockDraw()
395bf215546Sopenharmony_ci{
396bf215546Sopenharmony_ci	if (!fClipInfo || !fClipInfo->enable_direct_mode)
397bf215546Sopenharmony_ci		return;
398bf215546Sopenharmony_ci
399bf215546Sopenharmony_ci	fDrawLock.Unlock();
400bf215546Sopenharmony_ci}
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci
403bf215546Sopenharmony_civoid
404bf215546Sopenharmony_ciBGLView::_CallDirectConnected()
405bf215546Sopenharmony_ci{
406bf215546Sopenharmony_ci	if (!fClipInfo || !fClipInfo->direct_connected) {
407bf215546Sopenharmony_ci		fRenderer->DirectConnected(NULL);
408bf215546Sopenharmony_ci		return;
409bf215546Sopenharmony_ci	}
410bf215546Sopenharmony_ci
411bf215546Sopenharmony_ci	direct_buffer_info* localInfo = fClipInfo->direct_info;
412bf215546Sopenharmony_ci	direct_buffer_info* info = (direct_buffer_info*)malloc(
413bf215546Sopenharmony_ci		DIRECT_BUFFER_INFO_AREA_SIZE);
414bf215546Sopenharmony_ci	if (info == NULL)
415bf215546Sopenharmony_ci		return;
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci	memcpy(info, localInfo, DIRECT_BUFFER_INFO_AREA_SIZE);
418bf215546Sopenharmony_ci
419bf215546Sopenharmony_ci	// Collect the rects into a BRegion, then clip to the view's bounds
420bf215546Sopenharmony_ci	BRegion region;
421bf215546Sopenharmony_ci	for (uint32 c = 0; c < localInfo->clip_list_count; c++)
422bf215546Sopenharmony_ci		region.Include(localInfo->clip_list[c]);
423bf215546Sopenharmony_ci	BRegion boundsRegion = fBounds.OffsetByCopy(localInfo->window_bounds.left,
424bf215546Sopenharmony_ci		localInfo->window_bounds.top);
425bf215546Sopenharmony_ci	info->window_bounds = boundsRegion.RectAtInt(0);
426bf215546Sopenharmony_ci		// window_bounds are now view bounds
427bf215546Sopenharmony_ci	region.IntersectWith(&boundsRegion);
428bf215546Sopenharmony_ci
429bf215546Sopenharmony_ci	info->clip_list_count = region.CountRects();
430bf215546Sopenharmony_ci	info->clip_bounds = region.FrameInt();
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci	for (uint32 c = 0; c < info->clip_list_count; c++)
433bf215546Sopenharmony_ci		info->clip_list[c] = region.RectAtInt(c);
434bf215546Sopenharmony_ci	fRenderer->DirectConnected(info);
435bf215546Sopenharmony_ci	free(info);
436bf215546Sopenharmony_ci}
437bf215546Sopenharmony_ci
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_ci//---- virtual reserved methods ----------
440bf215546Sopenharmony_ci
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_civoid BGLView::_ReservedGLView1() {}
443bf215546Sopenharmony_civoid BGLView::_ReservedGLView2() {}
444bf215546Sopenharmony_civoid BGLView::_ReservedGLView3() {}
445bf215546Sopenharmony_civoid BGLView::_ReservedGLView4() {}
446bf215546Sopenharmony_civoid BGLView::_ReservedGLView5() {}
447bf215546Sopenharmony_civoid BGLView::_ReservedGLView6() {}
448bf215546Sopenharmony_civoid BGLView::_ReservedGLView7() {}
449bf215546Sopenharmony_civoid BGLView::_ReservedGLView8() {}
450bf215546Sopenharmony_ci
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci// #pragma mark -
453bf215546Sopenharmony_ci
454bf215546Sopenharmony_ci
455bf215546Sopenharmony_ci// BeOS compatibility: contrary to others BView's contructors,
456bf215546Sopenharmony_ci// BGLView one wants a non-const name argument.
457bf215546Sopenharmony_ciBGLView::BGLView(BRect rect, char* name, ulong resizingMode, ulong mode,
458bf215546Sopenharmony_ci	ulong options)
459bf215546Sopenharmony_ci	:
460bf215546Sopenharmony_ci	BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS),
461bf215546Sopenharmony_ci	fGc(NULL),
462bf215546Sopenharmony_ci	fOptions(options),
463bf215546Sopenharmony_ci	fDitherCount(0),
464bf215546Sopenharmony_ci	fDrawLock("BGLView draw lock"),
465bf215546Sopenharmony_ci	fDisplayLock("BGLView display lock"),
466bf215546Sopenharmony_ci	fClipInfo(NULL),
467bf215546Sopenharmony_ci	fRenderer(NULL),
468bf215546Sopenharmony_ci	fDitherMap(NULL)
469bf215546Sopenharmony_ci{
470bf215546Sopenharmony_ci	fRenderer = GLRendererRoster::Roster()->GetRenderer(this, options);
471bf215546Sopenharmony_ci}
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci
474bf215546Sopenharmony_ci#if 0
475bf215546Sopenharmony_ci// TODO: implement BGLScreen class...
476bf215546Sopenharmony_ci
477bf215546Sopenharmony_ci
478bf215546Sopenharmony_ciBGLScreen::BGLScreen(char* name, ulong screenMode, ulong options,
479bf215546Sopenharmony_ci		status_t* error, bool debug)
480bf215546Sopenharmony_ci	:
481bf215546Sopenharmony_ci	BWindowScreen(name, screenMode, error, debug)
482bf215546Sopenharmony_ci{
483bf215546Sopenharmony_ci}
484bf215546Sopenharmony_ci
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_ciBGLScreen::~BGLScreen()
487bf215546Sopenharmony_ci{
488bf215546Sopenharmony_ci}
489bf215546Sopenharmony_ci
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_civoid
492bf215546Sopenharmony_ciBGLScreen::LockGL()
493bf215546Sopenharmony_ci{
494bf215546Sopenharmony_ci}
495bf215546Sopenharmony_ci
496bf215546Sopenharmony_ci
497bf215546Sopenharmony_civoid
498bf215546Sopenharmony_ciBGLScreen::UnlockGL()
499bf215546Sopenharmony_ci{
500bf215546Sopenharmony_ci}
501bf215546Sopenharmony_ci
502bf215546Sopenharmony_ci
503bf215546Sopenharmony_civoid
504bf215546Sopenharmony_ciBGLScreen::SwapBuffers()
505bf215546Sopenharmony_ci{
506bf215546Sopenharmony_ci}
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci
509bf215546Sopenharmony_civoid
510bf215546Sopenharmony_ciBGLScreen::ErrorCallback(unsigned long errorCode)
511bf215546Sopenharmony_ci{
512bf215546Sopenharmony_ci	// Mesa's GLenum is not ulong but uint!
513bf215546Sopenharmony_ci	char msg[32];
514bf215546Sopenharmony_ci	sprintf(msg, "GL: Error code $%04lx.", errorCode);
515bf215546Sopenharmony_ci	// debugger(msg);
516bf215546Sopenharmony_ci	fprintf(stderr, "%s\n", msg);
517bf215546Sopenharmony_ci	return;
518bf215546Sopenharmony_ci}
519bf215546Sopenharmony_ci
520bf215546Sopenharmony_ci
521bf215546Sopenharmony_civoid
522bf215546Sopenharmony_ciBGLScreen::ScreenConnected(bool enabled)
523bf215546Sopenharmony_ci{
524bf215546Sopenharmony_ci}
525bf215546Sopenharmony_ci
526bf215546Sopenharmony_ci
527bf215546Sopenharmony_civoid
528bf215546Sopenharmony_ciBGLScreen::FrameResized(float width, float height)
529bf215546Sopenharmony_ci{
530bf215546Sopenharmony_ci	return BWindowScreen::FrameResized(width, height);
531bf215546Sopenharmony_ci}
532bf215546Sopenharmony_ci
533bf215546Sopenharmony_ci
534bf215546Sopenharmony_cistatus_t
535bf215546Sopenharmony_ciBGLScreen::Perform(perform_code d, void* arg)
536bf215546Sopenharmony_ci{
537bf215546Sopenharmony_ci	return BWindowScreen::Perform(d, arg);
538bf215546Sopenharmony_ci}
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci
541bf215546Sopenharmony_cistatus_t
542bf215546Sopenharmony_ciBGLScreen::Archive(BMessage* data, bool deep) const
543bf215546Sopenharmony_ci{
544bf215546Sopenharmony_ci	return BWindowScreen::Archive(data, deep);
545bf215546Sopenharmony_ci}
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci
548bf215546Sopenharmony_civoid
549bf215546Sopenharmony_ciBGLScreen::MessageReceived(BMessage* msg)
550bf215546Sopenharmony_ci{
551bf215546Sopenharmony_ci	BWindowScreen::MessageReceived(msg);
552bf215546Sopenharmony_ci}
553bf215546Sopenharmony_ci
554bf215546Sopenharmony_ci
555bf215546Sopenharmony_civoid
556bf215546Sopenharmony_ciBGLScreen::Show()
557bf215546Sopenharmony_ci{
558bf215546Sopenharmony_ci	BWindowScreen::Show();
559bf215546Sopenharmony_ci}
560bf215546Sopenharmony_ci
561bf215546Sopenharmony_ci
562bf215546Sopenharmony_civoid
563bf215546Sopenharmony_ciBGLScreen::Hide()
564bf215546Sopenharmony_ci{
565bf215546Sopenharmony_ci	BWindowScreen::Hide();
566bf215546Sopenharmony_ci}
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_ci
569bf215546Sopenharmony_ciBHandler*
570bf215546Sopenharmony_ciBGLScreen::ResolveSpecifier(BMessage* msg, int32 index, BMessage* specifier,
571bf215546Sopenharmony_ci	int32 form, const char* property)
572bf215546Sopenharmony_ci{
573bf215546Sopenharmony_ci	return BWindowScreen::ResolveSpecifier(msg, index, specifier,
574bf215546Sopenharmony_ci		form, property);
575bf215546Sopenharmony_ci}
576bf215546Sopenharmony_ci
577bf215546Sopenharmony_ci
578bf215546Sopenharmony_cistatus_t
579bf215546Sopenharmony_ciBGLScreen::GetSupportedSuites(BMessage* data)
580bf215546Sopenharmony_ci{
581bf215546Sopenharmony_ci	return BWindowScreen::GetSupportedSuites(data);
582bf215546Sopenharmony_ci}
583bf215546Sopenharmony_ci
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_ci//---- virtual reserved methods ----------
586bf215546Sopenharmony_ci
587bf215546Sopenharmony_civoid BGLScreen::_ReservedGLScreen1() {}
588bf215546Sopenharmony_civoid BGLScreen::_ReservedGLScreen2() {}
589bf215546Sopenharmony_civoid BGLScreen::_ReservedGLScreen3() {}
590bf215546Sopenharmony_civoid BGLScreen::_ReservedGLScreen4() {}
591bf215546Sopenharmony_civoid BGLScreen::_ReservedGLScreen5() {}
592bf215546Sopenharmony_civoid BGLScreen::_ReservedGLScreen6() {}
593bf215546Sopenharmony_civoid BGLScreen::_ReservedGLScreen7() {}
594bf215546Sopenharmony_civoid BGLScreen::_ReservedGLScreen8() {}
595bf215546Sopenharmony_ci#endif
596bf215546Sopenharmony_ci
597bf215546Sopenharmony_ci
598bf215546Sopenharmony_ciconst char* color_space_name(color_space space)
599bf215546Sopenharmony_ci{
600bf215546Sopenharmony_ci#define C2N(a)	case a:	return #a
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_ci	switch (space) {
603bf215546Sopenharmony_ci	C2N(B_RGB24);
604bf215546Sopenharmony_ci	C2N(B_RGB32);
605bf215546Sopenharmony_ci	C2N(B_RGBA32);
606bf215546Sopenharmony_ci	C2N(B_RGB32_BIG);
607bf215546Sopenharmony_ci	C2N(B_RGBA32_BIG);
608bf215546Sopenharmony_ci	C2N(B_GRAY8);
609bf215546Sopenharmony_ci	C2N(B_GRAY1);
610bf215546Sopenharmony_ci	C2N(B_RGB16);
611bf215546Sopenharmony_ci	C2N(B_RGB15);
612bf215546Sopenharmony_ci	C2N(B_RGBA15);
613bf215546Sopenharmony_ci	C2N(B_CMAP8);
614bf215546Sopenharmony_ci	default:
615bf215546Sopenharmony_ci		return "Unknown!";
616bf215546Sopenharmony_ci	};
617bf215546Sopenharmony_ci
618bf215546Sopenharmony_ci#undef C2N
619bf215546Sopenharmony_ci};
620bf215546Sopenharmony_ci
621bf215546Sopenharmony_ci
622bf215546Sopenharmony_ciglview_direct_info::glview_direct_info()
623bf215546Sopenharmony_ci{
624bf215546Sopenharmony_ci	// TODO: See direct_window_data() in app_server's ServerWindow.cpp
625bf215546Sopenharmony_ci	direct_info = (direct_buffer_info*)calloc(1, DIRECT_BUFFER_INFO_AREA_SIZE);
626bf215546Sopenharmony_ci	direct_connected = false;
627bf215546Sopenharmony_ci	enable_direct_mode = false;
628bf215546Sopenharmony_ci}
629bf215546Sopenharmony_ci
630bf215546Sopenharmony_ci
631bf215546Sopenharmony_ciglview_direct_info::~glview_direct_info()
632bf215546Sopenharmony_ci{
633bf215546Sopenharmony_ci	free(direct_info);
634bf215546Sopenharmony_ci}
635bf215546Sopenharmony_ci
636