#include "shell/Shell.h" #include "shell/ShellCallbacks.h" #include "nsopenglshell/NSOpenGLShell.h" #include "nsopenglshell/NSOpenGLTarget.h" #include #include #include #include #include "shell/ShellBatteryInfo.h" #include "shell/ShellCallbacks.h" #include "shell/ShellKeyCodes.h" #include "shell/ShellThreads.h" #include #define msleep(ms) usleep((ms) * 1000) #define VSYNC_DEFAULT_WINDOW true #define VSYNC_DEFAULT_FULLSCREEN true static unsigned int timer1ID = UINT_MAX, timer2ID = UINT_MAX; static bool deltaMode; static bool syncFullscreen = VSYNC_DEFAULT_FULLSCREEN, syncWindow = VSYNC_DEFAULT_WINDOW; static bool printMouseMoved = true; static bool allowQuit = true; static bool enableDisplaySleep = true; static bool receiveMouseMoveEventsOutsideWindow = false; static unsigned int unhideCursorThreshold; static void registerShellCallbacks(); static void unregisterShellCallbacks(); static bool Target_draw(double referenceTime, double activeDrawDelta) { printf("Target_draw(%f, %f)\n", referenceTime, activeDrawDelta); glClearColor(0.0f, 0.25f, 0.5f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); return true; } static void Target_resized(unsigned int newWidth, unsigned int newHeight, double referenceTime) { printf("Target_resized(%d, %d, %f)\n", newWidth, newHeight, referenceTime); glViewport(0, 0, newWidth, newHeight); } static const char * keyboardConstantString(unsigned int keyCode) { #define KEYBOARD_CONST_STRING(constant) case constant: return #constant; switch (keyCode) { KEYBOARD_CONST_STRING(KEY_CODE_A); KEYBOARD_CONST_STRING(KEY_CODE_B); KEYBOARD_CONST_STRING(KEY_CODE_C); KEYBOARD_CONST_STRING(KEY_CODE_D); KEYBOARD_CONST_STRING(KEY_CODE_E); KEYBOARD_CONST_STRING(KEY_CODE_F); KEYBOARD_CONST_STRING(KEY_CODE_G); KEYBOARD_CONST_STRING(KEY_CODE_H); KEYBOARD_CONST_STRING(KEY_CODE_I); KEYBOARD_CONST_STRING(KEY_CODE_J); KEYBOARD_CONST_STRING(KEY_CODE_K); KEYBOARD_CONST_STRING(KEY_CODE_L); KEYBOARD_CONST_STRING(KEY_CODE_M); KEYBOARD_CONST_STRING(KEY_CODE_N); KEYBOARD_CONST_STRING(KEY_CODE_O); KEYBOARD_CONST_STRING(KEY_CODE_P); KEYBOARD_CONST_STRING(KEY_CODE_Q); KEYBOARD_CONST_STRING(KEY_CODE_R); KEYBOARD_CONST_STRING(KEY_CODE_S); KEYBOARD_CONST_STRING(KEY_CODE_T); KEYBOARD_CONST_STRING(KEY_CODE_U); KEYBOARD_CONST_STRING(KEY_CODE_V); KEYBOARD_CONST_STRING(KEY_CODE_W); KEYBOARD_CONST_STRING(KEY_CODE_X); KEYBOARD_CONST_STRING(KEY_CODE_Y); KEYBOARD_CONST_STRING(KEY_CODE_Z); KEYBOARD_CONST_STRING(KEY_CODE_1); KEYBOARD_CONST_STRING(KEY_CODE_2); KEYBOARD_CONST_STRING(KEY_CODE_3); KEYBOARD_CONST_STRING(KEY_CODE_4); KEYBOARD_CONST_STRING(KEY_CODE_5); KEYBOARD_CONST_STRING(KEY_CODE_6); KEYBOARD_CONST_STRING(KEY_CODE_7); KEYBOARD_CONST_STRING(KEY_CODE_8); KEYBOARD_CONST_STRING(KEY_CODE_9); KEYBOARD_CONST_STRING(KEY_CODE_0); KEYBOARD_CONST_STRING(KEY_CODE_ENTER); KEYBOARD_CONST_STRING(KEY_CODE_ESCAPE); KEYBOARD_CONST_STRING(KEY_CODE_BACKSPACE); KEYBOARD_CONST_STRING(KEY_CODE_TAB); KEYBOARD_CONST_STRING(KEY_CODE_SPACE); KEYBOARD_CONST_STRING(KEY_CODE_MINUS); KEYBOARD_CONST_STRING(KEY_CODE_EQUAL); KEYBOARD_CONST_STRING(KEY_CODE_OPEN_BRACKET); KEYBOARD_CONST_STRING(KEY_CODE_CLOSE_BRACKET); KEYBOARD_CONST_STRING(KEY_CODE_BACKSLASH); KEYBOARD_CONST_STRING(KEY_CODE_SEMICOLON); KEYBOARD_CONST_STRING(KEY_CODE_SINGLE_QUOTE); KEYBOARD_CONST_STRING(KEY_CODE_BACKTICK); KEYBOARD_CONST_STRING(KEY_CODE_COMMA); KEYBOARD_CONST_STRING(KEY_CODE_PERIOD); KEYBOARD_CONST_STRING(KEY_CODE_SLASH); KEYBOARD_CONST_STRING(KEY_CODE_CAPS_LOCK); KEYBOARD_CONST_STRING(KEY_CODE_F1); KEYBOARD_CONST_STRING(KEY_CODE_F2); KEYBOARD_CONST_STRING(KEY_CODE_F3); KEYBOARD_CONST_STRING(KEY_CODE_F4); KEYBOARD_CONST_STRING(KEY_CODE_F5); KEYBOARD_CONST_STRING(KEY_CODE_F6); KEYBOARD_CONST_STRING(KEY_CODE_F7); KEYBOARD_CONST_STRING(KEY_CODE_F8); KEYBOARD_CONST_STRING(KEY_CODE_F9); KEYBOARD_CONST_STRING(KEY_CODE_F10); KEYBOARD_CONST_STRING(KEY_CODE_F11); KEYBOARD_CONST_STRING(KEY_CODE_F12); KEYBOARD_CONST_STRING(KEY_CODE_PRINT_SCREEN); KEYBOARD_CONST_STRING(KEY_CODE_SCROLL_LOCK); KEYBOARD_CONST_STRING(KEY_CODE_PAUSE); KEYBOARD_CONST_STRING(KEY_CODE_INSERT); KEYBOARD_CONST_STRING(KEY_CODE_HOME); KEYBOARD_CONST_STRING(KEY_CODE_PAGE_UP); KEYBOARD_CONST_STRING(KEY_CODE_FORWARD_DELETE); KEYBOARD_CONST_STRING(KEY_CODE_END); KEYBOARD_CONST_STRING(KEY_CODE_PAGE_DOWN); KEYBOARD_CONST_STRING(KEY_CODE_RIGHT_ARROW); KEYBOARD_CONST_STRING(KEY_CODE_LEFT_ARROW); KEYBOARD_CONST_STRING(KEY_CODE_DOWN_ARROW); KEYBOARD_CONST_STRING(KEY_CODE_UP_ARROW); KEYBOARD_CONST_STRING(KEY_CODE_NUM_LOCK); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_SLASH); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_ASTERISK); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_MINUS); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_PLUS); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_ENTER); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_1); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_2); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_3); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_4); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_5); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_6); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_7); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_8); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_9); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_0); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_PERIOD); KEYBOARD_CONST_STRING(KEY_CODE_NUMPAD_EQUAL); KEYBOARD_CONST_STRING(KEY_CODE_F13); KEYBOARD_CONST_STRING(KEY_CODE_F14); KEYBOARD_CONST_STRING(KEY_CODE_F15); KEYBOARD_CONST_STRING(KEY_CODE_MENU); KEYBOARD_CONST_STRING(KEY_CODE_LEFT_CONTROL); KEYBOARD_CONST_STRING(KEY_CODE_LEFT_SHIFT); KEYBOARD_CONST_STRING(KEY_CODE_LEFT_ALT); KEYBOARD_CONST_STRING(KEY_CODE_LEFT_GUI); KEYBOARD_CONST_STRING(KEY_CODE_RIGHT_CONTROL); KEYBOARD_CONST_STRING(KEY_CODE_RIGHT_SHIFT); KEYBOARD_CONST_STRING(KEY_CODE_RIGHT_ALT); KEYBOARD_CONST_STRING(KEY_CODE_RIGHT_GUI); } return "Unknown key code!"; } static void timerCallback(unsigned int timerID, void * context) { printf("timerCallback(timerID, \"%s\")\n", (char *) context); if (timerID == timer2ID) { timer2ID = UINT_MAX; } } static void mainThreadFunction(void * context) { printf("Main thread function invoked on thread %p at %f\n", Shell_getCurrentThread(), Shell_getCurrentTime()); } static int threadFunc1(void * context) { printf("Secondary thread 1 %p begin\n", Shell_getCurrentThread()); Shell_lockMutex(context); msleep(1000); Shell_unlockMutex(context); printf("Secondary thread 1 %p end\n", Shell_getCurrentThread()); return 0; } static int threadFunc2(void * context) { printf("Secondary thread 2 %p begin\n", Shell_getCurrentThread()); msleep(1000); Shell_postSemaphore(context); printf("Secondary thread 2 %p end\n", Shell_getCurrentThread()); return 0; } static int threadFunc3(void * context) { printf("Secondary thread 3 %p begin\n", Shell_getCurrentThread()); msleep(1000); printf("Secondary thread 3 %p exit\n", Shell_getCurrentThread()); Shell_exitThread(2); printf("Secondary thread 3 %p end (bad!)\n", Shell_getCurrentThread()); return 0; } static int threadFunc4(void * context) { msleep(500); printf("Calling Shell_executeOnMainThread() called from %p (secondary) at %f\n", Shell_getCurrentThread(), Shell_getCurrentTime()); Shell_executeOnMainThread(mainThreadFunction, NULL); return 0; } static void restoreCallbacksTimer(unsigned int timerID, void * context) { registerShellCallbacks(); printf("Restored event callbacks\n"); } static void Target_keyDown(unsigned int charCode, unsigned int keyCode, unsigned int modifiers, bool isRepeat, double referenceTime) { printf("Target_keyDown(%u, %u, 0x%X, %s, %f) (%s)\n", charCode, keyCode, modifiers, isRepeat ? "true" : "false", referenceTime, keyboardConstantString(keyCode)); if (keyCode == KEY_CODE_Q) { ShellThread thread; ShellMutex mutex; ShellSemaphore semaphore; bool success; int status; printf("Current thread: %p\n\n", Shell_getCurrentThread()); mutex = Shell_createMutex(); printf("Created mutex %p\n", mutex); success = Shell_tryLockMutex(mutex); printf("Lock acquired: %s (expected true)\n", success ? "true" : "false"); success = Shell_tryLockMutex(mutex); printf("Lock acquired: %s (expected true)\n\n", success ? "true" : "false"); Shell_unlockMutex(mutex); Shell_unlockMutex(mutex); thread = Shell_createThread(threadFunc1, mutex); Shell_detachThread(thread); printf("Created thread %p at %f\n", thread, Shell_getCurrentTime()); msleep(500); Shell_lockMutex(mutex); printf("Acquired lock at %f\n\n", Shell_getCurrentTime()); Shell_unlockMutex(mutex); semaphore = Shell_createSemaphore(0); printf("Try wait semaphore: %s (expected false)\n", Shell_tryWaitSemaphore(semaphore) ? "true" : "false"); thread = Shell_createThread(threadFunc2, semaphore); Shell_detachThread(thread); printf("Created thread %p at %f\n", thread, Shell_getCurrentTime()); printf("Try wait semaphore: %s (expected false)\n", Shell_tryWaitSemaphore(semaphore) ? "true" : "false"); Shell_waitSemaphore(semaphore); printf("Acquired semaphore at %f\n\n", Shell_getCurrentTime()); thread = Shell_createThread(threadFunc3, mutex); printf("Created thread %p at %f\n", thread, Shell_getCurrentTime()); status = Shell_joinThread(thread); printf("Joined thread at %f, with status %d\n\n", Shell_getCurrentTime(), status); printf("Calling Shell_executeOnMainThread() called from %p (main) at %f\n", Shell_getCurrentThread(), Shell_getCurrentTime()); Shell_executeOnMainThread(mainThreadFunction, NULL); thread = Shell_createThread(threadFunc4, NULL); printf("Created thread %p at %f\n", thread, Shell_getCurrentTime()); Shell_disposeMutex(mutex); Shell_disposeSemaphore(semaphore); } else if (keyCode == KEY_CODE_T) { printf("Shell_getCurrentTime(): %f\n", Shell_getCurrentTime()); } else if (keyCode == KEY_CODE_R) { printf("Shell_getResourcePath(): %s\n", Shell_getResourcePath()); } else if (keyCode == KEY_CODE_Y) { printf("Shell_getSupportPath(NULL): %s\n", Shell_getSupportPath(NULL)); printf("Shell_getSupportPath(\"nsopenglshell\"): %s\n", Shell_getSupportPath("nsopenglshell")); } else if (keyCode == KEY_CODE_U) { Shell_openURL("http://ludobloom.com/"); } else if (keyCode == KEY_CODE_D) { Shell_redisplay(); } else if (keyCode == KEY_CODE_F) { static bool documentEdited; documentEdited = !documentEdited; Shell_setWindowDocumentEdited(documentEdited); } else if (keyCode == KEY_CODE_E) { unsigned int displayIndex = Shell_getDisplayIndexFromWindow(); printf("Shell_enterFullScreen(%u, %s): %s\n", displayIndex, (modifiers & MODIFIER_SHIFT_BIT) ? "true" : "false", Shell_enterFullScreen(displayIndex, (modifiers & MODIFIER_SHIFT_BIT) ? true : false) ? "true" : "false"); } else if (keyCode == KEY_CODE_W) { Shell_exitFullScreen(); } else if (keyCode == KEY_CODE_G) { printf("Shell_isFullScreen(): %s\n", Shell_isFullScreen() ? "true" : "false"); } else if (keyCode == KEY_CODE_B) { printf("Shell_getBatteryState(): %d\n", Shell_getBatteryState()); printf("Shell_getBatteryLevel(): %f\n", Shell_getBatteryLevel()); } else if (keyCode == KEY_CODE_Z) { int x = 0, y = 0; unsigned int width = 0, height = 0; static unsigned int screenIndex; screenIndex %= Shell_getDisplayCount(); Shell_getSafeWindowRect(screenIndex, &x, &y, &width, &height); printf("Shell_getSafeWindowRect(%u): %d, %d, %u, %u\n", screenIndex, x, y, width, height); printf("Shell_getDisplayRefreshRate(%u): %f\n", screenIndex, Shell_getDisplayRefreshRate(screenIndex)); printf("Shell_getDisplayScaleFactor(%u): %f\n", screenIndex, Shell_getDisplayScaleFactor(screenIndex)); printf("Shell_getDisplayDPI(%u): %f\n", screenIndex, Shell_getDisplayDPI(screenIndex)); screenIndex++; } else if (keyCode == KEY_CODE_X) { int x = 0, y = 0; unsigned int width = 0, height = 0; static unsigned int screenIndex; screenIndex %= Shell_getDisplayCount(); Shell_getDisplayBounds(screenIndex, &x, &y, &width, &height); printf("Shell_getDisplayBounds(%u): %d, %d, %u, %u\n", screenIndex, x, y, width, height); screenIndex++; } else if (keyCode == KEY_CODE_C && (modifiers & MODIFIER_COMMAND_BIT)) { printf("Shell_copyTextToClipboard(\"Pasteboard test text\"): %s\n", Shell_copyTextToClipboard("Pasteboard test text") ? "true" : "false"); } else if (keyCode == KEY_CODE_V && (modifiers & MODIFIER_COMMAND_BIT)) { printf("Shell_getClipboardText(): \"%s\"\n", Shell_getClipboardText()); } else if (keyCode == KEY_CODE_C) { printf("Shell_getDisplayCount(): %u\n", Shell_getDisplayCount()); } else if (keyCode == KEY_CODE_V) { bool sync, fullscreen; fullscreen = Shell_isFullScreen(); if (fullscreen) { syncFullscreen = !syncFullscreen; sync = syncFullscreen; } else { syncWindow = !syncWindow; sync = syncWindow; } Shell_setVSync(sync, fullscreen); printf("Shell_setVSync(%s, %s)\n", sync ? "true" : "false", fullscreen ? "true" : "false"); } else if (keyCode == KEY_CODE_O) { const char * extensions1[] = {"png", "jpg", "jpeg"}, * extensions2[] = {"ogg", "wav"}; struct ShellFileDialogFilter filters[] = { {"Image files", sizeof(extensions1) / sizeof(extensions1[0]), extensions1}, {"Sound files", sizeof(extensions2) / sizeof(extensions2[0]), extensions2} }; if (modifiers & MODIFIER_SHIFT_BIT) { unsigned int filePathCount = 0; const char ** filePaths = Shell_openFileDialogMultiple("Open dialog title", NULL, 0, NULL, &filePathCount, sizeof(filters) / sizeof(filters[0]), filters); if (filePaths != NULL) { printf("Shell_openFileDialogMultiple returned true %u path%s:\n", filePathCount, filePathCount == 1 ? "" : "s"); for (unsigned int fileIndex = 0; fileIndex < filePathCount; fileIndex++) { printf(" \"%s\"\n", filePaths[fileIndex]); } } else { printf("Shell_openFileDialogMultiple returned NULL\n"); } } else if (modifiers & MODIFIER_CONTROL_BIT) { const char * filePath = Shell_chooseFolderDialog("Folder dialog title", NULL); if (filePath != NULL) { printf("Shell_chooseFolderDialog returned path \"%s\"\n", filePath); } else { printf("Shell_chooseFolderDialog returned NULL\n"); } } else { const char * filePath = Shell_openFileDialog("Open multiple dialog title", NULL, NULL, sizeof(filters) / sizeof(filters[0]), filters); if (filePath != NULL) { printf("Shell_openFileDialog returned path \"%s\"\n", filePath); } else { printf("Shell_openFileDialog returned NULL\n"); } } } else if (keyCode == KEY_CODE_P) { const char * extensions1[] = {"png", "jpg", "jpeg"}, * extensions2[] = {"ogg", "wav"}; struct ShellFileDialogFilter filters[] = { {"Image files", sizeof(extensions1) / sizeof(extensions1[0]), extensions1}, {"Sound files", sizeof(extensions2) / sizeof(extensions2[0]), extensions2} }; const char * filePath = Shell_saveFileDialog("Save dialog title", NULL, "test", sizeof(filters) / sizeof(filters[0]), filters); if (filePath != NULL) { printf("Shell_saveFileDialog returned path \"%s\"\n", filePath); } else { printf("Shell_saveFileDialog returned NULL\n"); } } else if (keyCode == KEY_CODE_COMMA) { if (timer1ID == UINT_MAX) { timer1ID = Shell_setTimer(1.0, true, timerCallback, "Timer 1 context"); printf("Shell_setTimer(1.0, true, %p, \"Timer 1 context\"): %u\n", timerCallback, timer1ID); } else { printf("Shell_cancelTimer(%u)\n", timer1ID); Shell_cancelTimer(timer1ID); timer1ID = UINT_MAX; } } else if (keyCode == KEY_CODE_PERIOD) { if (timer2ID == UINT_MAX) { timer2ID = Shell_setTimer(2.0, false, timerCallback, "Timer 2 context"); printf("Shell_setTimer(2.0, false, %p, \"Timer 2 context\"): %u\n", timerCallback, timer2ID); } else { printf("Shell_cancelTimer(%u)\n", timer2ID); Shell_cancelTimer(timer2ID); timer2ID = UINT_MAX; } } else if (keyCode == KEY_CODE_SLASH) { float x, y; Shell_getMousePosition(&x, &y); printf("Shell_getMousePosition(): %f, %f\n", x, y); } else if (keyCode == KEY_CODE_SEMICOLON) { deltaMode = !deltaMode; Shell_setMouseDeltaMode(deltaMode); printf("Shell_setMouseDeltaMode(%s)\n", deltaMode ? "true" : "false"); } else if (keyCode == KEY_CODE_H) { Shell_setCursorVisible(false); } else if (keyCode == KEY_CODE_J) { if (modifiers & MODIFIER_SHIFT_BIT) { Shell_moveResizeWindow(300, 200, 800, 600); } else { Shell_moveWindow(300, 200); } } else if (keyCode == KEY_CODE_K) { Shell_resizeWindow(800, 600); } else if (keyCode == KEY_CODE_S) { Shell_setCursorVisible(true); } else if (keyCode == KEY_CODE_M) { if (modifiers & MODIFIER_SHIFT_BIT) { unhideCursorThreshold = (unhideCursorThreshold + 1) % 3; printf("Shell_setUnhideCursorMovementThreshold(%f)\n", (float) unhideCursorThreshold); Shell_setUnhideCursorMovementThreshold(unhideCursorThreshold); } else { printf("Shell_hideCursorUntilMouseMoves()\n"); Shell_hideCursorUntilMouseMoves(); } } else if (keyCode == KEY_CODE_N) { if (modifiers & MODIFIER_SHIFT_BIT) { receiveMouseMoveEventsOutsideWindow = !receiveMouseMoveEventsOutsideWindow; NSOpenGLShell_receiveMouseMoveEventsOutsideWindow(receiveMouseMoveEventsOutsideWindow); printf("Mouse move events outside window %s\n", receiveMouseMoveEventsOutsideWindow ? "enabled" : "disabled"); } else { printMouseMoved = !printMouseMoved; printf("Mouse move messages %s\n", printMouseMoved ? "enabled" : "disabled"); } } else if (keyCode == KEY_CODE_BACKSPACE) { unregisterShellCallbacks(); printf("Removed all event callbacks for 5 seconds\n"); Shell_setTimer(5.0, false, restoreCallbacksTimer, NULL); } else if (keyCode == KEY_CODE_BACKSLASH) { allowQuit = !allowQuit; printf("Quitting %s\n", allowQuit ? "enabled" : "disabled"); } else if (keyCode == KEY_CODE_SINGLE_QUOTE) { enableDisplaySleep = !enableDisplaySleep; Shell_setDisplaySleepEnabled(enableDisplaySleep); printf("Display sleep %s\n", enableDisplaySleep ? "enabled" : "disabled"); } else if (keyCode == KEY_CODE_SPACE) { printf("Shell_systemBeep()\n"); Shell_systemBeep(); } else if (keyCode == KEY_CODE_L) { printf("Shell_getModifierKeys: 0x%X\n", Shell_getModifierKeys()); } else if (keyCode == KEY_CODE_0 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(ShellCursor_arrow); } else if (keyCode == KEY_CODE_1 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(ShellCursor_iBeam); } else if (keyCode == KEY_CODE_2 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(ShellCursor_crosshair); } else if (keyCode == KEY_CODE_3 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_closedHand); } else if (keyCode == KEY_CODE_4 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_openHand); } else if (keyCode == KEY_CODE_5 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(ShellCursor_hand); } else if (keyCode == KEY_CODE_6 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_resizeLeft); } else if (keyCode == KEY_CODE_7 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_resizeRight); } else if (keyCode == KEY_CODE_8 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_resizeLeftRight); } else if (keyCode == KEY_CODE_9 && !(modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_resizeUp); } else if (keyCode == KEY_CODE_1 && (modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_resizeDown); } else if (keyCode == KEY_CODE_2 && (modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_resizeUpDown); } else if (keyCode == KEY_CODE_3 && (modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_disappearingItem); } else if (keyCode == KEY_CODE_4 && (modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_contextualMenu); } else if (keyCode == KEY_CODE_5 && (modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_dragCopy); } else if (keyCode == KEY_CODE_6 && (modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_dragLink); } else if (keyCode == KEY_CODE_7 && (modifiers & MODIFIER_SHIFT_BIT)) { Shell_setCursor(NSOpenGLShellCursor_operationNotAllowed); } else if (keyCode == KEY_CODE_BACKTICK) { static ShellCursorID customCursorID; if (customCursorID == 0) { #define _ 0x00,0x00,0x00,0x00 #define B 0x00,0x00,0x00,0xFF #define W 0xFF,0xFF,0xFF,0xFF #define R 0xFF,0x00,0x00,0xFF #define b 0x00,0x00,0x00,0x3F #define w 0xFF,0xFF,0xFF,0x3F unsigned char cursor1x[] = { _,_,_,_,_,_,_,W,_,_,_,_,_,_,_, _,_,_,_,_,_,W,R,W,_,_,_,_,_,_, _,_,_,_,_,W,R,W,B,W,_,_,_,_,_, _,_,_,_,W,R,W,w,W,B,W,_,_,_,_, _,_,_,W,R,W,_,w,_,W,B,W,_,_,_, _,_,W,R,W,_,_,w,_,_,W,B,W,_,_, _,W,R,W,_,_,_,w,_,_,_,W,B,W,_, W,R,W,w,w,w,w,b,w,w,w,w,W,B,W, _,W,B,W,_,_,_,b,_,_,_,W,B,W,_, _,_,W,B,W,_,_,w,_,_,W,B,W,_,_, _,_,_,W,B,W,_,w,_,W,B,W,_,_,_, _,_,_,_,W,B,W,w,W,B,W,_,_,_,_, _,_,_,_,_,W,B,W,B,W,_,_,_,_,_, _,_,_,_,_,_,W,B,W,_,_,_,_,_,_, _,_,_,_,_,_,_,W,_,_,_,_,_,_,_ }; unsigned char cursor2x[] = { _,_,_,_,_,_,_,_,_,_,_,_,_,_,W,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,_,_,W,R,W,_,_,_,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,_,W,R,R,B,W,_,_,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,W,R,R,R,B,B,W,_,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,W,R,R,R,W,B,B,B,W,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,W,R,R,R,W,w,W,B,B,B,W,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,W,R,R,R,W,_,w,_,W,B,B,B,W,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,W,R,R,R,W,_,_,w,_,_,W,B,B,B,W,_,_,_,_,_,_,_,_, _,_,_,_,_,_,W,R,R,R,W,_,_,_,w,_,_,_,W,B,B,B,W,_,_,_,_,_,_,_, _,_,_,_,_,W,R,R,R,W,_,_,_,_,w,_,_,_,_,W,B,B,B,W,_,_,_,_,_,_, _,_,_,_,W,R,R,R,W,_,_,_,_,_,w,_,_,_,_,_,W,B,B,B,W,_,_,_,_,_, _,_,_,W,R,R,R,W,_,_,_,_,_,_,w,_,_,_,_,_,_,W,B,B,B,W,_,_,_,_, _,_,W,R,R,R,W,_,_,_,_,_,_,_,w,_,_,_,_,_,_,_,W,B,B,B,W,_,_,_, _,W,R,R,R,W,_,_,_,_,_,_,_,w,b,w,_,_,_,_,_,_,_,W,B,B,B,W,_,_, W,R,R,R,W,w,w,w,w,w,w,w,w,b,b,b,w,w,w,w,w,w,w,w,W,B,B,B,W,_, _,W,B,B,B,W,_,_,_,_,_,_,_,w,b,w,_,_,_,_,_,_,_,W,B,B,B,W,_,_, _,_,W,B,B,B,W,_,_,_,_,_,_,_,w,_,_,_,_,_,_,_,W,B,B,B,W,_,_,_, _,_,_,W,B,B,B,W,_,_,_,_,_,_,w,_,_,_,_,_,_,W,B,B,B,W,_,_,_,_, _,_,_,_,W,B,B,B,W,_,_,_,_,_,w,_,_,_,_,_,W,B,B,B,W,_,_,_,_,_, _,_,_,_,_,W,B,B,B,W,_,_,_,_,w,_,_,_,_,W,B,B,B,W,_,_,_,_,_,_, _,_,_,_,_,_,W,B,B,B,W,_,_,_,w,_,_,_,W,B,B,B,W,_,_,_,_,_,_,_, _,_,_,_,_,_,_,W,B,B,B,W,_,_,w,_,_,W,B,B,B,W,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,W,B,B,B,W,_,w,_,W,B,B,B,W,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,W,B,B,B,W,w,W,B,B,B,W,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,W,B,B,B,W,B,B,B,W,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,W,B,B,B,B,B,W,_,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,_,W,B,B,B,W,_,_,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,_,_,W,B,W,_,_,_,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,_,_,_,W,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_, _,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_ }; #undef _ #undef B #undef W struct ShellCustomCursorImage images[2] = { {15, 15, cursor1x, 1.0f}, {30, 30, cursor2x, 2.0f} }; customCursorID = Shell_registerCustomCursor(sizeof(images) / sizeof(images[0]), images, 7, 7); } Shell_setCursor(customCursorID); } } static void Target_keyUp(unsigned int keyCode, unsigned int modifiers, double referenceTime) { printf("Target_keyUp(%u, 0x%X, %f) (%s)\n", keyCode, modifiers, referenceTime, keyboardConstantString(keyCode)); } static void Target_keyModifiersChanged(unsigned int modifiers, unsigned int lastModifiers, double referenceTime) { printf("Target_keyModifiersChanged(0x%X, 0x%X, %f)\n", modifiers, lastModifiers, referenceTime); } static void Target_mouseDown(unsigned int buttonNumber, unsigned int buttonMask, float x, float y, unsigned int modifiers, double referenceTime) { printf("Target_mouseDown(%d, 0x%X, %f, %f, 0x%X, %f)\n", buttonNumber, buttonMask, x, y, modifiers, referenceTime); } static void Target_mouseUp(unsigned int buttonNumber, unsigned int buttonMask, float x, float y, unsigned int modifiers, double referenceTime) { printf("Target_mouseUp(%d, 0x%X, %f, %f, 0x%X, %f)\n", buttonNumber, buttonMask, x, y, modifiers, referenceTime); } static void Target_mouseMoved(float x, float y, float deltaX, float deltaY, unsigned int modifiers, double referenceTime) { if (printMouseMoved) { printf("Target_mouseMoved(%f, %f, %f, %f, 0x%X, %f)\n", x, y, deltaX, deltaY, modifiers, referenceTime); } } static void Target_mouseDragged(unsigned int buttonMask, float x, float y, float deltaX, float deltaY, unsigned int modifiers, double referenceTime) { printf("Target_mouseDragged(0x%X, %f, %f, %f, %f, 0x%X, %f)\n", buttonMask, x, y, deltaX, deltaY, modifiers, referenceTime); } static void Target_mouseLeave(unsigned int modifiers, double referenceTime) { printf("Target_mouseLeave(0x%X, %f)\n", modifiers, referenceTime); } static void Target_cursorUnhidden(bool fromMouseMovement, double referenceTime) { printf("Target_cursorUnhidden(%s, %f)\n", fromMouseMovement ? "true" : "false", referenceTime); } static void Target_scrollWheel(float x, float y, int deltaX, int deltaY, unsigned int buttonMask, unsigned int modifiers, double referenceTime) { printf("Target_scrollWheel(%f, %f, %d, %d, 0x%X, 0x%X, %f)\n", x, y, deltaX, deltaY, buttonMask, modifiers, referenceTime); } static void Target_backgrounded(double referenceTime) { printf("Target_backgrounded(%f)\n", referenceTime); } static void Target_foregrounded(double referenceTime) { printf("Target_foregrounded(%f)\n", referenceTime); } static bool Target_confirmQuit(double referenceTime) { printf("Target_confirmQuit(%f) (returning %s)\n", referenceTime, allowQuit ? "true" : "false"); return allowQuit; } static void registerShellCallbacks() { Shell_drawFunc(Target_draw); Shell_resizeFunc(Target_resized); Shell_keyDownFunc(Target_keyDown); Shell_keyUpFunc(Target_keyUp); Shell_keyModifiersChangedFunc(Target_keyModifiersChanged); Shell_mouseDownFunc(Target_mouseDown); Shell_mouseUpFunc(Target_mouseUp); Shell_mouseMovedFunc(Target_mouseMoved); Shell_mouseDraggedFunc(Target_mouseDragged); Shell_mouseLeaveFunc(Target_mouseLeave); Shell_cursorUnhiddenFunc(Target_cursorUnhidden); Shell_scrollWheelFunc(Target_scrollWheel); Shell_backgroundedFunc(Target_backgrounded); Shell_foregroundedFunc(Target_foregrounded); Shell_confirmQuitFunc(Target_confirmQuit); } static void unregisterShellCallbacks() { Shell_drawFunc(NULL); Shell_resizeFunc(NULL); Shell_keyDownFunc(NULL); Shell_keyUpFunc(NULL); Shell_keyModifiersChangedFunc(NULL); Shell_mouseDownFunc(NULL); Shell_mouseUpFunc(NULL); Shell_mouseMovedFunc(NULL); Shell_mouseDraggedFunc(NULL); Shell_mouseLeaveFunc(NULL); Shell_cursorUnhiddenFunc(NULL); Shell_scrollWheelFunc(NULL); Shell_backgroundedFunc(NULL); Shell_foregroundedFunc(NULL); Shell_confirmQuitFunc(NULL); } void NSOpenGLTarget_configure(int argc, const char ** argv, struct NSOpenGLShellConfiguration * configuration) { int argIndex; char workingDir[PATH_MAX]; printf("NSOpenGLTarget_configure(%d", argc); for (argIndex = 0; argIndex < argc; argIndex++) { printf(", \"%s\"", argv[argIndex]); } printf(", %p)\n", configuration); printf("configuration->windowX: %d\n", configuration->windowX); printf("configuration->windowY: %d\n", configuration->windowY); printf("configuration->windowWidth: %d\n", configuration->windowWidth); printf("configuration->windowHeight: %d\n", configuration->windowHeight); printf("configuration->windowTitle: %s\n", configuration->windowTitle); printf("configuration->fullScreenMenuItem: %s\n", configuration->fullScreenMenuItem ? "true" : "false"); printf("configuration->displayMode.doubleBuffer: %s\n", configuration->displayMode.doubleBuffer ? "true" : "false"); printf("configuration->displayMode.depthBuffer: %s\n", configuration->displayMode.depthBuffer ? "true" : "false"); printf("configuration->displayMode.depthBits: %u\n", configuration->displayMode.depthBits); printf("configuration->displayMode.stencilBuffer: %s\n", configuration->displayMode.stencilBuffer ? "true" : "false"); printf("configuration->displayMode.stencilBits: %u\n", configuration->displayMode.stencilBits); printf("configuration->displayMode.accumBuffer: %s\n", configuration->displayMode.accumBuffer ? "true" : "false"); printf("configuration->displayMode.accumBits: %u\n", configuration->displayMode.accumBits); printf("configuration->displayMode.multisample: %s\n", configuration->displayMode.multisample ? "true" : "false"); printf("configuration->displayMode.sampleBuffers: %u\n", configuration->displayMode.sampleBuffers); printf("configuration->displayMode.samples: %u\n", configuration->displayMode.samples); configuration->windowTitle = "NSOpenGLShell Test Harness"; printf("configuration->windowTitle = \"%s\"\n", configuration->windowTitle); configuration->fullScreenMenuItem = true; printf("configuration->fullScreenMenuItem = true\n"); for (argIndex = 0; argIndex < argc; argIndex++) { if (!strcmp(argv[argIndex], "--windowRect") && argIndex < argc - 4) { sscanf(argv[argIndex + 1], "%d", &configuration->windowX); sscanf(argv[argIndex + 2], "%d", &configuration->windowY); sscanf(argv[argIndex + 3], "%d", &configuration->windowWidth); sscanf(argv[argIndex + 4], "%d", &configuration->windowHeight); printf("configuration->windowX = %d\n", configuration->windowX); printf("configuration->windowY = %d\n", configuration->windowY); printf("configuration->windowWidth = %d\n", configuration->windowWidth); printf("configuration->windowHeight = %d\n", configuration->windowHeight); argIndex += 4; } } printf("getcwd(): %s\n", getcwd(workingDir, PATH_MAX)); registerShellCallbacks(); } void Target_init() { printf("Target_init()\n"); Shell_mainLoop(); }