XEmacs 21.2.9
[chise/xemacs-chise.git.1] / src / frame-msw.c
index 2b1dee1..5a88a67 100644 (file)
@@ -26,14 +26,17 @@ Boston, MA 02111-1307, USA.  */
    Ultimately based on FSF.
    Substantially rewritten for XEmacs by Ben Wing.
    Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
+   Graphics features added and frame resizing fiddled with by Andy Piper.
  */
 
 #include <config.h>
 #include "lisp.h"
 
 #include "buffer.h"
+#include "elhash.h"
 #include "console-msw.h"
 #include "glyphs-msw.h"
+#include "elhash.h"
 #include "events.h"
 #include "faces.h"
 #include "frame.h"
@@ -125,12 +128,14 @@ mswindows_init_frame_1 (struct frame *f, Lisp_Object props)
   FRAME_MSWINDOWS_DATA(f)->ignore_next_lbutton_up = 0;
   FRAME_MSWINDOWS_DATA(f)->ignore_next_rbutton_up = 0;
   FRAME_MSWINDOWS_DATA(f)->sizing = 0;
-  FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Qnil;
+  FRAME_MSWINDOWS_MENU_HASH_TABLE(f) = Qnil;
 #ifdef HAVE_TOOLBARS
-  FRAME_MSWINDOWS_TOOLBAR_HASHTABLE(f) = Fmake_hashtable (make_int (50), 
-                                                         Qequal);
+  FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE(f) = 
+    make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
 #endif
-
+  /* hashtable of instantiated glyphs on the frame. */
+  FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f) = 
+    make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQUAL);
   /* Will initialize these in WM_SIZE handler. We cannot do it now,
      because we do not know what is CW_USEDEFAULT height and width */
   FRAME_WIDTH (f) = 0;
@@ -176,7 +181,9 @@ mswindows_init_frame_1 (struct frame *f, Lisp_Object props)
   hwnd = CreateWindowEx (exstyle,
                         XEMACS_CLASS,
                         STRINGP(f->name) ? XSTRING_DATA(f->name) :
-                        (STRINGP(name) ? XSTRING_DATA(name) : XEMACS_CLASS),
+                        (STRINGP(name) ? 
+                         (CONST Extbyte*)XSTRING_DATA(name) : 
+                         (CONST Extbyte*)XEMACS_CLASS),
                         style,
                         rect_default.left, rect_default.top,
                         rect_default.width, rect_default.height,
@@ -233,8 +240,8 @@ mswindows_after_init_frame (struct frame *f, int first_on_device,
      frame is created, it will never be displayed, except for 
      hollow border, unless we start pumping messages. Load progress
      messages show in the bottom of the hollow frame, which is ugly.
-     We redipsplay the initial frame here, so modeline and root window
-     backgorund show.
+     We redisplay the initial frame here, so modeline and root window
+     background show.
   */
   if (first_on_console)
     redisplay ();
@@ -243,10 +250,11 @@ mswindows_after_init_frame (struct frame *f, int first_on_device,
 static void
 mswindows_mark_frame (struct frame *f, void (*markobj) (Lisp_Object))
 {
-  ((markobj) (FRAME_MSWINDOWS_MENU_HASHTABLE (f)));
+  markobj (FRAME_MSWINDOWS_MENU_HASH_TABLE (f));
 #ifdef HAVE_TOOLBARS
-  ((markobj) (FRAME_MSWINDOWS_TOOLBAR_HASHTABLE (f)));
+  markobj (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f));
 #endif
+  markobj (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
 }
 
 static void
@@ -321,7 +329,7 @@ mswindows_frame_totally_visible_p (struct frame *f)
   RECT rc_me, rc_other, rc_temp;
   HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
 
-  /* We test against not a whole window rectangle, only agaist its
+  /* We test against not a whole window rectangle, only against its
      client part. So, if non-client are is covered and client area is
      not, we return true. */
   GetClientRect (hwnd, &rc_me);
@@ -392,6 +400,10 @@ mswindows_set_frame_pointer (struct frame *f)
     {
       SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HCURSOR,
                    (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
+      /* we only have to do this because GC doesn't cause a mouse
+         event and doesn't give time to event processing even if it
+         did. */
+      SetCursor (XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
     }
 }
 
@@ -594,7 +606,7 @@ void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
   int pixel_width, pixel_height;
   int size_p = (dest->width >=0 || dest->height >=0);
   int move_p = (dest->top >=0 || dest->left >=0);
-
+  struct device* d = XDEVICE (FRAME_DEVICE (f));
   char_to_real_pixel_size (f, dest->width, dest->height, &pixel_width, &pixel_height);
   
   if (dest->width < 0)
@@ -607,7 +619,7 @@ void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
     dest->left = rect.left;
   if (dest->top < 0)
     dest->top = rect.top;
-
+  
   rect.left = rect.top = 0;
   rect.right = pixel_width;
   rect.bottom = pixel_height;
@@ -617,12 +629,41 @@ void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
                      GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
                      GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
 
+  /* resize and move the window so that it fits on the screen. This is
+  not restrictive since this will happen later anyway in WM_SIZE.  We
+  have to do this after adjusting the rect to account for menubar
+  etc. */
+  pixel_width = rect.right - rect.left;
+  pixel_height = rect.bottom - rect.top;
+  if (pixel_width > DEVICE_MSWINDOWS_HORZRES(d))
+    {
+      pixel_width = DEVICE_MSWINDOWS_HORZRES(d);
+      size_p=1;
+    }
+  if (pixel_height > DEVICE_MSWINDOWS_VERTRES(d))
+    {
+      pixel_height = DEVICE_MSWINDOWS_VERTRES(d);
+      size_p=1;
+    }
+
+  /* adjust position so window is on screen */
+  if (dest->left + pixel_width > DEVICE_MSWINDOWS_HORZRES(d))
+    {
+      dest->left = DEVICE_MSWINDOWS_HORZRES(d) - pixel_width;
+      move_p=1;
+    }
+  if (dest->top + pixel_height > DEVICE_MSWINDOWS_VERTRES(d))
+    {
+      dest->top = DEVICE_MSWINDOWS_VERTRES(d) - pixel_height;
+      move_p=1;
+    }
+
   if (IsIconic (FRAME_MSWINDOWS_HANDLE(f)) 
       || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
 
   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL, 
-               dest->left, dest->top, rect.right - rect.left, rect.bottom - rect.top,
+               dest->left, dest->top, pixel_width, pixel_height,
                SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING
                | (size_p ? 0 : SWP_NOSIZE)
                | (move_p ? 0 : SWP_NOMOVE));