src/video/directfb/SDL_DirectFB_window.c
author Sam Lantinga
Tue, 15 Mar 2011 21:44:56 -0700
changeset 5495 b3680e05286d
parent 5489 e0c63a55b67d
child 5535 96594ac5fd1a
permissions -rw-r--r--
Removed obsolete window positioning code.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2011 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     SDL1.3 DirectFB driver by couriersud@arcor.de
    23 	
    24 */
    25 
    26 #include "SDL_DirectFB_video.h"
    27 #include "SDL_DirectFB_modes.h"
    28 #include "SDL_DirectFB_window.h"
    29 #include "SDL_DirectFB_shape.h"
    30 
    31 #if SDL_DIRECTFB_OPENGL
    32 #include "SDL_DirectFB_opengl.h"
    33 #endif
    34 
    35 #include "SDL_syswm.h"
    36 
    37 #include "../SDL_pixels_c.h"
    38 
    39 int
    40 DirectFB_CreateWindow(_THIS, SDL_Window * window)
    41 {
    42     SDL_DFB_DEVICEDATA(_this);
    43     SDL_DFB_DISPLAYDATA(window);
    44     DFB_WindowData *windata = NULL;
    45     DFBWindowOptions wopts;
    46     DFBWindowDescription desc;
    47     int x, y;
    48     int bshaped = 0;
    49 
    50     SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
    51     windata = (DFB_WindowData *) window->driverdata;
    52 
    53     windata->is_managed = devdata->has_own_wm;
    54 #if 1
    55     SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
    56                                                        DFSCL_NORMAL));
    57     SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
    58                                                           DLSCL_ADMINISTRATIVE));
    59 #endif
    60 	/* FIXME ... ughh, ugly */
    61 	if (window->x == -1000 && window->y == -1000)
    62 		bshaped = 1;
    63 	
    64     /* Fill the window description. */
    65     x = window->x;
    66     y = window->y;
    67 
    68     DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
    69 
    70     /* Create Window */
    71 	desc.caps = 0;
    72     desc.flags =
    73         DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
    74 
    75     if (bshaped) {
    76     	desc.flags |= DWDESC_CAPS;
    77     	desc.caps |= DWCAPS_ALPHACHANNEL;
    78     }
    79     else
    80     {
    81     	desc.flags |= DWDESC_PIXELFORMAT;
    82     }
    83 
    84     if (!(window->flags & SDL_WINDOW_BORDERLESS))
    85 		desc.caps |= DWCAPS_NODECORATION;
    86 
    87     desc.posx = x;
    88     desc.posy = y;
    89     desc.width = windata->size.w;
    90     desc.height = windata->size.h;
    91     desc.pixelformat = dispdata->pixelformat;
    92     desc.surface_caps = DSCAPS_PREMULTIPLIED;
    93     
    94     /* Create the window. */
    95     SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
    96                                                    &windata->dfbwin));
    97 
    98     /* Set Options */
    99     SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
   100 
   101     /* explicit rescaling of surface */
   102     wopts |= DWOP_SCALE;
   103     if (window->flags & SDL_WINDOW_RESIZABLE) {
   104         wopts &= ~DWOP_KEEP_SIZE;
   105     }
   106     else {
   107         wopts |= DWOP_KEEP_SIZE;
   108     }
   109 
   110     if (window->flags & SDL_WINDOW_FULLSCREEN) {
   111         wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
   112         SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
   113     }
   114     
   115     if (bshaped) {
   116         wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
   117         wopts &= ~DWOP_OPAQUE_REGION;
   118     }
   119 
   120     SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
   121 
   122     /* See what we got */
   123     SDL_DFB_CHECK(DirectFB_WM_GetClientSize
   124                      (_this, window, &window->w, &window->h));
   125 
   126     /* Get the window's surface. */
   127     SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
   128                                                  &windata->window_surface));
   129 
   130     /* And get a subsurface for rendering */
   131     SDL_DFB_CHECKERR(windata->window_surface->
   132                      GetSubSurface(windata->window_surface, &windata->client,
   133                                    &windata->surface));
   134 
   135     SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
   136 
   137     /* Create Eventbuffer */
   138 
   139     SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
   140                                                         &windata->
   141                                                         eventbuffer));
   142     SDL_DFB_CHECKERR(windata->dfbwin->
   143                      EnableEvents(windata->dfbwin, DWET_ALL));
   144 
   145     /* Create a font */
   146     /* FIXME: once during Video_Init */
   147     windata->font = NULL;
   148 
   149     /* Make it the top most window. */
   150     SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
   151 
   152     /* remember parent */
   153     //windata->sdlwin = window;
   154 
   155     /* Add to list ... */
   156 
   157     windata->next = devdata->firstwin;
   158     windata->opacity = 0xFF;
   159     devdata->firstwin = window;
   160 
   161     /* Draw Frame */
   162     DirectFB_WM_RedrawLayout(_this, window);
   163 
   164     return 0;
   165   error:
   166 	SDL_DFB_RELEASE(windata->surface);
   167     SDL_DFB_RELEASE(windata->dfbwin);
   168     return -1;
   169 }
   170 
   171 int
   172 DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
   173 {
   174     SDL_Unsupported();
   175     return -1;
   176 }
   177 
   178 void
   179 DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
   180 {
   181     SDL_DFB_WINDOWDATA(window);
   182 
   183     if (windata->is_managed) {
   184         windata->wm_needs_redraw = 1;
   185         DirectFB_WM_RedrawLayout(_this, window);
   186     } else
   187         SDL_Unsupported();
   188 }
   189 
   190 void
   191 DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
   192 {
   193     SDL_DFB_DEVICEDATA(_this);
   194     SDL_DFB_WINDOWDATA(window);
   195     SDL_Surface *surface = NULL;
   196 
   197     if (icon) {
   198         SDL_PixelFormat format;
   199         DFBSurfaceDescription dsc;
   200         Uint32 *dest;
   201         Uint32 *p;
   202         int pitch, i;
   203 
   204         /* Convert the icon to ARGB for modern window managers */
   205         SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
   206         surface = SDL_ConvertSurface(icon, &format, 0);
   207         if (!surface) {
   208             return;
   209         }
   210         dsc.flags =
   211             DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   212         dsc.caps = DSCAPS_VIDEOONLY;
   213         dsc.width = surface->w;
   214         dsc.height = surface->h;
   215         dsc.pixelformat = DSPF_ARGB;
   216 
   217         SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
   218                                                      &windata->icon));
   219 
   220         SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
   221                                              (void *) &dest, &pitch));
   222 
   223         p = surface->pixels;
   224         for (i = 0; i < surface->h; i++)
   225             memcpy((char *) dest + i * pitch,
   226                    (char *) p + i * surface->pitch, 4 * surface->w);
   227 
   228         SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
   229         SDL_FreeSurface(surface);
   230     } else {
   231         SDL_DFB_RELEASE(windata->icon);
   232     }
   233     return;
   234   error:
   235     if (surface)
   236         SDL_FreeSurface(surface);
   237     SDL_DFB_RELEASE(windata->icon);
   238     return;
   239 }
   240 
   241 void
   242 DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
   243 {
   244     SDL_DFB_WINDOWDATA(window);
   245     int x, y;
   246 
   247     x = window->x;
   248     y = window->y;
   249 
   250     DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
   251     SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
   252 }
   253 
   254 void
   255 DirectFB_SetWindowSize(_THIS, SDL_Window * window)
   256 {
   257     SDL_DFB_WINDOWDATA(window);
   258 
   259     if(SDL_IsShapedWindow(window))
   260         DirectFB_ResizeWindowShape(window);
   261 
   262     if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
   263         int cw;
   264         int ch;
   265 
   266         /* Make sure all events are disabled for this operation ! */
   267         SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
   268                                                         DWET_ALL));
   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, window->flags, window->w, window->h);
   274             SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
   275                                                      windata->size.w,
   276                                                      windata->size.h));
   277         }
   278 
   279         SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
   280                      (_this, window, &window->w, &window->h));
   281         DirectFB_AdjustWindowSurface(window);
   282 
   283         SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
   284                                                        DWET_ALL));
   285 
   286     }
   287     return;
   288   error:
   289     SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
   290     return;
   291 }
   292 
   293 void
   294 DirectFB_ShowWindow(_THIS, SDL_Window * window)
   295 {
   296     SDL_DFB_WINDOWDATA(window);
   297 
   298     SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
   299 
   300 }
   301 
   302 void
   303 DirectFB_HideWindow(_THIS, SDL_Window * window)
   304 {
   305     SDL_DFB_WINDOWDATA(window);
   306 
   307     SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
   308     SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
   309 }
   310 
   311 void
   312 DirectFB_RaiseWindow(_THIS, SDL_Window * window)
   313 {
   314     SDL_DFB_WINDOWDATA(window);
   315 
   316     SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
   317     SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
   318 }
   319 
   320 void
   321 DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
   322 {
   323     SDL_DFB_WINDOWDATA(window);
   324     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
   325     DFBWindowOptions wopts;
   326 
   327     SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
   328                                  &windata->restore.x, &windata->restore.y));
   329     SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
   330                              &windata->restore.h));
   331 
   332     DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;
   333 
   334     SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
   335     SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
   336                             display->current_mode.w, display->current_mode.h));
   337 
   338     /* Set Options */
   339     SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
   340     wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
   341     SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
   342 }
   343 
   344 void
   345 DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
   346 {
   347     /* FIXME: Size to 32x32 ? */
   348 
   349     SDL_Unsupported();
   350 }
   351 
   352 void
   353 DirectFB_RestoreWindow(_THIS, SDL_Window * window)
   354 {
   355     SDL_DFB_WINDOWDATA(window);
   356     DFBWindowOptions wopts;
   357 
   358     /* Set Options */
   359     SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
   360     wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
   361     SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
   362 
   363     /* Window layout */
   364     DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
   365     	windata->restore.w, windata->restore.h);
   366     SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
   367                             windata->restore.h));
   368     SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
   369                             windata->restore.y));
   370 
   371     if (!(window->flags & SDL_WINDOW_RESIZABLE))
   372         wopts |= DWOP_KEEP_SIZE;
   373 
   374     if (window->flags & SDL_WINDOW_FULLSCREEN)
   375         wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
   376     SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
   377 
   378 
   379 }
   380 
   381 void
   382 DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
   383 {
   384     SDL_DFB_DEVICEDATA(_this);
   385     SDL_DFB_WINDOWDATA(window);
   386     DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
   387 
   388     if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
   389         if (gwindata != NULL)
   390         {
   391 		    SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
   392 		    SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
   393         }
   394         SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
   395         SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
   396         devdata->grabbed_window = window;
   397     } else {
   398         SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
   399         SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
   400         devdata->grabbed_window = NULL;
   401     }
   402 }
   403 
   404 void
   405 DirectFB_DestroyWindow(_THIS, SDL_Window * window)
   406 {
   407     SDL_DFB_DEVICEDATA(_this);
   408     SDL_DFB_WINDOWDATA(window);
   409     DFB_WindowData *p;
   410 
   411     /* Some cleanups */
   412     SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
   413     SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
   414 
   415 #if SDL_DIRECTFB_OPENGL
   416 	DirectFB_GL_DestroyWindowContexts(_this, window);
   417 #endif
   418 
   419 	if (window->shaper)
   420 	{
   421 	    SDL_ShapeData *data = window->shaper->driverdata;
   422 	    SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
   423     	SDL_DFB_RELEASE(data->surface);
   424     	SDL_DFB_FREE(data);
   425     	SDL_DFB_FREE(window->shaper);
   426 	}
   427 
   428     SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
   429     SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
   430     SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
   431   	SDL_DFB_RELEASE(windata->icon);
   432     SDL_DFB_RELEASE(windata->font);
   433     SDL_DFB_RELEASE(windata->eventbuffer);
   434     SDL_DFB_RELEASE(windata->surface);
   435     SDL_DFB_RELEASE(windata->window_surface);
   436 
   437     SDL_DFB_RELEASE(windata->dfbwin);
   438 
   439     /* Remove from list ... */
   440 
   441     p = devdata->firstwin->driverdata;
   442 
   443     while (p && p->next != window)
   444         p = (p->next ? p->next->driverdata : NULL);
   445     if (p)
   446         p->next = windata->next;
   447     else
   448         devdata->firstwin = windata->next;
   449     SDL_free(windata);
   450     return;
   451 }
   452 
   453 SDL_bool
   454 DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
   455                          struct SDL_SysWMinfo * info)
   456 {
   457     SDL_DFB_DEVICEDATA(_this);
   458     SDL_DFB_WINDOWDATA(window);
   459 
   460     if (info->version.major == SDL_MAJOR_VERSION &&
   461         info->version.minor == SDL_MINOR_VERSION) {
   462         info->subsystem = SDL_SYSWM_DIRECTFB;
   463         info->info.dfb.dfb = devdata->dfb;
   464         info->info.dfb.window = windata->dfbwin;
   465         info->info.dfb.surface = windata->surface;
   466         return SDL_TRUE;
   467     } else {
   468         SDL_SetError("Application not compiled with SDL %d.%d\n",
   469                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
   470         return SDL_FALSE;
   471     }
   472 }
   473 
   474 void
   475 DirectFB_AdjustWindowSurface(SDL_Window * window)
   476 {
   477     SDL_DFB_WINDOWDATA(window);
   478     int adjust = windata->wm_needs_redraw;
   479     int cw, ch;
   480 
   481     DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
   482 
   483     SDL_DFB_CHECKERR(windata->
   484                      window_surface->GetSize(windata->window_surface, &cw,
   485                                              &ch));
   486     if (cw != windata->size.w || ch != windata->size.h) {
   487         adjust = 1;
   488     }
   489 
   490     if (adjust) {
   491 #if SDL_DIRECTFB_OPENGL
   492 		DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
   493 #endif
   494 
   495 #if (DFB_VERSION_ATLEAST(1,2,1))
   496         SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
   497                                                         windata->size.w,
   498                                                         windata->size.h));
   499         SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
   500                                                           windata->
   501                                                           window_surface,
   502                                                           &windata->client));
   503 #else
   504         DFBWindowOptions opts;
   505 
   506         SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
   507         /* recreate subsurface */
   508         SDL_DFB_RELEASE(windata->surface);
   509 
   510         if (opts & DWOP_SCALE)
   511             SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
   512                                                             windata->size.w,
   513                                                             windata->size.h));
   514         SDL_DFB_CHECKERR(windata->window_surface->
   515                          GetSubSurface(windata->window_surface,
   516                                        &windata->client, &windata->surface));
   517 #endif
   518         DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);
   519         
   520 #if SDL_DIRECTFB_OPENGL
   521 		DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
   522 #endif
   523    }
   524   error:
   525     return;
   526 }