/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_GFX_BORROWED_CONTEXT_H
#define MOZILLA_GFX_BORROWED_CONTEXT_H

#include "2D.h"

#ifdef MOZ_X11
#  include <X11/Xlib.h>
#  include "X11UndefineNone.h"
#endif

namespace mozilla {

namespace gfx {

#ifdef XP_DARWIN
/* This is a helper class that let's you borrow a CGContextRef from a
 * DrawTargetCG. This is used for drawing themed widgets.
 *
 * Callers should check the cg member after constructing the object
 * to see if it succeeded. The DrawTarget should not be used while
 * the context is borrowed. */
class BorrowedCGContext {
 public:
  BorrowedCGContext() : cg(nullptr), mDT(nullptr) {}

  explicit BorrowedCGContext(DrawTarget* aDT) : mDT(aDT) {
    MOZ_ASSERT(aDT, "Caller should check for nullptr");
    cg = BorrowCGContextFromDrawTarget(aDT);
  }

  // We can optionally Init after construction in
  // case we don't know what the DT will be at construction
  // time.
  CGContextRef Init(DrawTarget* aDT) {
    MOZ_ASSERT(aDT, "Caller should check for nullptr");
    MOZ_ASSERT(!mDT, "Can't initialize twice!");
    mDT = aDT;
    cg = BorrowCGContextFromDrawTarget(aDT);
    return cg;
  }

  // The caller needs to call Finish if cg is non-null when
  // they are done with the context. This is currently explicit
  // instead of happening implicitly in the destructor to make
  // what's happening in the caller more clear. It also
  // let's you resume using the DrawTarget in the same scope.
  void Finish() {
    if (cg) {
      ReturnCGContextToDrawTarget(mDT, cg);
      cg = nullptr;
    }
  }

  ~BorrowedCGContext() { MOZ_ASSERT(!cg); }

  CGContextRef cg;

 private:
  static CGContextRef BorrowCGContextFromDrawTarget(DrawTarget* aDT);
  static void ReturnCGContextToDrawTarget(DrawTarget* aDT, CGContextRef cg);
  DrawTarget* mDT;
};
#endif

}  // namespace gfx
}  // namespace mozilla

#endif  // MOZILLA_GFX_BORROWED_CONTEXT_H
