src/video/directfb/SDL_DirectFB_window.c
changeset 3023 d72a0dd80e8b
parent 3013 8cc00819c8d6
child 3037 490f3e4fe753
     1.1 --- a/src/video/directfb/SDL_DirectFB_window.c	Sun Jan 11 23:39:11 2009 +0000
     1.2 +++ b/src/video/directfb/SDL_DirectFB_window.c	Sun Jan 11 23:49:23 2009 +0000
     1.3 @@ -27,27 +27,27 @@
     1.4  
     1.5  #include "SDL_DirectFB_video.h"
     1.6  
     1.7 +
     1.8  int
     1.9  DirectFB_CreateWindow(_THIS, SDL_Window * window)
    1.10  {
    1.11      SDL_DFB_DEVICEDATA(_this);
    1.12      SDL_DFB_DISPLAYDATA(_this, window);
    1.13 -    DFB_WindowData *windata;
    1.14 +    DFB_WindowData *windata = NULL;
    1.15      DFBWindowOptions wopts;
    1.16      DFBWindowDescription desc;
    1.17 +    IDirectFBFont *font;
    1.18      int ret, x, y;
    1.19  
    1.20 -    SDL_DFB_DEBUG("Trace x %d y %d w %d h %d\n", window->x, window->y,
    1.21 -                  window->w, window->h);
    1.22 -    window->driverdata = NULL;
    1.23      SDL_DFB_CALLOC(window->driverdata, 1, sizeof(DFB_WindowData));
    1.24      windata = (DFB_WindowData *) window->driverdata;
    1.25  
    1.26 -    SDL_DFB_CHECKERR(devdata->dfb->
    1.27 -                     SetCooperativeLevel(devdata->dfb, DFSCL_NORMAL));
    1.28 -    SDL_DFB_CHECKERR(dispdata->layer->
    1.29 -                     SetCooperativeLevel(dispdata->layer,
    1.30 -                                         DLSCL_ADMINISTRATIVE));
    1.31 +    windata->is_managed = devdata->has_own_wm;
    1.32 +
    1.33 +    SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
    1.34 +                                                       DFSCL_NORMAL));
    1.35 +    SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
    1.36 +                                                          DLSCL_ADMINISTRATIVE));
    1.37  
    1.38      /* Fill the window description. */
    1.39      if (window->x == SDL_WINDOWPOS_CENTERED) {
    1.40 @@ -69,76 +69,76 @@
    1.41          y = 0;
    1.42      }
    1.43  
    1.44 -    desc.flags = DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT;
    1.45 -    /*| DWDESC_CAPS | DWDESC_SURFACE_CAPS */
    1.46 +    DirectFB_WM_AdjustWindowLayout(window);
    1.47  
    1.48 -#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0)
    1.49 -    /* Needed for 1.2 */
    1.50 -    desc.flags |= DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
    1.51 +    /* Create Window */
    1.52 +    desc.flags =
    1.53 +        DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_POSX
    1.54 +        | DWDESC_POSY | DWDESC_SURFACE_CAPS;
    1.55      desc.posx = x;
    1.56      desc.posy = y;
    1.57 -#else
    1.58 -    if (!(window->flags & SDL_WINDOW_FULLSCREEN)
    1.59 -        && window->x != SDL_WINDOWPOS_UNDEFINED
    1.60 -        && window->y != SDL_WINDOWPOS_UNDEFINED) {
    1.61 -        desc.flags |= DWDESC_POSX | DWDESC_POSY;
    1.62 -        desc.posx = x;
    1.63 -        desc.posy = y;
    1.64 -    }
    1.65 -#endif
    1.66 -
    1.67 -    desc.width = window->w;
    1.68 -    desc.height = window->h;
    1.69 +    desc.width = windata->size.w;
    1.70 +    desc.height = windata->size.h;
    1.71      desc.pixelformat = dispdata->pixelformat;
    1.72 -#if 0
    1.73 -    desc.caps = 0;
    1.74 -    desc.surface_caps =
    1.75 -        DSCAPS_DOUBLE | DSCAPS_TRIPLE | DSCAPS_PREMULTIPLIED |
    1.76 -        DSCAPS_VIDEOONLY;
    1.77 -#endif
    1.78      desc.surface_caps = DSCAPS_PREMULTIPLIED;
    1.79 -    /* DSCAPS_VIDEOONLY has negative impact on performance */
    1.80  
    1.81      /* Create the window. */
    1.82 -    SDL_DFB_CHECKERR(dispdata->layer->
    1.83 -                     CreateWindow(dispdata->layer, &desc, &windata->window));
    1.84 +    SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
    1.85 +                                                   &windata->window));
    1.86  
    1.87 +    /* Set Options */
    1.88      windata->window->GetOptions(windata->window, &wopts);
    1.89 -#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0)
    1.90  
    1.91      if (window->flags & SDL_WINDOW_RESIZABLE)
    1.92          wopts |= DWOP_SCALE;
    1.93      else
    1.94          wopts |= DWOP_KEEP_SIZE;
    1.95 -#else
    1.96 -    wopts |= DWOP_KEEP_SIZE;    /* if not we will crash ... */
    1.97 -#endif
    1.98  
    1.99 -    if (window->flags & SDL_WINDOW_FULLSCREEN)
   1.100 +    if (window->flags & SDL_WINDOW_FULLSCREEN) {
   1.101          wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
   1.102 +        windata->window->SetStackingClass(windata->window, DWSC_UPPER);
   1.103 +    }
   1.104 +    windata->window->SetOptions(windata->window, wopts);
   1.105  
   1.106 -    windata->window->SetOptions(windata->window, wopts);
   1.107 +    /* See what we got */
   1.108 +    SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &window->w, &window->h));
   1.109 +
   1.110      /* Get the window's surface. */
   1.111 -    SDL_DFB_CHECKERR(windata->window->
   1.112 -                     GetSurface(windata->window, &windata->surface));
   1.113 +    SDL_DFB_CHECKERR(windata->window->GetSurface(windata->window,
   1.114 +                                                 &windata->window_surface));
   1.115 +    /* And get a subsurface for rendering */
   1.116 +    SDL_DFB_CHECKERR(windata->window_surface->
   1.117 +                     GetSubSurface(windata->window_surface, &windata->client,
   1.118 +                                   &windata->surface));
   1.119 +
   1.120      windata->window->SetOpacity(windata->window, 0xFF);
   1.121 -    SDL_DFB_CHECKERR(windata->window->
   1.122 -                     CreateEventBuffer(windata->window,
   1.123 -                                       &(windata->eventbuffer)));
   1.124 -    SDL_DFB_CHECKERR(windata->window->
   1.125 -                     EnableEvents(windata->window, DWET_ALL));
   1.126 +
   1.127 +    /* Create Eventbuffer */
   1.128 +    SDL_DFB_CHECKERR(windata->window->CreateEventBuffer(windata->window,
   1.129 +                                                        &windata->eventbuffer));
   1.130 +    SDL_DFB_CHECKERR(windata->
   1.131 +                     window->EnableEvents(windata->window, DWET_ALL));
   1.132  
   1.133 -    if (window->flags & SDL_WINDOW_FULLSCREEN)
   1.134 -        windata->window->SetStackingClass(windata->window, DWSC_UPPER);
   1.135 +    /* Create a font */
   1.136 +    /* FIXME: once during Video_Init */
   1.137 +    if (windata->is_managed) {
   1.138 +        DFBFontDescription fdesc;
   1.139 +
   1.140 +        fdesc.flags = DFDESC_HEIGHT;
   1.141 +        fdesc.height = windata->theme.font_size;
   1.142 +        font = NULL;
   1.143 +        SDL_DFB_CHECK(devdata->
   1.144 +                      dfb->CreateFont(devdata->dfb, windata->theme.font,
   1.145 +                                      &fdesc, &font));
   1.146 +        windata->window_surface->SetFont(windata->window_surface, font);
   1.147 +        SDL_DFB_RELEASE(font);
   1.148 +    }
   1.149 +
   1.150      /* Make it the top most window. */
   1.151      windata->window->RaiseToTop(windata->window);
   1.152  
   1.153 -    windata->window->GetID(windata->window, &windata->windowID);
   1.154 -
   1.155 -    windata->window->GetSize(windata->window, &window->w, &window->h);
   1.156 -
   1.157      /* remember parent */
   1.158 -    windata->id = window->id;
   1.159 +    windata->sdl_id = window->id;
   1.160  
   1.161      /* Add to list ... */
   1.162  
   1.163 @@ -146,6 +146,9 @@
   1.164      windata->opacity = 0xFF;
   1.165      devdata->firstwin = windata;
   1.166  
   1.167 +    /* Draw Frame */
   1.168 +    DirectFB_WM_RedrawLayout(window);
   1.169 +
   1.170      return 0;
   1.171    error:
   1.172      SDL_DFB_RELEASE(windata->window);
   1.173 @@ -163,7 +166,65 @@
   1.174  void
   1.175  DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
   1.176  {
   1.177 -    SDL_Unsupported();
   1.178 +    SDL_DFB_WINDOWDATA(window);
   1.179 +
   1.180 +    if (windata->is_managed) {
   1.181 +        windata->wm_needs_redraw = 1;
   1.182 +    } else
   1.183 +        SDL_Unsupported();
   1.184 +}
   1.185 +
   1.186 +void
   1.187 +DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
   1.188 +{
   1.189 +    SDL_DFB_DEVICEDATA(_this);
   1.190 +    SDL_DFB_WINDOWDATA(window);
   1.191 +    SDL_Surface *surface = NULL;
   1.192 +    DFBResult ret;
   1.193 +
   1.194 +    if (icon) {
   1.195 +        SDL_PixelFormat format;
   1.196 +        DFBSurfaceDescription dsc;
   1.197 +        Uint32 *dest;
   1.198 +        Uint32 *p;
   1.199 +        int pitch, i;
   1.200 +
   1.201 +        /* Convert the icon to ARGB for modern window managers */
   1.202 +        SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
   1.203 +                       0xFF000000);
   1.204 +        surface = SDL_ConvertSurface(icon, &format, 0);
   1.205 +        if (!surface) {
   1.206 +            return;
   1.207 +        }
   1.208 +        dsc.flags =
   1.209 +            DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   1.210 +        dsc.caps = DSCAPS_VIDEOONLY;
   1.211 +        dsc.width = surface->w;
   1.212 +        dsc.height = surface->h;
   1.213 +        dsc.pixelformat = DSPF_ARGB;
   1.214 +
   1.215 +        SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
   1.216 +                                                     &windata->icon));
   1.217 +
   1.218 +        SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
   1.219 +                                             (void *) &dest, &pitch));
   1.220 +
   1.221 +        p = surface->pixels;
   1.222 +        for (i = 0; i < surface->h; i++)
   1.223 +            memcpy((char *) dest + i * pitch,
   1.224 +                   (char *) p + i * surface->pitch, 4 * surface->w);
   1.225 +
   1.226 +        windata->icon->Unlock(windata->icon);
   1.227 +        SDL_FreeSurface(surface);
   1.228 +    } else {
   1.229 +        SDL_DFB_RELEASE(windata->icon);
   1.230 +    }
   1.231 +    return;
   1.232 +  error:
   1.233 +    if (surface)
   1.234 +        SDL_FreeSurface(surface);
   1.235 +    SDL_DFB_RELEASE(windata->icon);
   1.236 +    return;
   1.237  }
   1.238  
   1.239  void
   1.240 @@ -186,37 +247,39 @@
   1.241          x = 0;
   1.242          y = 0;
   1.243      }
   1.244 -
   1.245 +    DirectFB_WM_AdjustWindowLayout(window);
   1.246      windata->window->MoveTo(windata->window, x, y);
   1.247  }
   1.248  
   1.249  void
   1.250  DirectFB_SetWindowSize(_THIS, SDL_Window * window)
   1.251  {
   1.252 +    SDL_DFB_DEVICEDATA(_this);
   1.253 +    SDL_DFB_WINDOWDATA(window);
   1.254      int ret;
   1.255 -    SDL_DFB_WINDOWDATA(window);
   1.256  
   1.257      if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
   1.258 -#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0)
   1.259          int cw;
   1.260          int ch;
   1.261  
   1.262          /* Make sure all events are disabled for this operation ! */
   1.263 -        SDL_DFB_CHECKERR(windata->window->
   1.264 -                         DisableEvents(windata->window, DWET_ALL));
   1.265 +        SDL_DFB_CHECKERR(windata->window->DisableEvents(windata->window,
   1.266 +                                                        DWET_ALL));
   1.267 +
   1.268 +        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
   1.269 +
   1.270 +        if (cw != window->w || ch != window->h) {
   1.271  
   1.272 -        SDL_DFB_CHECKERR(windata->window->GetSize(windata->window, &cw, &ch));
   1.273 -        if (cw != window->w || ch != window->h)
   1.274 -            SDL_DFB_CHECKERR(windata->window->
   1.275 -                             Resize(windata->window, window->w, window->h));
   1.276 -        SDL_DFB_CHECKERR(windata->window->
   1.277 -                         EnableEvents(windata->window, DWET_ALL));
   1.278 +            DirectFB_WM_AdjustWindowLayout(window);
   1.279 +            SDL_DFB_CHECKERR(windata->window->Resize(windata->window,
   1.280 +                                                     windata->size.w,
   1.281 +                                                     windata->size.h));
   1.282 +        }
   1.283  
   1.284 -#else
   1.285 -        SDL_DFB_CHECKERR(windata->window->
   1.286 -                         Resize(windata->window, window->w, window->h));
   1.287 -#endif
   1.288 -        SDL_DFB_CHECKERR(windata->window->GetSize(windata->window, &window->w, &window->h));    /* if a window manager should have decided otherwise */
   1.289 +        SDL_DFB_CHECKERR(windata->window->EnableEvents(windata->window,
   1.290 +                                                       DWET_ALL));
   1.291 +
   1.292 +        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &window->w, &window->h));
   1.293  
   1.294          SDL_OnWindowResized(window);
   1.295      }
   1.296 @@ -256,9 +319,12 @@
   1.297  void
   1.298  DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
   1.299  {
   1.300 -    /* FIXME: Size to Desktop ? */
   1.301 +    SDL_DFB_WINDOWDATA(window);
   1.302  
   1.303 -    SDL_Unsupported();
   1.304 +    if (windata->is_managed) {
   1.305 +    	DirectFB_WM_MaximizeWindow(_this, window);
   1.306 +    } else
   1.307 +        SDL_Unsupported();
   1.308  }
   1.309  
   1.310  void
   1.311 @@ -272,7 +338,12 @@
   1.312  void
   1.313  DirectFB_RestoreWindow(_THIS, SDL_Window * window)
   1.314  {
   1.315 -    SDL_Unsupported();
   1.316 +    SDL_DFB_WINDOWDATA(window);
   1.317 +
   1.318 +    if (windata->is_managed) {
   1.319 +    	DirectFB_WM_RestoreWindow(_this, window);
   1.320 +    } else
   1.321 +        SDL_Unsupported();
   1.322  }
   1.323  
   1.324  void
   1.325 @@ -280,8 +351,7 @@
   1.326  {
   1.327      SDL_DFB_WINDOWDATA(window);
   1.328  
   1.329 -    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
   1.330 -        (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   1.331 +    if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
   1.332          windata->window->GrabPointer(windata->window);
   1.333          windata->window->GrabKeyboard(windata->window);
   1.334      } else {
   1.335 @@ -299,8 +369,16 @@
   1.336  
   1.337      SDL_DFB_DEBUG("Trace\n");
   1.338  
   1.339 +    /* Some cleanups */
   1.340 +    windata->window->UngrabPointer(windata->window);
   1.341 +    windata->window->UngrabKeyboard(windata->window);
   1.342 +
   1.343 +    windata->window_surface->SetFont(windata->window_surface, NULL);
   1.344 +    SDL_DFB_RELEASE(windata->icon);
   1.345      SDL_DFB_RELEASE(windata->eventbuffer);
   1.346      SDL_DFB_RELEASE(windata->surface);
   1.347 +    SDL_DFB_RELEASE(windata->window_surface);
   1.348 +
   1.349      SDL_DFB_RELEASE(windata->window);
   1.350  
   1.351      /* Remove from list ... */
   1.352 @@ -323,3 +401,35 @@
   1.353      SDL_Unsupported();
   1.354      return SDL_FALSE;
   1.355  }
   1.356 +
   1.357 +void
   1.358 +DirectFB_AdjustWindowSurface(SDL_Window * window)
   1.359 +{
   1.360 +    SDL_DFB_WINDOWDATA(window);
   1.361 +    int adjust = windata->wm_needs_redraw;
   1.362 +    int cw, ch;
   1.363 +    int ret;
   1.364 +
   1.365 +    DirectFB_WM_AdjustWindowLayout(window);
   1.366 +
   1.367 +    SDL_DFB_CHECKERR(windata->
   1.368 +                     window_surface->GetSize(windata->window_surface, &cw,
   1.369 +                                             &ch));
   1.370 +    if (cw != windata->size.w || ch != windata->size.h) {
   1.371 +        adjust = 1;
   1.372 +    }
   1.373 +
   1.374 +    if (adjust) {
   1.375 +        SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window,
   1.376 +                                                        windata->size.w,
   1.377 +                                                        windata->size.h));
   1.378 +        SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
   1.379 +                                                          windata->
   1.380 +                                                          window_surface,
   1.381 +                                                          &windata->client));
   1.382 +        DirectFB_WM_RedrawLayout(window);
   1.383 +    }
   1.384 +  error:
   1.385 +    return;
   1.386 +}
   1.387 +