VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/load.c@ 30512

Last change on this file since 30512 was 30487, checked in by vboxsync, 15 years ago

crOpenGL: disable new tracking code for compiz

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 23.3 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_spu.h"
8#include "cr_net.h"
9#include "cr_error.h"
10#include "cr_mem.h"
11#include "cr_string.h"
12#include "cr_net.h"
13#include "cr_environment.h"
14#include "cr_process.h"
15#include "cr_rand.h"
16#include "cr_netserver.h"
17#include "stub.h"
18#include <stdlib.h>
19#include <string.h>
20#include <signal.h>
21#include <iprt/initterm.h>
22#include <iprt/thread.h>
23#include <iprt/err.h>
24#include <iprt/asm.h>
25#ifndef WINDOWS
26# include <sys/types.h>
27# include <unistd.h>
28#endif
29#ifdef CHROMIUM_THREADSAFE
30#include "cr_threads.h"
31#endif
32
33/**
34 * If you change this, see the comments in tilesortspu_context.c
35 */
36#define MAGIC_CONTEXT_BASE 500
37
38#define CONFIG_LOOKUP_FILE ".crconfigs"
39
40#ifdef WINDOWS
41#define PYTHON_EXE "python.exe"
42#else
43#define PYTHON_EXE "python"
44#endif
45
46#ifdef WINDOWS
47static char* gsViewportHackApps[] = {"googleearth.exe", NULL};
48#endif
49
50static int stub_initialized = 0;
51
52/* NOTE: 'SPUDispatchTable glim' is declared in NULLfuncs.py now */
53/* NOTE: 'SPUDispatchTable stubThreadsafeDispatch' is declared in tsfuncs.c */
54Stub stub;
55
56
57static void stubInitNativeDispatch( void )
58{
59#define MAX_FUNCS 1000
60 SPUNamedFunctionTable gl_funcs[MAX_FUNCS];
61 int numFuncs;
62
63 numFuncs = crLoadOpenGL( &stub.wsInterface, gl_funcs );
64
65 stub.haveNativeOpenGL = (numFuncs > 0);
66
67 /* XXX call this after context binding */
68 numFuncs += crLoadOpenGLExtensions( &stub.wsInterface, gl_funcs + numFuncs );
69
70 CRASSERT(numFuncs < MAX_FUNCS);
71
72 crSPUInitDispatchTable( &stub.nativeDispatch );
73 crSPUInitDispatch( &stub.nativeDispatch, gl_funcs );
74 crSPUInitDispatchNops( &stub.nativeDispatch );
75#undef MAX_FUNCS
76}
77
78
79/** Pointer to the SPU's real glClear and glViewport functions */
80static ClearFunc_t origClear;
81static ViewportFunc_t origViewport;
82static SwapBuffersFunc_t origSwapBuffers;
83static DrawBufferFunc_t origDrawBuffer;
84static ScissorFunc_t origScissor;
85
86static void stubCheckWindowState(WindowInfo *window, GLboolean bFlushOnChange)
87{
88 bool bForceUpdate = false;
89 bool bChanged = false;
90
91#ifdef WINDOWS
92 /* @todo install hook and track for WM_DISPLAYCHANGE */
93 {
94 DEVMODE devMode;
95
96 devMode.dmSize = sizeof(DEVMODE);
97 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
98
99 if (devMode.dmPelsWidth!=window->dmPelsWidth || devMode.dmPelsHeight!=window->dmPelsHeight)
100 {
101 crDebug("Resolution changed(%d,%d), forcing window Pos/Size update", devMode.dmPelsWidth, devMode.dmPelsHeight);
102 window->dmPelsWidth = devMode.dmPelsWidth;
103 window->dmPelsHeight = devMode.dmPelsHeight;
104 bForceUpdate = true;
105 }
106 }
107#endif
108
109 bChanged = stubUpdateWindowGeometry(window, bForceUpdate) || bForceUpdate;
110
111#if defined(GLX) || defined (WINDOWS)
112 if (stub.trackWindowVisibleRgn)
113 {
114 bChanged = stubUpdateWindowVisibileRegions(window) || bChanged;
115 }
116#endif
117
118 if (stub.trackWindowVisibility && window->type == CHROMIUM && window->drawable) {
119 const int mapped = stubIsWindowVisible(window);
120 if (mapped != window->mapped) {
121 crDebug("Dispatched: WindowShow(%i, %i)", window->spuWindow, mapped);
122 stub.spu->dispatch_table.WindowShow(window->spuWindow, mapped);
123 window->mapped = mapped;
124 bChanged = true;
125 }
126 }
127
128 if (bFlushOnChange && bChanged)
129 {
130 stub.spu->dispatch_table.Flush();
131 }
132}
133
134static bool stubSystemWindowExist(WindowInfo *pWindow)
135{
136#ifdef WINDOWS
137 if (!WindowFromDC(pWindow->drawable))
138 {
139 return false;
140 }
141#else
142 Window root;
143 int x, y;
144 unsigned int border, depth, w, h;
145 Display *dpy;
146
147 dpy = stubGetWindowDisplay(pWindow);
148
149 XLOCK(dpy);
150 if (!XGetGeometry(dpy, pWindow->drawable, &root, &x, &y, &w, &h, &border, &depth))
151 {
152 XUNLOCK(dpy);
153 return false;
154 }
155 XUNLOCK(dpy);
156#endif
157
158 return true;
159}
160
161static void stubCheckWindowsCB(unsigned long key, void *data1, void *data2)
162{
163 WindowInfo *pWindow = (WindowInfo *) data1;
164 ContextInfo *pCtx = (ContextInfo *) data2;
165
166 if (pWindow == pCtx->currentDrawable
167 || pWindow->type!=CHROMIUM
168 || pWindow->pOwner!=pCtx)
169 {
170 return;
171 }
172
173 if (!stubSystemWindowExist(pWindow))
174 {
175#ifdef WINDOWS
176 crWindowDestroy((GLint)pWindow->hWnd);
177#else
178 crWindowDestroy((GLint)pWindow->drawable);
179#endif
180 return;
181 }
182
183 stubCheckWindowState(pWindow, GL_FALSE);
184}
185
186static void stubCheckWindowsState(void)
187{
188 CRASSERT(stub.trackWindowSize || stub.trackWindowPos);
189
190 if (!stub.currentContext)
191 return;
192
193#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
194 crLockMutex(&stub.mutex);
195#endif
196
197 stubCheckWindowState(stub.currentContext->currentDrawable, GL_TRUE);
198 crHashtableWalk(stub.windowTable, stubCheckWindowsCB, stub.currentContext);
199
200#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
201 crUnlockMutex(&stub.mutex);
202#endif
203}
204
205
206/**
207 * Override the head SPU's glClear function.
208 * We're basically trapping this function so that we can poll the
209 * application window size at a regular interval.
210 */
211static void SPU_APIENTRY trapClear(GLbitfield mask)
212{
213 stubCheckWindowsState();
214 /* call the original SPU glClear function */
215 origClear(mask);
216}
217
218/**
219 * As above, but for glViewport. Most apps call glViewport before
220 * glClear when a window is resized.
221 */
222static void SPU_APIENTRY trapViewport(GLint x, GLint y, GLsizei w, GLsizei h)
223{
224 stubCheckWindowsState();
225 /* call the original SPU glViewport function */
226 if (!stub.viewportHack)
227 {
228 origViewport(x, y, w, h);
229 }
230 else
231 {
232 int winX, winY;
233 unsigned int winW, winH;
234 WindowInfo *pWindow;
235 pWindow = stub.currentContext->currentDrawable;
236 stubGetWindowGeometry(pWindow, &winX, &winY, &winW, &winH);
237 origViewport(0, 0, winW, winH);
238 }
239}
240
241static void SPU_APIENTRY trapSwapBuffers(GLint window, GLint flags)
242{
243 stubCheckWindowsState();
244 origSwapBuffers(window, flags);
245}
246
247static void SPU_APIENTRY trapDrawBuffer(GLenum buf)
248{
249 stubCheckWindowsState();
250 origDrawBuffer(buf);
251}
252
253static void SPU_APIENTRY trapScissor(GLint x, GLint y, GLsizei w, GLsizei h)
254{
255 int winX, winY;
256 unsigned int winW, winH;
257 WindowInfo *pWindow;
258 pWindow = stub.currentContext->currentDrawable;
259 stubGetWindowGeometry(pWindow, &winX, &winY, &winW, &winH);
260 origScissor(0, 0, winW, winH);
261}
262
263/**
264 * Use the GL function pointers in <spu> to initialize the static glim
265 * dispatch table.
266 */
267static void stubInitSPUDispatch(SPU *spu)
268{
269 crSPUInitDispatchTable( &stub.spuDispatch );
270 crSPUCopyDispatchTable( &stub.spuDispatch, &(spu->dispatch_table) );
271
272 if (stub.trackWindowSize || stub.trackWindowPos || stub.trackWindowVisibleRgn) {
273 /* patch-in special glClear/Viewport function to track window sizing */
274 origClear = stub.spuDispatch.Clear;
275 origViewport = stub.spuDispatch.Viewport;
276 origSwapBuffers = stub.spuDispatch.SwapBuffers;
277 origDrawBuffer = stub.spuDispatch.DrawBuffer;
278 origScissor = stub.spuDispatch.Scissor;
279 stub.spuDispatch.Clear = trapClear;
280 stub.spuDispatch.Viewport = trapViewport;
281
282 if (stub.viewportHack)
283 stub.spuDispatch.Scissor = trapScissor;
284 /*stub.spuDispatch.SwapBuffers = trapSwapBuffers;
285 stub.spuDispatch.DrawBuffer = trapDrawBuffer;*/
286 }
287
288 crSPUCopyDispatchTable( &glim, &stub.spuDispatch );
289}
290
291// Callback function, used to destroy all created contexts
292static void hsWalkStubDestroyContexts(unsigned long key, void *data1, void *data2)
293{
294 stubDestroyContext(key);
295}
296
297/**
298 * This is called when we exit.
299 * We call all the SPU's cleanup functions.
300 */
301static void stubSPUTearDown(void)
302{
303 crDebug("stubSPUTearDown");
304 if (!stub_initialized) return;
305
306 stub_initialized = 0;
307
308#ifdef WINDOWS
309# ifndef CR_NEWWINTRACK
310 stubUninstallWindowMessageHook();
311# endif
312#endif
313
314#ifdef CR_NEWWINTRACK
315 ASMAtomicWriteBool(&stub.bShutdownSyncThread, true);
316#endif
317
318 //delete all created contexts
319 stubMakeCurrent( NULL, NULL);
320 crHashtableWalk(stub.contextTable, hsWalkStubDestroyContexts, NULL);
321
322 /* shutdown, now trap any calls to a NULL dispatcher */
323 crSPUCopyDispatchTable(&glim, &stubNULLDispatch);
324
325 crSPUUnloadChain(stub.spu);
326 stub.spu = NULL;
327
328#ifndef Linux
329 crUnloadOpenGL();
330#endif
331
332 crNetTearDown();
333
334#ifdef GLX
335 if (stub.xshmSI.shmid>=0)
336 {
337 shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
338 shmdt(stub.xshmSI.shmaddr);
339 }
340 crFreeHashtable(stub.pGLXPixmapsHash, crFree);
341#endif
342
343 crFreeHashtable(stub.windowTable, crFree);
344 crFreeHashtable(stub.contextTable, NULL);
345
346 crMemset(&stub, 0, sizeof(stub) );
347}
348
349static void stubSPUSafeTearDown(void)
350{
351#ifdef CHROMIUM_THREADSAFE
352 CRmutex *mutex;
353#endif
354
355 if (!stub_initialized) return;
356 stub_initialized = 0;
357
358#ifdef CHROMIUM_THREADSAFE
359 mutex = &stub.mutex;
360 crLockMutex(mutex);
361#endif
362 crDebug("stubSPUSafeTearDown");
363
364#ifdef WINDOWS
365# ifndef CR_NEWWINTRACK
366 stubUninstallWindowMessageHook();
367# endif
368#endif
369
370#if defined(WINDOWS) && defined(CR_NEWWINTRACK)
371 crUnlockMutex(mutex);
372 if (RTThreadGetState(stub.hSyncThread)!=RTTHREADSTATE_TERMINATED)
373 {
374 ASMAtomicWriteBool(&stub.bShutdownSyncThread, true);
375 if (PostThreadMessage(RTThreadGetNative(stub.hSyncThread), WM_QUIT, 0, 0))
376 {
377 RTThreadWait(stub.hSyncThread, 1000, NULL);
378 }
379 else
380 {
381 crDebug("Sync thread killed before DLL_PROCESS_DETACH");
382 }
383 }
384 crLockMutex(mutex);
385#endif
386
387 crNetTearDown();
388 crMemset(&stub, 0, sizeof(stub));
389#ifdef CHROMIUM_THREADSAFE
390 crUnlockMutex(mutex);
391 crFreeMutex(mutex);
392#endif
393}
394
395
396static void stubExitHandler(void)
397{
398 stubSPUSafeTearDown();
399}
400
401/**
402 * Called when we receive a SIGTERM signal.
403 */
404static void stubSignalHandler(int signo)
405{
406 stubSPUSafeTearDown();
407 exit(0); /* this causes stubExitHandler() to be called */
408}
409
410
411/**
412 * Init variables in the stub structure, install signal handler.
413 */
414static void stubInitVars(void)
415{
416 WindowInfo *defaultWin;
417
418#ifdef CHROMIUM_THREADSAFE
419 crInitMutex(&stub.mutex);
420#endif
421
422 /* At the very least we want CR_RGB_BIT. */
423 stub.haveNativeOpenGL = GL_FALSE;
424 stub.spu = NULL;
425 stub.appDrawCursor = 0;
426 stub.minChromiumWindowWidth = 0;
427 stub.minChromiumWindowHeight = 0;
428 stub.maxChromiumWindowWidth = 0;
429 stub.maxChromiumWindowHeight = 0;
430 stub.matchChromiumWindowCount = 0;
431 stub.matchChromiumWindowID = NULL;
432 stub.matchWindowTitle = NULL;
433 stub.ignoreFreeglutMenus = 0;
434 stub.threadSafe = GL_FALSE;
435 stub.trackWindowSize = 0;
436 stub.trackWindowPos = 0;
437 stub.trackWindowVisibility = 0;
438 stub.trackWindowVisibleRgn = 0;
439 stub.mothershipPID = 0;
440 stub.spu_dir = NULL;
441
442 stub.freeContextNumber = MAGIC_CONTEXT_BASE;
443 stub.contextTable = crAllocHashtable();
444 stub.currentContext = NULL;
445
446 stub.windowTable = crAllocHashtable();
447
448#ifdef CR_NEWWINTRACK
449 stub.bShutdownSyncThread = false;
450 stub.hSyncThread = NIL_RTTHREAD;
451#endif
452
453 defaultWin = (WindowInfo *) crCalloc(sizeof(WindowInfo));
454 defaultWin->type = CHROMIUM;
455 defaultWin->spuWindow = 0; /* window 0 always exists */
456#ifdef WINDOWS
457 defaultWin->hVisibleRegion = INVALID_HANDLE_VALUE;
458#elif defined(GLX)
459 defaultWin->pVisibleRegions = NULL;
460 defaultWin->cVisibleRegions = 0;
461#endif
462 crHashtableAdd(stub.windowTable, 0, defaultWin);
463
464#if 1
465 atexit(stubExitHandler);
466 signal(SIGTERM, stubSignalHandler);
467 signal(SIGINT, stubSignalHandler);
468#ifndef WINDOWS
469 signal(SIGPIPE, SIG_IGN); /* the networking code should catch this */
470#endif
471#else
472 (void) stubExitHandler;
473 (void) stubSignalHandler;
474#endif
475}
476
477
478/**
479 * Return a free port number for the mothership to use, or -1 if we
480 * can't find one.
481 */
482static int
483GenerateMothershipPort(void)
484{
485 const int MAX_PORT = 10100;
486 unsigned short port;
487
488 /* generate initial port number randomly */
489 crRandAutoSeed();
490 port = (unsigned short) crRandInt(10001, MAX_PORT);
491
492#ifdef WINDOWS
493 /* XXX should implement a free port check here */
494 return port;
495#else
496 /*
497 * See if this port number really is free, try another if needed.
498 */
499 {
500 struct sockaddr_in servaddr;
501 int so_reuseaddr = 1;
502 int sock, k;
503
504 /* create socket */
505 sock = socket(AF_INET, SOCK_STREAM, 0);
506 CRASSERT(sock > 2);
507
508 /* deallocate socket/port when we exit */
509 k = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
510 (char *) &so_reuseaddr, sizeof(so_reuseaddr));
511 CRASSERT(k == 0);
512
513 /* initialize the servaddr struct */
514 crMemset(&servaddr, 0, sizeof(servaddr) );
515 servaddr.sin_family = AF_INET;
516 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
517
518 while (port < MAX_PORT) {
519 /* Bind to the given port number, return -1 if we fail */
520 servaddr.sin_port = htons((unsigned short) port);
521 k = bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
522 if (k) {
523 /* failed to create port. try next one. */
524 port++;
525 }
526 else {
527 /* free the socket/port now so mothership can make it */
528 close(sock);
529 return port;
530 }
531 }
532 }
533#endif /* WINDOWS */
534 return -1;
535}
536
537
538/**
539 * Try to determine which mothership configuration to use for this program.
540 */
541static char **
542LookupMothershipConfig(const char *procName)
543{
544 const int procNameLen = crStrlen(procName);
545 FILE *f;
546 const char *home;
547 char configPath[1000];
548
549 /* first, check if the CR_CONFIG env var is set */
550 {
551 const char *conf = crGetenv("CR_CONFIG");
552 if (conf && crStrlen(conf) > 0)
553 return crStrSplit(conf, " ");
554 }
555
556 /* second, look up config name from config file */
557 home = crGetenv("HOME");
558 if (home)
559 sprintf(configPath, "%s/%s", home, CONFIG_LOOKUP_FILE);
560 else
561 crStrcpy(configPath, CONFIG_LOOKUP_FILE); /* from current dir */
562 /* Check if the CR_CONFIG_PATH env var is set. */
563 {
564 const char *conf = crGetenv("CR_CONFIG_PATH");
565 if (conf)
566 crStrcpy(configPath, conf); /* from env var */
567 }
568
569 f = fopen(configPath, "r");
570 if (!f) {
571 return NULL;
572 }
573
574 while (!feof(f)) {
575 char line[1000];
576 char **args;
577 fgets(line, 999, f);
578 line[crStrlen(line) - 1] = 0; /* remove trailing newline */
579 if (crStrncmp(line, procName, procNameLen) == 0 &&
580 (line[procNameLen] == ' ' || line[procNameLen] == '\t'))
581 {
582 crWarning("Using Chromium configuration for %s from %s",
583 procName, configPath);
584 args = crStrSplit(line + procNameLen + 1, " ");
585 return args;
586 }
587 }
588 fclose(f);
589 return NULL;
590}
591
592
593static int Mothership_Awake = 0;
594
595
596/**
597 * Signal handler to determine when mothership is ready.
598 */
599static void
600MothershipPhoneHome(int signo)
601{
602 crDebug("Got signal %d: mothership is awake!", signo);
603 Mothership_Awake = 1;
604}
605
606void stubSetDefaultConfigurationOptions(void)
607{
608 unsigned char key[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
609
610 stub.appDrawCursor = 0;
611 stub.minChromiumWindowWidth = 0;
612 stub.minChromiumWindowHeight = 0;
613 stub.maxChromiumWindowWidth = 0;
614 stub.maxChromiumWindowHeight = 0;
615 stub.matchChromiumWindowID = NULL;
616 stub.numIgnoreWindowID = 0;
617 stub.matchWindowTitle = NULL;
618 stub.ignoreFreeglutMenus = 0;
619 stub.trackWindowSize = 1;
620 stub.trackWindowPos = 1;
621 stub.trackWindowVisibility = 1;
622 stub.trackWindowVisibleRgn = 1;
623 stub.matchChromiumWindowCount = 0;
624 stub.spu_dir = NULL;
625 crNetSetRank(0);
626 crNetSetContextRange(32, 35);
627 crNetSetNodeRange("iam0", "iamvis20");
628 crNetSetKey(key,sizeof(key));
629 stub.force_pbuffers = 0;
630 stub.viewportHack = 0;
631
632#ifdef WINDOWS
633 {
634 char name[1000];
635 int i;
636
637 /* Apply viewport hack only if we're running under wine */
638 if (NULL!=GetModuleHandle("wined3d.dll"))
639 {
640 crGetProcName(name, 1000);
641 for (i=0; gsViewportHackApps[i]; ++i)
642 {
643 if (!stricmp(name, gsViewportHackApps[i]))
644 {
645 stub.viewportHack = 1;
646 break;
647 }
648 }
649 }
650 }
651#endif
652}
653
654#ifdef CR_NEWWINTRACK
655static void stubSyncTrCheckWindowsCB(unsigned long key, void *data1, void *data2)
656{
657 WindowInfo *pWindow = (WindowInfo *) data1;
658 ContextInfo *pCtx = (ContextInfo *) data2;
659
660 if (pWindow->type!=CHROMIUM || pWindow->spuWindow==0)
661 {
662 return;
663 }
664
665 stub.spu->dispatch_table.VBoxPackSetInjectID(pWindow->u32ClientID);
666
667 if (!stubSystemWindowExist(pWindow))
668 {
669#ifdef WINDOWS
670 crWindowDestroy((GLint)pWindow->hWnd);
671#else
672 crWindowDestroy((GLint)pWindow->drawable);
673#endif
674 /*No need to flush here as crWindowDestroy does it*/
675 return;
676 }
677
678 stubCheckWindowState(pWindow, GL_TRUE);
679}
680
681static DECLCALLBACK(int) stubSyncThreadProc(RTTHREAD ThreadSelf, void *pvUser)
682{
683#ifdef WINDOWS
684 MSG msg;
685#endif
686
687 (void) pvUser;
688
689 crDebug("Sync thread started");
690#ifdef WINDOWS
691 PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
692#endif
693
694 crLockMutex(&stub.mutex);
695 stub.spu->dispatch_table.VBoxPackSetInjectThread();
696 crUnlockMutex(&stub.mutex);
697
698 RTThreadUserSignal(ThreadSelf);
699
700 while(!stub.bShutdownSyncThread)
701 {
702#ifdef WINDOWS
703 if (!PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
704 {
705 crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL);
706 RTThreadSleep(50);
707 }
708 else
709 {
710 if (WM_QUIT==msg.message)
711 {
712 crDebug("Sync thread got WM_QUIT");
713 break;
714 }
715 else
716 {
717 TranslateMessage(&msg);
718 DispatchMessage(&msg);
719 }
720 }
721#else
722 crLockMutex(&stub.mutex);
723 crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL);
724 crUnlockMutex(&stub.mutex);
725 RTThreadSleep(50);
726#endif
727 }
728
729 crDebug("Sync thread stopped");
730 return 0;
731}
732#endif
733
734/**
735 * Do one-time initializations for the faker.
736 * Returns TRUE on success, FALSE otherwise.
737 */
738bool
739stubInit(void)
740{
741 /* Here is where we contact the mothership to find out what we're supposed
742 * to be doing. Networking code in a DLL initializer. I sure hope this
743 * works :)
744 *
745 * HOW can I pass the mothership address to this if I already know it?
746 */
747
748 CRConnection *conn = NULL;
749 char response[1024];
750 char **spuchain;
751 int num_spus;
752 int *spu_ids;
753 char **spu_names;
754 const char *app_id;
755 int i;
756 int disable_sync = 0;
757
758 if (stub_initialized)
759 return true;
760
761 stubInitVars();
762
763 crGetProcName(response, 1024);
764 crDebug("Stub launched for %s", response);
765
766#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
767 /*@todo when vm boots with compiz turned on, new code causes hang in xcb_wait_for_reply in the sync thread*/
768 if (!crStrcmp(response, "compiz") || !crStrcmp(response, "compiz_real"))
769 {
770 disable_sync = 1;
771 }
772#endif
773
774 /* @todo check if it'd be of any use on other than guests, no use for windows */
775 app_id = crGetenv( "CR_APPLICATION_ID_NUMBER" );
776
777 crNetInit( NULL, NULL );
778
779#ifndef WINDOWS
780 {
781 CRNetServer ns;
782
783 ns.name = "vboxhgcm://host:0";
784 ns.buffer_size = 1024;
785 crNetServerConnect(&ns);
786 if (!ns.conn)
787 {
788 crWarning("Failed to connect to host. Make sure 3D acceleration is enabled for this VM.");
789 return false;
790 }
791 else
792 {
793 crNetFreeConnection(ns.conn);
794 }
795#if 0 && defined(CR_NEWWINTRACK)
796 {
797 Status st = XInitThreads();
798 if (st==0)
799 {
800 crWarning("XInitThreads returned %i", (int)st);
801 }
802 }
803#endif
804 }
805#endif
806
807 strcpy(response, "2 0 feedback 1 pack");
808 spuchain = crStrSplit( response, " " );
809 num_spus = crStrToInt( spuchain[0] );
810 spu_ids = (int *) crAlloc( num_spus * sizeof( *spu_ids ) );
811 spu_names = (char **) crAlloc( num_spus * sizeof( *spu_names ) );
812 for (i = 0 ; i < num_spus ; i++)
813 {
814 spu_ids[i] = crStrToInt( spuchain[2*i+1] );
815 spu_names[i] = crStrdup( spuchain[2*i+2] );
816 crDebug( "SPU %d/%d: (%d) \"%s\"", i+1, num_spus, spu_ids[i], spu_names[i] );
817 }
818
819 stubSetDefaultConfigurationOptions();
820
821 stub.spu = crSPULoadChain( num_spus, spu_ids, spu_names, stub.spu_dir, NULL );
822
823 crFree( spuchain );
824 crFree( spu_ids );
825 for (i = 0; i < num_spus; ++i)
826 crFree(spu_names[i]);
827 crFree( spu_names );
828
829 // spu chain load failed somewhere
830 if (!stub.spu) {
831 return false;
832 }
833
834 crSPUInitDispatchTable( &glim );
835
836 /* This is unlikely to change -- We still want to initialize our dispatch
837 * table with the functions of the first SPU in the chain. */
838 stubInitSPUDispatch( stub.spu );
839
840 /* we need to plug one special stub function into the dispatch table */
841 glim.GetChromiumParametervCR = stub_GetChromiumParametervCR;
842
843#if !defined(VBOX_NO_NATIVEGL)
844 /* Load pointers to native OpenGL functions into stub.nativeDispatch */
845 stubInitNativeDispatch();
846#endif
847
848/*crDebug("stub init");
849raise(SIGINT);*/
850
851#ifdef WINDOWS
852# ifndef CR_NEWWINTRACK
853 stubInstallWindowMessageHook();
854# endif
855#endif
856
857#ifdef CR_NEWWINTRACK
858 {
859 int rc;
860
861 RTR3Init();
862
863 if (!disable_sync)
864 {
865 crDebug("Starting sync thread");
866
867 rc = RTThreadCreate(&stub.hSyncThread, stubSyncThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "Sync");
868 if (RT_FAILURE(rc))
869 {
870 crError("Failed to start sync thread! (%x)", rc);
871 }
872 RTThreadUserWait(stub.hSyncThread, 60 * 1000);
873 RTThreadUserReset(stub.hSyncThread);
874
875 crDebug("Going on");
876 }
877 }
878#endif
879
880#ifdef GLX
881 stub.xshmSI.shmid = -1;
882 stub.bShmInitFailed = GL_FALSE;
883 stub.pGLXPixmapsHash = crAllocHashtable();
884#endif
885
886 stub_initialized = 1;
887 return true;
888}
889
890/* Sigh -- we can't do initialization at load time, since Windows forbids
891 * the loading of other libraries from DLLMain. */
892
893#ifdef LINUX
894/* GCC crap
895 *void (*stub_init_ptr)(void) __attribute__((section(".ctors"))) = __stubInit; */
896#endif
897
898#ifdef WINDOWS
899#define WIN32_LEAN_AND_MEAN
900#include <windows.h>
901
902/* Windows crap */
903BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
904{
905 (void) lpvReserved;
906
907 switch (fdwReason)
908 {
909 case DLL_PROCESS_ATTACH:
910 {
911 CRNetServer ns;
912
913 crNetInit(NULL, NULL);
914 ns.name = "vboxhgcm://host:0";
915 ns.buffer_size = 1024;
916 crNetServerConnect(&ns);
917 if (!ns.conn)
918 {
919 crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load.");
920 return FALSE;
921 }
922 else
923 crNetFreeConnection(ns.conn);
924
925 break;
926 }
927
928 case DLL_PROCESS_DETACH:
929 {
930 stubSPUSafeTearDown();
931 break;
932 }
933
934 case DLL_THREAD_ATTACH:
935 break;
936
937 case DLL_THREAD_DETACH:
938 break;
939
940 default:
941 break;
942 }
943
944 return TRUE;
945}
946#endif
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette