00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "internal.h"
00029
00030 #include <stdlib.h>
00031 #if defined(_MSC_VER)
00032 #include <malloc.h>
00033 #endif
00034
00035
00036 #define _GLFW_STICK 3
00037
00038
00039
00040
00041 static void setCursorMode(_GLFWwindow* window, int newMode)
00042 {
00043 const int oldMode = window->cursorMode;
00044
00045 if (newMode != GLFW_CURSOR_NORMAL &&
00046 newMode != GLFW_CURSOR_HIDDEN &&
00047 newMode != GLFW_CURSOR_DISABLED)
00048 {
00049 _glfwInputError(GLFW_INVALID_ENUM, "Invalid cursor mode");
00050 return;
00051 }
00052
00053 if (oldMode == newMode)
00054 return;
00055
00056 window->cursorMode = newMode;
00057
00058 if (_glfw.cursorWindow == window)
00059 {
00060 if (oldMode == GLFW_CURSOR_DISABLED)
00061 {
00062 _glfwPlatformSetCursorPos(window,
00063 _glfw.cursorPosX,
00064 _glfw.cursorPosY);
00065 }
00066 else if (newMode == GLFW_CURSOR_DISABLED)
00067 {
00068 int width, height;
00069
00070 _glfwPlatformGetCursorPos(window,
00071 &_glfw.cursorPosX,
00072 &_glfw.cursorPosY);
00073
00074 window->cursorPosX = _glfw.cursorPosX;
00075 window->cursorPosY = _glfw.cursorPosY;
00076
00077 _glfwPlatformGetWindowSize(window, &width, &height);
00078 _glfwPlatformSetCursorPos(window, width / 2, height / 2);
00079 }
00080
00081 _glfwPlatformApplyCursorMode(window);
00082 }
00083 }
00084
00085
00086
00087 static void setStickyKeys(_GLFWwindow* window, int enabled)
00088 {
00089 if (window->stickyKeys == enabled)
00090 return;
00091
00092 if (!enabled)
00093 {
00094 int i;
00095
00096
00097 for (i = 0; i <= GLFW_KEY_LAST; i++)
00098 {
00099 if (window->keys[i] == _GLFW_STICK)
00100 window->keys[i] = GLFW_RELEASE;
00101 }
00102 }
00103
00104 window->stickyKeys = enabled;
00105 }
00106
00107
00108
00109 static void setStickyMouseButtons(_GLFWwindow* window, int enabled)
00110 {
00111 if (window->stickyMouseButtons == enabled)
00112 return;
00113
00114 if (!enabled)
00115 {
00116 int i;
00117
00118
00119 for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
00120 {
00121 if (window->mouseButtons[i] == _GLFW_STICK)
00122 window->mouseButtons[i] = GLFW_RELEASE;
00123 }
00124 }
00125
00126 window->stickyMouseButtons = enabled;
00127 }
00128
00129
00133
00134 void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods)
00135 {
00136 if (key >= 0 && key <= GLFW_KEY_LAST)
00137 {
00138 GLboolean repeated = GL_FALSE;
00139
00140 if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)
00141 return;
00142
00143 if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)
00144 repeated = GL_TRUE;
00145
00146 if (action == GLFW_RELEASE && window->stickyKeys)
00147 window->keys[key] = _GLFW_STICK;
00148 else
00149 window->keys[key] = (char) action;
00150
00151 if (repeated)
00152 action = GLFW_REPEAT;
00153 }
00154
00155 if (window->callbacks.key)
00156 window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods);
00157 }
00158
00159 void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, int plain)
00160 {
00161 if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
00162 return;
00163
00164 if (window->callbacks.charmods)
00165 window->callbacks.charmods((GLFWwindow*) window, codepoint, mods);
00166
00167 if (plain)
00168 {
00169 if (window->callbacks.character)
00170 window->callbacks.character((GLFWwindow*) window, codepoint);
00171 }
00172 }
00173
00174 void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
00175 {
00176 if (window->callbacks.scroll)
00177 window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
00178 }
00179
00180 void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
00181 {
00182 if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
00183 return;
00184
00185
00186 if (action == GLFW_RELEASE && window->stickyMouseButtons)
00187 window->mouseButtons[button] = _GLFW_STICK;
00188 else
00189 window->mouseButtons[button] = (char) action;
00190
00191 if (window->callbacks.mouseButton)
00192 window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
00193 }
00194
00195 void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y)
00196 {
00197 if (window->cursorMode == GLFW_CURSOR_DISABLED)
00198 {
00199 if (x == 0.0 && y == 0.0)
00200 return;
00201
00202 window->cursorPosX += x;
00203 window->cursorPosY += y;
00204
00205 x = window->cursorPosX;
00206 y = window->cursorPosY;
00207 }
00208
00209 if (window->callbacks.cursorPos)
00210 window->callbacks.cursorPos((GLFWwindow*) window, x, y);
00211 }
00212
00213 void _glfwInputCursorEnter(_GLFWwindow* window, int entered)
00214 {
00215 if (window->callbacks.cursorEnter)
00216 window->callbacks.cursorEnter((GLFWwindow*) window, entered);
00217 }
00218
00219 void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
00220 {
00221 if (window->callbacks.drop)
00222 window->callbacks.drop((GLFWwindow*) window, count, paths);
00223 }
00224
00225
00229
00230 GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
00231 {
00232 _GLFWwindow* window = (_GLFWwindow*) handle;
00233
00234 _GLFW_REQUIRE_INIT_OR_RETURN(0);
00235
00236 switch (mode)
00237 {
00238 case GLFW_CURSOR:
00239 return window->cursorMode;
00240 case GLFW_STICKY_KEYS:
00241 return window->stickyKeys;
00242 case GLFW_STICKY_MOUSE_BUTTONS:
00243 return window->stickyMouseButtons;
00244 default:
00245 _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode");
00246 return 0;
00247 }
00248 }
00249
00250 GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
00251 {
00252 _GLFWwindow* window = (_GLFWwindow*) handle;
00253
00254 _GLFW_REQUIRE_INIT();
00255
00256 switch (mode)
00257 {
00258 case GLFW_CURSOR:
00259 setCursorMode(window, value);
00260 break;
00261 case GLFW_STICKY_KEYS:
00262 setStickyKeys(window, value ? GL_TRUE : GL_FALSE);
00263 break;
00264 case GLFW_STICKY_MOUSE_BUTTONS:
00265 setStickyMouseButtons(window, value ? GL_TRUE : GL_FALSE);
00266 break;
00267 default:
00268 _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode");
00269 break;
00270 }
00271 }
00272
00273 GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
00274 {
00275 _GLFWwindow* window = (_GLFWwindow*) handle;
00276
00277 _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
00278
00279 if (key < 0 || key > GLFW_KEY_LAST)
00280 {
00281 _glfwInputError(GLFW_INVALID_ENUM, "Invalid key");
00282 return GLFW_RELEASE;
00283 }
00284
00285 if (window->keys[key] == _GLFW_STICK)
00286 {
00287
00288 window->keys[key] = GLFW_RELEASE;
00289 return GLFW_PRESS;
00290 }
00291
00292 return (int) window->keys[key];
00293 }
00294
00295 GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
00296 {
00297 _GLFWwindow* window = (_GLFWwindow*) handle;
00298
00299 _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
00300
00301 if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
00302 {
00303 _glfwInputError(GLFW_INVALID_ENUM,
00304 "Invalid mouse button");
00305 return GLFW_RELEASE;
00306 }
00307
00308 if (window->mouseButtons[button] == _GLFW_STICK)
00309 {
00310
00311 window->mouseButtons[button] = GLFW_RELEASE;
00312 return GLFW_PRESS;
00313 }
00314
00315 return (int) window->mouseButtons[button];
00316 }
00317
00318 GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
00319 {
00320 _GLFWwindow* window = (_GLFWwindow*) handle;
00321
00322 if (xpos)
00323 *xpos = 0;
00324 if (ypos)
00325 *ypos = 0;
00326
00327 _GLFW_REQUIRE_INIT();
00328
00329 if (window->cursorMode == GLFW_CURSOR_DISABLED)
00330 {
00331 if (xpos)
00332 *xpos = window->cursorPosX;
00333 if (ypos)
00334 *ypos = window->cursorPosY;
00335 }
00336 else
00337 _glfwPlatformGetCursorPos(window, xpos, ypos);
00338 }
00339
00340 GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
00341 {
00342 _GLFWwindow* window = (_GLFWwindow*) handle;
00343
00344 _GLFW_REQUIRE_INIT();
00345
00346 if (_glfw.cursorWindow != window)
00347 return;
00348
00349 if (window->cursorMode == GLFW_CURSOR_DISABLED)
00350 {
00351
00352 window->cursorPosX = xpos;
00353 window->cursorPosY = ypos;
00354 }
00355 else
00356 {
00357
00358 _glfwPlatformSetCursorPos(window, xpos, ypos);
00359 }
00360 }
00361
00362 GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
00363 {
00364 _GLFWcursor* cursor;
00365
00366 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00367
00368 cursor = calloc(1, sizeof(_GLFWcursor));
00369 cursor->next = _glfw.cursorListHead;
00370 _glfw.cursorListHead = cursor;
00371
00372 if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot))
00373 {
00374 glfwDestroyCursor((GLFWcursor*) cursor);
00375 return NULL;
00376 }
00377
00378 return (GLFWcursor*) cursor;
00379 }
00380
00381 GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
00382 {
00383 _GLFWcursor* cursor;
00384
00385 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00386
00387 if (shape != GLFW_ARROW_CURSOR &&
00388 shape != GLFW_IBEAM_CURSOR &&
00389 shape != GLFW_CROSSHAIR_CURSOR &&
00390 shape != GLFW_HAND_CURSOR &&
00391 shape != GLFW_HRESIZE_CURSOR &&
00392 shape != GLFW_VRESIZE_CURSOR)
00393 {
00394 _glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor");
00395 return NULL;
00396 }
00397
00398 cursor = calloc(1, sizeof(_GLFWcursor));
00399 cursor->next = _glfw.cursorListHead;
00400 _glfw.cursorListHead = cursor;
00401
00402 if (!_glfwPlatformCreateStandardCursor(cursor, shape))
00403 {
00404 glfwDestroyCursor((GLFWcursor*) cursor);
00405 return NULL;
00406 }
00407
00408 return (GLFWcursor*) cursor;
00409 }
00410
00411 GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
00412 {
00413 _GLFWcursor* cursor = (_GLFWcursor*) handle;
00414
00415 _GLFW_REQUIRE_INIT();
00416
00417 if (cursor == NULL)
00418 return;
00419
00420
00421 {
00422 _GLFWwindow* window;
00423
00424 for (window = _glfw.windowListHead; window; window = window->next)
00425 {
00426 if (window->cursor == cursor)
00427 glfwSetCursor((GLFWwindow*) window, NULL);
00428 }
00429 }
00430
00431 _glfwPlatformDestroyCursor(cursor);
00432
00433
00434 {
00435 _GLFWcursor** prev = &_glfw.cursorListHead;
00436
00437 while (*prev != cursor)
00438 prev = &((*prev)->next);
00439
00440 *prev = cursor->next;
00441 }
00442
00443 free(cursor);
00444 }
00445
00446 GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
00447 {
00448 _GLFWwindow* window = (_GLFWwindow*) windowHandle;
00449 _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;
00450
00451 _GLFW_REQUIRE_INIT();
00452
00453 _glfwPlatformSetCursor(window, cursor);
00454
00455 window->cursor = cursor;
00456 }
00457
00458 GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
00459 {
00460 _GLFWwindow* window = (_GLFWwindow*) handle;
00461 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00462 _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun);
00463 return cbfun;
00464 }
00465
00466 GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
00467 {
00468 _GLFWwindow* window = (_GLFWwindow*) handle;
00469 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00470 _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun);
00471 return cbfun;
00472 }
00473
00474 GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun)
00475 {
00476 _GLFWwindow* window = (_GLFWwindow*) handle;
00477 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00478 _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun);
00479 return cbfun;
00480 }
00481
00482 GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
00483 GLFWmousebuttonfun cbfun)
00484 {
00485 _GLFWwindow* window = (_GLFWwindow*) handle;
00486 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00487 _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun);
00488 return cbfun;
00489 }
00490
00491 GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
00492 GLFWcursorposfun cbfun)
00493 {
00494 _GLFWwindow* window = (_GLFWwindow*) handle;
00495 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00496 _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun);
00497 return cbfun;
00498 }
00499
00500 GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
00501 GLFWcursorenterfun cbfun)
00502 {
00503 _GLFWwindow* window = (_GLFWwindow*) handle;
00504 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00505 _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun);
00506 return cbfun;
00507 }
00508
00509 GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
00510 GLFWscrollfun cbfun)
00511 {
00512 _GLFWwindow* window = (_GLFWwindow*) handle;
00513 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00514 _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun);
00515 return cbfun;
00516 }
00517
00518 GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
00519 {
00520 _GLFWwindow* window = (_GLFWwindow*) handle;
00521 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00522 _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
00523 return cbfun;
00524 }
00525
00526 GLFWAPI int glfwJoystickPresent(int joy)
00527 {
00528 _GLFW_REQUIRE_INIT_OR_RETURN(0);
00529
00530 if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
00531 {
00532 _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick");
00533 return 0;
00534 }
00535
00536 return _glfwPlatformJoystickPresent(joy);
00537 }
00538
00539 GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count)
00540 {
00541 *count = 0;
00542
00543 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00544
00545 if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
00546 {
00547 _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick");
00548 return NULL;
00549 }
00550
00551 return _glfwPlatformGetJoystickAxes(joy, count);
00552 }
00553
00554 GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count)
00555 {
00556 *count = 0;
00557
00558 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00559
00560 if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
00561 {
00562 _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick");
00563 return NULL;
00564 }
00565
00566 return _glfwPlatformGetJoystickButtons(joy, count);
00567 }
00568
00569 GLFWAPI const char* glfwGetJoystickName(int joy)
00570 {
00571 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00572
00573 if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
00574 {
00575 _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick");
00576 return NULL;
00577 }
00578
00579 return _glfwPlatformGetJoystickName(joy);
00580 }
00581
00582 GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
00583 {
00584 _GLFWwindow* window = (_GLFWwindow*) handle;
00585 _GLFW_REQUIRE_INIT();
00586 _glfwPlatformSetClipboardString(window, string);
00587 }
00588
00589 GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
00590 {
00591 _GLFWwindow* window = (_GLFWwindow*) handle;
00592 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
00593 return _glfwPlatformGetClipboardString(window);
00594 }
00595
00596 GLFWAPI double glfwGetTime(void)
00597 {
00598 _GLFW_REQUIRE_INIT_OR_RETURN(0.0);
00599 return _glfwPlatformGetTime();
00600 }
00601
00602 GLFWAPI void glfwSetTime(double time)
00603 {
00604 _GLFW_REQUIRE_INIT();
00605
00606 if (time != time || time < 0.0 || time > 18446744073.0)
00607 {
00608 _glfwInputError(GLFW_INVALID_VALUE, "Invalid time");
00609 return;
00610 }
00611
00612 _glfwPlatformSetTime(time);
00613 }
00614