1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <ctype.h> 2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfb.h> 3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/keysym.h> 4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehattypedef struct { 6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreenInfoPtr screen; 7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFontDataPtr font; 8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char** list; 9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int listSize; 10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int selected; 11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int displayStart; 12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x1,y1,x2,y2,textH,pageH; 13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int xhot,yhot; 14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int buttonWidth,okBX,cancelBX,okX,cancelX,okY; 15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbBool okInverted,cancelInverted; 16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int lastButtons; 17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbPixel colour,backColour; 18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat SelectionChangedHookPtr selChangedHook; 19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat enum { SELECTING, OK, CANCEL } state; 20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} rfbSelectData; 21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic const char* okStr="OK"; 23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic const char* cancelStr="Cancel"; 24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void selPaintButtons(rfbSelectData* m,rfbBool invertOk,rfbBool invertCancel) 26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreenInfoPtr s = m->screen; 28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbPixel bcolour = m->backColour; 29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbPixel colour = m->colour; 30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFillRect(s,m->x1,m->okY-m->textH,m->x2,m->okY,bcolour); 32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(invertOk) { 34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFillRect(s,m->okBX,m->okY-m->textH,m->okBX+m->buttonWidth,m->okY,colour); 35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDrawStringWithClip(s,m->font,m->okX+m->xhot,m->okY-1+m->yhot,okStr, 36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->x1,m->okY-m->textH,m->x2,m->okY, 37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bcolour,colour); 38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else 39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDrawString(s,m->font,m->okX+m->xhot,m->okY-1+m->yhot,okStr,colour); 40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(invertCancel) { 42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFillRect(s,m->cancelBX,m->okY-m->textH, 43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->cancelBX+m->buttonWidth,m->okY,colour); 44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDrawStringWithClip(s,m->font,m->cancelX+m->xhot,m->okY-1+m->yhot, 45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat cancelStr,m->x1,m->okY-m->textH,m->x2,m->okY, 46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat bcolour,colour); 47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else 48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDrawString(s,m->font,m->cancelX+m->xhot,m->okY-1+m->yhot,cancelStr,colour); 49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->okInverted = invertOk; 51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->cancelInverted = invertCancel; 52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* line is relative to displayStart */ 55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void selPaintLine(rfbSelectData* m,int line,rfbBool invert) 56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int y1 = m->y1+line*m->textH, y2 = y1+m->textH; 58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(y2>m->y2) 59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat y2=m->y2; 60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFillRect(m->screen,m->x1,y1,m->x2,y2,invert?m->colour:m->backColour); 61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(m->displayStart+line<m->listSize) 62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDrawStringWithClip(m->screen,m->font,m->x1+m->xhot,y2-1+m->yhot, 63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->list[m->displayStart+line], 64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->x1,y1,m->x2,y2, 65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat invert?m->backColour:m->colour, 66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat invert?m->backColour:m->colour); 67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void selSelect(rfbSelectData* m,int _index) 70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int delta; 72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(_index==m->selected || _index<0 || _index>=m->listSize) 74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(m->selected>=0) 77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selPaintLine(m,m->selected-m->displayStart,FALSE); 78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(_index<m->displayStart || _index>=m->displayStart+m->pageH) { 80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* targetLine is the screen line in which the selected line will 81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat be displayed. 82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat targetLine = m->pageH/2 doesn't look so nice */ 83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int targetLine = m->selected-m->displayStart; 84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int lineStart,lineEnd; 85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* scroll */ 87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(_index<targetLine) 88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat targetLine = _index; 89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if(_index+m->pageH-targetLine>=m->listSize) 90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat targetLine = _index+m->pageH-m->listSize; 91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat delta = _index-(m->displayStart+targetLine); 92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(delta>-m->pageH && delta<m->pageH) { 94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(delta>0) { 95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lineStart = m->pageH-delta; 96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lineEnd = m->pageH; 97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDoCopyRect(m->screen,m->x1,m->y1,m->x2,m->y1+lineStart*m->textH, 98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 0,-delta*m->textH); 99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lineStart = 0; 101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lineEnd = -delta; 102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDoCopyRect(m->screen, 103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->x1,m->y1+lineEnd*m->textH,m->x2,m->y2, 104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 0,-delta*m->textH); 105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lineStart = 0; 108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat lineEnd = m->pageH; 109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->displayStart += delta; 111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(delta=lineStart;delta<lineEnd;delta++) 112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(delta!=_index) 113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selPaintLine(m,delta,FALSE); 114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->selected = _index; 117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selPaintLine(m,m->selected-m->displayStart,TRUE); 118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(m->selChangedHook) 120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->selChangedHook(_index); 121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* todo: scrollbars */ 123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void selKbdAddEvent(rfbBool down,rfbKeySym keySym,rfbClientPtr cl) 126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(down) { 128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(keySym>' ' && keySym<0xff) { 129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i; 130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSelectData* m = (rfbSelectData*)cl->screen->screenData; 131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char c = tolower(keySym); 132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=m->selected+1;m->list[i] && tolower(m->list[i][0])!=c;i++); 134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!m->list[i]) 135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=0;i<m->selected && tolower(m->list[i][0])!=c;i++); 136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(m,i); 137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if(keySym==XK_Escape) { 138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSelectData* m = (rfbSelectData*)cl->screen->screenData; 139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->state = CANCEL; 140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if(keySym==XK_Return) { 141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSelectData* m = (rfbSelectData*)cl->screen->screenData; 142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->state = OK; 143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSelectData* m = (rfbSelectData*)cl->screen->screenData; 145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int curSel=m->selected; 146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(keySym==XK_Up) { 147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(curSel>0) 148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(m,curSel-1); 149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if(keySym==XK_Down) { 150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(curSel+1<m->listSize) 151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(m,curSel+1); 152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(keySym==XK_Page_Down) { 154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(curSel+m->pageH<m->listSize) 155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(m,curSel+m->pageH); 156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(m,m->listSize-1); 158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if(keySym==XK_Page_Up) { 159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(curSel-m->pageH>=0) 160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(m,curSel-m->pageH); 161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(m,0); 163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic void selPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl) 170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSelectData* m = (rfbSelectData*)cl->screen->screenData; 172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(y<m->okY && y>=m->okY-m->textH) { 173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(x>=m->okBX && x<m->okBX+m->buttonWidth) { 174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!m->okInverted) 175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selPaintButtons(m,TRUE,FALSE); 176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(buttonMask) 177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->state = OK; 178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if(x>=m->cancelBX && x<m->cancelBX+m->buttonWidth) { 179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!m->cancelInverted) 180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selPaintButtons(m,FALSE,TRUE); 181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(buttonMask) 182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->state = CANCEL; 183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else if(m->okInverted || m->cancelInverted) 184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selPaintButtons(m,FALSE,FALSE); 185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } else { 186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(m->okInverted || m->cancelInverted) 187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selPaintButtons(m,FALSE,FALSE); 188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(!m->lastButtons && buttonMask) { 189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(x>=m->x1 && x<m->x2 && y>=m->y1 && y<m->y2) 190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(m,m->displayStart+(y-m->y1)/m->textH); 191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat m->lastButtons = buttonMask; 194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* todo: scrollbars */ 196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatstatic rfbCursorPtr selGetCursorPtr(rfbClientPtr cl) 199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return NULL; 201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint rfbSelectBox(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font, 204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char** list, 205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int x1,int y1,int x2,int y2, 206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbPixel colour,rfbPixel backColour, 207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int border,SelectionChangedHookPtr selChangedHook) 208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int bpp = rfbScreen->bitsPerPixel/8; 210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat char* frameBufferBackup; 211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat void* screenDataBackup = rfbScreen->screenData; 212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbKbdAddEventProcPtr kbdAddEventBackup = rfbScreen->kbdAddEvent; 213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbPtrAddEventProcPtr ptrAddEventBackup = rfbScreen->ptrAddEvent; 214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbGetCursorProcPtr getCursorPtrBackup = rfbScreen->getCursorPtr; 215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbDisplayHookPtr displayHookBackup = rfbScreen->displayHook; 216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbSelectData selData; 217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int i,j,k; 218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int fx1,fy1,fx2,fy2; /* for font bbox */ 219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(list==0 || *list==0) 221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return(-1); 222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbWholeFontBBox(font, &fx1, &fy1, &fx2, &fy2); 224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.textH = fy2-fy1; 225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* I need at least one line for the choice and one for the buttons */ 226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(y2-y1<selData.textH*2+3*border) 227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return(-1); 228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.xhot = -fx1; 229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.yhot = -fy2; 230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.x1 = x1+border; 231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.y1 = y1+border; 232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.y2 = y2-selData.textH-3*border; 233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.x2 = x2-2*border; 234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.pageH = (selData.y2-selData.y1)/selData.textH; 235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat i = rfbWidthOfString(font,okStr); 237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat j = rfbWidthOfString(font,cancelStr); 2381d80c6a8d34f59543f7df1963c22d7efa292bcb0Greg Hartman selData.buttonWidth= k = 4*border+(i<j?j:i); 239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.okBX = x1+(x2-x1-2*k)/3; 240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(selData.okBX<x1+border) /* too narrow! */ 241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return(-1); 242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.cancelBX = x1+k+(x2-x1-2*k)*2/3; 243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.okX = selData.okBX+(k-i)/2; 244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.cancelX = selData.cancelBX+(k-j)/2; 245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.okY = y2-border; 246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat frameBufferBackup = (char*)malloc(bpp*(x2-x1)*(y2-y1)); 248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.state = SELECTING; 250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.screen = rfbScreen; 251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.font = font; 252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.list = list; 253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.colour = colour; 254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.backColour = backColour; 255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(i=0;list[i];i++); 256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.selected = i; 257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.listSize = i; 258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.displayStart = i; 259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.lastButtons = 0; 260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.selChangedHook = selChangedHook; 261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->screenData = &selData; 263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->kbdAddEvent = selKbdAddEvent; 264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->ptrAddEvent = selPtrAddEvent; 265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->getCursorPtr = selGetCursorPtr; 266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->displayHook = NULL; 267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* backup screen */ 269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(j=0;j<y2-y1;j++) 270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(frameBufferBackup+j*(x2-x1)*bpp, 271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->frameBuffer+j*rfbScreen->paddedWidthInBytes+x1*bpp, 272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (x2-x1)*bpp); 273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* paint list and buttons */ 275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbFillRect(rfbScreen,x1,y1,x2,y2,colour); 276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selPaintButtons(&selData,FALSE,FALSE); 277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selSelect(&selData,0); 278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* modal loop */ 280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while(selData.state == SELECTING) 281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbProcessEvents(rfbScreen,20000); 282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* copy back screen data */ 284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat for(j=0;j<y2-y1;j++) 285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat memcpy(rfbScreen->frameBuffer+j*rfbScreen->paddedWidthInBytes+x1*bpp, 286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat frameBufferBackup+j*(x2-x1)*bpp, 287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat (x2-x1)*bpp); 288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat free(frameBufferBackup); 289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbMarkRectAsModified(rfbScreen,x1,y1,x2,y2); 290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->screenData = screenDataBackup; 291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->kbdAddEvent = kbdAddEventBackup; 292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->ptrAddEvent = ptrAddEventBackup; 293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->getCursorPtr = getCursorPtrBackup; 294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbScreen->displayHook = displayHookBackup; 295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(selData.state==CANCEL) 297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat selData.selected=-1; 298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return(selData.selected); 299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 301