Esempio n. 1
0
void progressive_display_add_rect(struct xrdp_screen * self)
{
  int i, j;
  struct list* update_rects = self->update_rects;
  struct update_rect* urect;
  struct update_rect* fu_rect;
  struct update_rect* ur;
  struct xrdp_rect intersection;
  struct update_rect* tmp;
  struct list* l_tmp = list_create();
  l_tmp->auto_free = 1;

  bool no_inter = true;
  while (!fifo_is_empty(self->candidate_update_rects))
  {
    fu_rect = (struct update_rect*) fifo_pop(self->candidate_update_rects);
    if (update_rects->count > 0)
    {
      no_inter = true;
      for (i = update_rects->count - 1; i >= 0; i--)
      {
        urect = (struct update_rect*) list_get_item(update_rects, i);
        if (!rect_equal(&urect->rect, &fu_rect->rect))
        {
          if (rect_intersect(&urect->rect, &fu_rect->rect, &intersection))
          {
            no_inter = false;
            progressive_display_rect_union(fu_rect, urect, l_tmp);
            list_remove_item(update_rects, i);
            for (j = 0; j < l_tmp->count; j++)
            {
              ur = (struct update_rect*) list_get_item(l_tmp, j);
              tmp = (struct update_rect*) g_malloc(sizeof(struct update_rect), 0);
              g_memcpy(tmp, ur, sizeof(struct update_rect));
              fifo_push(self->candidate_update_rects, tmp);
            }
            list_clear(l_tmp);
            break;
          }
        }
        else
        {
          no_inter = false;
          urect->quality = fu_rect->quality;
          urect->quality_already_send = fu_rect->quality_already_send;
          break;
        }
      }
      if (no_inter)
      {
        list_add_progressive_display_rect(update_rects, fu_rect->rect.left, fu_rect->rect.top, fu_rect->rect.right, fu_rect->rect.bottom, fu_rect->quality, fu_rect->quality_already_send);
      }
    }
    else
    {
      list_add_progressive_display_rect(update_rects, fu_rect->rect.left, fu_rect->rect.top, fu_rect->rect.right, fu_rect->rect.bottom, fu_rect->quality, fu_rect->quality_already_send);
    }
  }
  list_delete(l_tmp);
}
static bool rect_fullscreen(struct fb_info *info, struct omap3epfb_update_area *p)
{
	struct omap3epfb_update_area full = {0};
	full.x0 = 0;
	full.y0 = 0;
	full.x1 = info->var.xres-1;
	full.y1 = info->var.yres-1;
	full.wvfid = OMAP3EPFB_WVFID_GC;
	full.threshold = 0;

	return rect_equal(&full, p);
}
// Find the area(s) that fit into the update.
// If any, then draw the update and then draw the areas that fit into it on top.
// This functio is trying to recover from the case where Android merge multiple updates into
// a single update.
static int waveform_decompose(struct fb_info *info, struct omap3epfb_update_area *p)
{
	struct omap3epfb_par *par = info->par;
	int i = 0;
	int ret = 0; // Nothing to do

	DEBUG_LOG(DEBUG_LEVEL5,"DECOMPOSE++\n");
	mutex_lock(&par->area_mutex);
	{
		// Intercept updates to force waveform.
		if (par->effect_active != 0)
		{
			for (i = 0; i < EFFECT_ARRAY_SIZE; i++)
			{
				// Setup a new update
				struct omap3epfb_update_area new_sub_area = par->effect_array[i].effect_area;
				// Setup a new effect
				struct omap3epfb_area new_effect_area = {0};
				new_effect_area.effect_area = *p;
				new_effect_area.effect_area.wvfid = par->effect_array[i].effect_area.wvfid;
				new_effect_area.effect_flags = par->effect_array[i].effect_flags;
 
				if ((par->effect_active & (1 << i)) &&
				    process_area(i, info, &new_effect_area, &new_sub_area))
				{
					if ((ret == 0) && !rect_equal(&new_sub_area, p))
					{
						// Do the update as a normal update first
						batch_update(info, p);
					}
					// Indicate that we have a match.
					ret = 1;
					// Override AUTO waveform behaviour
					if (batch_update(info, &new_sub_area))
					{
						// If is was full screen, do not continue
						break;
					}
				}
			}
		}
	}
	mutex_unlock(&par->area_mutex);
	DEBUG_LOG(DEBUG_LEVEL5,"DECOMPOSE--\n");

	return ret;
}
Esempio n. 4
0
/* returns int */
int APP_CC
rect_update_bounding_box(struct xrdp_rect* BB, struct xrdp_rect* r, int DELTA)
{
  struct xrdp_rect inter;
  if (rect_equal(BB, r))
  {
    return 0;
  }
  if (rect_contained_by(r, BB->left, BB->top, BB->right, BB->bottom))
  {
    BB->left = r->left;
    BB->top = r->top;
    BB->bottom = r->bottom;
    BB->right = r->right;
    return 0;
  }
  if (rect_contained_by(BB, r->left, r->top, r->right, r->bottom))
  {
    return 0;
  }
  struct xrdp_rect tmp;
  tmp.left = BB->left - DELTA;
  tmp.right = BB->right + DELTA;
  tmp.top = BB->top - DELTA;
  tmp.bottom = BB->bottom + DELTA;

  if (rect_intersect(BB, r, &inter) || rect_intersect(&tmp, r, &inter))
  {
    BB->top = MIN(BB->top, r->top);
    BB->left = MIN(BB->left, r->left);
    BB->right = MAX(BB->right, r->right);
    BB->bottom = MAX(BB->bottom, r->bottom);
    return 0;
  }
  else
  {
    return 1;
  }
  return -1;
}
Esempio n. 5
0
graphene_rect_t
ops_set_viewport (RenderOpBuilder       *builder,
                  const graphene_rect_t *viewport)
{
  RenderOp op;
  graphene_rect_t prev_viewport;

  if (builder->current_program_state != NULL &&
      rect_equal (&builder->current_program_state->viewport, viewport))
    return builder->current_program_state->viewport;

  op.op = OP_CHANGE_VIEWPORT;
  op.viewport = *viewport;
  g_array_append_val (builder->render_ops, op);

  if (builder->current_program != NULL)
    builder->current_program_state->viewport = *viewport;

  prev_viewport = builder->current_viewport;
  builder->current_viewport = *viewport;

  return prev_viewport;
}
Esempio n. 6
0
static pdf_obj*
pdf_get_page_obj (pdf_file *pf, int page_no,
                  pdf_obj **ret_bbox, pdf_obj **ret_resources)
{
  pdf_obj *page_tree;
  pdf_obj *bbox = NULL, *resources = NULL, *rotate = NULL;
  int page_idx;

  /*
   * Get Page Tree.
   */
  page_tree = NULL;
  {
    pdf_obj *trailer, *catalog;
    pdf_obj *markinfo, *tmp;

    trailer = pdf_file_get_trailer(pf);

    if (pdf_lookup_dict(trailer, "Encrypt")) {
      WARN("This PDF document is encrypted.");
      pdf_release_obj(trailer);
      return NULL;
    }

    catalog = pdf_deref_obj(pdf_lookup_dict(trailer, "Root"));
    if (!PDF_OBJ_DICTTYPE(catalog)) {
      WARN("Can't read document catalog.");
      pdf_release_obj(trailer);
      if (catalog)
	pdf_release_obj(catalog);
      return NULL;
    }
    pdf_release_obj(trailer);

    markinfo = pdf_deref_obj(pdf_lookup_dict(catalog, "MarkInfo"));
    if (markinfo) {
      tmp = pdf_lookup_dict(markinfo, "Marked");
      if (PDF_OBJ_BOOLEANTYPE(tmp) && pdf_boolean_value(tmp))
        WARN("PDF file is tagged... Ignoring tags.");
      pdf_release_obj(markinfo);
    }

    page_tree = pdf_deref_obj(pdf_lookup_dict(catalog, "Pages"));
    pdf_release_obj(catalog);
  }
  if (!page_tree) {
    WARN("Page tree not found.");
    return NULL;
  }

  /*
   * Negative page numbers are counted from the back.
   */
  {
    int count = pdf_number_value(pdf_lookup_dict(page_tree, "Count"));
    page_idx = page_no + (page_no >= 0 ? -1 : count);
    if (page_idx < 0 || page_idx >= count) {
	WARN("Page %ld does not exist.", page_no);
	pdf_release_obj(page_tree);
	return NULL;
      }
    page_no = page_idx+1;
  }

  /*
   * Seek correct page. Get Media/Crop Box.
   * Media box and resources can be inherited.
   */
  {
    pdf_obj *kids_ref, *kids;
    pdf_obj *crop_box = NULL;
    pdf_obj *tmp;

    tmp = pdf_lookup_dict(page_tree, "Resources");
    resources = tmp ? pdf_deref_obj(tmp) : pdf_new_dict();

    while (1) {
      int kids_length, i;
 
      if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "MediaBox")))) {
	if (bbox)
	  pdf_release_obj(bbox);
	bbox = tmp;
      }
      if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "BleedBox")))) {
        if (!rect_equal(tmp, bbox)) {
	  if (bbox)
	    pdf_release_obj(bbox);
	  bbox = tmp;
        } else {
          pdf_release_obj(tmp);
      }
      }
      if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "TrimBox")))) {
        if (!rect_equal(tmp, bbox)) {
	  if (bbox)
	    pdf_release_obj(bbox);
	  bbox = tmp;
        } else {
          pdf_release_obj(tmp);
      }
      }
      if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "ArtBox")))) {
        if (!rect_equal(tmp, bbox)) {
	  if (bbox)
	    pdf_release_obj(bbox);
	  bbox = tmp;
        } else {
          pdf_release_obj(tmp);
      }
      }
      if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "CropBox")))) {
	if (crop_box)
	  pdf_release_obj(crop_box);
	crop_box = tmp;
      }
      if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Rotate")))) {
	if (rotate)
	  pdf_release_obj(rotate);
	rotate = tmp;
      }
      if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Resources")))) {
#if 0
	pdf_merge_dict(tmp, resources);
#endif
	if (resources)
	  pdf_release_obj(resources);
	resources = tmp;
      }

      kids_ref = pdf_lookup_dict(page_tree, "Kids");
      if (!kids_ref)
	break;
      kids = pdf_deref_obj(kids_ref);
      kids_length = pdf_array_length(kids);

      for (i = 0; i < kids_length; i++) {
	int count;

	pdf_release_obj(page_tree);
	page_tree = pdf_deref_obj(pdf_get_array(kids, i));

	tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Count"));
	if (tmp) {
	  /* Pages object */
	  count = pdf_number_value(tmp);
	  pdf_release_obj(tmp);
        } else {
	  /* Page object */
	  count = 1;
        }
	if (page_idx < count)
	  break;

	page_idx -= count;
      }
      
      pdf_release_obj(kids);

      if (i == kids_length) {
	WARN("Page %ld not found! Broken PDF file?", page_no);
	if (bbox)
	  pdf_release_obj(bbox);
	if (crop_box)
	  pdf_release_obj(crop_box);
	if (rotate)
	  pdf_release_obj(rotate);
	pdf_release_obj(resources);
	pdf_release_obj(page_tree);
	return NULL;
      }
    }
    if (crop_box) {
      pdf_release_obj(bbox);
      bbox = crop_box;
    }
  }

  if (!bbox) {
    WARN("No BoundingBox information available.");
    pdf_release_obj(page_tree);
    pdf_release_obj(resources);
    if (rotate)
      pdf_release_obj(rotate);
    return NULL;
  }

  if (rotate) {
    if (pdf_number_value(rotate) != 0.0)
      WARN("<< /Rotate %d >> found. (Not supported yet)",
            (int)pdf_number_value(rotate));
    pdf_release_obj(rotate);
    rotate = NULL;
  }
  
  if (ret_bbox != NULL)
    *ret_bbox = bbox;
  if (ret_resources != NULL)
    *ret_resources = resources;

  return page_tree;
}
Esempio n. 7
0
File: screen.c Progetto: rasilon/vim
static int scrollrect(VTermRect rect, int downward, int rightward, void *user)
{
  VTermScreen *screen = user;

  if(screen->damage_merge != VTERM_DAMAGE_SCROLL) {
    vterm_scroll_rect(rect, downward, rightward,
        moverect_internal, erase_internal, screen);

    vterm_screen_flush_damage(screen);

    vterm_scroll_rect(rect, downward, rightward,
        moverect_user, erase_user, screen);

    return 1;
  }

  if(screen->damaged.start_row != -1 &&
     !rect_intersects(&rect, &screen->damaged)) {
    vterm_screen_flush_damage(screen);
  }

  if(screen->pending_scrollrect.start_row == -1) {
    screen->pending_scrollrect = rect;
    screen->pending_scroll_downward  = downward;
    screen->pending_scroll_rightward = rightward;
  }
  else if(rect_equal(&screen->pending_scrollrect, &rect) &&
     ((screen->pending_scroll_downward  == 0 && downward  == 0) ||
      (screen->pending_scroll_rightward == 0 && rightward == 0))) {
    screen->pending_scroll_downward  += downward;
    screen->pending_scroll_rightward += rightward;
  }
  else {
    vterm_screen_flush_damage(screen);

    screen->pending_scrollrect = rect;
    screen->pending_scroll_downward  = downward;
    screen->pending_scroll_rightward = rightward;
  }

  vterm_scroll_rect(rect, downward, rightward,
      moverect_internal, erase_internal, screen);

  if(screen->damaged.start_row == -1)
    return 1;

  if(rect_contains(&rect, &screen->damaged)) {
    /* Scroll region entirely contains the damage; just move it */
    vterm_rect_move(&screen->damaged, -downward, -rightward);
    rect_clip(&screen->damaged, &rect);
  }
  /* There are a number of possible cases here, but lets restrict this to only
   * the common case where we might actually gain some performance by
   * optimising it. Namely, a vertical scroll that neatly cuts the damage
   * region in half.
   */
  else if(rect.start_col <= screen->damaged.start_col &&
          rect.end_col   >= screen->damaged.end_col &&
          rightward == 0) {
    if(screen->damaged.start_row >= rect.start_row &&
       screen->damaged.start_row  < rect.end_row) {
      screen->damaged.start_row -= downward;
      if(screen->damaged.start_row < rect.start_row)
        screen->damaged.start_row = rect.start_row;
      if(screen->damaged.start_row > rect.end_row)
        screen->damaged.start_row = rect.end_row;
    }
    if(screen->damaged.end_row >= rect.start_row &&
       screen->damaged.end_row  < rect.end_row) {
      screen->damaged.end_row -= downward;
      if(screen->damaged.end_row < rect.start_row)
        screen->damaged.end_row = rect.start_row;
      if(screen->damaged.end_row > rect.end_row)
        screen->damaged.end_row = rect.end_row;
    }
  }
  else {
    DEBUG_LOG2("TODO: Just flush and redo damaged=" STRFrect " rect=" STRFrect "\n",
        ARGSrect(screen->damaged), ARGSrect(rect));
  }

  return 1;
}
Esempio n. 8
0
void
ops_set_program (RenderOpBuilder *builder,
                 const Program   *program)
{
  /* The tricky part about this is that we want to initialize all uniforms of a program
   * to the current value from the builder, but only once. */
  static const GskRoundedRect empty_clip;
  static const graphene_matrix_t empty_matrix;
  static const graphene_rect_t empty_rect;
  RenderOp op;
  ProgramState *program_state;

  if (builder->current_program == program)
    return;

  op.op = OP_CHANGE_PROGRAM;
  op.program = program;
  g_array_append_val (builder->render_ops, op);
  builder->current_program = program;

  program_state = &builder->program_state[program->index];

  /* If the projection is not yet set for this program, we use the current one. */
  if (memcmp (&empty_matrix, &program_state->projection, sizeof (graphene_matrix_t)) == 0 ||
      memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0)
    {
      op.op = OP_CHANGE_PROJECTION;
      op.projection = builder->current_projection;
      g_array_append_val (builder->render_ops, op);
      program_state->projection = builder->current_projection;
    }

  if (memcmp (&empty_matrix, &program_state->modelview, sizeof (graphene_matrix_t)) == 0 ||
      memcmp (builder->current_modelview, &program_state->modelview, sizeof (graphene_matrix_t)) != 0)
    {
      op.op = OP_CHANGE_MODELVIEW;
      op.modelview = *builder->current_modelview;
      g_array_append_val (builder->render_ops, op);
      program_state->modelview = *builder->current_modelview;
    }

  if (rect_equal (&empty_rect, &program_state->viewport) ||
      !rect_equal (&builder->current_viewport, &program_state->viewport))
    {
      op.op = OP_CHANGE_VIEWPORT;
      op.viewport = builder->current_viewport;
      g_array_append_val (builder->render_ops, op);
      program_state->viewport = builder->current_viewport;
    }

  if (memcmp (&empty_clip, &program_state->clip, sizeof (GskRoundedRect)) == 0 ||
      memcmp (&builder->current_clip, &program_state->clip, sizeof (GskRoundedRect)) != 0)
    {
      op.op = OP_CHANGE_CLIP;
      op.clip = *builder->current_clip;
      g_array_append_val (builder->render_ops, op);
      program_state->clip = *builder->current_clip;
    }

  if (program_state->opacity != builder->current_opacity)
    {
      op.op = OP_CHANGE_OPACITY;
      op.opacity = builder->current_opacity;
      g_array_append_val (builder->render_ops, op);
      program_state->opacity = builder->current_opacity;
    }

  builder->current_program_state = &builder->program_state[program->index];
}
static int process_area(int index, struct fb_info *info, struct omap3epfb_area *area, struct omap3epfb_update_area *p)
{
	struct omap3epfb_par *par = info->par;
	int change = 0;

	if (!(area->effect_flags & (EFFECT_ONESHOT | EFFECT_ACTIVE | EFFECT_CLEAR)))
		return change;

	if (!rect_inside(&area->effect_area, p))
	{
		DEBUG_REGION(DEBUG_LEVEL5, p,"no match 0x%02x region %d = ", area->effect_flags, index);
		return change;
	}

	if (area->effect_flags & EFFECT_ONESHOT)
	{
		p->wvfid = area->effect_area.wvfid;
		p->threshold = area->effect_area.threshold;
		DEBUG_REGION(DEBUG_LEVEL2, p,"process ONESHOT region %d = ", index);
		if (area->effect_flags & EFFECT_REGION)
		{
			p->x0 = area->effect_area.x0;
			p->y0 = area->effect_area.y0;
			p->x1 = area->effect_area.x1;
			p->y1 = area->effect_area.y1;
		}
		par->effect_array[index].effect_flags = 0;
		change = 1;
	}
	else if (area->effect_flags & EFFECT_ACTIVE)
	{
		p->wvfid = area->effect_area.wvfid;
		p->threshold = area->effect_area.threshold;
		DEBUG_REGION(DEBUG_LEVEL2, p,"process ACTIVE region %d = ", index);
		change = 1;
		if (p->wvfid == OMAP3EPFB_WVFID_AUTO)
		{
			// Calculate the percentage of the screen that needs an update.
			int percent = ((rect_width(p) * rect_height(p) * 100)) /
			      ((info->var.xres-1) * (info->var.yres-1));

			// Check if we need to do a GC of the whole screen
			if ((par->refresh_percent > 0) && (percent >= par->refresh_percent))
			{
				DEBUG_REGION(DEBUG_LEVEL1, p,"process ACTIVE %d%% region %d = ", percent, index);
				p->x0 = p->y0 = 0;
				p->x1 = info->var.xres-1;
				p->y1 = info->var.yres-1;
				p->wvfid = OMAP3EPFB_WVFID_GC;
				p->threshold = 0;
			}
		}
		else
		{
			if (area->effect_flags & EFFECT_REGION)
			{
				p->x0 = area->effect_area.x0;
				p->y0 = area->effect_area.y0;
				p->x1 = area->effect_area.x1;
				p->y1 = area->effect_area.y1;
			}
		}
	}
	else if ((area->effect_flags & EFFECT_CLEAR) && rect_equal(&area->effect_area, p))
	{
		// Turn the next update of the effect area into a full page flushing update,
		// then clear the effect area.
		// This is used as a hint that a dialog is closing, then we forcing a full screen GC update.
		p->wvfid = area->effect_area.wvfid;
		p->threshold = area->effect_area.threshold;
		DEBUG_REGION(DEBUG_LEVEL2, p,"process RESET region %d = ", index);
		p->x0 = p->y0 = 0;
		p->x1 = info->var.xres-1;
		p->y1 = info->var.yres-1;
		p->wvfid = OMAP3EPFB_WVFID_GC;
		par->effect_array[index].effect_flags = 0;
		change = 1;
	}

	// Update the fast scan flags.
	update_effect(par, index);

	return change;
}
Esempio n. 10
0
/*************************************************************************
**                                                                      **
**       Function Definitions                                           **
**                                                                      **
**************************************************************************/
int
abobjP_move_object_outline(
    ABObj         	obj, 
    XMotionEvent        *mevent
)
{
    static XRectangle parent_rect;
    static XRectangle last_rect;
    static int        x_offset, y_offset;
    static Dimension  border_w;
    static Display    *dpy;
    XRectangle	      widget_rect;
    int               trans_x, trans_y;

    /* First time: set up initial move variables */
    if (first_move)
    {
	if (obj_is_item(obj))
	    obj = obj_get_parent(obj);

	obj    = obj_get_root(obj);
	
        /* Multiple objects might be selected...*/ 
        if (obj_is_control(obj) || 
	    obj_is_group(obj) ||
	    obj_is_pane(obj)) 
        { 
            abobj_get_selected(obj_get_root(obj_get_parent(obj)), False, False, &sel);
        } 
        else
	{
            sel.count = 1; 
	    sel.list = (ABObj*)util_malloc(sizeof(ABObj));
	    sel.list[0] = obj;
	}

	xy_obj = objxm_comp_get_subobj(obj, AB_CFG_POSITION_OBJ);
        xy_widget = (Widget)xy_obj->ui_handle;

        if (xy_widget == NULL)
        {
            if (util_get_verbosity() > 2)
                fprintf(stderr,"abobjP_move_object_outline: %s :no POSITION widget\n",
			util_strsafe(obj_get_name(obj)));
            return ERROR;
        }

        dpy    = XtDisplay(xy_widget);
        parent = XtParent(xy_widget);

	x_get_widget_rect(xy_widget, &widget_rect);
        x_get_widget_rect(parent, &parent_rect);

	if (sel.count > 1)
	{
            abobj_get_rect_for_objects(sel.list, sel.count, &orig_rect);
	} 
	else
	{
	    orig_rect = widget_rect;
	    XtVaGetValues(xy_widget, XtNborderWidth, &border_w, NULL);
	    orig_rect.width  += (2*border_w);
	    orig_rect.height += (2*border_w);
	    orig_rect.width--;
	    orig_rect.height--;
	}
	move_rect = orig_rect;

        drag_init_rect.x     = mevent->x - AB_drag_threshold;
        drag_init_rect.y     = mevent->y - AB_drag_threshold;
        drag_init_rect.width = drag_init_rect.height = 2 * AB_drag_threshold;

	x_offset = widget_rect.x - orig_rect.x + mevent->x;
	y_offset = widget_rect.y - orig_rect.y + mevent->y;

        first_move  = False;

        rect_zero_out(&last_rect);
    }
    /* Don't begin rendering move outline until pointer is out of
     * the drag_init bounding box
     */
    else if (!rect_includespoint(&drag_init_rect, mevent->x, mevent->y))
    {    
        Window win;

        /* event coords are relative to widget-must translate to parent */
        XTranslateCoordinates(dpy, XtWindow(xy_widget), XtWindow(parent),
            mevent->x, mevent->y, &trans_x, &trans_y, &win);

        move_rect.x = trans_x - x_offset;
        move_rect.y = trans_y - y_offset;

        /* Ensure move outline is within the parent's rect */
        if (move_rect.x < 0)
            move_rect.x = 0;
        else if ((move_rect.x + (short)move_rect.width + 1) >= (short)parent_rect.width)
            move_rect.x = parent_rect.width - (move_rect.width + 1);

        if (move_rect.y < 0)
            move_rect.y = 0;
        else if ((move_rect.y + (short)move_rect.height + 1) >= (short)parent_rect.height)
            move_rect.y = parent_rect.height - (move_rect.height + 1);

        /* If cursor has moved since last event, erase previous outline
         * and render new one (using XOR function)
         */
        if (!rect_equal(&move_rect, &last_rect))
        {
            if (!rect_isnull(&last_rect))
                x_box_r(parent, &last_rect);
            x_box_r(parent, &move_rect);
            last_rect = move_rect;
        }
    }
    return OK;
}
Esempio n. 11
0
void progressive_display_split_and_merge(struct list* self)
{
  int i, j;
  struct update_rect* item1;
  struct update_rect* item2;
  struct xrdp_rect first;
  struct xrdp_rect second;
  bool merged = true;
  bool remove;

  while (merged)
  {
    merged = false;
    for (i = 0; i < self->count; i++)
    {
      item1 = (struct update_rect*) list_get_item(self, i);
      first = item1->rect;
      for (j = self->count - 1; j > i; j--)
      {
        item2 = (struct update_rect*) list_get_item(self, j);
        second = item2->rect;
        if (item1->quality_already_send == item2->quality_already_send)
        {
          if (!rect_equal(&first, &second))
          {
            int adj = rect_adjacency(&first, &second);
            switch (adj)
            {
            case 0:
              break;
            case 1: // first is at right of second
              merged = true;
              if (rect_height(&first) == rect_height(&second))
              {
                item1->rect.left = item2->rect.left;
                list_remove_item(self, j);
              }
              else
              {
                progressive_display_rect_split_h(self, item1, item2, &remove);
                if (remove)
                {
                  list_remove_item(self, j);
                  list_remove_item(self, i);
                }
                else
                  merged = false;
              }
              break;
            case 2: // first is at left of second
              merged = true;
              if (rect_height(&first) == rect_height(&second))
              {
                item1->rect.right = item2->rect.right;
                list_remove_item(self, j);
              }
              else
              {
                progressive_display_rect_split_h(self, item2, item1, &remove);
                if (remove)
                {
                  list_remove_item(self, j);
                  list_remove_item(self, i);
                }
                else
                  merged = false;
              }
              break;
            case 3: // first is under second
              merged = true;
              if (rect_width(&first) == rect_width(&second))
              {
                item1->rect.top = item2->rect.top;
                list_remove_item(self, j);
              }
              else
              {
                progressive_display_rect_split_v(self, item1, item2, &remove);
                if (remove)
                {
                  list_remove_item(self, j);
                  list_remove_item(self, i);
                }
                else
                  merged = false;
              }
              break;
            case 4: // first is above second
              merged = true;
              if (rect_width(&first) == rect_width(&second))
              {
                item1->rect.bottom = item2->rect.bottom;
                list_remove_item(self, j);
              }
              else
              {
                progressive_display_rect_split_v(self, item2, item1, &remove);
                if (remove)
                {
                  list_remove_item(self, j);
                  list_remove_item(self, i);
                }
                else
                  merged = false;
              }
              break;
            }
          }
          else
          {
            list_remove_item(self, j);
            merged = true;
          }
        }
        else
        {
          merged = false;
        }
        if (merged)
          break;
      }
      if (merged)
        break;
    }
  }
}
Esempio n. 12
0
/* returns boolean */
int APP_CC
rect_union(struct xrdp_rect* in1, struct xrdp_rect* in2, struct list* out) {
	struct xrdp_rect tmp;
	if (!rect_intersect(in1, in2, &tmp)) {
		return 0;
	}
	if (rect_equal(in1, in2)) {
		return 0; 
	} 
	if (in1->left <= in2->left &&
		in1->top <= in2->top &&
		in1->right >= in2->right &&
		in1->bottom >= in2->bottom) {
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
	} else if (in1->left <= in2->left &&
		in1->right >= in2->right &&
		in1->bottom < in2->bottom &&
		in1->top <= in2->top) { /* partially covered(whole top) */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in2->left, in1->bottom, in2->right, in2->bottom);
	} else if (in1->top <= in2->top &&
			   in1->bottom >= in2->bottom &&
			   in1->right < in2->right &&
			   in1->left <= in2->left) { /* partially covered(left) */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in1->right, in2->top, in2->right, in2->bottom);
	} else if (in1->left <= in2->left &&
			   in1->right >= in2->right &&
			   in1->top > in2->top &&
			   in1->bottom >= in2->bottom) { /* partially covered(bottom) */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in2->left, in2->top, in2->right, in1->top);
	} else if (in1->top <= in2->top &&
			   in1->bottom >= in2->bottom &&
			   in1->left > in2->left &&
			   in1->right >= in2->right) { /* partially covered(right) */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in2->left, in2->top, in1->left, in2->bottom);
	} else if (in1->left <= in2->left &&
			   in1->top <= in2->top &&
			   in1->right < in2->right &&
			   in1->bottom < in2->bottom) { /* partially covered(top left) */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in1->right, in2->top, in2->right, in1->bottom);
		list_add_rect(out, in2->left, in1->bottom, in2->right, in2->bottom);
	} else if (in1->left <= in2->left &&
			   in1->bottom >= in2->bottom &&
			   in1->right < in2->right &&
			   in1->top > in2->top) { /* partially covered(bottom left) */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in2->left, in2->top, in2->right, in1->top);
		list_add_rect(out, in1->right, in1->top, in2->right, in2->bottom);
	} else if (in1->left > in2->left &&
			   in1->right >= in2->right &&
			   in1->top <= in2->top &&
			   in1->bottom < in2->bottom) { /* partially covered(top right) */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in2->left, in2->top, in1->left, in2->bottom);
		list_add_rect(out, in2->left, in1->bottom, in2->right, in2->bottom);
	} else if (in1->left > in2->left &&
			   in1->right >= in2->right &&
			   in1->top > in2->top &&
			   in1->bottom >= in2->bottom) { /* partially covered(bottom right) */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in2->left, in2->top, in2->right, in1->top);
		list_add_rect(out, in2->left, in1->top, in1->left, in2->bottom);
	} else if (in1->left > in2->left &&
			   in1->top <= in2->top &&
			   in1->right < in2->right &&
			   in1->bottom >= in2->bottom) { /* 2 rects, one on each end */
		list_add_rect(out, in1->left, in1->top, in1->right, in1->bottom);
		list_add_rect(out, in2->left, in2->top, in1->left, in2->bottom);
		list_add_rect(out, in1->right, in2->top, in2->right, in2->bottom);
	} else if (in1->left <= in2->left &&
			   in1->top > in2->top &&
			   in1->right >= in2->right &&
			   in1->bottom < in2->bottom) { /* 2 rects, one on each end */
		list_add_rect(out, in2->left, in2->top, in2->right, in2->bottom);
		list_add_rect(out, in1->left, in1->top, in2->left, in1->bottom);
		list_add_rect(out, in2->right, in1->top, in1->right, in1->bottom);
	 } else if (in1->left > in2->left &&
			 in1->right < in2->right &&
			 in1->top <= in2->top &&
			 in1->bottom < in2->bottom) { /* partially covered(top) */
		 list_add_rect(out, in2->left, in2->top, in2->right, in2->bottom);
		 list_add_rect(out, in1->left, in1->top, in1->right, in2->top);
	} else if (in1->top > in2->top &&
			   in1->bottom < in2->bottom &&
			   in1->left <= in2->left &&
			   in1->right < in2->right) { /* partially covered(left) */
		list_add_rect(out, in2->left, in2->top, in2->right, in2->bottom);
		list_add_rect(out, in1->left, in1->top, in2->left, in1->bottom);
	} else if (in1->left > in2->left &&
			   in1->right < in2->right &&
			   in1->bottom >= in2->bottom &&
			   in1->top > in2->top) { /* partially covered(bottom) */
		list_add_rect(out, in2->left, in2->top, in2->right, in2->bottom);
		list_add_rect(out, in1->left, in2->bottom, in1->right, in1->bottom);
	} else if (in1->top > in2->top &&
			   in1->bottom < in2->bottom &&
			   in1->right >= in2->right &&
			   in1->left > in2->left) { /* partially covered(right) */
		list_add_rect(out, in2->left, in2->top, in2->right, in2->bottom);
		list_add_rect(out, in2->right, in1->top, in1->right, in1->bottom);
	} else if (in1->left > in2->left &&
			   in1->top > in2->top &&
			   in1->right < in2->right &&
			   in1->bottom < in2->bottom) { /* totally contained, 4 rects */
		list_add_rect(out, in2->left, in2->top, in2->right, in2->bottom);
	}
	return 0;
}