static rfbBool rfbInitConnection(rfbClient* client) { /* Unless we accepted an incoming connection, make a TCP connection to the given VNC server */ if (!client->listenSpecified) { if (!client->serverHost) return FALSE; if (client->destHost) { if (!ConnectToRFBRepeater(client,client->serverHost,client->serverPort,client->destHost,client->destPort)) return FALSE; } else { if (!ConnectToRFBServer(client,client->serverHost,client->serverPort)) return FALSE; } } /* Initialise the VNC connection, including reading the password */ if (!InitialiseRFBConnection(client)) return FALSE; client->width=client->si.framebufferWidth; client->height=client->si.framebufferHeight; if (!client->MallocFrameBuffer(client)) return FALSE; if (!SetFormatAndEncodings(client)) return FALSE; if (client->updateRect.x < 0) { client->updateRect.x = client->updateRect.y = 0; client->updateRect.w = client->width; client->updateRect.h = client->height; } if (client->appData.scaleSetting>1) { if (!SendScaleSetting(client, client->appData.scaleSetting)) return FALSE; if (!SendFramebufferUpdateRequest(client, client->updateRect.x / client->appData.scaleSetting, client->updateRect.y / client->appData.scaleSetting, client->updateRect.w / client->appData.scaleSetting, client->updateRect.h / client->appData.scaleSetting, FALSE)) return FALSE; } else { if (!SendFramebufferUpdateRequest(client, client->updateRect.x, client->updateRect.y, client->updateRect.w, client->updateRect.h, FALSE)) return FALSE; } return TRUE; }
//************************************************************************************************ // cMenu::Show() //************************************************************************************************ EMenuValue cMenu::Show(int rc_fd) { IMPORT_FRAMEBUFFER_VARS; STORE_PALETTE(&colormap); gl_fillbox(0, 0, p_xsize, p_ysize, TRANSP); Draw(); //ShowOsd(True); int rccode; while( 1 ) { cMenu::GetRCCode(rc_fd, rccode); if(!ProcessKey(rccode)) break; if (m_RetValue != eMVNone) break; } gl_fillbox(0, 0, p_xsize, p_ysize, TRANSP); STORE_PALETTE(NULL); SendFramebufferUpdateRequest(0, 0, p_xsize, p_ysize, False); return m_RetValue; }
Bool RequestNewUpdate() { if (!SendFramebufferUpdateRequest(appData.rectX, appData.rectY, appData.rectWidth, appData.rectHeight, True)) { return False; } return True; }
static rfbBool resize(rfbClient* cl) { if(cl->frameBuffer) free(cl->frameBuffer); cl->frameBuffer=(char*)malloc(cl->width*cl->height*cl->format.bitsPerPixel/8); if(!cl->frameBuffer) return FALSE; SendFramebufferUpdateRequest(cl,0,0,cl->width,cl->height,FALSE); return TRUE; }
Bool SendIncrementalFramebufferUpdateRequest() { return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, True); }
int main(int argc, char **argv) { #ifndef NANOX fd_set fds; struct timeval tv, *tvp; int msWait; #endif processArgs(argc, argv); if (listenSpecified) { #ifndef NANOX listenForIncomingConnections(); /* returns only with a succesful connection */ #endif } else { if (!ConnectToRFBServer(hostname, port)) exit(1); } if (!InitialiseRFBConnection(rfbsock)) exit(1); if (!CreateXWindow()) exit(1); if (!SetFormatAndEncodings()) { ShutdownX(); exit(1); } if (!SendFramebufferUpdateRequest(updateRequestX, updateRequestY, updateRequestW, updateRequestH, False)) { ShutdownX(); exit(1); } printf("nanox fd = %d, rfbsock = %d\n", ConnectionNumber(dpy), rfbsock); #ifdef NANOX /* register the RFB socket */ GrRegisterInput(rfbsock); /* call the nanox main loop to wait for all events */ while (True) { GrMainLoop(HandleEvents); } #else while (True) { /* * Always handle all X events before doing select. This is the * simplest way of ensuring that we don't block in select while * Xlib has some events on its queue. */ if (!HandleXEvents()) { ShutdownX(); exit(1); } tvp = NULL; if (sendUpdateRequest) { gettimeofday(&tv, NULL); msWait = (updateRequestPeriodms + ((updateRequestTime.tv_sec - tv.tv_sec) * 1000) + ((updateRequestTime.tv_usec - tv.tv_usec) / 1000)); if (msWait > 0) { tv.tv_sec = msWait / 1000; tv.tv_usec = (msWait % 1000) * 1000; tvp = &tv; } else { if (!SendIncrementalFramebufferUpdateRequest()) { ShutdownX(); exit(1); } } } FD_ZERO(&fds); FD_SET(ConnectionNumber(dpy),&fds); FD_SET(rfbsock,&fds); if (select(FD_SETSIZE, &fds, NULL, NULL, tvp) < 0) { perror("select"); ShutdownX(); exit(1); } if (FD_ISSET(rfbsock, &fds)) { if (!HandleRFBServerMessage()) { ShutdownX(); exit(1); } } } #endif /* NANOX */ return 0; }
static void request_screen_refresh (GtkMenuItem *menuitem, gpointer user_data) { SendFramebufferUpdateRequest (cl, 0, 0, cl->width, cl->height, FALSE); }
static rfbBool handleSDLEvent(rfbClient *cl, SDL_Event *e) { rfbKeySym rfbkey; switch(e->type) { case SDL_WINDOWEVENT: switch (e->window.event) { case SDL_WINDOWEVENT_EXPOSED: SendFramebufferUpdateRequest(cl, 0, 0, cl->width, cl->height, FALSE); break; default: break; } break; case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEMOTION: { int x, y, state, i; if (viewOnly) break; if (e->type == SDL_MOUSEMOTION) { x = e->motion.x; y = e->motion.y; state = e->motion.state; } else { x = e->button.x; y = e->button.y; state = e->button.button; } if (e->type == SDL_MOUSEBUTTONDOWN) buttonMask |= SDL_BUTTON(state); if (e->type == SDL_MOUSEBUTTONUP) buttonMask &= ~SDL_BUTTON(state); SendPointerEvent(cl, x, y, buttonMask); break; } case SDL_MOUSEWHEEL: // mouse coords need to be sent along with button presses int x, y; SDL_GetMouseState(&x, &y); if (e->wheel.y == 1) { buttonMask |= SDL_BUTTON(SDL_BUTTON_X1); SendPointerEvent(cl, x, y, buttonMask); buttonMask &= ~SDL_BUTTON(SDL_BUTTON_X1); SendPointerEvent(cl, x, y, buttonMask); } if (e->wheel.y == -1) { buttonMask |= SDL_BUTTON(SDL_BUTTON_X2); SendPointerEvent(cl, x, y, buttonMask); buttonMask &= ~SDL_BUTTON(SDL_BUTTON_X2); SendPointerEvent(cl, x, y, buttonMask); } break; case SDL_KEYDOWN: if (viewOnly) break; rfbkey = SDL_key2rfbKeySym(&e->key); if (rfbkey > 0) { SendKeyEvent(cl, rfbkey, TRUE); } else { symDown = e->key.keysym.sym; } break; case SDL_KEYUP: if (viewOnly) break; rfbkey = SDL_key2rfbKeySym(&e->key); if (rfbkey > 0) { SendKeyEvent(cl, rfbkey, FALSE); } else { SDL_Keycode sym = e->key.keysym.sym; if (keysDown.find(sym) != keysDown.end()) { SendKeyEvent(cl, keysDown[sym], FALSE); keysDown.erase(sym); } } break; case SDL_TEXTINPUT: keysDown[symDown] = e->text.text[0]; symDown = 0; SendKeyEvent(cl, e->text.text[0], TRUE); break; case SDL_QUIT: if(listenLoop) { cleanup(cl); Quit_DRC(); return FALSE; } else { rfbClientCleanup(cl); exit(0); } default: rfbClientLog("ignore SDL event: 0x%x\n", e->type); } return TRUE; }
inline Bool HandleRFBServerMessage() { rfbServerToClientMsg msg; if(!ReadExact(rfbsock, (char *)&msg, 1)) return False; dprintf("HandleRFBServerMessage %d\n",msg.type); switch(msg.type) { case rfbSetColourMapEntries: { dprintf("rfbSetColourMapEntries\n"); int i; CARD16 rgb[3]; XColor xc; if(!ReadExact(rfbsock, ((char *)&msg.scme) + 1, sz_rfbSetColourMapEntriesMsg - 1)) return False; msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); msg.scme.nColours = Swap16IfLE(msg.scme.nColours); INIT_PALETTE(msg.scme.nColours); for(i = 0; i < msg.scme.nColours; i++) { xc.pixel = msg.scme.firstColour + i; if(addUseAlpha) { if(!ReadExact(rfbsock, (char *)rgb, 8)) return False; xc.transp = ((double)(0xff - (Swap16IfLE(rgb[0]) >> 8))) / ((double)0xff / (double)0xA0); xc.red = Swap16IfLE(rgb[1]) >> 8; xc.green = Swap16IfLE(rgb[2]) >> 8; xc.blue = Swap16IfLE(rgb[3]) >> 8; } else { if(!ReadExact(rfbsock, (char *)rgb, 6)) return False; xc.transp = 0; xc.red = Swap16IfLE(rgb[0]) >> 8; xc.green = Swap16IfLE(rgb[1]) >> 8; xc.blue = Swap16IfLE(rgb[2]) >> 8; } xc.flags = DoRed|DoGreen|DoBlue; INSERT_COLOUR (xc); } STORE_PALETTE(NULL); break; } case rfbFramebufferUpdate: { dprintf("rfbFramebufferUpdate\n"); //ShowOsd(True); rfbFramebufferUpdateRectHeader rect; int linesToRead; int bytesPerLine; int i; if(!ReadExact(rfbsock, ((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1)) return False; msg.fu.nRects = Swap16IfLE(msg.fu.nRects); dprintf("# Rect %d\n",msg.fu.nRects); for(i = 0; i < msg.fu.nRects; i++) { if(!ReadExact(rfbsock, (char *)&rect, sz_rfbFramebufferUpdateRectHeader)) return False; rect.r.x = Swap16IfLE(rect.r.x); rect.r.y = Swap16IfLE(rect.r.y); rect.r.w = Swap16IfLE(rect.r.w); rect.r.h = Swap16IfLE(rect.r.h); rect.encoding = Swap32IfLE(rect.encoding); dprintf("Rect x/y/w/h %d/%d/%d/%d %u\n",rect.r.x,rect.r.y,rect.r.w,rect.r.h, (uint)rect.encoding); if((rect.r.x + rect.r.w > si.framebufferWidth) || (rect.r.y + rect.r.h > si.framebufferHeight)) { fprintf(stderr,"%s: rect too large: %dx%d at (%d, %d)\n", programName, rect.r.w, rect.r.h, rect.r.x, rect.r.y); return False; } if((rect.r.h * rect.r.w) == 0) { fprintf(stderr,"%s: zero size rect - ignoring\n",programName); continue; } switch(rect.encoding) { case rfbEncodingRaw: bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8; linesToRead = BUFFER_SIZE / bytesPerLine; while(rect.r.h > 0) { if(linesToRead > rect.r.h) linesToRead = rect.r.h; if(!ReadExact(rfbsock, buffer,bytesPerLine * linesToRead)) return False; CopyDataToScreen((CARD8 *)buffer, rect.r.x, rect.r.y, rect.r.w, linesToRead); rect.r.h -= linesToRead; rect.r.y += linesToRead; } break; case rfbEncodingCopyRect: { dprintf("rfbEncodingCopyRect\n"); rfbCopyRect cr; if(!ReadExact(rfbsock, (char *)&cr, sz_rfbCopyRect)) return False; cr.srcX = Swap16IfLE(cr.srcX); cr.srcY = Swap16IfLE(cr.srcY); COPY_AREA (cr.srcX, cr.srcY, rect.r.w, rect.r.h, rect.r.x, rect.r.y); break; } case rfbEncodingRRE: { dprintf("RRE\n"); rfbRREHeader hdr; CARD8 pix8; CARD16 pix16; CARD32 pix32; rfbRectangle subrect; int j; int dataSize; char *netbuff; char *p; if(!ReadExact(rfbsock, (char *)&hdr, sz_rfbRREHeader)) return False; hdr.nSubrects = Swap32IfLE(hdr.nSubrects); switch(myFormat.bitsPerPixel) { case 8: if(!ReadExact(rfbsock, (char *)&pix8, 1)) return False; FILL_RECTNOREDRAW (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix8); dataSize = (sizeof(pix8) + sz_rfbRectangle) * hdr.nSubrects; netbuff = malloc(dataSize + 256); if(!ReadExact(rfbsock, netbuff, dataSize)) return False; p = netbuff; for(j = 0; j < hdr.nSubrects; j++) { memcpy((char*)&pix8, p, sizeof(pix8)); p += sizeof(pix8); memcpy((char*)&subrect, p, sz_rfbRectangle); p += sz_rfbRectangle; subrect.x = Swap16IfLE(subrect.x); subrect.y = Swap16IfLE(subrect.y); subrect.w = Swap16IfLE(subrect.w); subrect.h = Swap16IfLE(subrect.h); FILL_RECTNOREDRAW (rect.r.x + subrect.x, rect.r.y + subrect.y, subrect.w, subrect.h, pix8); } free(netbuff); REDRAWBOX(rect.r.x, rect.r.y, rect.r.w, rect.r.h); break; case 16: if(!ReadExact(rfbsock, (char *)&pix16, 2)) return False; FILL_RECTNOREDRAW (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix16); dataSize = (sizeof(pix16) + sz_rfbRectangle) * hdr.nSubrects; netbuff = malloc(dataSize + 256); if(!ReadExact(rfbsock, netbuff, dataSize)) return False; p = netbuff; for(j = 0; j < hdr.nSubrects; j++) { memcpy((char*)&pix16, p, sizeof(pix16)); p += sizeof(pix16); memcpy((char*)&subrect, p, sz_rfbRectangle); p += sz_rfbRectangle; subrect.x = Swap16IfLE(subrect.x); subrect.y = Swap16IfLE(subrect.y); subrect.w = Swap16IfLE(subrect.w); subrect.h = Swap16IfLE(subrect.h); FILL_RECTNOREDRAW (rect.r.x + subrect.x, rect.r.y + subrect.y, subrect.w, subrect.h, pix16); } free(netbuff); REDRAWBOX(rect.r.x, rect.r.y, rect.r.w, rect.r.h); break; case 32: if(!ReadExact(rfbsock, (char *)&pix32, 4)) return False; FILL_RECTNOREDRAW (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix32); dataSize = (sizeof(pix32) + sz_rfbRectangle) * hdr.nSubrects; netbuff = malloc(dataSize + 256); if(!ReadExact(rfbsock, netbuff, dataSize)) return False; p = netbuff; for(j = 0; j < hdr.nSubrects; j++) { memcpy((char*)&pix32, p, sizeof(pix32)); p += sizeof(pix32); memcpy((char*)&subrect, p, sz_rfbRectangle); p += sz_rfbRectangle; subrect.x = Swap16IfLE(subrect.x); subrect.y = Swap16IfLE(subrect.y); subrect.w = Swap16IfLE(subrect.w); subrect.h = Swap16IfLE(subrect.h); FILL_RECTNOREDRAW (rect.r.x + subrect.x, rect.r.y + subrect.y, subrect.w, subrect.h, pix32); } free(netbuff); REDRAWBOX(rect.r.x, rect.r.y, rect.r.w, rect.r.h); break; } break; } case rfbEncodingCoRRE: { dprintf("rfbEncodingCoRRE\n"); rfbRREHeader hdr; CARD8 pix8; CARD16 pix16; CARD32 pix32; int j; CARD8 *ptr; register int x, y, w, h; if(!ReadExact(rfbsock, (char *)&hdr, sz_rfbRREHeader)) return False; hdr.nSubrects = Swap32IfLE(hdr.nSubrects); switch(myFormat.bitsPerPixel) { case 8: if(!ReadExact(rfbsock, (char *)&pix8, 1)) return False; FILL_RECT (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix8); if(!ReadExact(rfbsock, buffer, hdr.nSubrects * 5)) return False; ptr = (CARD8 *)buffer; for(j = 0; j < hdr.nSubrects; j++) { pix8 = *ptr++; x = *ptr++; y = *ptr++; w = *ptr++; h = *ptr++; FILL_RECT (rect.r.x + x, rect.r.y + y, w, h, pix8); } break; case 16: if(!ReadExact(rfbsock, (char *)&pix16, 2)) return False; FILL_RECT (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix16); if(!ReadExact(rfbsock, buffer, hdr.nSubrects * 6)) return False; ptr = (CARD8 *)buffer; for(j = 0; j < hdr.nSubrects; j++) { pix16 = *(CARD16 *)ptr; ptr += 2; x = *ptr++; y = *ptr++; w = *ptr++; h = *ptr++; FILL_RECT (rect.r.x + x, rect.r.y + y, w, h, pix16); } break; case 32: if(!ReadExact(rfbsock, (char *)&pix32, 4)) return False; FILL_RECT (rect.r.x, rect.r.y, rect.r.w, rect.r.h, pix32); if(!ReadExact(rfbsock, buffer, hdr.nSubrects * 8)) return False; ptr = (CARD8 *)buffer; for(j = 0; j < hdr.nSubrects; j++) { pix32 = *(CARD32 *)ptr; ptr += 4; x = *ptr++; y = *ptr++; w = *ptr++; h = *ptr++; FILL_RECT (rect.r.x + x, rect.r.y + y, w, h, pix32); } break; } break; } case rfbEncodingHextile: { dprintf("Hextile\n"); switch(myFormat.bitsPerPixel) { case 8: if(!HandleHextileEncoding8(rect.r.x, rect.r.y, rect.r.w, rect.r.h)) return False; break; case 16: if(!HandleHextileEncoding16(rect.r.x, rect.r.y, rect.r.w, rect.r.h)) return False; break; case 32: if(!HandleHextileEncoding32(rect.r.x, rect.r.y, rect.r.w, rect.r.h)) return False; break; } break; } default: printf("vnc: unknown rect encoding %u\n",(uint)rect.encoding); return False; } } //sendUpdateRequest = True; break; } case rfbBell: BELL; //ShowOsd(False); break; case rfbServerCutText: { char *str; if(!ReadExact(rfbsock, ((char *)&msg.sct) + 1, sz_rfbServerCutTextMsg - 1)) return False; msg.sct.length = Swap32IfLE(msg.sct.length); str = malloc(msg.sct.length); if(!ReadExact(rfbsock, str, msg.sct.length)) { free(str); return False; } /* XSelectInput(dpy, DefaultRootWindow(dpy), 0); XStoreBytes(dpy, str, msg.sct.length); XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime); XSelectInput(dpy, DefaultRootWindow(dpy), PropertyChangeMask); */ free(str); break; } case rfbReSizeFrameBuffer: { if(!ReadExact(rfbsock, ((char *)&msg.rsfb) + 1, sz_rfbReSizeFrameBufferMsg - 1)) return False; dprintf("rfbReSizeFrameBuffer: %d/%d | %d/%d\n",msg.rsfb.buffer_w,msg.rsfb.buffer_h,msg.rsfb.desktop_w,msg.rsfb.desktop_h); si.framebufferWidth = Swap16IfLE(msg.rsfb.buffer_w); si.framebufferHeight = Swap16IfLE(msg.rsfb.buffer_h); FILL_RECT(0, 0, si.framebufferWidth, si.framebufferHeight, 0); if(!SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False)) return False; } break; default: printf("%s: unknown message type %d from VNC server\n", programName,msg.type); return False; }