Exemplo n.º 1
0
/* _al_run_destructors:
 *  Run all the destructors on the list in reverse order.
 */
void _al_run_destructors(_AL_DTOR_LIST *dtors)
{
   if (!dtors) {
      return;
   }

   /* call the destructors in reverse order */
   _al_mutex_lock(&dtors->mutex);
   {
      while (!_al_vector_is_empty(&dtors->dtors)) {
         DTOR *dtor = _al_vector_ref_back(&dtors->dtors);
         void *object = dtor->object;
         void (*func)(void *) = dtor->func;

         ALLEGRO_DEBUG("calling dtor for %s %p, func %p\n",
            dtor->name, object, func);
         _al_mutex_unlock(&dtors->mutex);
         {
            (*func)(object);
         }
         _al_mutex_lock(&dtors->mutex);
      }
   }
   _al_mutex_unlock(&dtors->mutex);
}
Exemplo n.º 2
0
static void _al_xsys_xinerama_init(ALLEGRO_SYSTEM_XGLX *s)
{
   int event_base = 0;
   int error_base = 0;

   /* init xinerama info to defaults */
   s->xinerama_available = 0;
   s->xinerama_screen_count = 0;
   s->xinerama_screen_info = NULL;

   _al_mutex_lock(&s->lock);

   if (XineramaQueryExtension(s->x11display, &event_base, &error_base)) {
      int minor_version = 0, major_version = 0;
      int status = XineramaQueryVersion(s->x11display, &major_version, &minor_version);
      ALLEGRO_INFO("Xinerama version: %i.%i\n", major_version, minor_version);

      if (status && !XineramaIsActive(s->x11display)) {
         ALLEGRO_WARN("Xinerama is not active\n");
      }
      else {
         ALLEGRO_INFO("Xinerama is active\n");
         s->xinerama_available = 1;
      }
   }
   else {
      ALLEGRO_WARN("Xinerama extension is not available.\n");
   }

   _al_mutex_unlock(&s->lock);
}
Exemplo n.º 3
0
static bool xfvm_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *mi)
{
#ifdef ALLEGRO_XWINDOWS_WITH_XINERAMA
    if (s->xinerama_available) {
        return xinerama_get_monitor_info(s, adapter, mi);
    }
#endif

    if (adapter < 0 || adapter > s->xfvm_screen_count)
        return false;

    XWindowAttributes xwa;
    Window root;

    _al_mutex_lock(&s->lock);
    root = RootWindow(s->x11display, adapter);
    XGetWindowAttributes(s->x11display, root, &xwa);
    _al_mutex_unlock(&s->lock);

    /* under plain X, each screen has its own origin,
       and theres no way to figure out orientation
       or relative position */
    mi->x1 = 0;
    mi->y1 = 0;
    mi->x2 = xwa.width;
    mi->y2 = xwa.height;
    return true;
}
Exemplo n.º 4
0
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 */
}
Exemplo n.º 5
0
/* Function: al_start_thread
 */
void al_start_thread(ALLEGRO_THREAD *thread)
{
   ASSERT(thread);

   switch (thread->thread_state) {
      case THREAD_STATE_CREATED:
         _al_mutex_lock(&thread->mutex);
         thread->thread_state = THREAD_STATE_STARTING;
         _al_cond_broadcast(&thread->cond);
         _al_mutex_unlock(&thread->mutex);
         break;
      case THREAD_STATE_STARTING:
         break;
      case THREAD_STATE_STARTED:
         break;
      /* invalid cases */
      case THREAD_STATE_JOINING:
         ASSERT(thread->thread_state != THREAD_STATE_JOINING);
         break;
      case THREAD_STATE_JOINED:
         ASSERT(thread->thread_state != THREAD_STATE_JOINED);
         break;
      case THREAD_STATE_DESTROYED:
         ASSERT(thread->thread_state != THREAD_STATE_DESTROYED);
         break;
      case THREAD_STATE_DETACHED:
         ASSERT(thread->thread_state != THREAD_STATE_DETACHED);
         break;
   }
}
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);
}
Exemplo n.º 7
0
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);
   }
}
Exemplo n.º 8
0
/* [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);
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 10
0
/* 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;
}
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;
}
Exemplo n.º 12
0
/* Function: al_pause_event_queue
 */
void al_pause_event_queue(ALLEGRO_EVENT_QUEUE *queue, bool pause)
{
   ASSERT(queue);

   _al_mutex_lock(&queue->mutex);
   queue->paused = pause;
   _al_mutex_unlock(&queue->mutex);
}
Exemplo n.º 13
0
/* returns -1 on timeout */
static int cond_wait(_AL_COND *cond, _AL_MUTEX *mtxExternal, DWORD timeout)
{
   int nSignalsWasLeft;
   bool bTimedOut;
   DWORD dwWaitResult;

   EnterCriticalSection(&cond->semBlockLock);
   ++cond->nWaitersBlocked;
   LeaveCriticalSection(&cond->semBlockLock);

   _al_mutex_unlock(mtxExternal);

   dwWaitResult = WaitForSingleObject(cond->semBlockQueue, timeout);
   if (dwWaitResult == WAIT_TIMEOUT)
      bTimedOut = true;
   else if (dwWaitResult == WAIT_OBJECT_0)
      bTimedOut = false;
   else {
      /* bad! what to do? */
      _al_mutex_lock(mtxExternal);
      ASSERT(false);
      return 0;
   }

   EnterCriticalSection(&cond->mtxUnblockLock);
   if (0 != (nSignalsWasLeft = cond->nWaitersToUnblock)) {
      --(cond->nWaitersToUnblock);
   }
   else if (INT_MAX/2 == ++(cond->nWaitersGone)) { /* timeout/canceled or spurious semaphore :-) */
      EnterCriticalSection(&cond->semBlockLock);
      cond->nWaitersBlocked -= cond->nWaitersGone; /* something is going on here
                                                      - test of timeouts? :-) */
      LeaveCriticalSection(&cond->semBlockLock);
      cond->nWaitersGone = 0;
   }
   LeaveCriticalSection(&cond->mtxUnblockLock);

   if (1 == nSignalsWasLeft) {
      LeaveCriticalSection(&cond->semBlockLock); /* open the gate */
   }

   _al_mutex_lock(mtxExternal);

   return bTimedOut ? -1 : 0;
}
Exemplo n.º 14
0
static void xdpy_set_window_title(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;

   _al_mutex_lock(&system->lock);
   glx->overridable_vt->set_window_title(display, title);
   _al_mutex_unlock(&system->lock);
}
Exemplo n.º 15
0
bool _al_xwin_ungrab_mouse(void)
{
   ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();

   _al_mutex_lock(&system->lock);
   XUngrabPointer(system->x11display, CurrentTime);
   system->mouse_grab_display = NULL;
   _al_mutex_unlock(&system->lock);
   return true;
}
Exemplo n.º 16
0
static void xglx_get_smonitor_info(ALLEGRO_SYSTEM_XGLX *system, ALLEGRO_MONITOR_INFO *info)
{
   XWindowAttributes xwa;
   Window root = RootWindow(system->x11display, 0);
   _al_mutex_lock(&system->lock);
   XGetWindowAttributes(system->x11display, root, &xwa);
   _al_mutex_unlock(&system->lock);
   
   info->x1 = 0;
   info->y1 = 0;
   info->x2 = xwa.width;
   info->y2 = xwa.height;
}
Exemplo n.º 17
0
/* Function: al_unregister_event_source
 */
void al_unregister_event_source(ALLEGRO_EVENT_QUEUE *queue,
   ALLEGRO_EVENT_SOURCE *source)
{
   bool found;
   ASSERT(queue);
   ASSERT(source);

   /* Remove source from our list. */
   _al_mutex_lock(&queue->mutex);
   found = _al_vector_find_and_delete(&queue->sources, &source);
   _al_mutex_unlock(&queue->mutex);

   if (found) {
      /* Tell the event source that it was unregistered. */
      _al_event_source_on_unregistration_from_queue(source, queue);

      /* Drop all the events in the queue that belonged to the source. */
      _al_mutex_lock(&queue->mutex);
      discard_events_of_source(queue, source);
      _al_mutex_unlock(&queue->mutex);
   }
}
Exemplo n.º 18
0
static bool xglx_get_cursor_position(int *ret_x, int *ret_y)
{
   ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
   Window root = RootWindow(system->x11display, 0);
   Window child;
   int wx, wy;
   unsigned int mask;

   _al_mutex_lock(&system->lock);
   XQueryPointer(system->x11display, root, &root, &child, ret_x, ret_y,
      &wx, &wy, &mask);
   _al_mutex_unlock(&system->lock);
   return true;
}
Exemplo n.º 19
0
static void xdpy_destroy_display(ALLEGRO_DISPLAY *d)
{
   ALLEGRO_SYSTEM_XGLX *s = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver();
   ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d;
   ALLEGRO_OGL_EXTRAS *ogl = d->ogl_extras;
   bool is_last;

   ALLEGRO_DEBUG("destroying display.\n");

   /* If we're the last display, convert all bitmaps to display independent
    * (memory) bitmaps. Otherwise, pass all bitmaps to any other living
    * display. We assume all displays are compatible.)
    */
   is_last = (s->system.displays._size == 1);
   if (is_last)
      convert_display_bitmaps_to_memory_bitmap(d);
   else
      transfer_display_bitmaps_to_any_other_display(s, d);

   _al_ogl_unmanage_extensions(d);
   ALLEGRO_DEBUG("unmanaged extensions.\n");

   _al_mutex_lock(&s->lock);
   _al_vector_find_and_delete(&s->system.displays, &d);

   if (ogl->backbuffer) {
      _al_ogl_destroy_backbuffer(ogl->backbuffer);
      ogl->backbuffer = NULL;
      ALLEGRO_DEBUG("destroy backbuffer.\n");
   }

   if (glx->overridable_vt) {
      glx->overridable_vt->destroy_display_hook(d, is_last);
   }

   if (s->mouse_grab_display == d) {
      s->mouse_grab_display = NULL;
   }

   _al_vector_free(&d->bitmaps);
   _al_event_source_free(&d->es);

   al_free(d->ogl_extras);
   al_free(d->vertex_cache);
   al_free(d);

   _al_mutex_unlock(&s->lock);

   ALLEGRO_DEBUG("destroy display finished.\n");
}
/* Internal function: _al_foreach_destructor
 *  Call the callback for each registered object.
 *  [thread-safe]
 */
void _al_foreach_destructor(_AL_DTOR_LIST *dtors,
   void (*callback)(void *object, void (*func)(void *), void *udata),
   void *userdata)
{
   _al_mutex_lock(&dtors->mutex);
   {
      unsigned int i;

      for (i = 0; i < _al_vector_size(&dtors->dtors); i++) {
         DTOR *dtor = _al_vector_ref(&dtors->dtors, i);
         callback(dtor->object, dtor->func, userdata);
      }
   }
   _al_mutex_unlock(&dtors->mutex);
}
Exemplo n.º 21
0
/* Function: al_register_event_source
 */
void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue,
   ALLEGRO_EVENT_SOURCE *source)
{
   ALLEGRO_EVENT_SOURCE **slot;
   ASSERT(queue);
   ASSERT(source);

   if (!_al_vector_contains(&queue->sources, &source)) {
      _al_event_source_on_registration_to_queue(source, queue);
      _al_mutex_lock(&queue->mutex);
      slot = _al_vector_alloc_back(&queue->sources);
      *slot = source;
      _al_mutex_unlock(&queue->mutex);
   }
}
/* Show the system mouse cursor. */
static bool xdpy_show_mouse_cursor(ALLEGRO_DISPLAY *display)
{
   ALLEGRO_DISPLAY_XGLX *glx = (void *)display;
   ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
   Display *xdisplay = system->x11display;
   Window xwindow = glx->window;

   if (!glx->cursor_hidden)
      return true;

   _al_mutex_lock(&system->lock);
   XDefineCursor(xdisplay, xwindow, glx->current_cursor);
   glx->cursor_hidden = false;
   _al_mutex_unlock(&system->lock);
   return true;
}
Exemplo n.º 23
0
static void xdpy_set_fullscreen_window(ALLEGRO_DISPLAY *display, bool onoff)
{
   ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
   if (onoff == !(display->flags & ALLEGRO_FULLSCREEN_WINDOW)) {
      _al_mutex_lock(&system->lock);
      _al_xwin_reset_size_hints(display);
      _al_xwin_set_fullscreen_window(display, 2);
      /* XXX Technically, the user may fiddle with the _NET_WM_STATE_FULLSCREEN
       * property outside of Allegro so this flag may not be in sync with
       * reality.
       */
      display->flags ^= ALLEGRO_FULLSCREEN_WINDOW;
      _al_xwin_set_size_hints(display, INT_MAX, INT_MAX);
      _al_mutex_unlock(&system->lock);
   }
}
Exemplo n.º 24
0
bool _al_xglx_get_monitor_info(ALLEGRO_SYSTEM_XGLX *s, int adapter, ALLEGRO_MONITOR_INFO *info)
{
    if (!init_mmon_interface(s))
        return false;

    if (!_al_xglx_mmon_interface.get_monitor_info) {
        _al_mutex_lock(&s->lock);
        info->x1 = 0;
        info->y1 = 0;
        info->x2 = DisplayWidth(s->x11display, DefaultScreen(s->x11display));
        info->y2 = DisplayHeight(s->x11display, DefaultScreen(s->x11display));
        _al_mutex_unlock(&s->lock);
        return true;
    }

    return _al_xglx_mmon_interface.get_monitor_info(s, adapter, info);
}
Exemplo n.º 25
0
/* Function: al_join_thread
 */
void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value)
{
   ASSERT(thread);

   /* If al_join_thread() is called soon after al_start_thread(), the thread
    * function may not yet have noticed the STARTING state and executed the
    * user's thread function.  Hence we must wait until the thread enters the
    * STARTED state.
    */
   while (thread->thread_state == THREAD_STATE_STARTING) {
      al_rest(0.001);
   }

   switch (thread->thread_state) {
      case THREAD_STATE_CREATED: /* fall through */
      case THREAD_STATE_STARTED:
         _al_mutex_lock(&thread->mutex);
         thread->thread_state = THREAD_STATE_JOINING;
         _al_cond_broadcast(&thread->cond);
         _al_mutex_unlock(&thread->mutex);
         _al_cond_destroy(&thread->cond);
         _al_mutex_destroy(&thread->mutex);
         _al_thread_join(&thread->thread);
         thread->thread_state = THREAD_STATE_JOINED;
         break;
      case THREAD_STATE_STARTING:
         ASSERT(thread->thread_state != THREAD_STATE_STARTING);
         break;
      case THREAD_STATE_JOINING:
         ASSERT(thread->thread_state != THREAD_STATE_JOINING);
         break;
      case THREAD_STATE_JOINED:
         ASSERT(thread->thread_state != THREAD_STATE_JOINED);
         break;
      case THREAD_STATE_DESTROYED:
         ASSERT(thread->thread_state != THREAD_STATE_DESTROYED);
         break;
      case THREAD_STATE_DETACHED:
         ASSERT(thread->thread_state != THREAD_STATE_DETACHED);
         break;
   }

   if (ret_value) {
      *ret_value = thread->retval;
   }
}
Exemplo n.º 26
0
/* used for xinerama and pure xrandr modes */
void _al_xsys_get_active_window_center(ALLEGRO_SYSTEM_XGLX *s, int *x, int *y)
{
    Window focus;
    int revert_to = 0;

    _al_mutex_lock(&s->lock);

    if (!XGetInputFocus(s->x11display, &focus, &revert_to)) {
        ALLEGRO_ERROR("XGetInputFocus failed!\n");
        _al_mutex_unlock(&s->lock);
        return;
    }

    if (focus == None || focus == PointerRoot) {
        ALLEGRO_DEBUG("XGetInputFocus returned special window, selecting default root!\n");
        focus = DefaultRootWindow(s->x11display);
    }
    else {
        /* this horribleness is due to toolkits like GTK (and probably Qt) creating
         * a 1x1 window under the window you're looking at that actually accepts
         * all input, so we need to grab the top level parent window rather than
         * whatever happens to have focus */

        focus = get_toplevel_parent(s, focus);
    }

    ALLEGRO_DEBUG("XGetInputFocus returned %i\n", (int)focus);

    XWindowAttributes attr;

    if (XGetWindowAttributes(s->x11display, focus, &attr) == 0) {
        ALLEGRO_ERROR("XGetWindowAttributes failed :(\n");
        _al_mutex_unlock(&s->lock);
        return;
    }

    _al_mutex_unlock(&s->lock);

    /* check the center of the window with focus
     * might be a bit more useful than just checking the top left */
    ALLEGRO_DEBUG("focus geom: %ix%i %ix%i\n", attr.x, attr.y, attr.width, attr.height);
    *x = (attr.x + (attr.x + attr.width)) / 2;
    *y = (attr.y + (attr.y + attr.height)) / 2;
}
static bool xdpy_set_mouse_cursor(ALLEGRO_DISPLAY *display,
   ALLEGRO_MOUSE_CURSOR *cursor)
{
   ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)display;
   ALLEGRO_MOUSE_CURSOR_XGLX *xcursor = (ALLEGRO_MOUSE_CURSOR_XGLX *)cursor;
   ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver();
   Display *xdisplay = system->x11display;
   Window xwindow = glx->window;

   glx->current_cursor = xcursor->cursor;

   if (!glx->cursor_hidden) {
      _al_mutex_lock(&system->lock);
      XDefineCursor(xdisplay, xwindow, glx->current_cursor);
      _al_mutex_unlock(&system->lock);
   }

   return true;
}
Exemplo n.º 28
0
static void xdpy_set_icons(ALLEGRO_DISPLAY *d,
   int num_icons, ALLEGRO_BITMAP *bitmaps[])
{
   ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX *)al_get_system_driver();
   ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d;
   int prop_mode = PropModeReplace;
   int i;

   _al_mutex_lock(&system->lock);

   for (i = 0; i < num_icons; i++) {
      if (xdpy_set_icon_inner(system->x11display, glx->window, bitmaps[i],
            prop_mode)) {
         prop_mode = PropModeAppend;
      }
   }

   _al_mutex_unlock(&system->lock);
}
Exemplo n.º 29
0
/* Internal function: _al_register_destructor
 *  Register OBJECT to be destroyed by FUNC during Allegro shutdown.
 *  This would be done in the object's constructor function.
 *
 *  [thread-safe]
 */
void _al_register_destructor(_AL_DTOR_LIST *dtors, char const *name,
   void *object, void (*func)(void*))
{
   int *dtor_owner_count;
   ASSERT(object);
   ASSERT(func);

   dtor_owner_count = _al_tls_get_dtor_owner_count();
   if (*dtor_owner_count > 0)
      return;

   _al_mutex_lock(&dtors->mutex);
   {
#ifdef DEBUGMODE
      /* make sure the object is not registered twice */
      {
         unsigned int i;

         for (i = 0; i < _al_vector_size(&dtors->dtors); i++) {
            DTOR *dtor = _al_vector_ref(&dtors->dtors, i);
            ASSERT(dtor->object != object);
         }
      }
#endif /* DEBUGMODE */

      /* add the destructor to the list */
      {
         DTOR *new_dtor = _al_vector_alloc_back(&dtors->dtors);
         if (new_dtor) {
            new_dtor->object = object;
            new_dtor->func = func;
            new_dtor->name = name;
            ALLEGRO_DEBUG("added dtor for %s %p, func %p\n", name,
               object, func);
         }
         else {
            ALLEGRO_WARN("failed to add dtor for %s %p\n", name,
               object);
         }
      }
   }
   _al_mutex_unlock(&dtors->mutex);
}
/* Hide the system mouse cursor. */
static bool xdpy_hide_mouse_cursor(ALLEGRO_DISPLAY *display)
{
   ALLEGRO_DISPLAY_XGLX *glx = (void *)display;
   ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
   Display *xdisplay = system->x11display;
   Window xwindow = glx->window;

   if (glx->cursor_hidden)
      return true;

   _al_mutex_lock(&system->lock);

   if (glx->invisible_cursor == None) {
      unsigned long gcmask;
      XGCValues gcvalues;

      Pixmap pixmap = XCreatePixmap(xdisplay, xwindow, 1, 1, 1);

      GC temp_gc;
      XColor color;

      gcmask = GCFunction | GCForeground | GCBackground;
      gcvalues.function = GXcopy;
      gcvalues.foreground = 0;
      gcvalues.background = 0;
      temp_gc = XCreateGC(xdisplay, pixmap, gcmask, &gcvalues);
      XDrawPoint(xdisplay, pixmap, temp_gc, 0, 0);
      XFreeGC(xdisplay, temp_gc);
      color.pixel = 0;
      color.red = color.green = color.blue = 0;
      color.flags = DoRed | DoGreen | DoBlue;
      glx->invisible_cursor = XCreatePixmapCursor(xdisplay, pixmap,
         pixmap, &color, &color, 0, 0);
      XFreePixmap(xdisplay, pixmap);
   }

   XDefineCursor(xdisplay, xwindow, glx->invisible_cursor);
   glx->cursor_hidden = true;

   _al_mutex_unlock(&system->lock);

   return true;
}