text: #include "./api_impl.h"
  #include "./window_info.h"
  
  namespace bitsdojo_window {
  
  void getScreenRect(GtkWindow* window, int* x, int* y, int* width, int* height) {
      auto windowInfo = getWindowInfo(window);
      *x = windowInfo->screenX;
      *y = windowInfo->screenY;
      *width = windowInfo->screenWidth;
      *height = windowInfo->screenHeight;
  }
  
  void getScaleFactor(GtkWindow* window, int* scaleFactor) {
      auto windowInfo = getWindowInfo(window);
      *scaleFactor = windowInfo->scaleFactor;
  }
  
  void getPosition(GtkWindow* window, int* x, int* y) {
      auto windowInfo = getWindowInfo(window);
      *x = windowInfo->x;
      *y = windowInfo->y;
  }
  
  typedef struct SetPositionParams {
      GtkWindow* window;
      int x;
      int y;
  } SetPositionParams;
  
  gboolean setPositionProc(gpointer data) {
      SetPositionParams* params = static_cast<SetPositionParams*>(data);
      GdkWindow* gdw = gtk_widget_get_window(GTK_WIDGET(params->window));
      gdk_window_move(gdw, params->x, params->y);
      free(params);
      return FALSE;
  }
  
  void setPosition(GtkWindow* window, int x, int y) {
      SetPositionParams* params = new SetPositionParams();
      params->window = window;
      params->x = x;
      params->y = y;
  
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, setPositionProc, params, NULL);
  }
  
  void getSize(GtkWindow* window, int* width, int* height) {
      auto windowInfo = getWindowInfo(window);
      *width = windowInfo->width;
      *height = windowInfo->height;
  }
  
  typedef struct SetSizeParams {
      GtkWindow* window;
      int width;
      int height;
  } SetSizeParams;
  
  gboolean setSizeProc(gpointer data) {
      SetSizeParams* params = static_cast<SetSizeParams*>(data);
      GdkWindow* gdw = gtk_widget_get_window(GTK_WIDGET(params->window));
      gdk_window_resize(gdw, params->width, params->height);
      free(params);
      return FALSE;
  }
  
  void setSize(GtkWindow* window, int width, int height) {
      SetSizeParams* params = new SetSizeParams();
      params->window = window;
      params->width = width;
      params->height = height;
  
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, setSizeProc, params, NULL);
  }
  
  typedef struct SetRectParams {
      GtkWindow* window;
      int x;
      int y;
      int width;
      int height;
  } SetRectParams;
  
  gboolean setRectProc(gpointer data) {
      SetRectParams* params = static_cast<SetRectParams*>(data);
      GdkWindow* gdw = gtk_widget_get_window(GTK_WIDGET(params->window));
      gdk_window_move_resize(gdw, params->x, params->y, params->width,
                             params->height);
      free(params);
      return FALSE;
  }
  
  void setRect(GtkWindow* window, int x, int y, int width, int height) {
      SetRectParams* params = new SetRectParams();
      params->window = window;
      params->x = x;
      params->y = y;
      params->width = width;
      params->height = height;
  
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, setRectProc, params, NULL);
  }
  
  void updateGeometry(GtkWindow* window, WindowInfo* windowInfo) {
      gint hints = 0;
      GdkGeometry geometry;
  
      geometry.min_width = windowInfo->minWidth;
      geometry.min_height = windowInfo->minHeight;
      geometry.max_width = windowInfo->maxWidth;
      geometry.max_height = windowInfo->maxHeight;
  
      if ((windowInfo->minWidth != -1) || (windowInfo->minHeight != -1)) {
          hints |= GDK_HINT_MIN_SIZE;
      }
  
      if ((windowInfo->maxWidth != -1) || (windowInfo->maxHeight != -1)) {
          hints |= GDK_HINT_MAX_SIZE;
      }
  
      gtk_window_set_geometry_hints(window, nullptr, &geometry,
                                    static_cast<GdkWindowHints>(hints));
  }
  
  void setMinSize(GtkWindow* window, int width, int height) {
      auto windowInfo = getWindowInfo(window);
      windowInfo->minWidth = width;
      windowInfo->minHeight = height;
  
      updateGeometry(window, windowInfo);
  }
  
  void setMaxSize(GtkWindow* window, int width, int height) {
      auto windowInfo = getWindowInfo(window);
      windowInfo->maxWidth = width;
      windowInfo->maxHeight = height;
  
      updateGeometry(window, windowInfo);
  }
  
  static gboolean showWindowProc(gpointer data) {
      GtkWindow* window = reinterpret_cast<GtkWindow*>(data);
      gtk_widget_show_all(GTK_WIDGET(window));
      return FALSE;
  }
  
  void showWindow(GtkWindow* window) {
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, showWindowProc, window, NULL);
  }
  
  static gboolean hideWindowProc(gpointer data) {
      GtkWindow* window = reinterpret_cast<GtkWindow*>(data);
      gtk_widget_hide(GTK_WIDGET(window));
      return FALSE;
  }
  
  void hideWindow(GtkWindow* window) {
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, hideWindowProc, window, NULL);
  }
  
  static gboolean minimizeWindowProc(gpointer data) {
      GtkWindow* window = reinterpret_cast<GtkWindow*>(data);
      gtk_window_iconify(window);
      return FALSE;
  }
  
  void minimizeWindow(GtkWindow* window) {
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, minimizeWindowProc, window, NULL);
  }
  
  static gboolean maximizeWindowProc(gpointer data) {
      GtkWindow* window = reinterpret_cast<GtkWindow*>(data);
      gtk_window_maximize(window);
      return FALSE;
  }
  
  void maximizeWindow(GtkWindow* window) {
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, maximizeWindowProc, window, NULL);
  }
  
  static gboolean unmaximizeWindowProc(gpointer data) {
      GtkWindow* window = reinterpret_cast<GtkWindow*>(data);
      gtk_window_unmaximize(window);
      return FALSE;
  }
  
  void unmaximizeWindow(GtkWindow* window) {
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, unmaximizeWindowProc, window, NULL);
  }
  
  typedef struct SetWindowTitleParams {
      GtkWindow* window;
      const gchar* title;
  } SetWindowTitleParams;
  
  gboolean setWindowTitleProc(gpointer data) {
      SetWindowTitleParams* params = static_cast<SetWindowTitleParams*>(data);
      gtk_window_set_title(params->window, params->title);
      free((void*)params->title);
      free(params);
      return FALSE;
  }
  
  void setWindowTitle(GtkWindow* window, const gchar* title) {
      SetWindowTitleParams* params = new SetWindowTitleParams();
      params->window = window;
      params->title = title;
      g_idle_add_full(G_PRIORITY_HIGH_IDLE, setWindowTitleProc, params, NULL);
  }
  
  }  // namespace bitsdojo_window
  