vfs: check userland buffers before reading them.
[haiku.git] / src / kits / game / WindowScreen.cpp
bloba5773de891e017aac341e79ce2efe5be85597b55
1 /*
2 * Copyright 2002-2009, Haiku. All Rights Reserved.
3 * Copyright 2002-2005,
4 * Marcus Overhagen,
5 * Stefano Ceccherini (stefano.ceccherini@gmail.com),
6 * Carwyn Jones (turok2@currantbun.com)
7 * All rights reserved.
9 * Distributed under the terms of the MIT License.
13 #include <WindowScreen.h>
15 #include <new>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
20 #include <Application.h>
21 #include <Screen.h>
22 #include <String.h>
24 #include <AppServerLink.h>
25 #include <input_globals.h>
26 #include <InputServerTypes.h>
27 #include <InterfacePrivate.h>
28 #include <ServerProtocol.h>
29 #include <WindowPrivate.h>
32 using BPrivate::AppServerLink;
35 //#define TRACE_WINDOWSCREEN 1
36 #if TRACE_WINDOWSCREEN
37 # define CALLED() printf("%s\n", __PRETTY_FUNCTION__);
38 #else
39 # define CALLED() ;
40 #endif
43 // Acceleration hooks pointers
44 static fill_rectangle sFillRectHook;
45 static screen_to_screen_blit sBlitRectHook;
46 static screen_to_screen_transparent_blit sTransparentBlitHook;
47 static screen_to_screen_scaled_filtered_blit sScaledFilteredBlitHook;
48 static wait_engine_idle sWaitIdleHook;
49 static acquire_engine sAcquireEngineHook;
50 static release_engine sReleaseEngineHook;
52 static engine_token *sEngineToken;
55 // Helper methods which translates the pre r5 graphics methods to r5 ones
56 static int32
57 card_sync()
59 sWaitIdleHook();
60 return 0;
64 static int32
65 blit(int32 sx, int32 sy, int32 dx, int32 dy, int32 width, int32 height)
67 blit_params param;
68 param.src_left = sx;
69 param.src_top = sy;
70 param.dest_left = dx;
71 param.dest_top = dy;
72 param.width = width;
73 param.height = height;
75 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken);
76 sBlitRectHook(sEngineToken, &param, 1);
77 sReleaseEngineHook(sEngineToken, NULL);
78 return 0;
82 // TODO: This function seems not to be exported through CardHookAt().
83 // At least, nothing I've tried uses it.
84 #if 0
85 static int32
86 transparent_blit(int32 sx, int32 sy, int32 dx, int32 dy, int32 width,
87 int32 height, uint32 transparent_color)
89 blit_params param;
90 param.src_left = sx;
91 param.src_top = sy;
92 param.dest_left = dx;
93 param.dest_top = dy;
94 param.width = width;
95 param.height = height;
97 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, 0, &sEngineToken);
98 sTransparentBlitHook(sEngineToken, transparent_color, &param, 1);
99 sReleaseEngineHook(sEngineToken, 0);
100 return 0;
102 #endif
105 static int32
106 scaled_filtered_blit(int32 sx, int32 sy, int32 sw, int32 sh, int32 dx, int32 dy,
107 int32 dw, int32 dh)
109 scaled_blit_params param;
110 param.src_left = sx;
111 param.src_top = sy;
112 param.src_width = sw;
113 param.src_height = sh;
114 param.dest_left = dx;
115 param.dest_top = dy;
116 param.dest_width = dw;
117 param.dest_height = dh;
119 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken);
120 sScaledFilteredBlitHook(sEngineToken, &param, 1);
121 sReleaseEngineHook(sEngineToken, NULL);
122 return 0;
126 static int32
127 draw_rect_8(int32 sx, int32 sy, int32 sw, int32 sh, uint8 color_index)
129 fill_rect_params param;
130 param.left = sx;
131 param.top = sy;
132 param.right = sw;
133 param.bottom = sh;
135 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken);
136 sFillRectHook(sEngineToken, color_index, &param, 1);
137 sReleaseEngineHook(sEngineToken, NULL);
138 return 0;
142 static int32
143 draw_rect_16(int32 sx, int32 sy, int32 sw, int32 sh, uint16 color)
145 fill_rect_params param;
146 param.left = sx;
147 param.top = sy;
148 param.right = sw;
149 param.bottom = sh;
151 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken);
152 sFillRectHook(sEngineToken, color, &param, 1);
153 sReleaseEngineHook(sEngineToken, NULL);
154 return 0;
158 static int32
159 draw_rect_32(int32 sx, int32 sy, int32 sw, int32 sh, uint32 color)
161 fill_rect_params param;
162 param.left = sx;
163 param.top = sy;
164 param.right = sw;
165 param.bottom = sh;
167 sAcquireEngineHook(B_2D_ACCELERATION, 0xff, NULL, &sEngineToken);
168 sFillRectHook(sEngineToken, color, &param, 1);
169 sReleaseEngineHook(sEngineToken, NULL);
170 return 0;
174 // #pragma mark - public API calls
177 void
178 set_mouse_position(int32 x, int32 y)
180 BMessage command(IS_SET_MOUSE_POSITION);
181 BMessage reply;
183 command.AddPoint("where", BPoint(x, y));
184 _control_input_server_(&command, &reply);
188 // #pragma mark -
191 BWindowScreen::BWindowScreen(const char *title, uint32 space, status_t *error,
192 bool debugEnable)
194 BWindow(BScreen().Frame(), title, B_NO_BORDER_WINDOW_LOOK,
195 kWindowScreenFeel, kWindowScreenFlag | B_NOT_MINIMIZABLE
196 | B_NOT_CLOSABLE | B_NOT_ZOOMABLE | B_NOT_MOVABLE | B_NOT_RESIZABLE,
197 B_CURRENT_WORKSPACE)
199 CALLED();
200 uint32 attributes = 0;
201 if (debugEnable)
202 attributes |= B_ENABLE_DEBUGGER;
204 status_t status = _InitData(space, attributes);
205 if (error)
206 *error = status;
210 BWindowScreen::BWindowScreen(const char *title, uint32 space,
211 uint32 attributes, status_t *error)
213 BWindow(BScreen().Frame(), title, B_NO_BORDER_WINDOW_LOOK,
214 kWindowScreenFeel, kWindowScreenFlag | B_NOT_MINIMIZABLE
215 | B_NOT_CLOSABLE | B_NOT_ZOOMABLE | B_NOT_MOVABLE | B_NOT_RESIZABLE,
216 B_CURRENT_WORKSPACE)
218 CALLED();
219 status_t status = _InitData(space, attributes);
220 if (error)
221 *error = status;
225 BWindowScreen::~BWindowScreen()
227 CALLED();
228 _DisposeData();
232 void
233 BWindowScreen::Quit(void)
235 CALLED();
236 Disconnect();
237 BWindow::Quit();
241 void
242 BWindowScreen::ScreenConnected(bool active)
244 // Implemented in subclasses
248 void
249 BWindowScreen::Disconnect()
251 CALLED();
252 if (fLockState == 1) {
253 if (fDebugState)
254 fDebugFirst = true;
255 _Deactivate();
258 be_app->ShowCursor();
262 void
263 BWindowScreen::WindowActivated(bool active)
265 CALLED();
266 fWindowState = active;
267 if (active && fLockState == 0 && fWorkState)
268 _Activate();
272 void
273 BWindowScreen::WorkspaceActivated(int32 workspace, bool state)
275 CALLED();
276 fWorkState = state;
278 if (state) {
279 if (fLockState == 0 && fWindowState) {
280 _Activate();
281 if (!IsHidden()) {
282 Activate(true);
283 WindowActivated(true);
286 } else if (fLockState)
287 _Deactivate();
291 void
292 BWindowScreen::ScreenChanged(BRect screenFrame, color_space depth)
294 // Implemented in subclasses
298 void
299 BWindowScreen::Hide()
301 CALLED();
303 Disconnect();
304 BWindow::Hide();
308 void
309 BWindowScreen::Show()
311 CALLED();
313 BWindow::Show();
317 void
318 BWindowScreen::SetColorList(rgb_color *list, int32 firstIndex, int32 lastIndex)
320 CALLED();
321 if (firstIndex < 0 || lastIndex > 255 || firstIndex > lastIndex)
322 return;
324 if (!Lock())
325 return;
327 if (!fActivateState) {
328 // If we aren't active, we just change our local palette
329 for (int32 x = firstIndex; x <= lastIndex; x++) {
330 fPalette[x] = list[x - firstIndex];
332 } else {
333 uint8 colors[3 * 256];
334 // the color table has 3 bytes per color
335 int32 j = 0;
337 for (int32 x = firstIndex; x <= lastIndex; x++) {
338 fPalette[x] = list[x - firstIndex];
339 // update our local palette as well
341 colors[j++] = fPalette[x].red;
342 colors[j++] = fPalette[x].green;
343 colors[j++] = fPalette[x].blue;
346 if (fAddonImage >= 0) {
347 set_indexed_colors setIndexedColors
348 = (set_indexed_colors)fGetAccelerantHook(B_SET_INDEXED_COLORS,
349 NULL);
350 if (setIndexedColors != NULL) {
351 setIndexedColors(255, 0,
352 colors, 0);
356 // TODO: Tell the app_server about our changes
358 BScreen screen(this);
359 screen.WaitForRetrace();
362 Unlock();
366 status_t
367 BWindowScreen::SetSpace(uint32 space)
369 CALLED();
371 display_mode mode;
372 status_t status = _GetModeFromSpace(space, &mode);
373 if (status == B_OK)
374 status = _AssertDisplayMode(&mode);
376 return status;
380 bool
381 BWindowScreen::CanControlFrameBuffer()
383 return (fCardInfo.flags & B_FRAME_BUFFER_CONTROL) != 0;
387 status_t
388 BWindowScreen::SetFrameBuffer(int32 width, int32 height)
390 CALLED();
391 display_mode highMode = *fDisplayMode;
392 highMode.flags |= B_SCROLL;
394 highMode.virtual_height = (int16)height;
395 highMode.virtual_width = (int16)width;
397 display_mode lowMode = highMode;
398 display_mode mode = highMode;
400 BScreen screen(this);
401 status_t status = screen.ProposeMode(&mode, &lowMode, &highMode);
402 if (status == B_OK)
403 status = _AssertDisplayMode(&mode);
405 return status;
409 status_t
410 BWindowScreen::MoveDisplayArea(int32 x, int32 y)
412 CALLED();
413 move_display_area moveDisplayArea
414 = (move_display_area)fGetAccelerantHook(B_MOVE_DISPLAY, NULL);
415 if (moveDisplayArea && moveDisplayArea((int16)x, (int16)y) == B_OK) {
416 fFrameBufferInfo.display_x = x;
417 fFrameBufferInfo.display_y = y;
418 fDisplayMode->h_display_start = x;
419 fDisplayMode->v_display_start = y;
420 return B_OK;
422 return B_ERROR;
426 #if 0
427 void *
428 BWindowScreen::IOBase()
430 // Not supported
431 return NULL;
433 #endif
436 rgb_color *
437 BWindowScreen::ColorList()
439 CALLED();
440 return fPalette;
444 frame_buffer_info *
445 BWindowScreen::FrameBufferInfo()
447 CALLED();
448 return &fFrameBufferInfo;
452 graphics_card_hook
453 BWindowScreen::CardHookAt(int32 index)
455 CALLED();
456 if (fAddonImage < 0)
457 return NULL;
459 graphics_card_hook hook = NULL;
461 switch (index) {
462 case 5: // 8 bit fill rect
463 if (sFillRectHook)
464 hook = (graphics_card_hook)draw_rect_8;
465 break;
466 case 6: // 32 bit fill rect
467 if (sFillRectHook)
468 hook = (graphics_card_hook)draw_rect_32;
469 break;
470 case 7: // screen to screen blit
471 if (sBlitRectHook)
472 hook = (graphics_card_hook)blit;
473 break;
474 case 8: // screen to screen scaled filtered blit
475 if (sScaledFilteredBlitHook)
476 hook = (graphics_card_hook)scaled_filtered_blit;
477 break;
478 case 10: // sync aka wait for graphics card idle
479 if (sWaitIdleHook)
480 hook = (graphics_card_hook)card_sync;
481 break;
482 case 13: // 16 bit fill rect
483 if (sFillRectHook)
484 hook = (graphics_card_hook)draw_rect_16;
485 break;
486 default:
487 break;
490 return hook;
494 graphics_card_info *
495 BWindowScreen::CardInfo()
497 CALLED();
498 return &fCardInfo;
502 void
503 BWindowScreen::RegisterThread(thread_id thread)
505 CALLED();
507 status_t status;
508 do {
509 status = acquire_sem(fDebugSem);
510 } while (status == B_INTERRUPTED);
512 if (status < B_OK)
513 return;
515 void *newDebugList = realloc(fDebugThreads,
516 (fDebugThreadCount + 1) * sizeof(thread_id));
517 if (newDebugList != NULL) {
518 fDebugThreads = (thread_id *)newDebugList;
519 fDebugThreads[fDebugThreadCount] = thread;
520 fDebugThreadCount++;
522 release_sem(fDebugSem);
526 void
527 BWindowScreen::SuspensionHook(bool active)
529 // Implemented in subclasses
533 void
534 BWindowScreen::Suspend(char* label)
536 CALLED();
537 if (fDebugState) {
538 fprintf(stderr, "## Debugger(\"%s\").", label);
539 fprintf(stderr, " Press Alt-F%" B_PRId32 " or Cmd-F%" B_PRId32 " to resume.\n",
540 fWorkspaceIndex + 1, fWorkspaceIndex + 1);
542 if (IsLocked())
543 Unlock();
545 activate_workspace(fDebugWorkspace);
547 // Suspend ourself
548 suspend_thread(find_thread(NULL));
550 Lock();
555 status_t
556 BWindowScreen::Perform(perform_code d, void* arg)
558 return inherited::Perform(d, arg);
562 // Reserved for future binary compatibility
563 void BWindowScreen::_ReservedWindowScreen1() {}
564 void BWindowScreen::_ReservedWindowScreen2() {}
565 void BWindowScreen::_ReservedWindowScreen3() {}
566 void BWindowScreen::_ReservedWindowScreen4() {}
569 status_t
570 BWindowScreen::_InitData(uint32 space, uint32 attributes)
572 CALLED();
574 fDebugState = attributes & B_ENABLE_DEBUGGER;
575 fDebugThreadCount = 0;
576 fDebugThreads = NULL;
577 fDebugFirst = true;
579 fAttributes = attributes;
580 // TODO: not really used right now, but should probably be known by
581 // the app_server
583 fWorkspaceIndex = fDebugWorkspace = current_workspace();
584 fLockState = 0;
585 fAddonImage = -1;
586 fWindowState = 0;
587 fOriginalDisplayMode = NULL;
588 fDisplayMode = NULL;
589 fModeList = NULL;
590 fModeCount = 0;
591 fDebugSem = -1;
592 fActivateState = false;
593 fWorkState = false;
595 status_t status = B_ERROR;
596 try {
597 fOriginalDisplayMode = new display_mode;
598 fDisplayMode = new display_mode;
600 BScreen screen(this);
601 status = screen.GetMode(fOriginalDisplayMode);
602 if (status < B_OK)
603 throw status;
605 status = screen.GetModeList(&fModeList, &fModeCount);
606 if (status < B_OK)
607 throw status;
609 status = _GetModeFromSpace(space, fDisplayMode);
610 if (status < B_OK)
611 throw status;
613 status = _GetCardInfo();
614 if (status < B_OK)
615 throw status;
617 fDebugSem = create_sem(1, "WindowScreen debug sem");
618 if (fDebugSem < B_OK)
619 throw (status_t)fDebugSem;
621 memcpy(fPalette, screen.ColorMap()->color_list, sizeof(fPalette));
622 fActivateState = false;
623 fWorkState = true;
625 status = B_OK;
626 } catch (std::bad_alloc) {
627 status = B_NO_MEMORY;
628 } catch (status_t error) {
629 status = error;
630 } catch (...) {
631 status = B_ERROR;
634 if (status != B_OK)
635 _DisposeData();
637 return status;
641 void
642 BWindowScreen::_DisposeData()
644 CALLED();
645 Disconnect();
646 if (fAddonImage >= 0) {
647 unload_add_on(fAddonImage);
648 fAddonImage = -1;
651 delete_sem(fDebugSem);
652 fDebugSem = -1;
654 if (fDebugState)
655 activate_workspace(fDebugWorkspace);
657 delete fDisplayMode;
658 fDisplayMode = NULL;
659 delete fOriginalDisplayMode;
660 fOriginalDisplayMode = NULL;
661 free(fModeList);
662 fModeList = NULL;
663 fModeCount = 0;
665 fLockState = 0;
669 status_t
670 BWindowScreen::_LockScreen(bool lock)
672 if (fActivateState == lock)
673 return B_OK;
675 // TODO: the BWindowScreen should use the same mechanism as BDirectWindows!
676 BPrivate::AppServerLink link;
678 link.StartMessage(AS_DIRECT_SCREEN_LOCK);
679 link.Attach<bool>(lock);
681 status_t status = B_ERROR;
682 if (link.FlushWithReply(status) == B_OK && status == B_OK)
683 fActivateState = lock;
685 return status;
689 status_t
690 BWindowScreen::_Activate()
692 CALLED();
693 status_t status = _AssertDisplayMode(fDisplayMode);
694 if (status < B_OK)
695 return status;
697 status = _SetupAccelerantHooks();
698 if (status < B_OK)
699 return status;
701 if (!fActivateState) {
702 status = _LockScreen(true);
703 if (status != B_OK)
704 return status;
707 be_app->HideCursor();
709 SetColorList(fPalette);
710 if (fDebugState && !fDebugFirst) {
711 SuspensionHook(true);
712 _Resume();
713 } else {
714 fDebugFirst = true;
715 ScreenConnected(true);
718 return B_OK;
722 status_t
723 BWindowScreen::_Deactivate()
725 CALLED();
727 if (fDebugState && !fDebugFirst) {
728 _Suspend();
729 SuspensionHook(false);
730 } else
731 ScreenConnected(false);
733 if (fActivateState) {
734 status_t status = _LockScreen(false);
735 if (status != B_OK)
736 return status;
738 BScreen screen(this);
739 SetColorList((rgb_color *)screen.ColorMap()->color_list);
742 _AssertDisplayMode(fOriginalDisplayMode);
743 _ResetAccelerantHooks();
745 be_app->ShowCursor();
747 return B_OK;
751 status_t
752 BWindowScreen::_SetupAccelerantHooks()
754 CALLED();
756 status_t status = B_OK;
757 if (fAddonImage < 0)
758 status = _InitClone();
759 else
760 _ResetAccelerantHooks();
762 if (status == B_OK) {
763 sWaitIdleHook = fWaitEngineIdle = (wait_engine_idle)
764 fGetAccelerantHook(B_WAIT_ENGINE_IDLE, NULL);
765 sReleaseEngineHook
766 = (release_engine)fGetAccelerantHook(B_RELEASE_ENGINE, NULL);
767 sAcquireEngineHook
768 = (acquire_engine)fGetAccelerantHook(B_ACQUIRE_ENGINE, NULL);
769 sFillRectHook
770 = (fill_rectangle)fGetAccelerantHook(B_FILL_RECTANGLE, NULL);
771 sBlitRectHook = (screen_to_screen_blit)
772 fGetAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, NULL);
773 sTransparentBlitHook = (screen_to_screen_transparent_blit)
774 fGetAccelerantHook(B_SCREEN_TO_SCREEN_TRANSPARENT_BLIT, NULL);
775 sScaledFilteredBlitHook = (screen_to_screen_scaled_filtered_blit)
776 fGetAccelerantHook(B_SCREEN_TO_SCREEN_SCALED_FILTERED_BLIT, NULL);
778 if (fWaitEngineIdle)
779 fWaitEngineIdle();
781 fLockState = 1;
784 return status;
788 void
789 BWindowScreen::_ResetAccelerantHooks()
791 CALLED();
792 if (fWaitEngineIdle)
793 fWaitEngineIdle();
795 sFillRectHook = NULL;
796 sBlitRectHook = NULL;
797 sTransparentBlitHook = NULL;
798 sScaledFilteredBlitHook = NULL;
799 sWaitIdleHook = NULL;
800 sEngineToken = NULL;
801 sAcquireEngineHook = NULL;
802 sReleaseEngineHook = NULL;
804 fWaitEngineIdle = NULL;
806 fLockState = 0;
810 status_t
811 BWindowScreen::_GetCardInfo()
813 CALLED();
815 BScreen screen(this);
816 display_mode mode;
817 status_t status = screen.GetMode(&mode);
818 if (status < B_OK)
819 return status;
821 uint32 bitsPerPixel;
822 switch(mode.space & 0x0fff) {
823 case B_CMAP8:
824 bitsPerPixel = 8;
825 break;
826 case B_RGB15:
827 bitsPerPixel = 15;
828 break;
829 case B_RGB16:
830 bitsPerPixel = 16;
831 break;
832 case B_RGB32:
833 bitsPerPixel = 32;
834 break;
835 default:
836 bitsPerPixel = 0;
837 break;
840 fCardInfo.version = 2;
841 fCardInfo.id = screen.ID().id;
842 fCardInfo.bits_per_pixel = bitsPerPixel;
843 fCardInfo.width = mode.virtual_width;
844 fCardInfo.height = mode.virtual_height;
846 if (mode.space & 0x10)
847 memcpy(fCardInfo.rgba_order, "rgba", 4);
848 else
849 memcpy(fCardInfo.rgba_order, "bgra", 4);
851 fCardInfo.flags = 0;
852 if (mode.flags & B_SCROLL)
853 fCardInfo.flags |= B_FRAME_BUFFER_CONTROL;
854 if (mode.flags & B_PARALLEL_ACCESS)
855 fCardInfo.flags |= B_PARALLEL_BUFFER_ACCESS;
857 AppServerLink link;
858 link.StartMessage(AS_GET_FRAME_BUFFER_CONFIG);
859 link.Attach<screen_id>(screen.ID());
861 status_t result = B_ERROR;
862 if (link.FlushWithReply(result) < B_OK || result < B_OK)
863 return result;
865 frame_buffer_config config;
866 link.Read<frame_buffer_config>(&config);
868 fCardInfo.frame_buffer = config.frame_buffer;
869 fCardInfo.bytes_per_row = config.bytes_per_row;
871 return B_OK;
875 void
876 BWindowScreen::_Suspend()
878 CALLED();
880 status_t status;
881 do {
882 status = acquire_sem(fDebugSem);
883 } while (status == B_INTERRUPTED);
885 if (status != B_OK)
886 return;
888 // Suspend all the registered threads
889 for (int32 i = 0; i < fDebugThreadCount; i++) {
890 snooze(10000);
891 suspend_thread(fDebugThreads[i]);
894 graphics_card_info *info = CardInfo();
895 size_t fbSize = info->bytes_per_row * info->height;
897 // Save the content of the frame buffer into the local buffer
898 fDebugFrameBuffer = (char *)malloc(fbSize);
899 memcpy(fDebugFrameBuffer, info->frame_buffer, fbSize);
903 void
904 BWindowScreen::_Resume()
906 CALLED();
907 graphics_card_info *info = CardInfo();
909 // Copy the content of the debug_buffer back into the frame buffer.
910 memcpy(info->frame_buffer, fDebugFrameBuffer,
911 info->bytes_per_row * info->height);
912 free(fDebugFrameBuffer);
913 fDebugFrameBuffer = NULL;
915 // Resume all the registered threads
916 for (int32 i = 0; i < fDebugThreadCount; i++) {
917 resume_thread(fDebugThreads[i]);
920 release_sem(fDebugSem);
924 status_t
925 BWindowScreen::_GetModeFromSpace(uint32 space, display_mode *dmode)
927 CALLED();
929 int32 width, height;
930 uint32 colorSpace;
931 if (!BPrivate::get_mode_parameter(space, width, height, colorSpace))
932 return B_BAD_VALUE;
934 for (uint32 i = 0; i < fModeCount; i++) {
935 if (fModeList[i].space == colorSpace
936 && fModeList[i].virtual_width == width
937 && fModeList[i].virtual_height == height) {
938 memcpy(dmode, &fModeList[i], sizeof(display_mode));
939 return B_OK;
943 return B_ERROR;
947 status_t
948 BWindowScreen::_InitClone()
950 CALLED();
952 if (fAddonImage >= 0)
953 return B_OK;
955 BScreen screen(this);
957 AppServerLink link;
958 link.StartMessage(AS_GET_ACCELERANT_PATH);
959 link.Attach<screen_id>(screen.ID());
961 status_t status = B_ERROR;
962 if (link.FlushWithReply(status) < B_OK || status < B_OK)
963 return status;
965 BString accelerantPath;
966 link.ReadString(accelerantPath);
968 link.StartMessage(AS_GET_DRIVER_PATH);
969 link.Attach<screen_id>(screen.ID());
971 status = B_ERROR;
972 if (link.FlushWithReply(status) < B_OK || status < B_OK)
973 return status;
975 BString driverPath;
976 link.ReadString(driverPath);
978 fAddonImage = load_add_on(accelerantPath.String());
979 if (fAddonImage < B_OK) {
980 fprintf(stderr, "InitClone: cannot load accelerant image\n");
981 return fAddonImage;
984 status = get_image_symbol(fAddonImage, B_ACCELERANT_ENTRY_POINT,
985 B_SYMBOL_TYPE_TEXT, (void**)&fGetAccelerantHook);
986 if (status < B_OK) {
987 fprintf(stderr, "InitClone: cannot get accelerant entry point\n");
988 unload_add_on(fAddonImage);
989 fAddonImage = -1;
990 return B_NOT_SUPPORTED;
993 clone_accelerant cloneHook
994 = (clone_accelerant)fGetAccelerantHook(B_CLONE_ACCELERANT, NULL);
995 if (cloneHook == NULL) {
996 fprintf(stderr, "InitClone: cannot get clone hook\n");
997 unload_add_on(fAddonImage);
998 fAddonImage = -1;
999 return B_NOT_SUPPORTED;
1002 status = cloneHook((void*)driverPath.String());
1003 if (status < B_OK) {
1004 fprintf(stderr, "InitClone: cannot clone accelerant\n");
1005 unload_add_on(fAddonImage);
1006 fAddonImage = -1;
1009 return status;
1013 status_t
1014 BWindowScreen::_AssertDisplayMode(display_mode* displayMode)
1016 CALLED();
1018 BScreen screen(this);
1020 display_mode currentMode;
1021 status_t status = screen.GetMode(&currentMode);
1022 if (status != B_OK)
1023 return status;
1025 if (currentMode.virtual_height != displayMode->virtual_height
1026 || currentMode.virtual_width != displayMode->virtual_width
1027 || currentMode.space != displayMode->space
1028 || currentMode.flags != displayMode->flags) {
1029 status = screen.SetMode(displayMode);
1030 if (status != B_OK) {
1031 fprintf(stderr, "AssertDisplayMode: Setting mode failed: %s\n",
1032 strerror(status));
1033 return status;
1036 memcpy(fDisplayMode, displayMode, sizeof(display_mode));
1039 status = _GetCardInfo();
1040 if (status != B_OK)
1041 return status;
1043 fFrameBufferInfo.bits_per_pixel = fCardInfo.bits_per_pixel;
1044 fFrameBufferInfo.bytes_per_row = fCardInfo.bytes_per_row;
1045 fFrameBufferInfo.width = fCardInfo.width;
1046 fFrameBufferInfo.height = fCardInfo.height;
1047 fFrameBufferInfo.display_width = fCardInfo.width;
1048 fFrameBufferInfo.display_height = fCardInfo.height;
1049 fFrameBufferInfo.display_x = 0;
1050 fFrameBufferInfo.display_y = 0;
1052 return B_OK;