/* Function: al_install_mouse */ bool al_install_mouse(void) { if (new_mouse_driver) return true; //FIXME: seems A4/A5 driver list stuff doesn't quite agree right now if (al_get_system_driver()->vt->get_mouse_driver) { new_mouse_driver = al_get_system_driver()->vt->get_mouse_driver(); if (!new_mouse_driver->init_mouse()) { new_mouse_driver = NULL; return false; } _al_add_exit_func(al_uninstall_mouse, "al_uninstall_mouse"); return true; } return false; #if 0 if (system_driver && system_driver->mouse_drivers) driver_list = system_driver->mouse_drivers(); else driver_list = _al_mouse_driver_list; ASSERT(driver_list); for (i=0; driver_list[i].driver; i++) { new_mouse_driver = driver_list[i].driver; //name = get_config_text(new_mouse_driver->msedrv_ascii_name); name = new_mouse_driver->msedrv_ascii_name; new_mouse_driver->msedrv_name = name; new_mouse_driver->msedrv_desc = name; if (new_mouse_driver->init_mouse()) { break; } } if (!driver_list[i].driver) { new_mouse_driver = NULL; return false; } _al_add_exit_func(al_uninstall_mouse, "al_uninstall_mouse"); return true; #endif }
static int xglx_get_num_video_adapters(void) { #ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); if (!system->xinerama_available) { return 1; } if (system->xinerama_screen_info) { XFree(system->xinerama_screen_info); system->xinerama_screen_info = NULL; system->xinerama_screen_count = 0; } _al_mutex_lock(&system->lock); system->xinerama_screen_info = XineramaQueryScreens(system->x11display, &(system->xinerama_screen_count)); _al_mutex_unlock(&system->lock); if (!system->xinerama_screen_info) { system->xinerama_available = 0; system->xinerama_screen_count = 0; return 1; } return system->xinerama_screen_count; #else /* !ALLEGRO_XWINDOWS_WITH_XINERAMA */ return 1; #endif /* !ALLEGRO_XWINDOWS_WITH_XINERAMA */ }
/* xmouse_get_mouse_num_buttons: * Return the number of buttons on the mouse. */ static unsigned int xmouse_get_mouse_num_buttons(void) { int num_buttons; unsigned char map[32]; ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ASSERT(xmouse_installed); _al_mutex_lock(&system->lock); num_buttons = XGetPointerMapping(system->x11display, map, sizeof(map)); _al_mutex_unlock(&system->lock); if (num_buttons > (int)sizeof(map)) num_buttons = sizeof(map); #ifdef DEBUGMODE char debug[num_buttons * 4 + 1]; debug[0] = 0; int i; for (i = 0; i < num_buttons; i++) { sprintf(debug + strlen(debug), "%2d,", map[i]); } ALLEGRO_DEBUG("XGetPointerMapping: %s\n", debug); #endif if (num_buttons < 1) num_buttons = 1; return num_buttons; }
/* xmouse_init: * Initialise the driver. */ static bool xmouse_init(void) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY *display; int x, y; if (system->x11display == NULL) return false; if (xmouse_installed) return false; /* Don't clobber mouse position in case the display was created before * the mouse is installed. */ display = the_mouse.state.display; x = the_mouse.state.x; y = the_mouse.state.y; memset(&the_mouse, 0, sizeof the_mouse); the_mouse.state.display = display; the_mouse.state.x = x; the_mouse.state.y = y; _al_event_source_init(&the_mouse.parent.es); xmouse_installed = true; return true; }
/* [user thread] */ static void xgtk_set_fullscreen_window(ALLEGRO_DISPLAY *display, bool onoff) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; if (onoff == (display->flags & ALLEGRO_FULLSCREEN_WINDOW)) { return; } _al_mutex_lock(&system->lock); { int old_resize_count; ARGS_FULLSCREEN_WINDOW args; display->flags ^= ALLEGRO_FULLSCREEN_WINDOW; old_resize_count = d->resize_count; d->programmatic_resize = true; if (_al_gtk_init_args(&args, sizeof(args))) { args.display = d; args.fullscreen = onoff; _al_gtk_wait_for_args(do_set_fullscreen_window, &args); _al_display_xglx_await_resize(display, old_resize_count, (display->flags & ALLEGRO_FULLSCREEN)); } d->programmatic_resize = false; } _al_mutex_unlock(&system->lock); }
static void win_shutdown(void) { ALLEGRO_SYSTEM *s; ASSERT(vt); /* Close all open displays. */ s = al_get_system_driver(); while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; al_destroy_display(d); } _al_vector_free(&s->displays); #ifdef ALLEGRO_CFG_D3D _al_d3d_shutdown_display(); #endif _al_win_shutdown_time(); if (using_higher_res_timer) { timeEndPeriod(1); } al_free(vt); vt = NULL; ASSERT(_al_win_system); al_free(_al_win_system); }
/* Note: The system mutex must be locked (exactly once) so when we * wait for the condition variable it gets auto-unlocked. For a * nested lock that would not be the case. */ void _al_display_xglx_await_resize(ALLEGRO_DISPLAY *d, int old_resize_count, bool delay_hack) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d; ALLEGRO_TIMEOUT timeout; ALLEGRO_DEBUG("Awaiting resize event\n"); XSync(system->x11display, False); /* Wait until we are actually resized. * Don't wait forever if an event never comes. */ al_init_timeout(&timeout, 1.0); while (old_resize_count == glx->resize_count) { if (_al_cond_timedwait(&system->resized, &system->lock, &timeout) == -1) { ALLEGRO_ERROR("Timeout while waiting for resize event.\n"); return; } } /* XXX: This hack helps when toggling between fullscreen windows and not, * on various window managers. */ if (delay_hack) { al_rest(0.2); } xdpy_acknowledge_resize(d); }
static int xglx_get_num_display_modes(void) { int adapter = al_get_new_display_adapter(); ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); return _al_xglx_get_num_display_modes(s, adapter); }
void _al_xglx_set_above(ALLEGRO_DISPLAY *display, int value) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; Display *x11 = system->x11display; ALLEGRO_DEBUG("Toggling _NET_WM_STATE_ABOVE hint: %d\n", value); XEvent xev; xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.message_type = X11_ATOM(_NET_WM_STATE); xev.xclient.window = glx->window; xev.xclient.format = 32; // Note: It seems 0 is not reliable except when mapping a window - // 2 is all we need though. xev.xclient.data.l[0] = value; /* 0 = off, 1 = on, 2 = toggle */ xev.xclient.data.l[1] = X11_ATOM(_NET_WM_STATE_ABOVE); xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 1; XSendEvent(x11, DefaultRootWindow(x11), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); }
static void xdpy_unset_current_display(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); (void)d; glXMakeContextCurrent(system->gfxdisplay, None, None, NULL); }
static void win_shutdown(void) { ALLEGRO_SYSTEM *s; ALLEGRO_DISPLAY_INTERFACE *display_driver; ASSERT(vt); /* Close all open displays. */ s = al_get_system_driver(); while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; _al_destroy_display_bitmaps(d); al_destroy_display(d); } _al_vector_free(&s->displays); display_driver = vt->get_display_driver(); if (display_driver && display_driver->shutdown) { display_driver->shutdown(); } _al_win_shutdown_time(); if (using_higher_res_timer) { timeEndPeriod(1); } al_free(vt); vt = NULL; ASSERT(_al_win_system); al_free(_al_win_system); }
static bool xdpy_create_display_hook_default(ALLEGRO_DISPLAY *display, int w, int h) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; (void)w; (void)h; set_initial_icon(system->x11display, d->window); XLockDisplay(system->x11display); XMapWindow(system->x11display, d->window); ALLEGRO_DEBUG("X11 window mapped.\n"); d->wm_delete_window_atom = XInternAtom(system->x11display, "WM_DELETE_WINDOW", False); XSetWMProtocols(system->x11display, d->window, &d->wm_delete_window_atom, 1); XUnlockDisplay(system->x11display); d->overridable_vt = &default_overridable_vt; return true; }
static void xdpy_set_window_title_default(ALLEGRO_DISPLAY *display, const char *title) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; { Atom WM_NAME = XInternAtom(system->x11display, "WM_NAME", False); Atom _NET_WM_NAME = XInternAtom(system->x11display, "_NET_WM_NAME", False); char *list[1] = { (char *) title }; XTextProperty property; Xutf8TextListToTextProperty(system->x11display, list, 1, XUTF8StringStyle, &property); XSetTextProperty(system->x11display, glx->window, &property, WM_NAME); XSetTextProperty(system->x11display, glx->window, &property, _NET_WM_NAME); XSetTextProperty(system->x11display, glx->window, &property, XA_WM_NAME); XFree(property.value); } { XClassHint *hint = XAllocClassHint(); if (hint) { ALLEGRO_PATH *exepath = al_get_standard_path(ALLEGRO_EXENAME_PATH); // hint doesn't use a const char*, so we use strdup to create a non const string hint->res_name = strdup(al_get_path_basename(exepath)); hint->res_class = strdup(al_get_path_basename(exepath)); XSetClassHint(system->x11display, glx->window, hint); free(hint->res_name); free(hint->res_class); XFree(hint); al_destroy_path(exepath); } } }
void _al_xwin_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor) { ALLEGRO_MOUSE_CURSOR_XGLX *xcursor = (ALLEGRO_MOUSE_CURSOR_XGLX *)cursor; ALLEGRO_SYSTEM *sys = al_get_system_driver(); ALLEGRO_SYSTEM_XGLX *sysx = (ALLEGRO_SYSTEM_XGLX *)sys; unsigned i; _al_mutex_lock(&sysx->lock); for (i = 0; i < _al_vector_size(&sys->displays); i++) { ALLEGRO_DISPLAY_XGLX **slot = _al_vector_ref(&sys->displays, i); ALLEGRO_DISPLAY_XGLX *glx = *slot; if (glx->current_cursor == xcursor->cursor) { if (!glx->cursor_hidden) XUndefineCursor(sysx->x11display, glx->window); glx->current_cursor = None; } } XFreeCursor(sysx->x11display, xcursor->cursor); al_free(xcursor); _al_mutex_unlock(&sysx->lock); }
static void xdpy_set_window_position(ALLEGRO_DISPLAY *display, int x, int y) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display; Window root, parent, child, *children; unsigned int n; _al_mutex_lock(&system->lock); /* To account for the window border, we have to find the parent window which * draws the border. If the parent is the root though, then we should not * translate. */ XQueryTree(system->x11display, glx->window, &root, &parent, &children, &n); if (parent != root) { XTranslateCoordinates(system->x11display, parent, glx->window, x, y, &x, &y, &child); } XMoveWindow(system->x11display, glx->window, x, y); XFlush(system->x11display); /* We have to store these immediately, as we will ignore the XConfigureEvent * that we receive in response. _al_display_xglx_configure() knows why. */ glx->x = x; glx->y = y; _al_mutex_unlock(&system->lock); }
static bool init_touch_input(void) { unsigned i; ALLEGRO_SYSTEM* system; if (installed) return false; if (!_al_win_init_touch_input_api()) return false; memset(&touch_input_state, 0, sizeof(touch_input_state)); _al_event_source_init(&touch_input.es); _al_event_source_init(&touch_input.mouse_emulation_es); touch_input.mouse_emulation_mode = ALLEGRO_MOUSE_EMULATION_TRANSPARENT; installed = true; system = al_get_system_driver(); for (i = 0; i < _al_vector_size(&system->displays); ++i) { bool r; ALLEGRO_DISPLAY_WIN *win_display = *((ALLEGRO_DISPLAY_WIN**)_al_vector_ref(&system->displays, i)); r = _al_win_register_touch_window(win_display->window, 0); ALLEGRO_INFO("registering touch window %p: %d\n", win_display, r); if (!r) { ALLEGRO_ERROR("RegisterTouchWindow failed: %s\n", get_error_desc(GetLastError())); return false; } } return true; }
/* Function: al_install_haptic */ bool al_install_haptic(void) { ALLEGRO_SYSTEM *sysdrv; ALLEGRO_HAPTIC_DRIVER *hapdrv; if (haptic_driver) return true; sysdrv = al_get_system_driver(); ASSERT(sysdrv); /* Currently every platform only has at most one haptic driver. */ if (sysdrv->vt->get_haptic_driver) { hapdrv = sysdrv->vt->get_haptic_driver(); /* Avoid race condition in case the haptic driver generates an * event right after ->init_haptic. */ if (hapdrv && hapdrv->init_haptic()) { haptic_driver = hapdrv; _al_add_exit_func(al_uninstall_haptic, "al_uninstall_haptic"); return true; } } return false; }
static bool xglx_inhibit_screensaver(bool inhibit) { ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver(); system->inhibit_screensaver = inhibit; return true; }
static ALLEGRO_DISPLAY_MODE *xglx_get_display_mode(int mode, ALLEGRO_DISPLAY_MODE *dm) { int adapter = al_get_new_display_adapter(); ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); return _al_xglx_get_display_mode(s, adapter, mode, dm); }
static void thread_func_trampoline(_AL_THREAD *inner, void *_outer) { ALLEGRO_THREAD *outer = (ALLEGRO_THREAD *) _outer; ALLEGRO_SYSTEM *system = al_get_system_driver(); (void)inner; if (system && system->vt && system->vt->thread_init) { system->vt->thread_init(outer); } /* Wait to start the actual user thread function. The thread could also be * destroyed before ever running the user function. */ _al_mutex_lock(&outer->mutex); while (outer->thread_state == THREAD_STATE_CREATED) { _al_cond_wait(&outer->cond, &outer->mutex); } _al_mutex_unlock(&outer->mutex); if (outer->thread_state == THREAD_STATE_STARTING) { outer->thread_state = THREAD_STATE_STARTED; outer->retval = ((void *(*)(ALLEGRO_THREAD *, void *))outer->proc)(outer, outer->arg); } if (system && system->vt && system->vt->thread_exit) { system->vt->thread_exit(outer); } }
static void sdl_destroy_display(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver(); al_lock_mutex(s->mutex); sdl_destroy_display_locked(d); al_unlock_mutex(s->mutex); }
static ALLEGRO_DISPLAY_INTERFACE *xglx_get_display_driver(void) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); /* Look up the toggle_mouse_grab_key binding. This isn't such a great place * to do it, but the config file is not available until after the system driver * is initialised. */ if (!system->toggle_mouse_grab_keycode) { const char *binding = al_get_config_value(al_get_system_config(), "keyboard", "toggle_mouse_grab_key"); if (binding) { system->toggle_mouse_grab_keycode = _al_parse_key_binding(binding, &system->toggle_mouse_grab_modifiers); if (system->toggle_mouse_grab_keycode) { ALLEGRO_DEBUG("Toggle mouse grab key: '%s'\n", binding); } else { ALLEGRO_WARN("Cannot parse key binding '%s'\n", binding); } } } return _al_display_xglx_driver(); }
static void wgl_destroy_display(ALLEGRO_DISPLAY *disp) { ALLEGRO_SYSTEM_WIN *system = (ALLEGRO_SYSTEM_WIN *)al_get_system_driver(); ALLEGRO_DISPLAY_WGL *wgl_disp = (ALLEGRO_DISPLAY_WGL *)disp; ALLEGRO_DISPLAY *old_disp = al_get_current_display(); if (old_disp != disp) _al_set_current_display_only(disp); if (system->mouse_grab_display == disp) system->mouse_grab_display = NULL; destroy_display_internals(wgl_disp); _al_event_source_free(&disp->es); _al_vector_find_and_delete(&system->system.displays, &disp); _al_vector_free(&disp->bitmaps); al_free(disp->ogl_extras); if (old_disp != disp) _al_set_current_display_only(old_disp); al_free(disp->vertex_cache); al_free(wgl_disp); }
ALLEGRO_MOUSE_CURSOR *_al_xwin_create_mouse_cursor(ALLEGRO_BITMAP *bmp, int x_focus, int y_focus) { ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver(); Display *xdisplay = system->x11display; int bmp_w; int bmp_h; ALLEGRO_MOUSE_CURSOR_XGLX *xcursor; XcursorImage *image; int c, ix, iy; bool was_locked; bmp_w = al_get_bitmap_width(bmp); bmp_h = al_get_bitmap_height(bmp); xcursor = al_malloc(sizeof *xcursor); if (!xcursor) { return NULL; } image = XcursorImageCreate(bmp->w, bmp->h); if (image == None) { al_free(xcursor); return NULL; } was_locked = al_is_bitmap_locked(bmp); if (!was_locked) { al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); } c = 0; for (iy = 0; iy < bmp_h; iy++) { for (ix = 0; ix < bmp_w; ix++) { ALLEGRO_COLOR col; unsigned char r, g, b, a; col = al_get_pixel(bmp, ix, iy); al_unmap_rgba(col, &r, &g, &b, &a); image->pixels[c++] = (a<<24) | (r<<16) | (g<<8) | (b); } } if (!was_locked) { al_unlock_bitmap(bmp); } image->xhot = x_focus; image->yhot = y_focus; _al_mutex_lock(&system->lock); xcursor->cursor = XcursorImageLoadCursor(xdisplay, image); _al_mutex_unlock(&system->lock); XcursorImageDestroy(image); return (ALLEGRO_MOUSE_CURSOR *)xcursor; }
static ALLEGRO_DISPLAY *sdl_create_display(int w, int h) { ALLEGRO_SYSTEM_SDL *s = (void *)al_get_system_driver(); al_lock_mutex(s->mutex); ALLEGRO_DISPLAY *d = sdl_create_display_locked(w, h); al_unlock_mutex(s->mutex); return d; }
static bool win_ungrab_mouse(void) { ALLEGRO_SYSTEM_WIN *system = (void *)al_get_system_driver(); ClipCursor(NULL); system->mouse_grab_display = NULL; return true; }
/* Function: al_install_keyboard */ bool al_install_keyboard(void) { if (new_keyboard_driver) return true; //FIXME: seems A4/A5 driver list stuff doesn't quite agree right now if (al_get_system_driver()->vt->get_keyboard_driver) { new_keyboard_driver = al_get_system_driver()->vt->get_keyboard_driver(); if (!new_keyboard_driver->init_keyboard()) { new_keyboard_driver = NULL; return false; } _al_add_exit_func(al_uninstall_keyboard, "al_uninstall_keyboard"); return true; } return false; /* if (system_driver->keyboard_drivers) driver_list = system_driver->keyboard_drivers(); else driver_list = _al_keyboard_driver_list; for (i=0; driver_list[i].driver; i++) { new_keyboard_driver = driver_list[i].driver; name = get_config_text(new_keyboard_driver->keydrv_ascii_name); new_keyboard_driver->keydrv_name = name; new_keyboard_driver->keydrv_desc = name; if (new_keyboard_driver->init_keyboard()) break; } if (!driver_list[i].driver) { new_keyboard_driver = NULL; return false; } //set_leds(-1); _al_add_exit_func(al_uninstall_keyboard, "al_uninstall_keyboard"); return true; */ }
void _al_iphone_update_visuals(void) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref; ALLEGRO_SYSTEM_IPHONE *system = (void *)al_get_system_driver(); ref = _al_get_new_display_settings(); /* If we aren't called the first time, only updated scores. */ if (system->visuals) { for (int i = 0; i < system->visuals_count; i++) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = system->visuals[i]; eds->score = _al_score_display_settings(eds, ref); } return; } system->visuals = al_calloc(VISUALS_COUNT, sizeof(*system->visuals)); system->visuals_count = VISUALS_COUNT; for (int i = 0; i < VISUALS_COUNT; i++) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = al_calloc(1, sizeof *eds); eds->settings[ALLEGRO_RENDER_METHOD] = 1; eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; eds->settings[ALLEGRO_SWAP_METHOD] = 2; eds->settings[ALLEGRO_VSYNC] = 1; switch (i) { case 0: set_rgba8888(eds); break; case 1: set_rgb565(eds); break; case 2: set_rgba8888(eds); eds->settings[ALLEGRO_DEPTH_SIZE] = 16; break; case 3: set_rgb565(eds); eds->settings[ALLEGRO_DEPTH_SIZE] = 16; break; case 4: set_rgba8888(eds); eds->settings[ALLEGRO_DEPTH_SIZE] = 24; eds->settings[ALLEGRO_STENCIL_SIZE] = 8; break; case 5: set_rgb565(eds); eds->settings[ALLEGRO_DEPTH_SIZE] = 24; eds->settings[ALLEGRO_STENCIL_SIZE] = 8; break; } eds->score = _al_score_display_settings(eds, ref); eds->index = i; system->visuals[i] = eds; } }
/* Function: al_grab_mouse */ bool al_grab_mouse(ALLEGRO_DISPLAY *display) { ALLEGRO_SYSTEM *alsys = al_get_system_driver(); if (alsys->vt->grab_mouse) return alsys->vt->grab_mouse(display); return false; }
/* Function: al_ungrab_mouse */ bool al_ungrab_mouse(void) { ALLEGRO_SYSTEM *alsys = al_get_system_driver(); if (alsys->vt->ungrab_mouse) return alsys->vt->ungrab_mouse(); return false; }