109ea3092SStefano Ceccherini /*
2*37fedaf8SJohn Scipione * Copyright 2003-2009 Haiku, Inc. All rights reserved.
3*37fedaf8SJohn Scipione * Distributed under the terms of the MIT License.
4*37fedaf8SJohn Scipione *
517495d0bSStefano Ceccherini * Authors:
6d9cebac2SStefano Ceccherini * Stefano Ceccherini <stefano.ceccherini@gmail.com>
7d9cebac2SStefano Ceccherini * Carwyn Jones <turok2@currantbun.com>
809ea3092SStefano Ceccherini */
90b4a36abSbeveloper
102c704682SAxel Dörfler
11cafaa5aaSStefano Ceccherini #include <DirectWindow.h>
122c704682SAxel Dörfler
132c704682SAxel Dörfler #include <stdio.h>
142c704682SAxel Dörfler #include <string.h>
152c704682SAxel Dörfler
164fbc3f58SStefano Ceccherini #include <Screen.h>
1771b55088SAxel Dörfler
18cafaa5aaSStefano Ceccherini #include <clipping.h>
19feee8cf2SStefano Ceccherini #include <AppServerLink.h>
202b6ac345SStefano Ceccherini #include <DirectWindowPrivate.h>
21feee8cf2SStefano Ceccherini #include <ServerProtocol.h>
22764ac9e5SAxel Dörfler
2397cccf16SStefano Ceccherini
2497cccf16SStefano Ceccherini //#define DEBUG 1
252c704682SAxel Dörfler #define OUTPUT printf
262c704682SAxel Dörfler //#define OUTPUT debug_printf
2797cccf16SStefano Ceccherini
28764ac9e5SAxel Dörfler
29af294326SPhilippe Houdoin // We don't need this kind of locking, since the directDaemonFunc
30cafaa5aaSStefano Ceccherini // doesn't access critical shared data.
31cafaa5aaSStefano Ceccherini #define DW_NEEDS_LOCKING 0
32cafaa5aaSStefano Ceccherini
33cafaa5aaSStefano Ceccherini enum dw_status_bits {
3417495d0bSStefano Ceccherini DW_STATUS_AREA_CLONED = 0x1,
3517495d0bSStefano Ceccherini DW_STATUS_THREAD_STARTED = 0x2,
3617495d0bSStefano Ceccherini DW_STATUS_SEM_CREATED = 0x4
37cafaa5aaSStefano Ceccherini };
38cafaa5aaSStefano Ceccherini
39cafaa5aaSStefano Ceccherini
405115ca08SStefano Ceccherini #if DEBUG
412c704682SAxel Dörfler
422c704682SAxel Dörfler
435115ca08SStefano Ceccherini static void
print_direct_buffer_state(const direct_buffer_state & state)445115ca08SStefano Ceccherini print_direct_buffer_state(const direct_buffer_state &state)
455115ca08SStefano Ceccherini {
465115ca08SStefano Ceccherini char string[128];
475115ca08SStefano Ceccherini int modeState = state & B_DIRECT_MODE_MASK;
48652f187eSStefano Ceccherini if (modeState == B_DIRECT_START)
495115ca08SStefano Ceccherini strcpy(string, "B_DIRECT_START");
50652f187eSStefano Ceccherini else if (modeState == B_DIRECT_MODIFY)
515115ca08SStefano Ceccherini strcpy(string, "B_DIRECT_MODIFY");
52652f187eSStefano Ceccherini else if (modeState == B_DIRECT_STOP)
535115ca08SStefano Ceccherini strcpy(string, "B_DIRECT_STOP");
545115ca08SStefano Ceccherini
555115ca08SStefano Ceccherini if (state & B_CLIPPING_MODIFIED)
565115ca08SStefano Ceccherini strcat(string, " | B_CLIPPING_MODIFIED");
575115ca08SStefano Ceccherini if (state & B_BUFFER_RESIZED)
585115ca08SStefano Ceccherini strcat(string, " | B_BUFFER_RESIZED");
595115ca08SStefano Ceccherini if (state & B_BUFFER_MOVED)
605115ca08SStefano Ceccherini strcat(string, " | B_BUFFER_MOVED");
615115ca08SStefano Ceccherini if (state & B_BUFFER_RESET)
625115ca08SStefano Ceccherini strcat(string, " | B_BUFFER_RESET");
635115ca08SStefano Ceccherini
642c704682SAxel Dörfler OUTPUT("direct_buffer_state: %s\n", string);
655115ca08SStefano Ceccherini }
665115ca08SStefano Ceccherini
675115ca08SStefano Ceccherini
685115ca08SStefano Ceccherini static void
print_direct_driver_state(const direct_driver_state & state)695115ca08SStefano Ceccherini print_direct_driver_state(const direct_driver_state &state)
705115ca08SStefano Ceccherini {
715115ca08SStefano Ceccherini if (state == 0)
725115ca08SStefano Ceccherini return;
735115ca08SStefano Ceccherini
745115ca08SStefano Ceccherini char string[64];
755115ca08SStefano Ceccherini if (state == B_DRIVER_CHANGED)
765115ca08SStefano Ceccherini strcpy(string, "B_DRIVER_CHANGED");
775115ca08SStefano Ceccherini else if (state == B_MODE_CHANGED)
785115ca08SStefano Ceccherini strcpy(string, "B_MODE_CHANGED");
795115ca08SStefano Ceccherini
802c704682SAxel Dörfler OUTPUT("direct_driver_state: %s\n", string);
815115ca08SStefano Ceccherini }
825115ca08SStefano Ceccherini
835115ca08SStefano Ceccherini
842c704682SAxel Dörfler #if DEBUG > 1
852c704682SAxel Dörfler
862c704682SAxel Dörfler
875115ca08SStefano Ceccherini static void
print_direct_buffer_layout(const buffer_layout & layout)8828fa0645SStefano Ceccherini print_direct_buffer_layout(const buffer_layout &layout)
8928fa0645SStefano Ceccherini {
9028fa0645SStefano Ceccherini char string[64];
9128fa0645SStefano Ceccherini if (layout == B_BUFFER_NONINTERLEAVED)
9228fa0645SStefano Ceccherini strcpy(string, "B_BUFFER_NONINTERLEAVED");
9328fa0645SStefano Ceccherini else
9428fa0645SStefano Ceccherini strcpy(string, "unknown");
9528fa0645SStefano Ceccherini
962c704682SAxel Dörfler OUTPUT("layout: %s\n", string);
9728fa0645SStefano Ceccherini }
9828fa0645SStefano Ceccherini
9928fa0645SStefano Ceccherini
10028fa0645SStefano Ceccherini static void
print_direct_buffer_orientation(const buffer_orientation & orientation)10128fa0645SStefano Ceccherini print_direct_buffer_orientation(const buffer_orientation &orientation)
10228fa0645SStefano Ceccherini {
10328fa0645SStefano Ceccherini char string[64];
10428fa0645SStefano Ceccherini switch (orientation) {
10528fa0645SStefano Ceccherini case B_BUFFER_TOP_TO_BOTTOM:
10628fa0645SStefano Ceccherini strcpy(string, "B_BUFFER_TOP_TO_BOTTOM");
10728fa0645SStefano Ceccherini break;
10828fa0645SStefano Ceccherini case B_BUFFER_BOTTOM_TO_TOP:
10928fa0645SStefano Ceccherini strcpy(string, "B_BUFFER_BOTTOM_TO_TOP");
11028fa0645SStefano Ceccherini break;
11128fa0645SStefano Ceccherini default:
11228fa0645SStefano Ceccherini strcpy(string, "unknown");
11328fa0645SStefano Ceccherini break;
11428fa0645SStefano Ceccherini }
11528fa0645SStefano Ceccherini
1162c704682SAxel Dörfler OUTPUT("orientation: %s\n", string);
11728fa0645SStefano Ceccherini }
11828fa0645SStefano Ceccherini
11928fa0645SStefano Ceccherini
1202c704682SAxel Dörfler #endif // DEBUG > 2
1212c704682SAxel Dörfler
1222c704682SAxel Dörfler
12328fa0645SStefano Ceccherini static void
print_direct_buffer_info(const direct_buffer_info & info)1245115ca08SStefano Ceccherini print_direct_buffer_info(const direct_buffer_info &info)
1255115ca08SStefano Ceccherini {
1265115ca08SStefano Ceccherini print_direct_buffer_state(info.buffer_state);
1275115ca08SStefano Ceccherini print_direct_driver_state(info.driver_state);
12828fa0645SStefano Ceccherini
12928fa0645SStefano Ceccherini # if DEBUG > 1
1302c704682SAxel Dörfler OUTPUT("bits: %p\n", info.bits);
1312c704682SAxel Dörfler OUTPUT("pci_bits: %p\n", info.pci_bits);
1322c704682SAxel Dörfler OUTPUT("bytes_per_row: %ld\n", info.bytes_per_row);
1332c704682SAxel Dörfler OUTPUT("bits_per_pixel: %lu\n", info.bits_per_pixel);
1342c704682SAxel Dörfler OUTPUT("pixel_format: %d\n", info.pixel_format);
13528fa0645SStefano Ceccherini print_direct_buffer_layout(info.layout);
13628fa0645SStefano Ceccherini print_direct_buffer_orientation(info.orientation);
13728fa0645SStefano Ceccherini
13828fa0645SStefano Ceccherini # if DEBUG > 2
1392c704682SAxel Dörfler // TODO: this won't work correctly with debug_printf()
14028fa0645SStefano Ceccherini printf("CLIPPING INFO:\n");
14128fa0645SStefano Ceccherini printf("clipping_rects count: %ld\n", info.clip_list_count);
14228fa0645SStefano Ceccherini
14328fa0645SStefano Ceccherini printf("- window_bounds:\n");
14428fa0645SStefano Ceccherini BRegion region;
14528fa0645SStefano Ceccherini region.Set(info.window_bounds);
14628fa0645SStefano Ceccherini region.PrintToStream();
14728fa0645SStefano Ceccherini
14828fa0645SStefano Ceccherini region.MakeEmpty();
14928fa0645SStefano Ceccherini for (uint32 i = 0; i < info.clip_list_count; i++)
15028fa0645SStefano Ceccherini region.Include(info.clip_list[i]);
15128fa0645SStefano Ceccherini
15228fa0645SStefano Ceccherini printf("- clip_list:\n");
15328fa0645SStefano Ceccherini region.PrintToStream();
15428fa0645SStefano Ceccherini # endif
15528fa0645SStefano Ceccherini # endif
15628fa0645SStefano Ceccherini
1572c704682SAxel Dörfler OUTPUT("\n");
1585115ca08SStefano Ceccherini }
1595115ca08SStefano Ceccherini
1602c704682SAxel Dörfler
1612c704682SAxel Dörfler #endif // DEBUG
1622c704682SAxel Dörfler
1632c704682SAxel Dörfler
1642c704682SAxel Dörfler // #pragma mark -
1655115ca08SStefano Ceccherini
16628fa0645SStefano Ceccherini
BDirectWindow(BRect frame,const char * title,window_type type,uint32 flags,uint32 workspace)167764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char* title, window_type type,
168764ac9e5SAxel Dörfler uint32 flags, uint32 workspace)
1692c704682SAxel Dörfler :
1702c704682SAxel Dörfler BWindow(frame, title, type, flags, workspace)
171cafaa5aaSStefano Ceccherini {
172d9cebac2SStefano Ceccherini _InitData();
1730b4a36abSbeveloper }
1740b4a36abSbeveloper
1750b4a36abSbeveloper
BDirectWindow(BRect frame,const char * title,window_look look,window_feel feel,uint32 flags,uint32 workspace)176764ac9e5SAxel Dörfler BDirectWindow::BDirectWindow(BRect frame, const char* title, window_look look,
177764ac9e5SAxel Dörfler window_feel feel, uint32 flags, uint32 workspace)
1782c704682SAxel Dörfler :
1792c704682SAxel Dörfler BWindow(frame, title, look, feel, flags, workspace)
1800b4a36abSbeveloper {
181d9cebac2SStefano Ceccherini _InitData();
1820b4a36abSbeveloper }
1830b4a36abSbeveloper
1840b4a36abSbeveloper
~BDirectWindow()1850b4a36abSbeveloper BDirectWindow::~BDirectWindow()
1860b4a36abSbeveloper {
187d9cebac2SStefano Ceccherini _DisposeData();
1880b4a36abSbeveloper }
1890b4a36abSbeveloper
1900b4a36abSbeveloper
1912c704682SAxel Dörfler // #pragma mark - BWindow API implementation
1922c704682SAxel Dörfler
1932c704682SAxel Dörfler
1940b4a36abSbeveloper BArchivable*
Instantiate(BMessage * data)1950b4a36abSbeveloper BDirectWindow::Instantiate(BMessage* data)
1960b4a36abSbeveloper {
1970b4a36abSbeveloper return NULL;
1980b4a36abSbeveloper }
1990b4a36abSbeveloper
2000b4a36abSbeveloper
2010b4a36abSbeveloper status_t
Archive(BMessage * data,bool deep) const202cafaa5aaSStefano Ceccherini BDirectWindow::Archive(BMessage* data, bool deep) const
2030b4a36abSbeveloper {
204cafaa5aaSStefano Ceccherini return inherited::Archive(data, deep);
2050b4a36abSbeveloper }
2060b4a36abSbeveloper
2070b4a36abSbeveloper
2080b4a36abSbeveloper void
Quit()209cafaa5aaSStefano Ceccherini BDirectWindow::Quit()
2100b4a36abSbeveloper {
211cafaa5aaSStefano Ceccherini inherited::Quit();
2120b4a36abSbeveloper }
2130b4a36abSbeveloper
2140b4a36abSbeveloper
2150b4a36abSbeveloper void
DispatchMessage(BMessage * message,BHandler * handler)216cafaa5aaSStefano Ceccherini BDirectWindow::DispatchMessage(BMessage* message, BHandler* handler)
2170b4a36abSbeveloper {
218cafaa5aaSStefano Ceccherini inherited::DispatchMessage(message, handler);
2190b4a36abSbeveloper }
2200b4a36abSbeveloper
2210b4a36abSbeveloper
2220b4a36abSbeveloper void
MessageReceived(BMessage * message)2230b4a36abSbeveloper BDirectWindow::MessageReceived(BMessage* message)
2240b4a36abSbeveloper {
225cafaa5aaSStefano Ceccherini inherited::MessageReceived(message);
2260b4a36abSbeveloper }
2270b4a36abSbeveloper
2280b4a36abSbeveloper
2290b4a36abSbeveloper void
FrameMoved(BPoint newPosition)230d9cebac2SStefano Ceccherini BDirectWindow::FrameMoved(BPoint newPosition)
2310b4a36abSbeveloper {
232d9cebac2SStefano Ceccherini inherited::FrameMoved(newPosition);
2330b4a36abSbeveloper }
2340b4a36abSbeveloper
2350b4a36abSbeveloper
2360b4a36abSbeveloper void
WorkspacesChanged(uint32 oldWorkspaces,uint32 newWorkspaces)237d9cebac2SStefano Ceccherini BDirectWindow::WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces)
2380b4a36abSbeveloper {
239d9cebac2SStefano Ceccherini inherited::WorkspacesChanged(oldWorkspaces, newWorkspaces);
2400b4a36abSbeveloper }
2410b4a36abSbeveloper
2420b4a36abSbeveloper
2430b4a36abSbeveloper void
WorkspaceActivated(int32 index,bool state)244d9cebac2SStefano Ceccherini BDirectWindow::WorkspaceActivated(int32 index, bool state)
2450b4a36abSbeveloper {
246d9cebac2SStefano Ceccherini inherited::WorkspaceActivated(index, state);
2470b4a36abSbeveloper }
2480b4a36abSbeveloper
2490b4a36abSbeveloper
2500b4a36abSbeveloper void
FrameResized(float newWidth,float newHeight)251d9cebac2SStefano Ceccherini BDirectWindow::FrameResized(float newWidth, float newHeight)
2520b4a36abSbeveloper {
253d9cebac2SStefano Ceccherini inherited::FrameResized(newWidth, newHeight);
2540b4a36abSbeveloper }
2550b4a36abSbeveloper
2560b4a36abSbeveloper
2570b4a36abSbeveloper void
Minimize(bool minimize)2580b4a36abSbeveloper BDirectWindow::Minimize(bool minimize)
2590b4a36abSbeveloper {
260cafaa5aaSStefano Ceccherini inherited::Minimize(minimize);
2610b4a36abSbeveloper }
2620b4a36abSbeveloper
2630b4a36abSbeveloper
2640b4a36abSbeveloper void
Zoom(BPoint recPosition,float recWidth,float recHeight)265d9cebac2SStefano Ceccherini BDirectWindow::Zoom(BPoint recPosition, float recWidth, float recHeight)
2660b4a36abSbeveloper {
267d9cebac2SStefano Ceccherini inherited::Zoom(recPosition, recWidth, recHeight);
2680b4a36abSbeveloper }
2690b4a36abSbeveloper
2700b4a36abSbeveloper
2710b4a36abSbeveloper void
ScreenChanged(BRect screenFrame,color_space depth)272d9cebac2SStefano Ceccherini BDirectWindow::ScreenChanged(BRect screenFrame, color_space depth)
2730b4a36abSbeveloper {
274d9cebac2SStefano Ceccherini inherited::ScreenChanged(screenFrame, depth);
2750b4a36abSbeveloper }
2760b4a36abSbeveloper
2770b4a36abSbeveloper
2780b4a36abSbeveloper void
MenusBeginning()2790b4a36abSbeveloper BDirectWindow::MenusBeginning()
2800b4a36abSbeveloper {
281cafaa5aaSStefano Ceccherini inherited::MenusBeginning();
2820b4a36abSbeveloper }
2830b4a36abSbeveloper
2840b4a36abSbeveloper
2850b4a36abSbeveloper void
MenusEnded()2860b4a36abSbeveloper BDirectWindow::MenusEnded()
2870b4a36abSbeveloper {
288cafaa5aaSStefano Ceccherini inherited::MenusEnded();
2890b4a36abSbeveloper }
2900b4a36abSbeveloper
2910b4a36abSbeveloper
2920b4a36abSbeveloper void
WindowActivated(bool state)2930b4a36abSbeveloper BDirectWindow::WindowActivated(bool state)
2940b4a36abSbeveloper {
295cafaa5aaSStefano Ceccherini inherited::WindowActivated(state);
2960b4a36abSbeveloper }
2970b4a36abSbeveloper
2980b4a36abSbeveloper
2990b4a36abSbeveloper void
Show()3000b4a36abSbeveloper BDirectWindow::Show()
3010b4a36abSbeveloper {
302cafaa5aaSStefano Ceccherini inherited::Show();
3030b4a36abSbeveloper }
3040b4a36abSbeveloper
3050b4a36abSbeveloper
3060b4a36abSbeveloper void
Hide()3070b4a36abSbeveloper BDirectWindow::Hide()
3080b4a36abSbeveloper {
309cafaa5aaSStefano Ceccherini inherited::Hide();
3100b4a36abSbeveloper }
3110b4a36abSbeveloper
3120b4a36abSbeveloper
3130b4a36abSbeveloper BHandler*
ResolveSpecifier(BMessage * message,int32 index,BMessage * specifier,int32 what,const char * property)314*37fedaf8SJohn Scipione BDirectWindow::ResolveSpecifier(BMessage* message, int32 index,
315*37fedaf8SJohn Scipione BMessage* specifier, int32 what, const char* property)
3160b4a36abSbeveloper {
317*37fedaf8SJohn Scipione return inherited::ResolveSpecifier(message, index, specifier, what,
318*37fedaf8SJohn Scipione property);
3190b4a36abSbeveloper }
3200b4a36abSbeveloper
3210b4a36abSbeveloper
3220b4a36abSbeveloper status_t
GetSupportedSuites(BMessage * data)3230b4a36abSbeveloper BDirectWindow::GetSupportedSuites(BMessage* data)
3240b4a36abSbeveloper {
325cafaa5aaSStefano Ceccherini return inherited::GetSupportedSuites(data);
3260b4a36abSbeveloper }
3270b4a36abSbeveloper
3280b4a36abSbeveloper
3290b4a36abSbeveloper status_t
Perform(perform_code d,void * arg)330cafaa5aaSStefano Ceccherini BDirectWindow::Perform(perform_code d, void* arg)
3310b4a36abSbeveloper {
332cafaa5aaSStefano Ceccherini return inherited::Perform(d, arg);
3330b4a36abSbeveloper }
3340b4a36abSbeveloper
3350b4a36abSbeveloper
336b816dc1eSIngo Weinhold void
task_looper()337b816dc1eSIngo Weinhold BDirectWindow::task_looper()
338b816dc1eSIngo Weinhold {
339cafaa5aaSStefano Ceccherini inherited::task_looper();
340b816dc1eSIngo Weinhold }
341b816dc1eSIngo Weinhold
342cafaa5aaSStefano Ceccherini
343b816dc1eSIngo Weinhold BMessage*
ConvertToMessage(void * raw,int32 code)344b816dc1eSIngo Weinhold BDirectWindow::ConvertToMessage(void* raw, int32 code)
345b816dc1eSIngo Weinhold {
346cafaa5aaSStefano Ceccherini return inherited::ConvertToMessage(raw, code);
347b816dc1eSIngo Weinhold }
3480b4a36abSbeveloper
3490b4a36abSbeveloper
350764ac9e5SAxel Dörfler // #pragma mark - BDirectWindow specific API
351764ac9e5SAxel Dörfler
352764ac9e5SAxel Dörfler
3530b4a36abSbeveloper void
DirectConnected(direct_buffer_info * info)3540b4a36abSbeveloper BDirectWindow::DirectConnected(direct_buffer_info* info)
3550b4a36abSbeveloper {
356cafaa5aaSStefano Ceccherini // implemented in subclasses
3570b4a36abSbeveloper }
3580b4a36abSbeveloper
3590b4a36abSbeveloper
3600b4a36abSbeveloper status_t
GetClippingRegion(BRegion * region,BPoint * origin) const361cafaa5aaSStefano Ceccherini BDirectWindow::GetClippingRegion(BRegion* region, BPoint* origin) const
3620b4a36abSbeveloper {
363cafaa5aaSStefano Ceccherini if (region == NULL)
364cafaa5aaSStefano Ceccherini return B_BAD_VALUE;
365cafaa5aaSStefano Ceccherini
366d9cebac2SStefano Ceccherini if (IsLocked() || !_LockDirect())
3675fdea13fSStefano Ceccherini return B_ERROR;
3685fdea13fSStefano Ceccherini
36949d7857eSJulian Harnath if (!fInDirectConnect) {
370d9cebac2SStefano Ceccherini _UnlockDirect();
371cafaa5aaSStefano Ceccherini return B_ERROR;
372cafaa5aaSStefano Ceccherini }
373cafaa5aaSStefano Ceccherini
374cafaa5aaSStefano Ceccherini // BPoint's coordinates are floats. We can only work
3752b73985eSStefano Ceccherini // with integers._DaemonStarter
376cafaa5aaSStefano Ceccherini int32 originX, originY;
377cafaa5aaSStefano Ceccherini if (origin == NULL) {
378cafaa5aaSStefano Ceccherini originX = 0;
379cafaa5aaSStefano Ceccherini originY = 0;
380cafaa5aaSStefano Ceccherini } else {
381cafaa5aaSStefano Ceccherini originX = (int32)origin->x;
382cafaa5aaSStefano Ceccherini originY = (int32)origin->y;
383cafaa5aaSStefano Ceccherini }
384cafaa5aaSStefano Ceccherini
385764ac9e5SAxel Dörfler #ifndef HAIKU_TARGET_PLATFORM_DANO
386cafaa5aaSStefano Ceccherini // Since we are friend of BRegion, we can access its private members.
387cafaa5aaSStefano Ceccherini // Otherwise, we would need to call BRegion::Include(clipping_rect)
388cafaa5aaSStefano Ceccherini // for every clipping_rect in our clip_list, and that would be much
3895fdea13fSStefano Ceccherini // more overkill than this (tested ).
390582da173SStephan Aßmus if (!region->_SetSize(fBufferDesc->clip_list_count)) {
391d9cebac2SStefano Ceccherini _UnlockDirect();
392582da173SStephan Aßmus return B_NO_MEMORY;
393582da173SStephan Aßmus }
394582da173SStephan Aßmus region->fCount = fBufferDesc->clip_list_count;
395ed225430SStephan Aßmus region->fBounds = region->_ConvertToInternal(fBufferDesc->clip_bounds);
396ed225430SStephan Aßmus for (uint32 c = 0; c < fBufferDesc->clip_list_count; c++) {
397ed225430SStephan Aßmus region->fData[c] = region->_ConvertToInternal(
398ed225430SStephan Aßmus fBufferDesc->clip_list[c]);
399ed225430SStephan Aßmus }
400cafaa5aaSStefano Ceccherini
401cafaa5aaSStefano Ceccherini // adjust bounds by the given origin point
4024f6f70e0SStefano Ceccherini region->OffsetBy(-originX, -originY);
403366fdcdfSMarcus Overhagen #endif
404366fdcdfSMarcus Overhagen
405d9cebac2SStefano Ceccherini _UnlockDirect();
406cafaa5aaSStefano Ceccherini
407cafaa5aaSStefano Ceccherini return B_OK;
408cafaa5aaSStefano Ceccherini
4090b4a36abSbeveloper }
4100b4a36abSbeveloper
4110b4a36abSbeveloper
4120b4a36abSbeveloper status_t
SetFullScreen(bool enable)4130b4a36abSbeveloper BDirectWindow::SetFullScreen(bool enable)
4140b4a36abSbeveloper {
4152b73985eSStefano Ceccherini if (fIsFullScreen == enable)
4162b73985eSStefano Ceccherini return B_OK;
4172b73985eSStefano Ceccherini
418cafaa5aaSStefano Ceccherini status_t status = B_ERROR;
41909ea3092SStefano Ceccherini if (Lock()) {
420ab6a6bedSAxel Dörfler fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN);
421feee8cf2SStefano Ceccherini fLink->Attach<bool>(enable);
422feee8cf2SStefano Ceccherini
423ab6a6bedSAxel Dörfler if (fLink->FlushWithReply(status) == B_OK
4249ecf9d1cSIngo Weinhold && status == B_OK) {
4252b73985eSStefano Ceccherini fIsFullScreen = enable;
4269ecf9d1cSIngo Weinhold }
42709ea3092SStefano Ceccherini Unlock();
42809ea3092SStefano Ceccherini }
429cafaa5aaSStefano Ceccherini return status;
4300b4a36abSbeveloper }
4310b4a36abSbeveloper
4320b4a36abSbeveloper
4330b4a36abSbeveloper bool
IsFullScreen() const4340b4a36abSbeveloper BDirectWindow::IsFullScreen() const
4350b4a36abSbeveloper {
4362b73985eSStefano Ceccherini return fIsFullScreen;
4370b4a36abSbeveloper }
4380b4a36abSbeveloper
4390b4a36abSbeveloper
4402c704682SAxel Dörfler /*static*/ bool
SupportsWindowMode(screen_id id)441cafaa5aaSStefano Ceccherini BDirectWindow::SupportsWindowMode(screen_id id)
4420b4a36abSbeveloper {
4432c704682SAxel Dörfler display_mode mode;
4444fbc3f58SStefano Ceccherini status_t status = BScreen(id).GetMode(&mode);
4454fbc3f58SStefano Ceccherini if (status == B_OK)
4462c704682SAxel Dörfler return (mode.flags & B_PARALLEL_ACCESS) != 0;
447feee8cf2SStefano Ceccherini
448fb984c13SStefano Ceccherini return false;
449cafaa5aaSStefano Ceccherini }
450cafaa5aaSStefano Ceccherini
451cafaa5aaSStefano Ceccherini
4520f4fb801SAxel Dörfler // #pragma mark - Private methods
4530f4fb801SAxel Dörfler
4542c704682SAxel Dörfler
4552c704682SAxel Dörfler /*static*/ int32
_daemon_thread(void * arg)456d9cebac2SStefano Ceccherini BDirectWindow::_daemon_thread(void* arg)
4572b73985eSStefano Ceccherini {
458d9cebac2SStefano Ceccherini return static_cast<BDirectWindow*>(arg)->_DirectDaemon();
4592b73985eSStefano Ceccherini }
4602b73985eSStefano Ceccherini
4610f4fb801SAxel Dörfler
462cafaa5aaSStefano Ceccherini int32
_DirectDaemon()463d9cebac2SStefano Ceccherini BDirectWindow::_DirectDaemon()
464cafaa5aaSStefano Ceccherini {
4652b73985eSStefano Ceccherini while (!fDaemonKiller) {
466cafaa5aaSStefano Ceccherini // This sem is released by the app_server when our
467cafaa5aaSStefano Ceccherini // clipping region changes, or when our window is moved,
468cafaa5aaSStefano Ceccherini // resized, etc. etc.
4690f4fb801SAxel Dörfler status_t status;
4700f4fb801SAxel Dörfler do {
4712b73985eSStefano Ceccherini status = acquire_sem(fDisableSem);
4720f4fb801SAxel Dörfler } while (status == B_INTERRUPTED);
4730f4fb801SAxel Dörfler
4742c704682SAxel Dörfler if (status != B_OK) {
475c9ad965cSStefano Ceccherini //fprintf(stderr, "DirectDaemon: failed to acquire direct sem: %s\n",
476c9ad965cSStefano Ceccherini // strerror(status));
4770f4fb801SAxel Dörfler return -1;
47897cccf16SStefano Ceccherini }
479cafaa5aaSStefano Ceccherini
4805115ca08SStefano Ceccherini #if DEBUG
4815115ca08SStefano Ceccherini print_direct_buffer_info(*fBufferDesc);
4825115ca08SStefano Ceccherini #endif
4835115ca08SStefano Ceccherini
484d9cebac2SStefano Ceccherini if (_LockDirect()) {
4852c704682SAxel Dörfler if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK)
4862c704682SAxel Dörfler == B_DIRECT_START)
4872b73985eSStefano Ceccherini fConnectionEnable = true;
488cafaa5aaSStefano Ceccherini
4892b73985eSStefano Ceccherini fInDirectConnect = true;
4902b73985eSStefano Ceccherini DirectConnected(fBufferDesc);
4912b73985eSStefano Ceccherini fInDirectConnect = false;
492cafaa5aaSStefano Ceccherini
4932c704682SAxel Dörfler if ((fBufferDesc->buffer_state & B_DIRECT_MODE_MASK)
4942c704682SAxel Dörfler == B_DIRECT_STOP)
4952b73985eSStefano Ceccherini fConnectionEnable = false;
496cafaa5aaSStefano Ceccherini
497d9cebac2SStefano Ceccherini _UnlockDirect();
498cafaa5aaSStefano Ceccherini }
499cafaa5aaSStefano Ceccherini
500cafaa5aaSStefano Ceccherini // The app_server then waits (with a timeout) on this sem.
501cafaa5aaSStefano Ceccherini // If we aren't quick enough to release this sem, our app
502cafaa5aaSStefano Ceccherini // will be terminated by the app_server
50397cccf16SStefano Ceccherini if ((status = release_sem(fDisableSemAck)) != B_OK) {
504c9ad965cSStefano Ceccherini //fprintf(stderr, "DirectDaemon: failed to release sem: %s\n",
505c9ad965cSStefano Ceccherini //strerror(status));
5060f4fb801SAxel Dörfler return -1;
507cafaa5aaSStefano Ceccherini }
50897cccf16SStefano Ceccherini }
509cafaa5aaSStefano Ceccherini
510cafaa5aaSStefano Ceccherini return 0;
511cafaa5aaSStefano Ceccherini }
512cafaa5aaSStefano Ceccherini
513cafaa5aaSStefano Ceccherini
514cafaa5aaSStefano Ceccherini bool
_LockDirect() const515d9cebac2SStefano Ceccherini BDirectWindow::_LockDirect() const
516cafaa5aaSStefano Ceccherini {
5172c704682SAxel Dörfler // LockDirect() and UnlockDirect() are no-op on BeOS. I tried to call BeOS's
5182c704682SAxel Dörfler // version repeatedly, from the same thread and from different threads,
5192c704682SAxel Dörfler // nothing happened.
5202c704682SAxel Dörfler // They're not needed though, as the direct_daemon_thread doesn't change
5212c704682SAxel Dörfler // any shared data. They are probably here for future enhancements.
522cafaa5aaSStefano Ceccherini status_t status = B_OK;
523cafaa5aaSStefano Ceccherini
524cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
525cafaa5aaSStefano Ceccherini BDirectWindow* casted = const_cast<BDirectWindow*>(this);
526cafaa5aaSStefano Ceccherini
5272b73985eSStefano Ceccherini if (atomic_add(&casted->fDirectLock, 1) > 0) {
528cafaa5aaSStefano Ceccherini do {
529d9cebac2SStefano Ceccherini status = acquire_sem(casted->fDirectSem);
530cafaa5aaSStefano Ceccherini } while (status == B_INTERRUPTED);
5315fdea13fSStefano Ceccherini }
532cafaa5aaSStefano Ceccherini
533cafaa5aaSStefano Ceccherini if (status == B_OK) {
5342b73985eSStefano Ceccherini casted->fDirectLockOwner = find_thread(NULL);
5352b73985eSStefano Ceccherini casted->fDirectLockCount++;
536cafaa5aaSStefano Ceccherini }
537cafaa5aaSStefano Ceccherini #endif
538cafaa5aaSStefano Ceccherini
539cafaa5aaSStefano Ceccherini return status == B_OK;
5400b4a36abSbeveloper }
5410b4a36abSbeveloper
5420b4a36abSbeveloper
5430b4a36abSbeveloper void
_UnlockDirect() const544d9cebac2SStefano Ceccherini BDirectWindow::_UnlockDirect() const
5450b4a36abSbeveloper {
546cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
547cafaa5aaSStefano Ceccherini BDirectWindow* casted = const_cast<BDirectWindow*>(this);
548cafaa5aaSStefano Ceccherini
5492b73985eSStefano Ceccherini if (atomic_add(&casted->fDirectLock, -1) > 1)
5502b73985eSStefano Ceccherini release_sem(casted->fDirectSem);
551cafaa5aaSStefano Ceccherini
5522b73985eSStefano Ceccherini casted->fDirectLockCount--;
553cafaa5aaSStefano Ceccherini #endif
5540b4a36abSbeveloper }
5550b4a36abSbeveloper
5560b4a36abSbeveloper
5570b4a36abSbeveloper void
_InitData()558d9cebac2SStefano Ceccherini BDirectWindow::_InitData()
5590b4a36abSbeveloper {
5602b73985eSStefano Ceccherini fConnectionEnable = false;
5612b73985eSStefano Ceccherini fIsFullScreen = false;
5622b73985eSStefano Ceccherini fInDirectConnect = false;
563cafaa5aaSStefano Ceccherini
5642b73985eSStefano Ceccherini fInitStatus = 0;
565cafaa5aaSStefano Ceccherini
5662b6ac345SStefano Ceccherini status_t status = B_ERROR;
5672b73985eSStefano Ceccherini struct direct_window_sync_data syncData;
5689fe35223SAxel Dörfler
5692b73985eSStefano Ceccherini fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA);
5702c704682SAxel Dörfler if (fLink->FlushWithReply(status) == B_OK && status == B_OK)
57171b55088SAxel Dörfler fLink->Read<direct_window_sync_data>(&syncData);
5722c704682SAxel Dörfler
5739fe35223SAxel Dörfler if (status != B_OK)
5745fdea13fSStefano Ceccherini return;
575cafaa5aaSStefano Ceccherini
576cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
5772b73985eSStefano Ceccherini fDirectLock = 0;
5782b73985eSStefano Ceccherini fDirectLockCount = 0;
5792b73985eSStefano Ceccherini fDirectLockOwner = -1;
5802b73985eSStefano Ceccherini fDirectLockStack = NULL;
58128fa0645SStefano Ceccherini fDirectSem = create_sem(0, "direct sem");
5822b73985eSStefano Ceccherini if (fDirectSem > 0)
5832b73985eSStefano Ceccherini fInitStatus |= DW_STATUS_SEM_CREATED;
584cafaa5aaSStefano Ceccherini #endif
585cafaa5aaSStefano Ceccherini
5862b73985eSStefano Ceccherini fSourceClippingArea = syncData.area;
5872b73985eSStefano Ceccherini fDisableSem = syncData.disable_sem;
5882b73985eSStefano Ceccherini fDisableSemAck = syncData.disable_sem_ack;
589cafaa5aaSStefano Ceccherini
59028fa0645SStefano Ceccherini fClonedClippingArea = clone_area("cloned direct area", (void**)&fBufferDesc,
5912b73985eSStefano Ceccherini B_ANY_ADDRESS, B_READ_AREA, fSourceClippingArea);
5925fdea13fSStefano Ceccherini
593302f6260SStefano Ceccherini if (fClonedClippingArea > 0) {
5942b73985eSStefano Ceccherini fInitStatus |= DW_STATUS_AREA_CLONED;
595cafaa5aaSStefano Ceccherini
596d9cebac2SStefano Ceccherini fDirectDaemonId = spawn_thread(_daemon_thread, "direct daemon",
597cafaa5aaSStefano Ceccherini B_DISPLAY_PRIORITY, this);
598cafaa5aaSStefano Ceccherini
5992b73985eSStefano Ceccherini if (fDirectDaemonId > 0) {
6002b73985eSStefano Ceccherini fDaemonKiller = false;
6012b73985eSStefano Ceccherini if (resume_thread(fDirectDaemonId) == B_OK)
6022b73985eSStefano Ceccherini fInitStatus |= DW_STATUS_THREAD_STARTED;
603cafaa5aaSStefano Ceccherini else
6042b73985eSStefano Ceccherini kill_thread(fDirectDaemonId);
605cafaa5aaSStefano Ceccherini }
606cafaa5aaSStefano Ceccherini }
607cafaa5aaSStefano Ceccherini }
6080b4a36abSbeveloper
6090b4a36abSbeveloper
6100b4a36abSbeveloper void
_DisposeData()611d9cebac2SStefano Ceccherini BDirectWindow::_DisposeData()
6120b4a36abSbeveloper {
613cafaa5aaSStefano Ceccherini // wait until the connection terminates: we can't destroy
614cafaa5aaSStefano Ceccherini // the object until the client receives the B_DIRECT_STOP
615cafaa5aaSStefano Ceccherini // notification, or bad things will happen
6162b73985eSStefano Ceccherini while (fConnectionEnable)
617cafaa5aaSStefano Ceccherini snooze(50000);
618cafaa5aaSStefano Ceccherini
619d9cebac2SStefano Ceccherini _LockDirect();
620cafaa5aaSStefano Ceccherini
6212b73985eSStefano Ceccherini if (fInitStatus & DW_STATUS_THREAD_STARTED) {
6222b73985eSStefano Ceccherini fDaemonKiller = true;
623020cbad9SStefano Ceccherini // delete this sem, otherwise the Direct daemon thread
624cafaa5aaSStefano Ceccherini // will wait forever on it
625020cbad9SStefano Ceccherini delete_sem(fDisableSem);
626cafaa5aaSStefano Ceccherini status_t retVal;
6272b73985eSStefano Ceccherini wait_for_thread(fDirectDaemonId, &retVal);
628cafaa5aaSStefano Ceccherini }
629cafaa5aaSStefano Ceccherini
630cafaa5aaSStefano Ceccherini #if DW_NEEDS_LOCKING
6312b73985eSStefano Ceccherini if (fInitStatus & DW_STATUS_SEM_CREATED)
6322b73985eSStefano Ceccherini delete_sem(fDirectSem);
633cafaa5aaSStefano Ceccherini #endif
634cafaa5aaSStefano Ceccherini
6352b73985eSStefano Ceccherini if (fInitStatus & DW_STATUS_AREA_CLONED)
6362b73985eSStefano Ceccherini delete_area(fClonedClippingArea);
6370b4a36abSbeveloper }
6380b4a36abSbeveloper
6390b4a36abSbeveloper
_ReservedDirectWindow1()640cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow1() {}
_ReservedDirectWindow2()641cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow2() {}
_ReservedDirectWindow3()642cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow3() {}
_ReservedDirectWindow4()643cafaa5aaSStefano Ceccherini void BDirectWindow::_ReservedDirectWindow4() {}
644