Exemple #1
0
rfbBool
sraRgnPopRect(sraRegion *rgn, sraRect *rect, unsigned long flags) {
  sraSpan *vcurr, *hcurr;
  sraSpan *vend, *hend;
  rfbBool right2left = flags & 2;
  rfbBool bottom2top = flags & 1;

  /* - Pick correct order */
  if (bottom2top) {
    vcurr = ((sraSpanList*)rgn)->back._prev;
    vend = &(((sraSpanList*)rgn)->front);
  } else {
    vcurr = ((sraSpanList*)rgn)->front._next;
    vend = &(((sraSpanList*)rgn)->back);
  }

  if (vcurr != vend) {
    rect->y1 = vcurr->start;
    rect->y2 = vcurr->end;

    /* - Pick correct order */
    if (right2left) {
      hcurr = vcurr->subspan->back._prev;
      hend = &(vcurr->subspan->front);
    } else {
      hcurr = vcurr->subspan->front._next;
      hend = &(vcurr->subspan->back);
    }

    if (hcurr != hend) {
      rect->x1 = hcurr->start;
      rect->x2 = hcurr->end;

      sraSpanRemove(hcurr);
      sraSpanDestroy(hcurr);
      
      if (sraSpanListEmpty(vcurr->subspan)) {
	sraSpanRemove(vcurr);
	sraSpanDestroy(vcurr);
      }

#if 0
      printf("poprect:(%dx%d)-(%dx%d)\n",
	     rect->x1, rect->y1, rect->x2, rect->y2);
#endif
      return 1;
    }
  }

  return 0;
}
Exemple #2
0
static void
sraSpanMergePrevious(sraSpan *dest)
{
    sraSpan *prev;

    if (!dest)
        return;

    prev = dest->_prev;

    while ((prev->_prev) &&
            (prev->end == dest->start) &&
            (sraSpanListEqual(prev->subspan, dest->subspan)))
    {
        /*
        printf("merge_prev:");
        sraSpanPrint(prev);
        printf(" & ");
        sraSpanPrint(dest);
        printf("\n");
        */
        dest->start = prev->start;
        sraSpanRemove(prev);
        sraSpanDestroy(prev);
        prev = dest->_prev;
    }
}
Exemple #3
0
static void
sraSpanListDestroy(sraSpanList *list) {
  sraSpan *curr, *next;
  while (list->front._next != &(list->back)) {
    curr = list->front._next;
    next = curr->_next;
    sraSpanRemove(curr);
    sraSpanDestroy(curr);
    curr = next;
  }
  free(list);
}
Exemple #4
0
static void
sraSpanListMakeEmpty(sraSpanList *list) {
  sraSpan *curr, *next;
  while (list->front._next != &(list->back)) {
    curr = list->front._next;
    next = curr->_next;
    sraSpanRemove(curr);
    sraSpanDestroy(curr);
    curr = next;
  }
  list->front._next = &(list->back);
  list->front._prev = NULL;
  list->back._prev = &(list->front);
  list->back._next = NULL;
}
Exemple #5
0
void
sraSpanListDestroy(sraSpanList *list)
{
    sraSpan *curr, *next;
    if (!list)
        return;

    while (list->front._next != &(list->back))
    {
        curr = list->front._next;
        next = curr->_next;
        sraSpanRemove(curr);
        sraSpanDestroy(curr);
        curr = next;
    }
    MemFree(list);
}
Exemple #6
0
static void
sraSpanMergeNext(sraSpan *dest) {
  sraSpan *next = dest->_next;
  while ((next->start == dest->end) &&
	 (next->_next) &&
	 (sraSpanListEqual(next->subspan, dest->subspan))) {
/*
	  printf("merge_next:");
    sraSpanPrint(dest);
    printf(" & ");
    sraSpanPrint(next);
    printf("\n");
	*/
    dest->end = next->end;
    sraSpanRemove(next);
    sraSpanDestroy(next);
    next = dest->_next;
  }
}
Exemple #7
0
static rfbBool
sraSpanListSubtract(sraSpanList *dest, const sraSpanList *src) {
  sraSpan *d_curr, *s_curr;

  if (!dest) {
    if (!src) {
      return 1;
    } else {
      printf("sraSpanListSubtract:incompatible spans (only one NULL!)\n");
      return FALSE;
    }
  }

  d_curr = dest->front._next;
  s_curr = src->front._next;
  while ((s_curr != &(src->back)) && (d_curr != &(dest->back))) {

    /* - If we haven't reached a destination span yet then move on */
    if (d_curr->start >= s_curr->end) {
      s_curr = s_curr->_next;
      continue;
    }

    /* - If we are beyond the current destination span then skip it */
    if (d_curr->end <= s_curr->start) {
      d_curr = d_curr->_next;
      continue;
    }

    /* - If we partially overlap the current span then split it up */
    if (s_curr->start > d_curr->start) {
      sraSpanInsertBefore(sraSpanCreate(d_curr->start,
					s_curr->start,
					d_curr->subspan),
			  d_curr);
      d_curr->start = s_curr->start;
    }
    if (s_curr->end < d_curr->end) {
      sraSpanInsertAfter(sraSpanCreate(s_curr->end,
				       d_curr->end,
				       d_curr->subspan),
			 d_curr);
      d_curr->end = s_curr->end;
    }

    /* - Now recursively process the affected span */
    if ((!d_curr->subspan) || !sraSpanListSubtract(d_curr->subspan, s_curr->subspan)) {
      /* - The destination subspan is now empty, so we should remove it */
      sraSpan *next = d_curr->_next;
      sraSpanRemove(d_curr);
      sraSpanDestroy(d_curr);
      d_curr = next;
    } else {
      /* Merge this span with previous or next? */
      if (d_curr->_prev != &(dest->front))
	sraSpanMergePrevious(d_curr);
      if (d_curr->_next != &(dest->back))
	sraSpanMergeNext(d_curr);

      /* - Move on to the next span */
      if (s_curr->end > d_curr->end) {
	d_curr = d_curr->_next;
      } else {
	s_curr = s_curr->_next;
      }
    }
  }

  return !sraSpanListEmpty(dest);
}
Exemple #8
0
static rfbBool
sraSpanListAnd(sraSpanList *dest, const sraSpanList *src)
{
    sraSpan *d_curr, *s_curr, *d_next;

    if (!dest)
    {
        if (!src)
        {
            return 1;
        }
        else
        {
            ///rfbErr("sraSpanListAnd:incompatible spans (only one NULL!)\n");
            return FALSE;
        }
    }
    else if (!src)
        return FALSE;

    d_curr = dest->front._next;
    s_curr = src->front._next;
    while ((s_curr != &(src->back)) && (d_curr != &(dest->back)))
    {

        /* - If we haven't reached a destination span yet then move on */
        if (d_curr->start >= s_curr->end)
        {
            s_curr = s_curr->_next;
            continue;
        }

        /* - If we are beyond the current destination span then remove it */
        if (d_curr->end <= s_curr->start)
        {
            sraSpan *next = d_curr->_next;
            sraSpanRemove(d_curr);
            sraSpanDestroy(d_curr);
            d_curr = next;
            continue;
        }

        /* - If we partially overlap a span then split it up or remove bits */
        if (s_curr->start > d_curr->start)
        {
            /* - The top bit of the span does not match */
            d_curr->start = s_curr->start;
        }
        if (s_curr->end < d_curr->end)
        {
            /* - The end of the span does not match */
            sraSpanInsertAfter(sraSpanCreate(s_curr->end,
                                             d_curr->end,
                                             d_curr->subspan),
                               d_curr);
            d_curr->end = s_curr->end;
        }

        /* - Now recursively process the affected span */
        if (!sraSpanListAnd(d_curr->subspan, s_curr->subspan))
        {
            /* - The destination subspan is now empty, so we should remove it */
            sraSpan *next = d_curr->_next;
            sraSpanRemove(d_curr);
            sraSpanDestroy(d_curr);
            d_curr = next;
        }
        else
        {
            /* Merge this span with previous or next? */
            if (d_curr->_prev != &(dest->front))
                sraSpanMergePrevious(d_curr);

            /* - Move on to the next span */
            d_next = d_curr;
            if (s_curr->end >= d_curr->end)
            {
                d_next = d_curr->_next;
            }
            if (s_curr->end <= d_curr->end)
            {
                s_curr = s_curr->_next;
            }
            d_curr = d_next;
        }
    }

    while (d_curr != &(dest->back))
    {
        sraSpan *next = d_curr->_next;
        sraSpanRemove(d_curr);
        sraSpanDestroy(d_curr);
        d_curr=next;
    }

    return !sraSpanListEmpty(dest);
}