]> code.delx.au - gnu-emacs/blobdiff - src/xdisp.c
merge from upstream
[gnu-emacs] / src / xdisp.c
index 2ec271cdb6b8cbb23a0e38c494dcf864e8ac60d3..c363a3e7a6200a52a847e1b9081a0e486cc2a3eb 100644 (file)
@@ -282,6 +282,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "font.h"
 
+#include "xwidget.h"
+
 #ifndef FRAME_X_OUTPUT
 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
 #endif
@@ -1035,6 +1037,7 @@ static int next_element_from_c_string (struct it *);
 static int next_element_from_buffer (struct it *);
 static int next_element_from_composition (struct it *);
 static int next_element_from_image (struct it *);
+static int next_element_from_xwidget(struct it *);
 static int next_element_from_stretch (struct it *);
 static void load_overlay_strings (struct it *, int);
 static int init_from_display_pos (struct it *, struct window *,
@@ -3979,6 +3982,7 @@ handle_display_prop (struct it *it)
   if (CONSP (prop)
       /* Simple properties.  */
       && !EQ (XCAR (prop), Qimage)
+      && !EQ (XCAR (prop), Qxwidget)
       && !EQ (XCAR (prop), Qspace)
       && !EQ (XCAR (prop), Qwhen)
       && !EQ (XCAR (prop), Qslice)
@@ -4076,6 +4080,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
   Lisp_Object location, value;
   struct text_pos start_pos, save_pos;
   int valid_p;
+  printf("handle_single_display_spec:\n");
 
   /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
      If the result is non-nil, use VALUE instead of SPEC.  */
@@ -4360,11 +4365,21 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
      LOCATION specifies where to display: `left-margin',
      `right-margin' or nil.  */
 
+
+  printf("handle_single_display_spec xwidgetp:%d  imagep:%d spacep:%d display_replaced_before_p:%d stringp:%d\n",
+         XWIDGETP(value),
+         valid_image_p (value),
+         (CONSP (value) && EQ (XCAR (value), Qspace)),
+         display_replaced_before_p,
+         STRINGP (value));
+  
   valid_p = (STRINGP (value)
 #ifdef HAVE_WINDOW_SYSTEM
              || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
 #endif /* not HAVE_WINDOW_SYSTEM */
-             || (CONSP (value) && EQ (XCAR (value), Qspace)));
+             || (CONSP (value) && EQ (XCAR (value), Qspace))
+             || XWIDGETP(value)
+             );
 
   if (valid_p && !display_replaced_before_p)
     {
@@ -4405,8 +4420,20 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
          it->object = value;
          *position = it->position = start_pos;
        }
+      else if (XWIDGETP(value))
+       {
+          printf("handle_single_display_spec: im an xwidget!!\n");
+          it->what = IT_XWIDGET;
+          it->method = GET_FROM_XWIDGET;
+          it->position = start_pos;
+         it->object = NILP (object) ? it->w->buffer : object;
+         *position = start_pos;
+
+          it->xwidget_id=lookup_xwidget(value);
+          assert_valid_xwidget_id(it->xwidget_id,"handle_single_display_spec");
+       }      
 #ifdef HAVE_WINDOW_SYSTEM
-      else
+      else //if nothing else, its an image
        {
          it->what = IT_IMAGE;
          it->image_id = lookup_image (it->f, value);
@@ -4469,7 +4496,8 @@ single_display_spec_intangible_p (Lisp_Object prop)
 
   return (CONSP (prop)
          && (EQ (XCAR (prop), Qimage)
-             || EQ (XCAR (prop), Qspace)));
+             || EQ (XCAR (prop), Qspace)
+              || XWIDGETP(prop)));
 }
 
 
@@ -5119,6 +5147,10 @@ push_it (struct it *it)
     case GET_FROM_STRETCH:
       p->u.stretch.object = it->object;
       break;
+    case GET_FROM_XWIDGET:
+      p->u.xwidget.object = it->object;
+      break;
+      
     }
   p->position = it->position;
   p->current = it->current;
@@ -5196,6 +5228,9 @@ pop_it (struct it *it)
       it->object = p->u.image.object;
       it->slice = p->u.image.slice;
       break;
+    case GET_FROM_XWIDGET:
+      it->object = p->u.xwidget.object;
+      break;
     case GET_FROM_STRETCH:
       it->object = p->u.comp.object;
       break;
@@ -5700,7 +5735,8 @@ static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
   next_element_from_string,
   next_element_from_c_string,
   next_element_from_image,
-  next_element_from_stretch
+  next_element_from_stretch,
+  next_element_from_xwidget
 };
 
 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
@@ -6328,6 +6364,7 @@ set_iterator_to_next (struct it *it, int reseat_p)
 
     case GET_FROM_IMAGE:
     case GET_FROM_STRETCH:
+    case GET_FROM_XWIDGET:
       /* The position etc with which we have to proceed are on
         the stack.  The position may be at the end of a string,
          if the `display' property takes up the whole string.  */
@@ -6586,6 +6623,19 @@ next_element_from_image (struct it *it)
   return 1;
 }
 
+/* im not sure about this FIXME JAVE*/
+static int
+next_element_from_xwidget (it)
+     struct it *it;
+{
+  it->what = IT_XWIDGET;
+  assert_valid_xwidget_id(it->xwidget_id,"next_element_from_xwidget");
+  //this is shaky because why do we set "what" if we dont set the other parts??
+  printf("xwidget_id %d: in next_element_from_xwidget: FIXME \n", it->xwidget_id);
+  return 1;
+}
+
+
 
 /* Fill iterator IT with next display element from a stretch glyph
    property.  IT->object is the value of the text property.  Value is
@@ -11508,6 +11558,9 @@ redisplay_internal (int preserve_echo_area)
      frames.  Zero means, only selected_window is considered.  */
   int consider_all_windows_p;
 
+  printf(">>>>redisplay\n");
+  //  xwidget_start_redisplay();
+  
   TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
 
   /* No redisplay if running in batch mode or frame is not yet fully
@@ -12209,6 +12262,9 @@ redisplay_internal (int preserve_echo_area)
  end_of_redisplay:
   unbind_to (count, Qnil);
   RESUME_POLLING;
+  //xwidget_end_redisplay();
+    
+  printf("<<<<redisplay\n");
 }
 
 
@@ -16216,6 +16272,27 @@ dump_glyph (row, glyph, area)
               glyph->left_box_line_p,
               glyph->right_box_line_p);
     }
+  else if (glyph->type == XWIDGET_GLYPH)
+    {
+      fprintf (stderr,
+              "  %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
+              glyph - row->glyphs[TEXT_AREA],
+              'X',
+              glyph->charpos,
+              (BUFFERP (glyph->object)
+               ? 'B'
+               : (STRINGP (glyph->object)
+                  ? 'S'
+                  : '-')),
+              glyph->pixel_width,
+              glyph->u.xwidget_id,
+              '.',
+              glyph->face_id,
+              glyph->left_box_line_p,
+              glyph->right_box_line_p);
+      
+      //      printf("dump xwidget glyph\n");
+    }
 }
 
 
@@ -20244,6 +20321,13 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
 
              return OK_PIXELS (width_p ? img->width : img->height);
            }
+
+         if (FRAME_WINDOW_P (it->f)
+             && valid_xwidget_p (prop))
+           {
+              printf("calc_pixel_width_or_height: return dummy size FIXME\n");
+              return OK_PIXELS (width_p ? 100 : 100);
+            }
 #endif
          if (EQ (car, Qplus) || EQ (car, Qminus))
            {
@@ -20704,6 +20788,20 @@ fill_image_glyph_string (struct glyph_string *s)
   s->ybase += s->first_glyph->voffset;
 }
 
+static void
+fill_xwidget_glyph_string (s)
+     struct glyph_string *s;
+{
+  xassert (s->first_glyph->type == XWIDGET_GLYPH);
+  printf("fill_xwidget_glyph_string: width:%d \n",s->first_glyph->pixel_width);
+  s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
+  s->font = s->face->font;
+  s->width = s->first_glyph->pixel_width;
+  s->ybase += s->first_glyph->voffset;
+  s->xwidget_id=s->first_glyph->u.xwidget_id;
+  assert_valid_xwidget_id(s->xwidget_id,"fill_xwidget_glyph_string");
+}
+
 
 /* Fill glyph string S from a sequence of stretch glyphs.
 
@@ -21038,6 +21136,20 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
        }                                                               \
      while (0)
 
+#define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
+     do                                                                        \
+       { \
+         printf("BUILD_XWIDGET_GLYPH_STRING\n");                                                      \
+        s = (struct glyph_string *) alloca (sizeof *s);                \
+        INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL);          \
+        fill_xwidget_glyph_string (s);                                 \
+        append_glyph_string (&HEAD, &TAIL, s);                         \
+        ++START;                                                       \
+         s->x = (X);                                                   \
+       }                                                               \
+     while (0)
+
+
 
 /* Add a glyph string for a sequence of character glyphs to the list
    of strings between HEAD and TAIL.  START is the index of the first
@@ -21171,6 +21283,10 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
              BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL,         \
                                        HL, X, LAST_X);                 \
              break;                                                    \
+            case XWIDGET_GLYPH:                                         \
+              BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL,       \
+                                          HL, X, LAST_X);               \
+              break;                                                    \
                                                                        \
            default:                                                    \
              abort ();                                                 \
@@ -21776,6 +21892,112 @@ produce_image_glyph (struct it *it)
     }
 }
 
+static void
+produce_xwidget_glyph (it)
+     struct it *it;
+{
+  //  struct image *img;
+  struct face *face;
+  int glyph_ascent, crop;
+  //  struct glyph_slice slice;
+
+  printf("produce_xwidget_glyph:\n");
+  xassert (it->what == IT_XWIDGET);
+
+  face = FACE_FROM_ID (it->f, it->face_id);
+  xassert (face);
+  /* Make sure X resources of the face is loaded.  */
+  PREPARE_FACE_FOR_DISPLAY (it->f, face);
+
+  /////////////////////////////////////////////
+  
+  //  img = IMAGE_FROM_ID (it->f, it->image_id);
+  //xassert (img);
+  /* Make sure X resources of the image is loaded.  */
+  //prepare_image_for_display (it->f, img);
+
+  struct xwidget* xw=xwidget_from_id(it->xwidget_id);
+  //xwidget_touch(xw);
+  
+  it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;//image_ascent (img, face, &slice);
+  it->descent = xw->height/2;//slice.height - glyph_ascent;
+
+  //it->descent += img->vmargin;
+  //it->descent += img->vmargin;
+  it->phys_descent = it->descent;
+
+  it->pixel_width = xw->width;
+
+  //it->pixel_width += img->hmargin;
+  //it->pixel_width += img->hmargin;
+
+  /////////////////////////////////////////
+  
+  /* It's quite possible for images to have an ascent greater than
+     their height, so don't get confused in that case.  */
+  if (it->descent < 0)
+    it->descent = 0;
+
+  it->nglyphs = 1;
+
+  if (face->box != FACE_NO_BOX)
+    {
+      if (face->box_line_width > 0)
+       {
+           it->ascent += face->box_line_width;
+           it->descent += face->box_line_width;
+       }
+
+      if (it->start_of_box_run_p)
+       it->pixel_width += eabs (face->box_line_width);
+      it->pixel_width += eabs (face->box_line_width);
+    }
+
+  take_vertical_position_into_account (it);
+
+  /* Automatically crop wide image glyphs at right edge so we can
+     draw the cursor on same display row.  */
+  if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
+      && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
+    {
+      it->pixel_width -= crop;
+    }
+
+  if (it->glyph_row)
+    {
+      struct glyph *glyph;
+      enum glyph_row_area area = it->area;
+
+      glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
+      if (glyph < it->glyph_row->glyphs[area + 1])
+       {
+         glyph->charpos = CHARPOS (it->position);
+         glyph->object = it->object;
+         glyph->pixel_width = it->pixel_width;
+         glyph->ascent = glyph_ascent;
+         glyph->descent = it->descent;
+         glyph->voffset = it->voffset;
+          //     glyph->type = IMAGE_GLYPH;
+         glyph->type = XWIDGET_GLYPH;          
+          
+         glyph->multibyte_p = it->multibyte_p;
+         glyph->left_box_line_p = it->start_of_box_run_p;
+         glyph->right_box_line_p = it->end_of_box_run_p;
+         glyph->overlaps_vertically_p = 0;
+          glyph->padding_p = 0;
+         glyph->glyph_not_available_p = 0;
+         glyph->face_id = it->face_id;
+          glyph->u.xwidget_id = it->xwidget_id;
+          assert_valid_xwidget_id(glyph->u.xwidget_id,"produce_xwidget_glyph");
+          //     glyph->slice = slice;
+         glyph->font_type = FONT_TYPE_UNKNOWN;
+         ++it->glyph_row->used[area];
+       }
+      else
+       IT_EXPAND_MATRIX_WIDTH (it, area);
+    }
+}
+
 
 /* Append a stretch glyph to IT->glyph_row.  OBJECT is the source
    of the glyph, WIDTH and HEIGHT are the width and height of the
@@ -22728,6 +22950,8 @@ x_produce_glyphs (struct it *it)
     produce_image_glyph (it);
   else if (it->what == IT_STRETCH)
     produce_stretch_glyph (it);
+  else if (it->what == IT_XWIDGET)
+    produce_xwidget_glyph (it);
 
   /* Accumulate dimensions.  Note: can't assume that it->descent > 0
      because this isn't true for images with `:ascent 100'.  */