Exemple #1
0
void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy)
{
   sraRectangleIterator* i;
   sraRect rect;
   int j,widthInBytes,bpp=rfbScreen->rfbServerFormat.bitsPerPixel/8,
    rowstride=rfbScreen->paddedWidthInBytes;
   char *in,*out;

   rfbUndrawCursor(rfbScreen);
  
   /* copy it, really */
   i = sraRgnGetReverseIterator(copyRegion,dx<0,dy<0);
   while(sraRgnIteratorNext(i,&rect)) {
     widthInBytes = (rect.x2-rect.x1)*bpp;
     out = rfbScreen->frameBuffer+rect.x1*bpp+rect.y1*rowstride;
     in = rfbScreen->frameBuffer+(rect.x1-dx)*bpp+(rect.y1-dy)*rowstride;
     if(dy<0)
       for(j=rect.y1;j<rect.y2;j++,out+=rowstride,in+=rowstride)
	 memmove(out,in,widthInBytes);
     else {
       out += rowstride*(rect.y2-rect.y1-1);
       in += rowstride*(rect.y2-rect.y1-1);
       for(j=rect.y2-1;j>=rect.y1;j--,out-=rowstride,in-=rowstride)
	 memmove(out,in,widthInBytes);
     }
   }
  
   rfbScheduleCopyRegion(rfbScreen,copyRegion,dx,dy);
}
Exemple #2
0
void
defaultPtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl)
{
   if(x!=cl->screen->cursorX || y!=cl->screen->cursorY) {
      cl->cursorWasMoved = TRUE;
      if(cl->screen->cursorIsDrawn)
	rfbUndrawCursor(cl->screen);
      LOCK(cl->screen->cursorMutex);
      if(!cl->screen->cursorIsDrawn) {
	  cl->screen->cursorX = x;
	  cl->screen->cursorY = y;
      }
      UNLOCK(cl->screen->cursorMutex);
   }
}
Exemple #3
0
int rfbSelectBox(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,
		 char** list,
		 int x1,int y1,int x2,int y2,
		 Pixel colour,Pixel backColour,
		 int border,SelectionChangedHookPtr selChangedHook)
{
   int bpp = rfbScreen->bitsPerPixel/8;
   char* frameBufferBackup;
   void* screenDataBackup = rfbScreen->screenData;
   KbdAddEventProcPtr kbdAddEventBackup = rfbScreen->kbdAddEvent;
   PtrAddEventProcPtr ptrAddEventBackup = rfbScreen->ptrAddEvent;
   GetCursorProcPtr getCursorPtrBackup = rfbScreen->getCursorPtr;
   DisplayHookPtr displayHookBackup = rfbScreen->displayHook;
   rfbSelectData selData;
   int i,j,k;
   int fx1,fy1,fx2,fy2; /* for font bbox */

   if(list==0 || *list==0)
     return(-1);
   
   rfbWholeFontBBox(font, &fx1, &fy1, &fx2, &fy2);
   selData.textH = fy2-fy1;
   /* I need at least one line for the choice and one for the buttons */
   if(y2-y1<selData.textH*2+3*border)
     return(-1);
   selData.xhot = -fx1;
   selData.yhot = -fy2;
   selData.x1 = x1+border;
   selData.y1 = y1+border;
   selData.y2 = y2-selData.textH-3*border;
   selData.x2 = x2-2*border;
   selData.pageH = (selData.y2-selData.y1)/selData.textH;

   i = rfbWidthOfString(font,okStr);
   j = rfbWidthOfString(font,cancelStr);
   selData.buttonWidth= k = 4*border+(i<j)?j:i;
   selData.okBX = x1+(x2-x1-2*k)/3;
   if(selData.okBX<x1+border) /* too narrow! */
     return(-1);
   selData.cancelBX = x1+k+(x2-x1-2*k)*2/3;
   selData.okX = selData.okBX+(k-i)/2;
   selData.cancelX = selData.cancelBX+(k-j)/2;
   selData.okY = y2-border;

   rfbUndrawCursor(rfbScreen);
   frameBufferBackup = (char*)malloc(bpp*(x2-x1)*(y2-y1));

   selData.state = SELECTING;
   selData.screen = rfbScreen;
   selData.font = font;
   selData.list = list;
   selData.colour = colour;
   selData.backColour = backColour;
   for(i=0;list[i];i++);
   selData.selected = i;
   selData.listSize = i;
   selData.displayStart = i;
   selData.lastButtons = 0;
   selData.selChangedHook = selChangedHook;
   
   rfbScreen->screenData = &selData;
   rfbScreen->kbdAddEvent = selKbdAddEvent;
   rfbScreen->ptrAddEvent = selPtrAddEvent;
   rfbScreen->getCursorPtr = selGetCursorPtr;
   rfbScreen->displayHook = 0;
   
   /* backup screen */
   for(j=0;j<y2-y1;j++)
     memcpy(frameBufferBackup+j*(x2-x1)*bpp,
	    rfbScreen->frameBuffer+j*rfbScreen->paddedWidthInBytes+x1*bpp,
	    (x2-x1)*bpp);

   /* paint list and buttons */
   rfbFillRect(rfbScreen,x1,y1,x2,y2,colour);
   selPaintButtons(&selData,FALSE,FALSE);
   selSelect(&selData,0);

   /* modal loop */
   while(selData.state == SELECTING)
     rfbProcessEvents(rfbScreen,20000);

   /* copy back screen data */
   for(j=0;j<y2-y1;j++)
     memcpy(rfbScreen->frameBuffer+j*rfbScreen->paddedWidthInBytes+x1*bpp,
	    frameBufferBackup+j*(x2-x1)*bpp,
	    (x2-x1)*bpp);
   free(frameBufferBackup);
   rfbMarkRectAsModified(rfbScreen,x1,y1,x2,y2);
   rfbScreen->screenData = screenDataBackup;
   rfbScreen->kbdAddEvent = kbdAddEventBackup;
   rfbScreen->ptrAddEvent = ptrAddEventBackup;
   rfbScreen->getCursorPtr = getCursorPtrBackup;
   rfbScreen->displayHook = displayHookBackup;

   if(selData.state==CANCEL)
     selData.selected=-1;
   return(selData.selected);
}
Exemple #4
0
void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy)
{  
   rfbClientIteratorPtr iterator;
   rfbClientPtr cl;

   rfbUndrawCursor(rfbScreen);
  
   iterator=rfbGetClientIterator(rfbScreen);
   while((cl=rfbClientIteratorNext(iterator))) {
     LOCK(cl->updateMutex);
     if(cl->useCopyRect) {
       sraRegionPtr modifiedRegionBackup;
       if(!sraRgnEmpty(cl->copyRegion)) {
	  if(cl->copyDX!=dx || cl->copyDY!=dy) {
	     /* if a copyRegion was not yet executed, treat it as a
	      * modifiedRegion. The idea: in this case it could be
	      * source of the new copyRect or modified anyway. */
	     sraRgnOr(cl->modifiedRegion,cl->copyRegion);
	     sraRgnMakeEmpty(cl->copyRegion);
	  } else {
	     /* we have to set the intersection of the source of the copy
	      * and the old copy to modified. */
	     modifiedRegionBackup=sraRgnCreateRgn(copyRegion);
	     sraRgnOffset(modifiedRegionBackup,-dx,-dy);
	     sraRgnAnd(modifiedRegionBackup,cl->copyRegion);
	     sraRgnOr(cl->modifiedRegion,modifiedRegionBackup);
	     sraRgnDestroy(modifiedRegionBackup);
	  }
       }
	  
       sraRgnOr(cl->copyRegion,copyRegion);
       cl->copyDX = dx;
       cl->copyDY = dy;

       /* if there were modified regions, which are now copied,
	* mark them as modified, because the source of these can be overlapped
	* either by new modified or now copied regions. */
       modifiedRegionBackup=sraRgnCreateRgn(cl->modifiedRegion);
       sraRgnOffset(modifiedRegionBackup,dx,dy);
       sraRgnAnd(modifiedRegionBackup,cl->copyRegion);
       sraRgnOr(cl->modifiedRegion,modifiedRegionBackup);
       sraRgnDestroy(modifiedRegionBackup);

#if 0
//TODO: is this needed? Or does it mess up deferring?
       /* while(!sraRgnEmpty(cl->copyRegion)) */ {
#ifdef HAVE_PTHREADS
	 if(!cl->screen->backgroundLoop)
#endif
	   {
	     sraRegionPtr updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
	     sraRgnOr(updateRegion,cl->copyRegion);
	     UNLOCK(cl->updateMutex);
	     rfbSendFramebufferUpdate(cl,updateRegion);
	     sraRgnDestroy(updateRegion);
	     continue;
	   }
       }
#endif
     } else {
       sraRgnOr(cl->modifiedRegion,copyRegion);
     }
     TSIGNAL(cl->updateCond);
     UNLOCK(cl->updateMutex);
   }

   rfbReleaseClientIterator(iterator);
}