src/video/directfb/SDL_DirectFB_window.c
author Couriersud
Tue, 13 Jan 2009 21:17:38 +0000
changeset 3037 490f3e4fe753
parent 3023 d72a0dd80e8b
child 3038 c73a5f8a03d2
permissions -rw-r--r--
Added DFB_VERSION_ATLEAST macro
First attempt at replacing MakeSubSurface for pre 1.2.0 ==> Scaling not yet working
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_syswm.h"
    25 #include "../SDL_sysvideo.h"
    26 #include "../../events/SDL_keyboard_c.h"
    27 
    28 #include "SDL_DirectFB_video.h"
    29 
    30 
    31 int
    32 DirectFB_CreateWindow(_THIS, SDL_Window * window)
    33 {
    34     SDL_DFB_DEVICEDATA(_this);
    35     SDL_DFB_DISPLAYDATA(_this, window);
    36     DFB_WindowData *windata = NULL;
    37     DFBWindowOptions wopts;
    38     DFBWindowDescription desc;
    39     IDirectFBFont *font;
    40     int ret, x, y;
    41 
    42     SDL_DFB_CALLOC(window->driverdata, 1, sizeof(DFB_WindowData));
    43     windata = (DFB_WindowData *) window->driverdata;
    44 
    45     windata->is_managed = devdata->has_own_wm;
    46 
    47     SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
    48                                                        DFSCL_NORMAL));
    49     SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
    50                                                           DLSCL_ADMINISTRATIVE));
    51 
    52     /* Fill the window description. */
    53     if (window->x == SDL_WINDOWPOS_CENTERED) {
    54         x = (dispdata->cw - window->w) / 2;
    55     } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
    56         x = 0;
    57     } else {
    58         x = window->x;
    59     }
    60     if (window->y == SDL_WINDOWPOS_CENTERED) {
    61         y = (dispdata->ch - window->h) / 2;
    62     } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
    63         y = 0;
    64     } else {
    65         y = window->y;
    66     }
    67     if (window->flags & SDL_WINDOW_FULLSCREEN) {
    68         x = 0;
    69         y = 0;
    70     }
    71 
    72     DirectFB_WM_AdjustWindowLayout(window);
    73 
    74     /* Create Window */
    75     desc.flags =
    76         DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_POSX
    77         | DWDESC_POSY | DWDESC_SURFACE_CAPS;
    78     desc.posx = x;
    79     desc.posy = y;
    80     desc.width = windata->size.w;
    81     desc.height = windata->size.h;
    82     desc.pixelformat = dispdata->pixelformat;
    83     desc.surface_caps = DSCAPS_PREMULTIPLIED;
    84 
    85     /* Create the window. */
    86     SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
    87                                                    &windata->window));
    88 
    89     /* Set Options */
    90     windata->window->GetOptions(windata->window, &wopts);
    91 
    92     if (window->flags & SDL_WINDOW_RESIZABLE)
    93         wopts |= DWOP_SCALE;
    94     else
    95         wopts |= DWOP_KEEP_SIZE;
    96 
    97     if (window->flags & SDL_WINDOW_FULLSCREEN) {
    98         wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
    99         windata->window->SetStackingClass(windata->window, DWSC_UPPER);
   100     }
   101     windata->window->SetOptions(windata->window, wopts);
   102 
   103     /* See what we got */
   104     SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &window->w, &window->h));
   105 
   106     /* Get the window's surface. */
   107     SDL_DFB_CHECKERR(windata->window->GetSurface(windata->window,
   108                                                  &windata->window_surface));
   109     /* And get a subsurface for rendering */
   110     SDL_DFB_CHECKERR(windata->window_surface->
   111                      GetSubSurface(windata->window_surface, &windata->client,
   112                                    &windata->surface));
   113 
   114     windata->window->SetOpacity(windata->window, 0xFF);
   115 
   116     /* Create Eventbuffer */
   117     SDL_DFB_CHECKERR(windata->window->CreateEventBuffer(windata->window,
   118                                                         &windata->eventbuffer));
   119     SDL_DFB_CHECKERR(windata->
   120                      window->EnableEvents(windata->window, DWET_ALL));
   121 
   122     /* Create a font */
   123     /* FIXME: once during Video_Init */
   124     if (windata->is_managed) {
   125         DFBFontDescription fdesc;
   126 
   127         fdesc.flags = DFDESC_HEIGHT;
   128         fdesc.height = windata->theme.font_size;
   129         font = NULL;
   130         SDL_DFB_CHECK(devdata->
   131                       dfb->CreateFont(devdata->dfb, windata->theme.font,
   132                                       &fdesc, &font));
   133         windata->window_surface->SetFont(windata->window_surface, font);
   134         SDL_DFB_RELEASE(font);
   135     }
   136 
   137     /* Make it the top most window. */
   138     windata->window->RaiseToTop(windata->window);
   139 
   140     /* remember parent */
   141     windata->sdl_id = window->id;
   142 
   143     /* Add to list ... */
   144 
   145     windata->next = devdata->firstwin;
   146     windata->opacity = 0xFF;
   147     devdata->firstwin = windata;
   148 
   149     /* Draw Frame */
   150     DirectFB_WM_RedrawLayout(window);
   151 
   152     return 0;
   153   error:
   154     SDL_DFB_RELEASE(windata->window);
   155     SDL_DFB_RELEASE(windata->surface);
   156     return -1;
   157 }
   158 
   159 int
   160 DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
   161 {
   162     SDL_Unsupported();
   163     return -1;
   164 }
   165 
   166 void
   167 DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
   168 {
   169     SDL_DFB_WINDOWDATA(window);
   170 
   171     if (windata->is_managed) {
   172         windata->wm_needs_redraw = 1;
   173     } else
   174         SDL_Unsupported();
   175 }
   176 
   177 void
   178 DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
   179 {
   180     SDL_DFB_DEVICEDATA(_this);
   181     SDL_DFB_WINDOWDATA(window);
   182     SDL_Surface *surface = NULL;
   183     DFBResult ret;
   184 
   185     if (icon) {
   186         SDL_PixelFormat format;
   187         DFBSurfaceDescription dsc;
   188         Uint32 *dest;
   189         Uint32 *p;
   190         int pitch, i;
   191 
   192         /* Convert the icon to ARGB for modern window managers */
   193         SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
   194                        0xFF000000);
   195         surface = SDL_ConvertSurface(icon, &format, 0);
   196         if (!surface) {
   197             return;
   198         }
   199         dsc.flags =
   200             DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   201         dsc.caps = DSCAPS_VIDEOONLY;
   202         dsc.width = surface->w;
   203         dsc.height = surface->h;
   204         dsc.pixelformat = DSPF_ARGB;
   205 
   206         SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
   207                                                      &windata->icon));
   208 
   209         SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
   210                                              (void *) &dest, &pitch));
   211 
   212         p = surface->pixels;
   213         for (i = 0; i < surface->h; i++)
   214             memcpy((char *) dest + i * pitch,
   215                    (char *) p + i * surface->pitch, 4 * surface->w);
   216 
   217         windata->icon->Unlock(windata->icon);
   218         SDL_FreeSurface(surface);
   219     } else {
   220         SDL_DFB_RELEASE(windata->icon);
   221     }
   222     return;
   223   error:
   224     if (surface)
   225         SDL_FreeSurface(surface);
   226     SDL_DFB_RELEASE(windata->icon);
   227     return;
   228 }
   229 
   230 void
   231 DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
   232 {
   233     SDL_DFB_WINDOWDATA(window);
   234     int x, y;
   235 
   236     if (window->y == SDL_WINDOWPOS_UNDEFINED)
   237         y = 0;
   238     else
   239         y = window->y;
   240 
   241     if (window->x == SDL_WINDOWPOS_UNDEFINED)
   242         x = 0;
   243     else
   244         x = window->x;
   245 
   246     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   247         x = 0;
   248         y = 0;
   249     }
   250     DirectFB_WM_AdjustWindowLayout(window);
   251     windata->window->MoveTo(windata->window, x, y);
   252 }
   253 
   254 void
   255 DirectFB_SetWindowSize(_THIS, SDL_Window * window)
   256 {
   257     SDL_DFB_DEVICEDATA(_this);
   258     SDL_DFB_WINDOWDATA(window);
   259     int ret;
   260 
   261     if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
   262         int cw;
   263         int ch;
   264 
   265         /* Make sure all events are disabled for this operation ! */
   266         SDL_DFB_CHECKERR(windata->window->DisableEvents(windata->window,
   267                                                         DWET_ALL));
   268 
   269         SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
   270 
   271         if (cw != window->w || ch != window->h) {
   272 
   273             DirectFB_WM_AdjustWindowLayout(window);
   274             SDL_DFB_CHECKERR(windata->window->Resize(windata->window,
   275                                                      windata->size.w,
   276                                                      windata->size.h));
   277         }
   278 
   279         SDL_DFB_CHECKERR(windata->window->EnableEvents(windata->window,
   280                                                        DWET_ALL));
   281 
   282         SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &window->w, &window->h));
   283 
   284         SDL_OnWindowResized(window);
   285     }
   286     return;
   287   error:
   288     windata->window->EnableEvents(windata->window, DWET_ALL);
   289     return;
   290 }
   291 
   292 void
   293 DirectFB_ShowWindow(_THIS, SDL_Window * window)
   294 {
   295     SDL_DFB_WINDOWDATA(window);
   296 
   297     windata->window->SetOpacity(windata->window, windata->opacity);
   298 
   299 }
   300 
   301 void
   302 DirectFB_HideWindow(_THIS, SDL_Window * window)
   303 {
   304     SDL_DFB_WINDOWDATA(window);
   305 
   306     windata->window->GetOpacity(windata->window, &windata->opacity);
   307     windata->window->SetOpacity(windata->window, 0);
   308 }
   309 
   310 void
   311 DirectFB_RaiseWindow(_THIS, SDL_Window * window)
   312 {
   313     SDL_DFB_WINDOWDATA(window);
   314 
   315     windata->window->RaiseToTop(windata->window);
   316     windata->window->RequestFocus(windata->window);
   317 }
   318 
   319 void
   320 DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
   321 {
   322     SDL_DFB_WINDOWDATA(window);
   323 
   324     if (windata->is_managed) {
   325     	DirectFB_WM_MaximizeWindow(_this, window);
   326     } else
   327         SDL_Unsupported();
   328 }
   329 
   330 void
   331 DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
   332 {
   333     /* FIXME: Size to 32x32 ? */
   334 
   335     SDL_Unsupported();
   336 }
   337 
   338 void
   339 DirectFB_RestoreWindow(_THIS, SDL_Window * window)
   340 {
   341     SDL_DFB_WINDOWDATA(window);
   342 
   343     if (windata->is_managed) {
   344     	DirectFB_WM_RestoreWindow(_this, window);
   345     } else
   346         SDL_Unsupported();
   347 }
   348 
   349 void
   350 DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
   351 {
   352     SDL_DFB_WINDOWDATA(window);
   353 
   354     if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
   355         windata->window->GrabPointer(windata->window);
   356         windata->window->GrabKeyboard(windata->window);
   357     } else {
   358         windata->window->UngrabPointer(windata->window);
   359         windata->window->UngrabKeyboard(windata->window);
   360     }
   361 }
   362 
   363 void
   364 DirectFB_DestroyWindow(_THIS, SDL_Window * window)
   365 {
   366     SDL_DFB_DEVICEDATA(_this);
   367     SDL_DFB_WINDOWDATA(window);
   368     DFB_WindowData *p;
   369 
   370     SDL_DFB_DEBUG("Trace\n");
   371 
   372     /* Some cleanups */
   373     windata->window->UngrabPointer(windata->window);
   374     windata->window->UngrabKeyboard(windata->window);
   375 
   376     windata->window_surface->SetFont(windata->window_surface, NULL);
   377     SDL_DFB_RELEASE(windata->icon);
   378     SDL_DFB_RELEASE(windata->eventbuffer);
   379     SDL_DFB_RELEASE(windata->surface);
   380     SDL_DFB_RELEASE(windata->window_surface);
   381 
   382     SDL_DFB_RELEASE(windata->window);
   383 
   384     /* Remove from list ... */
   385 
   386     p = devdata->firstwin;
   387     while (p && p->next != windata)
   388         p = p->next;
   389     if (p)
   390         p->next = windata->next;
   391     else
   392         devdata->firstwin = windata->next;
   393     SDL_free(windata);
   394     return;
   395 }
   396 
   397 SDL_bool
   398 DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
   399                          struct SDL_SysWMinfo * info)
   400 {
   401     SDL_Unsupported();
   402     return SDL_FALSE;
   403 }
   404 
   405 void
   406 DirectFB_AdjustWindowSurface(SDL_Window * window)
   407 {
   408     SDL_DFB_WINDOWDATA(window);
   409     int adjust = windata->wm_needs_redraw;
   410     int cw, ch;
   411     int ret;
   412 
   413     DirectFB_WM_AdjustWindowLayout(window);
   414 
   415     SDL_DFB_CHECKERR(windata->
   416                      window_surface->GetSize(windata->window_surface, &cw,
   417                                              &ch));
   418     if (cw != windata->size.w || ch != windata->size.h) {
   419         adjust = 1;
   420     }
   421 
   422     if (adjust) {
   423 #if DFB_VERSION_ATLEAST(1,2,0)
   424        SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window,
   425                                                         windata->size.w,
   426                                                         windata->size.h));
   427        SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
   428                                                           windata->
   429                                                           window_surface,
   430                                                           &windata->client));
   431 #else
   432        /* recreate subsurface */
   433        windata->surface->ReleaseSource(windata->surface);
   434        windata->window_surface->ReleaseSource(windata->window_surface);
   435        SDL_DFB_RELEASE(windata->surface);
   436        windata->surface = NULL;
   437        SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window,
   438                                                        windata->size.w,
   439                                                        windata->size.h));
   440        SDL_DFB_CHECKERR(windata->window_surface->
   441                         GetSubSurface(windata->window_surface, &windata->client,
   442                                       &windata->surface));
   443 #endif
   444        DirectFB_WM_RedrawLayout(window);
   445     }
   446   error:
   447     return;
   448 }
   449