add fullscreen support in software directdraw engine (win xp)
authorcaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 1 Dec 2008 20:38:05 +0000 (20:38 +0000)
committercaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 1 Dec 2008 20:38:05 +0000 (20:38 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@37887 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/modules/engines/software_ddraw/Evas_Engine_Software_DDraw.h
src/modules/engines/software_ddraw/evas_ddraw_main.cpp
src/modules/engines/software_ddraw/evas_engine.c
src/modules/engines/software_ddraw/evas_engine.h
src/modules/engines/software_ddraw/evas_outbuf.c

index f0628d6..e06ef4e 100644 (file)
@@ -16,9 +16,10 @@ struct _Evas_Engine_Info_Software_DDraw
    Evas_Engine_Info magic;
 
    struct {
-      HWND                window;
-      int                 depth;
-      int                 rotation;
+      HWND         window;
+      int          depth;
+      int          rotation;
+      unsigned int fullscreen : 1;
    } info;
 };
 
index ec5c606..46836a3 100644 (file)
@@ -4,12 +4,11 @@
 int
 evas_software_ddraw_init (HWND    window,
                           int     depth,
+                          int     fullscreen,
                           Outbuf *buf)
 {
    DDSURFACEDESC  surface_desc;
    DDPIXELFORMAT  pixel_format;
-   RECT           rect;
-   LPDIRECTDRAW   o;
    HRESULT        res;
    int            width;
    int            height;
@@ -17,62 +16,109 @@ evas_software_ddraw_init (HWND    window,
    if (!buf)
      return 0;
 
-   if (!GetClientRect(window, &rect))
-     return 0;
-
-   width = rect.right - rect.left;
-   height = rect.bottom - rect.top;
-
    buf->priv.dd.window = window;
 
    res = DirectDrawCreate(NULL, &buf->priv.dd.object, NULL);
    if (FAILED(res))
      return 0;
 
-   res = buf->priv.dd.object->SetCooperativeLevel(window, DDSCL_NORMAL);
-   if (FAILED(res))
-     goto release_object;
+   if (buf->priv.dd.fullscreen)
+     {
+        DDSCAPS caps;
 
-   res = buf->priv.dd.object->CreateClipper (0, &buf->priv.dd.clipper, NULL);
-   if (FAILED(res))
-     goto release_object;
+        res = buf->priv.dd.object->SetCooperativeLevel(window,
+                                                       DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
+        if (FAILED(res))
+          goto release_object;
 
-   res = buf->priv.dd.clipper->SetHWnd (0, window);
-   if (FAILED(res))
-     goto release_clipper;
+        width = GetSystemMetrics(SM_CXSCREEN);
+        height = GetSystemMetrics(SM_CYSCREEN);
 
-   memset(&surface_desc, 0, sizeof(surface_desc));
-   surface_desc.dwSize = sizeof(surface_desc);
-   surface_desc.dwFlags = DDSD_CAPS;
-   surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+        ZeroMemory(&pixel_format, sizeof(pixel_format));
+        pixel_format.dwSize = sizeof(pixel_format);
+        buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);
 
-   res = buf->priv.dd.object->CreateSurface (&surface_desc, &buf->priv.dd.surface_primary, NULL);
-   if (FAILED(res))
-     goto release_clipper;
+        if (pixel_format.dwRGBBitCount != depth)
+          goto release_object;
 
-   res = buf->priv.dd.surface_primary->SetClipper (buf->priv.dd.clipper);
-   if (FAILED(res))
-     goto release_surface_primary;
+        buf->priv.dd.depth = depth;
 
-   memset (&surface_desc, 0, sizeof(surface_desc));
-   surface_desc.dwSize = sizeof(surface_desc);
-   surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
-   surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
-   surface_desc.dwWidth = width;
-   surface_desc.dwHeight = height;
+        res = buf->priv.dd.object->SetDisplayMode(width, height, depth);
+        if (FAILED(res))
+          goto release_object;
 
-   res = buf->priv.dd.object->CreateSurface (&surface_desc, &buf->priv.dd.surface_back, NULL);
-   if (FAILED(res))
-     goto release_surface_primary;
+        memset(&surface_desc, 0, sizeof(surface_desc));
+        surface_desc.dwSize = sizeof(surface_desc);
+        surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
+        surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
+        surface_desc.dwBackBufferCount = 1;
 
-   ZeroMemory(&pixel_format, sizeof(pixel_format));
-   pixel_format.dwSize = sizeof(pixel_format);
-   buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);
+        res = buf->priv.dd.object->CreateSurface(&surface_desc,
+                                                 &buf->priv.dd.surface_primary, NULL);
+        if (FAILED(res))
+          goto release_object;
+
+        caps.dwCaps = DDSCAPS_BACKBUFFER;
+        res = buf->priv.dd.surface_primary->GetAttachedSurface(&caps,
+                                                               &buf->priv.dd.surface_back);
+        if (FAILED(res))
+          goto release_surface_primary;
+     }
+   else
+     {
+        RECT           rect;
+
+        if (!GetClientRect(window, &rect))
+          goto release_object;
+
+        width = rect.right - rect.left;
+        height = rect.bottom - rect.top;
+
+        res = buf->priv.dd.object->SetCooperativeLevel(window, DDSCL_NORMAL);
+        if (FAILED(res))
+          goto release_object;
+
+        res = buf->priv.dd.object->CreateClipper(0, &buf->priv.dd.clipper, NULL);
+        if (FAILED(res))
+          goto release_object;
+
+        res = buf->priv.dd.clipper->SetHWnd(0, window);
+        if (FAILED(res))
+          goto release_clipper;
+
+        memset(&surface_desc, 0, sizeof(surface_desc));
+        surface_desc.dwSize = sizeof(surface_desc);
+        surface_desc.dwFlags = DDSD_CAPS;
+        surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
 
-   if (pixel_format.dwRGBBitCount != depth)
-     goto release_surface_back;
+        res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_primary, NULL);
+        if (FAILED(res))
+          goto release_clipper;
 
-   buf->priv.dd.depth = depth;
+        res = buf->priv.dd.surface_primary->SetClipper(buf->priv.dd.clipper);
+        if (FAILED(res))
+          goto release_surface_primary;
+
+        memset (&surface_desc, 0, sizeof(surface_desc));
+        surface_desc.dwSize = sizeof(surface_desc);
+        surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
+        surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+        surface_desc.dwWidth = width;
+        surface_desc.dwHeight = height;
+
+        res = buf->priv.dd.object->CreateSurface(&surface_desc, &buf->priv.dd.surface_back, NULL);
+        if (FAILED(res))
+          goto release_surface_primary;
+
+        ZeroMemory(&pixel_format, sizeof(pixel_format));
+        pixel_format.dwSize = sizeof(pixel_format);
+        buf->priv.dd.surface_primary->GetPixelFormat(&pixel_format);
+
+        if (pixel_format.dwRGBBitCount != depth)
+          goto release_surface_back;
+
+        buf->priv.dd.depth = depth;
+     }
 
    return 1;
 
@@ -81,7 +127,8 @@ evas_software_ddraw_init (HWND    window,
  release_surface_primary:
    buf->priv.dd.surface_primary->Release();
  release_clipper:
-   buf->priv.dd.clipper->Release();
+   if (buf->priv.dd.fullscreen)
+     buf->priv.dd.clipper->Release();
  release_object:
    buf->priv.dd.object->Release();
 
@@ -94,10 +141,16 @@ evas_software_ddraw_shutdown(Outbuf *buf)
    if (!buf)
      return;
 
-   buf->priv.dd.surface_back->Release();
-   buf->priv.dd.surface_primary->Release();
-   buf->priv.dd.clipper->Release();
-   buf->priv.dd.object->Release();
+   if (buf->priv.dd.fullscreen)
+     if (buf->priv.dd.surface_back)
+       buf->priv.dd.surface_back->Release();
+   if (buf->priv.dd.surface_primary)
+     buf->priv.dd.surface_primary->Release();
+   if (buf->priv.dd.fullscreen)
+     if (buf->priv.dd.clipper)
+       buf->priv.dd.clipper->Release();
+   if (buf->priv.dd.object)
+     buf->priv.dd.object->Release();
 }
 
 int
index 114e7be..0b3ed48 100644 (file)
@@ -24,7 +24,8 @@ _output_setup(int  width,
               int  height,
               int  rot,
               HWND window,
-              int  depth)
+              int  depth,
+              int  fullscreen)
 {
    Render_Engine *re;
 
@@ -51,7 +52,7 @@ _output_setup(int  width,
 
    re->ob = evas_software_ddraw_outbuf_setup(width, height, rot,
                                              OUTBUF_DEPTH_INHERIT,
-                                             window, depth);
+                                             window, depth, fullscreen);
    if (!re->ob)
      {
        free(re);
@@ -59,7 +60,7 @@ _output_setup(int  width,
      }
 
    /* for updates return 1 big buffer, but only use portions of it, also cache
-    it and keepit around until an idle_flush */
+    it and keep it around until an idle_flush */
    /* disable for now - i am hunting down why some expedite tests are slower,
     * as well as shaped stuff is broken and probable non-32bpp is broken as
     * convert funcs dont do the right thing
@@ -116,7 +117,8 @@ eng_setup(Evas *e, void *in)
                                            e->output.h,
                                            info->info.rotation,
                                            info->info.window,
-                                           info->info.depth);
+                                           info->info.depth,
+                                           info->info.fullscreen);
    else
      {
        int ponebuf = 0;
@@ -129,7 +131,8 @@ eng_setup(Evas *e, void *in)
                                                   info->info.rotation,
                                                   OUTBUF_DEPTH_INHERIT,
                                                   info->info.window,
-                                                  info->info.depth);
+                                                  info->info.depth,
+                                                  info->info.fullscreen);
        re->ob->onebuf = ponebuf;
      }
    if (!e->engine.data.output) return;
index 36058d8..a692a42 100644 (file)
@@ -42,8 +42,9 @@ struct _Outbuf
          LPDIRECTDRAWSURFACE surface_back;
          LPDIRECTDRAWCLIPPER clipper;
          int                 depth;
-         unsigned char       swap : 1;
-         unsigned char       bit_swap : 1;
+         unsigned char       fullscreen : 1;
+         unsigned char       swap       : 1;
+         unsigned char       bit_swap   : 1;
       } dd;
       struct {
          DATA32              r, g, b;
@@ -58,10 +59,10 @@ struct _Outbuf
       /* a list of previous frame pending regions to write to the target */
       Eina_List             *prev_pending_writes;
 
-      unsigned char          mask_dither : 1;
+      unsigned char          mask_dither       : 1;
       unsigned char          destination_alpha : 1;
-      unsigned char          debug : 1;
-      unsigned char          synced : 1;
+      unsigned char          debug             : 1;
+      unsigned char          synced            : 1;
    } priv;
 };
 
@@ -97,7 +98,8 @@ Outbuf *evas_software_ddraw_outbuf_setup(int          width,
                                          int          rotation,
                                          Outbuf_Depth depth,
                                          HWND         window,
-                                         int          w_depth);
+                                         int          w_depth,
+                                         int          fullscreen);
 
 void evas_software_ddraw_outbuf_reconfigure(Outbuf      *buf,
                                             int          width,
@@ -168,6 +170,7 @@ extern "C" {
 
 int evas_software_ddraw_init (HWND    window,
                               int     depth,
+                              int     fullscreen,
                               Outbuf *buf);
 
 void evas_software_ddraw_shutdown(Outbuf *buf);
index 0887b9e..fc70a6e 100644 (file)
@@ -103,7 +103,8 @@ evas_software_ddraw_outbuf_setup(int          width,
                                  int          rotation,
                                  Outbuf_Depth depth,
                                  HWND         window,
-                                 int          w_depth)
+                                 int          w_depth,
+                                 int          fullscreen)
 {
    Outbuf *buf;
 
@@ -116,7 +117,7 @@ evas_software_ddraw_outbuf_setup(int          width,
    buf->depth = depth;
    buf->rot = rotation;
 
-   if (!evas_software_ddraw_init(window, w_depth, buf))
+   if (!evas_software_ddraw_init(window, w_depth, fullscreen, buf))
      {
         free(buf);
         return NULL;