Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
  22.  
  23. #include "iunknown.h"
  24. #include "util/u_atomic.h"
  25. #include "nine_helpers.h"
  26.  
  27. #define DBG_CHANNEL DBG_UNKNOWN
  28.  
  29. HRESULT
  30. NineUnknown_ctor( struct NineUnknown *This,
  31.                   struct NineUnknownParams *pParams )
  32. {
  33.     This->refs = pParams->container ? 0 : 1;
  34.     This->bind = 0;
  35.     This->forward = !This->refs;
  36.     This->container = pParams->container;
  37.     This->device = pParams->device;
  38.     if (This->refs && This->device)
  39.         NineUnknown_AddRef(NineUnknown(This->device));
  40.  
  41.     This->vtable = pParams->vtable;
  42.     This->guids = pParams->guids;
  43.     This->dtor = pParams->dtor;
  44.  
  45.     return D3D_OK;
  46. }
  47.  
  48. void
  49. NineUnknown_dtor( struct NineUnknown *This )
  50. {
  51.     FREE(This);
  52. }
  53.  
  54. HRESULT WINAPI
  55. NineUnknown_QueryInterface( struct NineUnknown *This,
  56.                             REFIID riid,
  57.                             void **ppvObject )
  58. {
  59.     unsigned i = 0;
  60.  
  61.     DBG("This=%p riid=%p ppvObject=%p\n", This, riid, ppvObject);
  62.  
  63.     if (!ppvObject) return E_POINTER;
  64.  
  65.     do {
  66.         if (GUID_equal(This->guids[i], riid)) {
  67.             *ppvObject = This;
  68.             assert(This->refs);
  69.             NineUnknown_AddRef(This);
  70.             return S_OK;
  71.         }
  72.     } while (This->guids[++i]);
  73.  
  74.     *ppvObject = NULL;
  75.     return E_NOINTERFACE;
  76. }
  77.  
  78. ULONG WINAPI
  79. NineUnknown_AddRef( struct NineUnknown *This )
  80. {
  81.     ULONG r;
  82.     if (This->forward)
  83.         return NineUnknown_AddRef(This->container);
  84.     else
  85.         r = p_atomic_inc_return(&This->refs);
  86.  
  87.     if (r == 1) {
  88.         if (This->device)
  89.             NineUnknown_AddRef(NineUnknown(This->device));
  90.         /* This shouldn't be necessary:
  91.         if (This->container)
  92.             NineUnknown_Bind(NineUnknown(This->container)); */
  93.     }
  94.     return r;
  95. }
  96.  
  97. ULONG WINAPI
  98. NineUnknown_Release( struct NineUnknown *This )
  99. {
  100.     if (This->forward)
  101.         return NineUnknown_Release(This->container);
  102.  
  103.     ULONG r = p_atomic_dec_return(&This->refs);
  104.  
  105.     if (r == 0) {
  106.         if (This->device) {
  107.             if (NineUnknown_Release(NineUnknown(This->device)) == 0)
  108.                 return r; /* everything's gone */
  109.         }
  110.         if (This->container) {
  111.             /* NineUnknown_Unbind(NineUnknown(This->container)); */
  112.         } else
  113.         if (This->bind == 0) {
  114.             This->dtor(This);
  115.         }
  116.     }
  117.     return r;
  118. }
  119.  
  120. HRESULT WINAPI
  121. NineUnknown_GetDevice( struct NineUnknown *This,
  122.                        IDirect3DDevice9 **ppDevice )
  123. {
  124.     user_assert(ppDevice, E_POINTER);
  125.     NineUnknown_AddRef(NineUnknown(This->device));
  126.     *ppDevice = (IDirect3DDevice9 *)This->device;
  127.     return D3D_OK;
  128. }
  129.