]> code.delx.au - gnu-emacs/blobdiff - src/nsterm.m
Avoid crashing due to closing of font whose driver pointer is NULL.
[gnu-emacs] / src / nsterm.m
index d995bfa835ba58972d3f8bbf701429831b598335..733c05ae53a7cf5cdb5c1c156de9a3adc8d1c467 100644 (file)
@@ -771,7 +771,12 @@ ns_update_window_end (struct window *w, bool cursor_on_p,
                                w->output_cursor.x, w->output_cursor.y);
 
       if (draw_window_fringes (w, 1))
-       x_draw_vertical_border (w);
+       {
+         if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+           x_draw_right_divider (w);
+         else
+           x_draw_vertical_border (w);
+       }
 
       unblock_input ();
     }
@@ -1150,9 +1155,7 @@ x_free_frame_resources (struct frame *f)
   block_input ();
 
   free_frame_menubar (f);
-
-  if (FRAME_FACE_CACHE (f))
-    free_frame_faces (f);
+  free_frame_faces (f);
 
   if (f == dpyinfo->x_focus_frame)
     dpyinfo->x_focus_frame = 0;
@@ -1235,7 +1238,11 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
 
 
 void
-x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
+x_set_window_size (struct frame *f,
+                   int change_grav,
+                   int width,
+                   int height,
+                   bool pixelwise)
 /* --------------------------------------------------------------------------
      Adjust window pixel size based on given character grid size
      Impl is a bit more complex than other terms, need to do some
@@ -1247,23 +1254,36 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
   NSRect wr = [window frame];
   int tb = FRAME_EXTERNAL_TOOL_BAR (f);
   int pixelwidth, pixelheight;
+  int rows, cols;
 
   NSTRACE (x_set_window_size);
 
   if (view == nil)
     return;
 
-/*fprintf (stderr, "\tsetWindowSize: %d x %d, font size %d x %d\n", cols, rows, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f)); */
+/*fprintf (stderr, "\tsetWindowSize: %d x %d, pixelwise %d, font size %d x %d\n", width, height, pixelwise, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f));*/
 
   block_input ();
 
-  check_frame_size (f, &rows, &cols);
+  check_frame_size (f, &width, &height, pixelwise);
 
   f->scroll_bar_actual_width = NS_SCROLL_BAR_WIDTH (f);
   compute_fringe_widths (f, 0);
 
-  pixelwidth =  FRAME_TEXT_COLS_TO_PIXEL_WIDTH   (f, cols);
-  pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+  if (pixelwise)
+    {
+      pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
+      pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
+      cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth);
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight);
+    }
+  else
+    {
+      pixelwidth =  FRAME_TEXT_COLS_TO_PIXEL_WIDTH   (f, width);
+      pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
+      cols = width;
+      rows = height;
+    }
 
   /* If we have a toolbar, take its height into account. */
   if (tb && ! [view isFullscreen])
@@ -1298,8 +1318,6 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
   [view setRows: rows andColumns: cols];
   [window setFrame: wr display: YES];
 
-/*fprintf (stderr, "\tx_set_window_size %d, %d\t%d, %d\n", cols, rows, pixelwidth, pixelheight); */
-
   /* This is a trick to compensate for Emacs' managing the scrollbar area
      as a fixed number of standard character columns.  Instead of leaving
      blank space for the extra, we chopped it off above.  Now for
@@ -1316,9 +1334,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
     [view setBoundsOrigin: origin];
   }
 
-  change_frame_size (f, rows, cols, 0, 1, 0); /* pretend, delay, safe */
-  FRAME_PIXEL_WIDTH (f) = pixelwidth;
-  FRAME_PIXEL_HEIGHT (f) = pixelheight;
+  change_frame_size (f, width, height, 0, 1, 0, pixelwise);
 /*  SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */
 
   mark_window_cursors_off (XWINDOW (f->root_window));
@@ -1385,7 +1401,7 @@ ns_index_color (NSColor *color, struct frame *f)
       color_table->empty_indices = [[NSMutableSet alloc] init];
     }
 
-  /* do we already have this color ? */
+  /* Do we already have this color?  */
   for (i = 1; i < color_table->avail; i++)
     if (color_table->colors[i] && [color_table->colors[i] isEqual: color])
       return i;
@@ -2504,6 +2520,28 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
 }
 
 
+static void
+ns_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+/* --------------------------------------------------------------------------
+     External (RIF): Draw a window divider.
+   -------------------------------------------------------------------------- */
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct face *face;
+  NSRect r = NSMakeRect (x0, y0, x1-x0, y1-y0);
+
+  NSTRACE (ns_draw_window_divider);
+
+  face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+  if (face)
+      [ns_lookup_indexed_color(face->foreground, f) set];
+
+  ns_focus (f, &r, 1);
+  NSRectFill(r);
+  ns_unfocus (f);
+}
+
+
 void
 show_hourglass (struct atimer *timer)
 {
@@ -4017,6 +4055,7 @@ static struct redisplay_interface ns_redisplay_interface =
   ns_clear_frame_area,
   ns_draw_window_cursor,
   ns_draw_vertical_window_border,
+  ns_draw_window_divider,
   ns_shift_glyphs_for_insert
 };
 
@@ -4367,15 +4406,22 @@ ns_term_shutdown (int sig)
 
 @implementation EmacsApp
 
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
 - (id)init
 {
   if (self = [super init])
-    self->isFirst = YES;
+    {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
+      self->isFirst = YES;
+#endif
+#ifdef NS_IMPL_GNUSTEP
+      self->applicationDidFinishLaunchingCalled = NO;
+#endif
+    }
 
   return self;
 }
 
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
 - (void)run
 {
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -4562,6 +4608,9 @@ ns_term_shutdown (int sig)
    -------------------------------------------------------------------------- */
 {
   NSTRACE (applicationDidFinishLaunching);
+#ifdef NS_IMPL_GNUSTEP
+  ((EmacsApp *)self)->applicationDidFinishLaunchingCalled = YES;
+#endif
   [NSApp setServicesProvider: NSApp];
   ns_send_appdefined (-2);
 }
@@ -4689,6 +4738,10 @@ not_in_argv (NSString *arg)
 {
   NSTRACE (applicationDidBecomeActive);
 
+#ifdef NS_IMPL_GNUSTEP
+  if (! applicationDidFinishLaunchingCalled)
+    [self applicationDidFinishLaunching:notification];
+#endif
   //ns_app_active=YES;
 
   ns_update_auto_hide_menu_bar ();
@@ -5620,44 +5673,44 @@ not_in_argv (NSString *arg)
   NSWindow *window = [self window];
   NSRect wr = [window frame];
   int extra = 0;
-  int gsextra = 0;
-#ifdef NS_IMPL_GNUSTEP
-  gsextra = 3;
-#endif
-
   int oldc = cols, oldr = rows;
   int oldw = FRAME_PIXEL_WIDTH (emacsframe),
     oldh = FRAME_PIXEL_HEIGHT (emacsframe);
   int neww, newh;
 
-  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, wr.size.width + gsextra);
-
-  if (cols < MINWIDTH)
-    cols = MINWIDTH;
-
   if (! [self isFullscreen])
     {
+#ifdef NS_IMPL_GNUSTEP
+      // GNUStep does not always update the tool bar height.  Force it.
+      if (toolbar) update_frame_tool_bar (emacsframe);
+#endif
+
       extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
-        + FRAME_TOOLBAR_HEIGHT (emacsframe) - gsextra;
+        + FRAME_TOOLBAR_HEIGHT (emacsframe);
     }
 
-  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, wr.size.height - extra);
+  neww = (int)wr.size.width - emacsframe->border_width;
+  newh = (int)wr.size.height - extra;
+
+  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, neww);
+  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, newh);
+
+  if (cols < MINWIDTH)
+    cols = MINWIDTH;
 
   if (rows < MINHEIGHT)
     rows = MINHEIGHT;
 
-  neww = (int)wr.size.width - emacsframe->border_width;
-  newh = (int)wr.size.height - extra;
-
   if (oldr != rows || oldc != cols || neww != oldw || newh != oldh)
     {
       NSView *view = FRAME_NS_VIEW (emacsframe);
       NSWindow *win = [view window];
       NSSize sz = [win resizeIncrements];
 
-      FRAME_PIXEL_WIDTH (emacsframe) = neww;
-      FRAME_PIXEL_HEIGHT (emacsframe) = newh;
-      change_frame_size (emacsframe, rows, cols, 0, delay, 0);
+      change_frame_size (emacsframe,
+                         FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww),
+                         FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh),
+                         0, delay, 0, 1);
       SET_FRAME_GARBAGED (emacsframe);
       cancel_mouse_face (emacsframe);
 
@@ -5679,10 +5732,6 @@ not_in_argv (NSString *arg)
 /* normalize frame to gridded text size */
 {
   int extra = 0;
-  int gsextra = 0;
-#ifdef NS_IMPL_GNUSTEP
-  gsextra = 3;
-#endif
 
   NSTRACE (windowWillResize);
 /*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */
@@ -5700,8 +5749,13 @@ not_in_argv (NSString *arg)
   if (fs_state == FULLSCREEN_NONE)
     maximized_width = maximized_height = -1;
 
-  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe,
-                                         frameSize.width + gsextra);
+  if (! [self isFullscreen])
+    {
+      extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
+        + FRAME_TOOLBAR_HEIGHT (emacsframe);
+    }
+
+  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, frameSize.width);
   if (cols < MINWIDTH)
     cols = MINWIDTH;
 
@@ -7297,6 +7351,7 @@ Lisp_Object
 x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 {
   struct font *font = XFONT_OBJECT (font_object);
+  EmacsView *view = FRAME_NS_VIEW (f);
 
   if (fontset < 0)
     fontset = fontset_from_font (font_object);
@@ -7329,8 +7384,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
     }
 
   /* Now make the frame display the given font.  */
-  if (FRAME_NS_WINDOW (f) != 0)
-       x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+  if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen])
+    x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+                       FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1);
 
   return font_object;
 }
@@ -7557,5 +7613,5 @@ baseline level.  The default value is nil.  */);
 #else
   Fprovide (Qgnustep, Qnil);
 #endif
-  
+
 }