// GENERATED — DO NOT EDIT

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/class.Surface.html).
pub type Surface

///|
pub(open) trait ISurface {
  fn as_surface(Self) -> Surface
  fn beep(Self) -> Unit = _
  fn create_gl_context(Self) -> GLContext raise @glib.Error_ = _
  fn destroy(Self) -> Unit = _
  fn get_cursor(Self) -> Cursor? = _
  fn get_device_cursor(Self, &IDevice) -> Cursor? = _
  fn get_device_position(Self, &IDevice) -> (Bool, Double, Double, ModifierType) = _
  fn get_display(Self) -> Display = _
  fn get_frame_clock(Self) -> FrameClock = _
  fn get_height(Self) -> Int = _
  fn get_mapped(Self) -> Bool = _
  fn get_scale(Self) -> Double = _
  fn get_scale_factor(Self) -> Int = _
  fn get_width(Self) -> Int = _
  fn hide(Self) -> Unit = _
  fn is_destroyed(Self) -> Bool = _
  fn queue_render(Self) -> Unit = _
  fn request_layout(Self) -> Unit = _
  fn set_cursor(Self, &ICursor?) -> Unit = _
  fn set_device_cursor(Self, &IDevice, &ICursor) -> Unit = _
  fn translate_coordinates(Self, &ISurface, Double, Double) -> (
    Bool,
    Double,
    Double,
  ) = _
  fn connect_enter_monitor(Self, (Surface, Monitor) -> Unit) -> UInt64 = _
  fn connect_layout(Self, (Surface, Int, Int) -> Unit) -> UInt64 = _
  fn connect_leave_monitor(Self, (Surface, Monitor) -> Unit) -> UInt64 = _
}

///|
pub impl ISurface for Surface with fn as_surface(self) {
  self
}

///|
#borrow(parent)
extern "c" fn moonbit_gdk_surface_new_popup(
  parent : Surface,
  autohide : Bool,
) -> Surface = "moonbit_gdk_surface_new_popup"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/ctor.Surface.new_popup.html).
pub fn Surface::new_popup(parent : &ISurface, autohide : Bool) -> Surface {
  moonbit_gdk_surface_new_popup(parent.as_surface(), autohide)
}

///|
#borrow(display)
extern "c" fn moonbit_gdk_surface_new_toplevel(display : Display) -> Surface = "moonbit_gdk_surface_new_toplevel"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/ctor.Surface.new_toplevel.html).
pub fn Surface::new_toplevel(display : &IDisplay) -> Surface {
  moonbit_gdk_surface_new_toplevel(display.as_display())
}

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.beep.html).
#borrow(self)
pub extern "c" fn Surface::beep(self : Surface) = "moonbit_gdk_surface_beep"

///|
#borrow(self_, error)
extern "c" fn moonbit_gdk_surface_create_gl_context(
  self_ : Surface,
  error : Ref[@glib.Nullable[@glib.Error_]],
) -> GLContext = "moonbit_gdk_surface_create_gl_context"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.create_gl_context.html).
pub fn Surface::create_gl_context(
  self : Surface,
) -> GLContext raise @glib.Error_ {
  let error_ : Ref[@glib.Nullable[@glib.Error_]] = Ref(@glib.Nullable::null())
  let result = moonbit_gdk_surface_create_gl_context(self, error_)
  match error_.val.to_option() {
    Some(e) => raise e
    None => ()
  }
  result
}

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.destroy.html).
#borrow(self)
pub extern "c" fn Surface::destroy(self : Surface) = "moonbit_gdk_surface_destroy"

///|
#borrow(self_)
extern "c" fn moonbit_gdk_surface_get_cursor(
  self_ : Surface,
) -> @glib.Nullable[Cursor] = "moonbit_gdk_surface_get_cursor"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_cursor.html).
pub fn Surface::get_cursor(self : Surface) -> Cursor? {
  let raw_result = moonbit_gdk_surface_get_cursor(self)
  raw_result.to_option()
}

///|
#borrow(self_, device)
extern "c" fn moonbit_gdk_surface_get_device_cursor(
  self_ : Surface,
  device : Device,
) -> @glib.Nullable[Cursor] = "moonbit_gdk_surface_get_device_cursor"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_device_cursor.html).
pub fn Surface::get_device_cursor(self : Surface, device : &IDevice) -> Cursor? {
  let raw_result = moonbit_gdk_surface_get_device_cursor(
    self,
    device.as_device(),
  )
  raw_result.to_option()
}

///|
#borrow(self_, device, x, y, mask)
extern "c" fn moonbit_gdk_surface_get_device_position(
  self_ : Surface,
  device : Device,
  x : Ref[Double],
  y : Ref[Double],
  mask : Ref[Int],
) -> Bool = "moonbit_gdk_surface_get_device_position"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_device_position.html).
pub fn Surface::get_device_position(
  self : Surface,
  device : &IDevice,
) -> (Bool, Double, Double, ModifierType) {
  let x = Ref(0.0)
  let y = Ref(0.0)
  let mask = Ref(0)
  let result = moonbit_gdk_surface_get_device_position(
    self,
    device.as_device(),
    x,
    y,
    mask,
  )
  (result, x.val, y.val, ModifierType::from_int(mask.val))
}

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_display.html).
#borrow(self)
pub extern "c" fn Surface::get_display(self : Surface) -> Display = "moonbit_gdk_surface_get_display"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_frame_clock.html).
#borrow(self)
pub extern "c" fn Surface::get_frame_clock(self : Surface) -> FrameClock = "moonbit_gdk_surface_get_frame_clock"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_height.html).
#borrow(self)
pub extern "c" fn Surface::get_height(self : Surface) -> Int = "moonbit_gdk_surface_get_height"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_mapped.html).
#borrow(self)
pub extern "c" fn Surface::get_mapped(self : Surface) -> Bool = "moonbit_gdk_surface_get_mapped"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_scale.html).
#borrow(self)
pub extern "c" fn Surface::get_scale(self : Surface) -> Double = "moonbit_gdk_surface_get_scale"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_scale_factor.html).
#borrow(self)
pub extern "c" fn Surface::get_scale_factor(self : Surface) -> Int = "moonbit_gdk_surface_get_scale_factor"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.get_width.html).
#borrow(self)
pub extern "c" fn Surface::get_width(self : Surface) -> Int = "moonbit_gdk_surface_get_width"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.hide.html).
#borrow(self)
pub extern "c" fn Surface::hide(self : Surface) = "moonbit_gdk_surface_hide"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.is_destroyed.html).
#borrow(self)
pub extern "c" fn Surface::is_destroyed(self : Surface) -> Bool = "moonbit_gdk_surface_is_destroyed"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.queue_render.html).
#borrow(self)
pub extern "c" fn Surface::queue_render(self : Surface) = "moonbit_gdk_surface_queue_render"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.request_layout.html).
#borrow(self)
pub extern "c" fn Surface::request_layout(self : Surface) = "moonbit_gdk_surface_request_layout"

///|
#borrow(self_, cursor)
extern "c" fn moonbit_gdk_surface_set_cursor(
  self_ : Surface,
  cursor : @glib.Nullable[Cursor],
) = "moonbit_gdk_surface_set_cursor"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.set_cursor.html).
pub fn Surface::set_cursor(self : Surface, cursor : &ICursor?) -> Unit {
  moonbit_gdk_surface_set_cursor(
    self,
    match cursor {
      Some(v) => @glib.Nullable::some(v.as_cursor())
      None => @glib.Nullable::null()
    },
  )
}

///|
#borrow(self_, device, cursor)
extern "c" fn moonbit_gdk_surface_set_device_cursor(
  self_ : Surface,
  device : Device,
  cursor : Cursor,
) = "moonbit_gdk_surface_set_device_cursor"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.set_device_cursor.html).
pub fn Surface::set_device_cursor(
  self : Surface,
  device : &IDevice,
  cursor : &ICursor,
) -> Unit {
  moonbit_gdk_surface_set_device_cursor(
    self,
    device.as_device(),
    cursor.as_cursor(),
  )
}

///|
#borrow(self_, to, x_ref, y_ref)
extern "c" fn moonbit_gdk_surface_translate_coordinates(
  self_ : Surface,
  to : Surface,
  x_ref : Ref[Double],
  y_ref : Ref[Double],
) -> Bool = "moonbit_gdk_surface_translate_coordinates"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/method.Surface.translate_coordinates.html).
pub fn Surface::translate_coordinates(
  self : Surface,
  to : &ISurface,
  x : Double,
  y : Double,
) -> (Bool, Double, Double) {
  let x_ref = Ref(x)
  let y_ref = Ref(y)
  let result = moonbit_gdk_surface_translate_coordinates(
    self,
    to.as_surface(),
    x_ref,
    y_ref,
  )
  (result, x_ref.val, y_ref.val)
}

///|
#borrow(instance)
extern "c" fn gdk_surface_connect_enter_monitor(
  instance : Surface,
  function : FuncRef[(Surface, Monitor, (Surface, Monitor) -> Unit) -> Unit],
  closure : (Surface, Monitor) -> Unit,
) -> UInt64 = "moonbit_gdk_surface_connect_enter_monitor"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/signal.Surface.enter-monitor.html).
pub fn Surface::connect_enter_monitor(
  self : Surface,
  f : (Surface, Monitor) -> Unit,
) -> UInt64 {
  gdk_surface_connect_enter_monitor(
    self,
    fn(instance_, monitor, f) { f(instance_, monitor) },
    f,
  )
}

///|
#borrow(instance)
extern "c" fn gdk_surface_connect_layout(
  instance : Surface,
  function : FuncRef[(Surface, Int, Int, (Surface, Int, Int) -> Unit) -> Unit],
  closure : (Surface, Int, Int) -> Unit,
) -> UInt64 = "moonbit_gdk_surface_connect_layout"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/signal.Surface.layout.html).
pub fn Surface::connect_layout(
  self : Surface,
  f : (Surface, Int, Int) -> Unit,
) -> UInt64 {
  gdk_surface_connect_layout(
    self,
    fn(instance_, width, height, f) { f(instance_, width, height) },
    f,
  )
}

///|
#borrow(instance)
extern "c" fn gdk_surface_connect_leave_monitor(
  instance : Surface,
  function : FuncRef[(Surface, Monitor, (Surface, Monitor) -> Unit) -> Unit],
  closure : (Surface, Monitor) -> Unit,
) -> UInt64 = "moonbit_gdk_surface_connect_leave_monitor"

///|
/// [Upstream documentation](https://docs.gtk.org/gdk4/signal.Surface.leave-monitor.html).
pub fn Surface::connect_leave_monitor(
  self : Surface,
  f : (Surface, Monitor) -> Unit,
) -> UInt64 {
  gdk_surface_connect_leave_monitor(
    self,
    fn(instance_, monitor, f) { f(instance_, monitor) },
    f,
  )
}

///|
impl ISurface with fn beep(self) -> Unit {
  self.as_surface().beep()
}

///|
impl ISurface with fn create_gl_context(self) -> GLContext raise @glib.Error_ {
  self.as_surface().create_gl_context()
}

///|
impl ISurface with fn destroy(self) -> Unit {
  self.as_surface().destroy()
}

///|
impl ISurface with fn get_cursor(self) -> Cursor? {
  self.as_surface().get_cursor()
}

///|
impl ISurface with fn get_device_cursor(self, device) -> Cursor? {
  self.as_surface().get_device_cursor(device)
}

///|
impl ISurface with fn get_device_position(self, device) -> (
  Bool,
  Double,
  Double,
  ModifierType,
) {
  self.as_surface().get_device_position(device)
}

///|
impl ISurface with fn get_display(self) -> Display {
  self.as_surface().get_display()
}

///|
impl ISurface with fn get_frame_clock(self) -> FrameClock {
  self.as_surface().get_frame_clock()
}

///|
impl ISurface with fn get_height(self) -> Int {
  self.as_surface().get_height()
}

///|
impl ISurface with fn get_mapped(self) -> Bool {
  self.as_surface().get_mapped()
}

///|
impl ISurface with fn get_scale(self) -> Double {
  self.as_surface().get_scale()
}

///|
impl ISurface with fn get_scale_factor(self) -> Int {
  self.as_surface().get_scale_factor()
}

///|
impl ISurface with fn get_width(self) -> Int {
  self.as_surface().get_width()
}

///|
impl ISurface with fn hide(self) -> Unit {
  self.as_surface().hide()
}

///|
impl ISurface with fn is_destroyed(self) -> Bool {
  self.as_surface().is_destroyed()
}

///|
impl ISurface with fn queue_render(self) -> Unit {
  self.as_surface().queue_render()
}

///|
impl ISurface with fn request_layout(self) -> Unit {
  self.as_surface().request_layout()
}

///|
impl ISurface with fn set_cursor(self, cursor) -> Unit {
  self.as_surface().set_cursor(cursor)
}

///|
impl ISurface with fn set_device_cursor(self, device, cursor) -> Unit {
  self.as_surface().set_device_cursor(device, cursor)
}

///|
impl ISurface with fn translate_coordinates(self, to, x, y) -> (
  Bool,
  Double,
  Double,
) {
  self.as_surface().translate_coordinates(to, x, y)
}

///|
impl ISurface with fn connect_enter_monitor(self, f) -> UInt64 {
  self.as_surface().connect_enter_monitor(f)
}

///|
impl ISurface with fn connect_layout(self, f) -> UInt64 {
  self.as_surface().connect_layout(f)
}

///|
impl ISurface with fn connect_leave_monitor(self, f) -> UInt64 {
  self.as_surface().connect_leave_monitor(f)
}

///|
pub fn Surface::as_gobject_object(self : Surface) -> @gobject.Object = "%identity"

///|
pub impl @gobject.IObject for Surface with fn as_object(self) {
  self.as_gobject_object()
}