]> Pileus Git - ~andy/gtk/blobdiff - gdk/win32/gdkdisplay-win32.c
List the three theme gtkrc files separately, zip doesn't do anything if
[~andy/gtk] / gdk / win32 / gdkdisplay-win32.c
index 4ecd1bb8ec1aaee50f38378db78cdbb1d0d0b780..16a5127254163bb02bd60c37e084594623de1425 100644 (file)
@@ -26,7 +26,7 @@
 
 #if defined(_MSC_VER) && (WINVER < 0x500) && (WINVER > 0x0400)
 #include <multimon.h>
-#elif (WINVER <= 0x0400)
+#elif defined(_MSC_VER) && (WINVER <= 0x0400)
 #undef HAVE_MONITOR_INFO
 #endif
 
@@ -80,33 +80,20 @@ enum_monitor (HMONITOR hmonitor,
 #define MONITORINFOF_PRIMARY 1
 #endif
 
-  if (monitor_info.dwFlags & MONITORINFOF_PRIMARY)
-    {
-      /* For the primary monitor, use SPI_GETWORKAREA */
-      RECT rect;
-
-      SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0);
-      monitor->x = rect.left;
-      monitor->y = rect.top;
-      monitor->width = rect.right - rect.left;
-      monitor->height = rect.bottom - rect.top;
+  monitor->x = monitor_info.rcMonitor.left;
+  monitor->y = monitor_info.rcMonitor.top;
+  monitor->width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
+  monitor->height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
 
+  if (monitor_info.dwFlags & MONITORINFOF_PRIMARY &&
+      *index != 0)
+    {
       /* Put primary monitor at index 0, just in case somebody needs
        * to know which one is the primary.
        */
-      if (*index != 0)
-       {
-         GdkRectangle temp = *monitor;
-         *monitor = _gdk_monitors[0];
-         _gdk_monitors[0] = temp;
-       }
-    }
-  else
-    {
-      monitor->x = monitor_info.rcMonitor.left;
-      monitor->y = monitor_info.rcMonitor.top;
-      monitor->width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left;
-      monitor->height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top;
+      GdkRectangle temp = *monitor;
+      *monitor = _gdk_monitors[0];
+      _gdk_monitors[0] = temp;
     }
 
   (*index)++;
@@ -115,23 +102,21 @@ enum_monitor (HMONITOR hmonitor,
 }
 #endif /* HAVE_MONITOR_INFO */
 
-GdkDisplay *
-gdk_display_open (const gchar *display_name)
+void
+_gdk_monitor_init (void)
 {
-  HMODULE user32;
-
-  if (_gdk_display != NULL)
-    return NULL; /* single display only */
+#ifdef HAVE_MONITOR_INFO
+  static HMODULE user32 = NULL;
 
-  _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL);
-  _gdk_screen = g_object_new (GDK_TYPE_SCREEN, NULL);
+  if (user32 == NULL)
+    {
+      user32 = GetModuleHandle ("user32.dll");
 
-#ifdef HAVE_MONITOR_INFO
-  user32 = GetModuleHandle ("user32.dll");
-  g_assert (user32 != NULL);
+      g_assert (user32 != NULL);
 
-  p_EnumDisplayMonitors = (t_EnumDisplayMonitors) GetProcAddress (user32, "EnumDisplayMonitors");
-  p_GetMonitorInfoA = (t_GetMonitorInfoA) GetProcAddress (user32, "GetMonitorInfoA");
+      p_EnumDisplayMonitors = (t_EnumDisplayMonitors) GetProcAddress (user32, "EnumDisplayMonitors");
+      p_GetMonitorInfoA = (t_GetMonitorInfoA) GetProcAddress (user32, "GetMonitorInfoA");
+    }
 
   if (p_EnumDisplayMonitors != NULL && p_GetMonitorInfoA != NULL)
     {
@@ -141,10 +126,11 @@ gdk_display_open (const gchar *display_name)
 
       (*p_EnumDisplayMonitors) (NULL, NULL, count_monitor, (LPARAM) &_gdk_num_monitors);
 
-      _gdk_monitors = g_new (GdkRectangle, _gdk_num_monitors);
+      _gdk_monitors = g_renew (GdkRectangle, _gdk_monitors, _gdk_num_monitors);
+
       index = 0;
       (*p_EnumDisplayMonitors) (NULL, NULL, enum_monitor, (LPARAM) &index);
-#if 1
+
       _gdk_offset_x = G_MININT;
       _gdk_offset_y = G_MININT;
 
@@ -167,24 +153,38 @@ gdk_display_open (const gchar *display_name)
                                   _gdk_monitors[i].height,
                                   _gdk_monitors[i].x, _gdk_monitors[i].y));
        }
-#endif
     }
   else
 #endif /* HAVE_MONITOR_INFO */
     {
-      RECT rect;
+      unsigned int width, height;
 
       _gdk_num_monitors = 1;
-      _gdk_monitors = g_new (GdkRectangle, 1);
-      SystemParametersInfo (SPI_GETWORKAREA, 0, &rect, 0);
-      _gdk_monitors[0].x = rect.left;
-      _gdk_monitors[0].y = rect.top;
-      _gdk_monitors[0].width = rect.right - rect.left;
-      _gdk_monitors[0].height = rect.bottom - rect.top;
+      _gdk_monitors = g_renew (GdkRectangle, _gdk_monitors, 1);
+
+      width = GetSystemMetrics (SM_CXSCREEN);
+      height = GetSystemMetrics (SM_CYSCREEN);
+
+      _gdk_monitors[0].x = 0;
+      _gdk_monitors[0].y = 0;
+      _gdk_monitors[0].width = width;
+      _gdk_monitors[0].height = height;
       _gdk_offset_x = 0;
       _gdk_offset_y = 0;
     }
 
+}
+
+GdkDisplay *
+gdk_display_open (const gchar *display_name)
+{
+  if (_gdk_display != NULL)
+    return NULL; /* single display only */
+
+  _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL);
+  _gdk_screen = g_object_new (GDK_TYPE_SCREEN, NULL);
+
+  _gdk_monitor_init ();
   _gdk_visual_init ();
   gdk_screen_set_default_colormap (_gdk_screen,
                                    gdk_screen_get_system_colormap (_gdk_screen));
@@ -234,3 +234,138 @@ gdk_display_get_default_group (GdkDisplay *display)
 
   return NULL;
 }
+
+gboolean 
+gdk_display_supports_selection_notification (GdkDisplay *display)
+{
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+  return TRUE;
+}
+
+static HWND _hwnd_next_viewer = NULL;
+
+/*
+ * maybe this should be integrated with the default message loop - or maybe not ;-)
+ */
+static LRESULT CALLBACK
+_win32_on_clipboard_change (HWND   hwnd,
+                            UINT   message,
+                            WPARAM wparam,
+                            LPARAM lparam)
+{
+  switch (message)
+    {
+    case WM_DESTROY : /* remove us from chain */
+      {
+        ChangeClipboardChain (hwnd, _hwnd_next_viewer);
+        return 0; 
+      }
+    case WM_CHANGECBCHAIN :
+      {
+        HWND hwndRemove = (HWND) wparam; /* handle of window being removed */
+        HWND hwndNext   = (HWND) lparam; /* handle of next window in chain */
+        if (hwndRemove == _hwnd_next_viewer)
+          _hwnd_next_viewer = hwndNext == hwnd ? NULL : hwndNext;
+        return 0;
+      }
+    case WM_DRAWCLIPBOARD :
+      {
+        /* create the appropriate gdk events */
+        HWND hwndOwner = GetClipboardOwner ();
+        UINT nFormat = 0;
+        int n = 0;
+
+        if (OpenClipboard (hwnd))
+          { 
+            for (; 0 != (nFormat = EnumClipboardFormats (nFormat)); )
+              {
+                char sFormat[80];
+                if (GetClipboardFormatName (nFormat, sFormat, 80) > 0)
+                  g_print ("%s ", sFormat);
+                n++; /* do something useful ? */
+              }
+            GDK_NOTE (DND, 
+                      g_print ("WM_DRAWCLIPBOARD :  formats %d owner %#lx\n", n, hwndOwner));
+
+            CloseClipboard ();
+          }
+        /* XXX: generate the apropriate GdkEventOwnerChange ... */
+
+        /* don't break the chain */
+        return PostMessage (_hwnd_next_viewer, message, wparam, lparam);
+      }
+    default :
+      return DefWindowProc (hwnd, message, wparam, lparam);
+    }
+}
+
+/*
+ * Creates a hidden window and adds it to the clipboard chain
+ */
+HWND
+_gdk_win32_register_clipboard_notification (void)
+{
+  WNDCLASS wclass;
+  HWND     hwnd;
+  ATOM     klass;
+
+  memset (&wclass, 0, sizeof(WNDCLASS));
+  wclass.lpszClassName = "GdkClipboardNotification";
+  wclass.lpfnWndProc   = _win32_on_clipboard_change;
+  wclass.hInstance     = _gdk_app_hmodule;
+
+  klass = RegisterClass (&wclass);
+  if (!klass)
+    return NULL;
+
+  hwnd = CreateWindow (MAKEINTRESOURCE(klass),
+                       NULL, WS_POPUP,
+                       0, 0, 0, 0, NULL, NULL,
+                       _gdk_app_hmodule, NULL);
+  if (!hwnd)
+    {
+      UnregisterClass (MAKEINTRESOURCE(klass), _gdk_app_hmodule);
+      return NULL;
+    }
+  _hwnd_next_viewer = SetClipboardViewer (hwnd);
+  return hwnd;
+}
+
+/*
+ * The whole function would only make sense if the gdk/win32 clipboard
+ * model is rewritten to do delayed rendering. Currently this is only
+ * testcode and as noted in
+ * http://mail.gnome.org/archives/gtk-devel-list/2004-May/msg00113.html
+ * probably not worth bothering ;)
+ */
+gboolean 
+gdk_display_request_selection_notification (GdkDisplay *display,
+                                            GdkAtom     selection)
+
+{
+  static HWND hwndViewer = NULL;
+  gboolean ret = FALSE;
+
+  GDK_NOTE (DND, 
+            g_print ("gdk_display_request_selection_notification (..., %s)",
+                     gdk_atom_name (selection)));
+
+  if (GDK_SELECTION_CLIPBOARD == selection)
+    {
+      if (!hwndViewer)
+        {
+          hwndViewer = _gdk_win32_register_clipboard_notification ();
+          GDK_NOTE (DND, g_print (" registered"));
+        }
+      ret = (hwndViewer != NULL);
+    }
+  else if (GDK_SELECTION_PRIMARY == selection)
+    {
+      /* seems to work by default ? */
+      GDK_NOTE (DND, g_print (" by default"));
+      ret = TRUE;
+    }
+  GDK_NOTE (DND, g_print (" -> %s\n", ret ? "TRUE" : "FALSE"));
+  return ret;
+}