vncserver.cc (11793:ef606668d247) vncserver.cc (12020:9f290c45493f)
1/*
2 * Copyright (c) 2010, 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 184 unchanged lines hidden (view full) ---

193 // have been called from a different thread. Migrate to "our"
194 // thread.
195 EventQueue::ScopedMigration migrate(eventQueue());
196
197 if (!listener.islistening())
198 panic("%s: cannot accept a connection if not listening!", name());
199
200 int fd = listener.accept(true);
1/*
2 * Copyright (c) 2010, 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 184 unchanged lines hidden (view full) ---

193 // have been called from a different thread. Migrate to "our"
194 // thread.
195 EventQueue::ScopedMigration migrate(eventQueue());
196
197 if (!listener.islistening())
198 panic("%s: cannot accept a connection if not listening!", name());
199
200 int fd = listener.accept(true);
201 fatal_if(fd < 0, "%s: failed to accept VNC connection!", name());
201 if (fd < 0) {
202 warn("%s: failed to accept VNC connection!", name());
203 return;
204 }
202
203 if (dataFd != -1) {
204 char message[] = "vnc server already attached!\n";
205 atomic_write(fd, message, sizeof(message));
206 ::close(fd);
207 return;
208 }
209
210 dataFd = fd;
211
212 // Send our version number to the client
205
206 if (dataFd != -1) {
207 char message[] = "vnc server already attached!\n";
208 atomic_write(fd, message, sizeof(message));
209 ::close(fd);
210 return;
211 }
212
213 dataFd = fd;
214
215 // Send our version number to the client
213 write((uint8_t*)vncVersion(), strlen(vncVersion()));
216 write((uint8_t *)vncVersion(), strlen(vncVersion()));
214
215 // read the client response
216 dataEvent = new DataEvent(this, dataFd, POLLIN);
217 pollQueue.schedule(dataEvent);
218
219 inform("VNC client attached\n");
220}
221
222// data called by data event
223void
224VncServer::data()
225{
226 // We have new data, see if we can handle it
217
218 // read the client response
219 dataEvent = new DataEvent(this, dataFd, POLLIN);
220 pollQueue.schedule(dataEvent);
221
222 inform("VNC client attached\n");
223}
224
225// data called by data event
226void
227VncServer::data()
228{
229 // We have new data, see if we can handle it
227 size_t len;
228 DPRINTF(VNC, "Vnc client message recieved\n");
229
230 switch (curState) {
231 case WaitForProtocolVersion:
232 checkProtocolVersion();
233 break;
234 case WaitForSecurityResponse:
235 checkSecurity();
236 break;
237 case WaitForClientInit:
238 // Don't care about shared, just need to read it out of the socket
239 uint8_t shared;
230 DPRINTF(VNC, "Vnc client message recieved\n");
231
232 switch (curState) {
233 case WaitForProtocolVersion:
234 checkProtocolVersion();
235 break;
236 case WaitForSecurityResponse:
237 checkSecurity();
238 break;
239 case WaitForClientInit:
240 // Don't care about shared, just need to read it out of the socket
241 uint8_t shared;
240 len = read(&shared);
241 assert(len == 1);
242 if (!read(&shared))
243 return;
242
243 // Send our idea of the frame buffer
244 sendServerInit();
245
246 break;
247 case NormalPhase:
248 uint8_t message_type;
244
245 // Send our idea of the frame buffer
246 sendServerInit();
247
248 break;
249 case NormalPhase:
250 uint8_t message_type;
249 len = read(&message_type);
250 if (!len) {
251 detach();
251 if (!read(&message_type))
252 return;
252 return;
253 }
254 assert(len == 1);
255
256 switch (message_type) {
257 case ClientSetPixelFormat:
258 setPixelFormat();
259 break;
260 case ClientSetEncodings:
261 setEncodings();
262 break;

--- 5 unchanged lines hidden (view full) ---

268 break;
269 case ClientPointerEvent:
270 recvPointerInput();
271 break;
272 case ClientCutText:
273 recvCutText();
274 break;
275 default:
253
254 switch (message_type) {
255 case ClientSetPixelFormat:
256 setPixelFormat();
257 break;
258 case ClientSetEncodings:
259 setEncodings();
260 break;

--- 5 unchanged lines hidden (view full) ---

266 break;
267 case ClientPointerEvent:
268 recvPointerInput();
269 break;
270 case ClientCutText:
271 recvCutText();
272 break;
273 default:
276 panic("Unimplemented message type recv from client: %d\n",
277 message_type);
274 warn("Unimplemented message type recv from client: %d\n",
275 message_type);
276 detach();
278 break;
279 }
280 break;
281 default:
282 panic("Unknown vnc server state\n");
283 }
284}
285
286
287// read from socket
277 break;
278 }
279 break;
280 default:
281 panic("Unknown vnc server state\n");
282 }
283}
284
285
286// read from socket
288size_t
287bool
289VncServer::read(uint8_t *buf, size_t len)
290{
291 if (dataFd < 0)
292 panic("vnc not properly attached.\n");
293
294 size_t ret;
295 do {
296 ret = ::read(dataFd, buf, len);
297 } while (ret == -1 && errno == EINTR);
298
299
288VncServer::read(uint8_t *buf, size_t len)
289{
290 if (dataFd < 0)
291 panic("vnc not properly attached.\n");
292
293 size_t ret;
294 do {
295 ret = ::read(dataFd, buf, len);
296 } while (ret == -1 && errno == EINTR);
297
298
300 if (ret <= 0){
301 DPRINTF(VNC, "Read failed.\n");
299 if (ret != len) {
300 DPRINTF(VNC, "Read failed %d.\n", ret);
302 detach();
301 detach();
303 return 0;
302 return false;
304 }
305
303 }
304
306 return ret;
305 return true;
307}
308
306}
307
309size_t
308bool
310VncServer::read1(uint8_t *buf, size_t len)
311{
309VncServer::read1(uint8_t *buf, size_t len)
310{
312 size_t read_len M5_VAR_USED;
313 read_len = read(buf + 1, len - 1);
314 assert(read_len == len - 1);
315 return read_len;
311 return read(buf + 1, len - 1);
316}
317
318
319template<typename T>
312}
313
314
315template<typename T>
320size_t
316bool
321VncServer::read(T* val)
322{
317VncServer::read(T* val)
318{
323 return read((uint8_t*)val, sizeof(T));
319 return read((uint8_t *)val, sizeof(T));
324}
325
326// write to socket
320}
321
322// write to socket
327size_t
323bool
328VncServer::write(const uint8_t *buf, size_t len)
329{
330 if (dataFd < 0)
331 panic("Vnc client not properly attached.\n");
332
324VncServer::write(const uint8_t *buf, size_t len)
325{
326 if (dataFd < 0)
327 panic("Vnc client not properly attached.\n");
328
333 ssize_t ret;
334 ret = atomic_write(dataFd, buf, len);
329 ssize_t ret = atomic_write(dataFd, buf, len);
335
330
336 if (ret < len)
331 if (ret != len) {
332 DPRINTF(VNC, "Write failed.\n");
337 detach();
333 detach();
334 return false;
335 }
338
336
339 return ret;
337 return true;
340}
341
342template<typename T>
338}
339
340template<typename T>
343size_t
341bool
344VncServer::write(T* val)
345{
342VncServer::write(T* val)
343{
346 return write((uint8_t*)val, sizeof(T));
344 return write((uint8_t *)val, sizeof(T));
347}
348
345}
346
349size_t
347bool
350VncServer::write(const char* str)
351{
348VncServer::write(const char* str)
349{
352 return write((uint8_t*)str, strlen(str));
350 return write((uint8_t *)str, strlen(str));
353}
354
355// detach a vnc client
356void
357VncServer::detach()
358{
359 if (dataFd != -1) {
360 ::close(dataFd);

--- 11 unchanged lines hidden (view full) ---

372 inform("VNC client detached\n");
373 DPRINTF(VNC, "detach vnc client %d\n", number);
374}
375
376void
377VncServer::sendError(const char* error_msg)
378{
379 uint32_t len = strlen(error_msg);
351}
352
353// detach a vnc client
354void
355VncServer::detach()
356{
357 if (dataFd != -1) {
358 ::close(dataFd);

--- 11 unchanged lines hidden (view full) ---

370 inform("VNC client detached\n");
371 DPRINTF(VNC, "detach vnc client %d\n", number);
372}
373
374void
375VncServer::sendError(const char* error_msg)
376{
377 uint32_t len = strlen(error_msg);
380 write(&len);
378 if (!write(&len))
379 return;
381 write(error_msg);
382}
383
384void
385VncServer::checkProtocolVersion()
386{
387 assert(curState == WaitForProtocolVersion);
388
389 size_t len M5_VAR_USED;
390 char version_string[13];
391
392 // Null terminate the message so it's easier to work with
393 version_string[12] = 0;
394
380 write(error_msg);
381}
382
383void
384VncServer::checkProtocolVersion()
385{
386 assert(curState == WaitForProtocolVersion);
387
388 size_t len M5_VAR_USED;
389 char version_string[13];
390
391 // Null terminate the message so it's easier to work with
392 version_string[12] = 0;
393
395 len = read((uint8_t*)version_string, 12);
396 assert(len == 12);
394 if (!read((uint8_t *)version_string, sizeof(version_string) - 1)) {
395 warn("Failed to read protocol version.");
396 return;
397 }
397
398 uint32_t major, minor;
399
400 // Figure out the major/minor numbers
401 if (sscanf(version_string, "RFB %03d.%03d\n", &major, &minor) != 2) {
402 warn(" Malformed protocol version %s\n", version_string);
403 sendError("Malformed protocol version\n");
404 detach();
398
399 uint32_t major, minor;
400
401 // Figure out the major/minor numbers
402 if (sscanf(version_string, "RFB %03d.%03d\n", &major, &minor) != 2) {
403 warn(" Malformed protocol version %s\n", version_string);
404 sendError("Malformed protocol version\n");
405 detach();
406 return;
405 }
406
407 DPRINTF(VNC, "Client request protocol version %d.%d\n", major, minor);
408
409 // If it's not 3.X we don't support it
410 if (major != 3 || minor < 2) {
411 warn("Unsupported VNC client version... disconnecting\n");
412 uint8_t err = AuthInvalid;
413 write(&err);
414 detach();
407 }
408
409 DPRINTF(VNC, "Client request protocol version %d.%d\n", major, minor);
410
411 // If it's not 3.X we don't support it
412 if (major != 3 || minor < 2) {
413 warn("Unsupported VNC client version... disconnecting\n");
414 uint8_t err = AuthInvalid;
415 write(&err);
416 detach();
417 return;
415 }
416 // Auth is different based on version number
417 if (minor < 7) {
418 uint32_t sec_type = htobe((uint32_t)AuthNone);
418 }
419 // Auth is different based on version number
420 if (minor < 7) {
421 uint32_t sec_type = htobe((uint32_t)AuthNone);
419 write(&sec_type);
422 if (!write(&sec_type))
423 return;
420 } else {
421 uint8_t sec_cnt = 1;
422 uint8_t sec_type = htobe((uint8_t)AuthNone);
424 } else {
425 uint8_t sec_cnt = 1;
426 uint8_t sec_type = htobe((uint8_t)AuthNone);
423 write(&sec_cnt);
424 write(&sec_type);
427 if (!write(&sec_cnt) || !write(&sec_type))
428 return;
425 }
426
427 // Wait for client to respond
428 curState = WaitForSecurityResponse;
429}
430
431void
432VncServer::checkSecurity()
433{
434 assert(curState == WaitForSecurityResponse);
435
436 uint8_t security_type;
429 }
430
431 // Wait for client to respond
432 curState = WaitForSecurityResponse;
433}
434
435void
436VncServer::checkSecurity()
437{
438 assert(curState == WaitForSecurityResponse);
439
440 uint8_t security_type;
437 size_t len M5_VAR_USED = read(&security_type);
441 if (!read(&security_type))
442 return;
438
443
439 assert(len == 1);
440
441 if (security_type != AuthNone) {
442 warn("Unknown VNC security type\n");
443 sendError("Unknown security type\n");
444 }
445
446 DPRINTF(VNC, "Sending security auth OK\n");
447
448 uint32_t success = htobe(VncOK);
444 if (security_type != AuthNone) {
445 warn("Unknown VNC security type\n");
446 sendError("Unknown security type\n");
447 }
448
449 DPRINTF(VNC, "Sending security auth OK\n");
450
451 uint32_t success = htobe(VncOK);
449 write(&success);
452 if (!write(&success))
453 return;
450 curState = WaitForClientInit;
451}
452
453void
454VncServer::sendServerInit()
455{
456 ServerInitMsg msg;
457

--- 12 unchanged lines hidden (view full) ---

470 msg.px.redshift = htobe(pixelFormat.redshift);
471 msg.px.greenshift = htobe(pixelFormat.greenshift);
472 msg.px.blueshift = htobe(pixelFormat.blueshift);
473 memset(msg.px.padding, 0, 3);
474 msg.namelen = 2;
475 msg.namelen = htobe(msg.namelen);
476 memcpy(msg.name, "M5", 2);
477
454 curState = WaitForClientInit;
455}
456
457void
458VncServer::sendServerInit()
459{
460 ServerInitMsg msg;
461

--- 12 unchanged lines hidden (view full) ---

474 msg.px.redshift = htobe(pixelFormat.redshift);
475 msg.px.greenshift = htobe(pixelFormat.greenshift);
476 msg.px.blueshift = htobe(pixelFormat.blueshift);
477 memset(msg.px.padding, 0, 3);
478 msg.namelen = 2;
479 msg.namelen = htobe(msg.namelen);
480 memcpy(msg.name, "M5", 2);
481
478 write(&msg);
482 if (!write(&msg))
483 return;
479 curState = NormalPhase;
480}
481
482void
483VncServer::setPixelFormat()
484{
485 DPRINTF(VNC, "Received pixel format from client message\n");
486
487 PixelFormatMessage pfm;
484 curState = NormalPhase;
485}
486
487void
488VncServer::setPixelFormat()
489{
490 DPRINTF(VNC, "Received pixel format from client message\n");
491
492 PixelFormatMessage pfm;
488 read1((uint8_t*)&pfm, sizeof(PixelFormatMessage));
493 if (!read1((uint8_t *)&pfm, sizeof(PixelFormatMessage)))
494 return;
489
490 DPRINTF(VNC, " -- bpp = %d; depth = %d; be = %d\n", pfm.px.bpp,
491 pfm.px.depth, pfm.px.bigendian);
492 DPRINTF(VNC, " -- true color = %d red,green,blue max = %d,%d,%d\n",
493 pfm.px.truecolor, betoh(pfm.px.redmax), betoh(pfm.px.greenmax),
494 betoh(pfm.px.bluemax));
495 DPRINTF(VNC, " -- red,green,blue shift = %d,%d,%d\n", pfm.px.redshift,
496 pfm.px.greenshift, pfm.px.blueshift);
497
498 if (betoh(pfm.px.bpp) != pixelFormat.bpp ||
499 betoh(pfm.px.depth) != pixelFormat.depth ||
500 betoh(pfm.px.bigendian) != pixelFormat.bigendian ||
501 betoh(pfm.px.truecolor) != pixelFormat.truecolor ||
502 betoh(pfm.px.redmax) != pixelFormat.redmax ||
503 betoh(pfm.px.greenmax) != pixelFormat.greenmax ||
504 betoh(pfm.px.bluemax) != pixelFormat.bluemax ||
505 betoh(pfm.px.redshift) != pixelFormat.redshift ||
506 betoh(pfm.px.greenshift) != pixelFormat.greenshift ||
495
496 DPRINTF(VNC, " -- bpp = %d; depth = %d; be = %d\n", pfm.px.bpp,
497 pfm.px.depth, pfm.px.bigendian);
498 DPRINTF(VNC, " -- true color = %d red,green,blue max = %d,%d,%d\n",
499 pfm.px.truecolor, betoh(pfm.px.redmax), betoh(pfm.px.greenmax),
500 betoh(pfm.px.bluemax));
501 DPRINTF(VNC, " -- red,green,blue shift = %d,%d,%d\n", pfm.px.redshift,
502 pfm.px.greenshift, pfm.px.blueshift);
503
504 if (betoh(pfm.px.bpp) != pixelFormat.bpp ||
505 betoh(pfm.px.depth) != pixelFormat.depth ||
506 betoh(pfm.px.bigendian) != pixelFormat.bigendian ||
507 betoh(pfm.px.truecolor) != pixelFormat.truecolor ||
508 betoh(pfm.px.redmax) != pixelFormat.redmax ||
509 betoh(pfm.px.greenmax) != pixelFormat.greenmax ||
510 betoh(pfm.px.bluemax) != pixelFormat.bluemax ||
511 betoh(pfm.px.redshift) != pixelFormat.redshift ||
512 betoh(pfm.px.greenshift) != pixelFormat.greenshift ||
507 betoh(pfm.px.blueshift) != pixelFormat.blueshift)
508 fatal("VNC client doesn't support true color raw encoding\n");
513 betoh(pfm.px.blueshift) != pixelFormat.blueshift) {
514 warn("VNC client doesn't support true color raw encoding\n");
515 detach();
516 }
509}
510
511void
512VncServer::setEncodings()
513{
514 DPRINTF(VNC, "Received supported encodings from client\n");
515
516 PixelEncodingsMessage pem;
517}
518
519void
520VncServer::setEncodings()
521{
522 DPRINTF(VNC, "Received supported encodings from client\n");
523
524 PixelEncodingsMessage pem;
517 read1((uint8_t*)&pem, sizeof(PixelEncodingsMessage));
525 if (!read1((uint8_t *)&pem, sizeof(PixelEncodingsMessage)))
526 return;
518
519 pem.num_encodings = betoh(pem.num_encodings);
520
521 DPRINTF(VNC, " -- %d encoding present\n", pem.num_encodings);
522 supportsRawEnc = supportsResizeEnc = false;
523
524 for (int x = 0; x < pem.num_encodings; x++) {
525 int32_t encoding;
527
528 pem.num_encodings = betoh(pem.num_encodings);
529
530 DPRINTF(VNC, " -- %d encoding present\n", pem.num_encodings);
531 supportsRawEnc = supportsResizeEnc = false;
532
533 for (int x = 0; x < pem.num_encodings; x++) {
534 int32_t encoding;
526 size_t len M5_VAR_USED;
527 len = read(&encoding);
528 assert(len == sizeof(encoding));
535 if (!read(&encoding))
536 return;
529 DPRINTF(VNC, " -- supports %d\n", betoh(encoding));
530
531 switch (betoh(encoding)) {
532 case EncodingRaw:
533 supportsRawEnc = true;
534 break;
535 case EncodingDesktopSize:
536 supportsResizeEnc = true;
537 break;
538 }
539 }
540
537 DPRINTF(VNC, " -- supports %d\n", betoh(encoding));
538
539 switch (betoh(encoding)) {
540 case EncodingRaw:
541 supportsRawEnc = true;
542 break;
543 case EncodingDesktopSize:
544 supportsResizeEnc = true;
545 break;
546 }
547 }
548
541 if (!supportsRawEnc)
542 fatal("VNC clients must always support raw encoding\n");
549 if (!supportsRawEnc) {
550 warn("VNC clients must always support raw encoding\n");
551 detach();
552 }
543}
544
545void
546VncServer::requestFbUpdate()
547{
548 DPRINTF(VNC, "Received frame buffer update request from client\n");
549
550 FrameBufferUpdateReq fbr;
553}
554
555void
556VncServer::requestFbUpdate()
557{
558 DPRINTF(VNC, "Received frame buffer update request from client\n");
559
560 FrameBufferUpdateReq fbr;
551 read1((uint8_t*)&fbr, sizeof(FrameBufferUpdateReq));
561 if (!read1((uint8_t *)&fbr, sizeof(FrameBufferUpdateReq)))
562 return;
552
553 fbr.x = betoh(fbr.x);
554 fbr.y = betoh(fbr.y);
555 fbr.width = betoh(fbr.width);
556 fbr.height = betoh(fbr.height);
557
558 DPRINTF(VNC, " -- x = %d y = %d w = %d h = %d\n", fbr.x, fbr.y, fbr.width,
559 fbr.height);
560
561 sendFrameBufferUpdate();
562}
563
564void
565VncServer::recvKeyboardInput()
566{
567 DPRINTF(VNC, "Received keyboard input from client\n");
568 KeyEventMessage kem;
563
564 fbr.x = betoh(fbr.x);
565 fbr.y = betoh(fbr.y);
566 fbr.width = betoh(fbr.width);
567 fbr.height = betoh(fbr.height);
568
569 DPRINTF(VNC, " -- x = %d y = %d w = %d h = %d\n", fbr.x, fbr.y, fbr.width,
570 fbr.height);
571
572 sendFrameBufferUpdate();
573}
574
575void
576VncServer::recvKeyboardInput()
577{
578 DPRINTF(VNC, "Received keyboard input from client\n");
579 KeyEventMessage kem;
569 read1((uint8_t*)&kem, sizeof(KeyEventMessage));
580 if (!read1((uint8_t *)&kem, sizeof(KeyEventMessage)))
581 return;
570
571 kem.key = betoh(kem.key);
572 DPRINTF(VNC, " -- received key code %d (%s)\n", kem.key, kem.down_flag ?
573 "down" : "up");
574
575 if (keyboard)
576 keyboard->keyPress(kem.key, kem.down_flag);
577}
578
579void
580VncServer::recvPointerInput()
581{
582 DPRINTF(VNC, "Received pointer input from client\n");
583 PointerEventMessage pem;
584
582
583 kem.key = betoh(kem.key);
584 DPRINTF(VNC, " -- received key code %d (%s)\n", kem.key, kem.down_flag ?
585 "down" : "up");
586
587 if (keyboard)
588 keyboard->keyPress(kem.key, kem.down_flag);
589}
590
591void
592VncServer::recvPointerInput()
593{
594 DPRINTF(VNC, "Received pointer input from client\n");
595 PointerEventMessage pem;
596
585 read1((uint8_t*)&pem, sizeof(PointerEventMessage));;
597 if (!read1((uint8_t *)&pem, sizeof(PointerEventMessage)))
598 return;
586
587 pem.x = betoh(pem.x);
588 pem.y = betoh(pem.y);
589 DPRINTF(VNC, " -- pointer at x = %d y = %d buttons = %#x\n", pem.x, pem.y,
590 pem.button_mask);
591
592 if (mouse)
593 mouse->mouseAt(pem.x, pem.y, pem.button_mask);
594}
595
596void
597VncServer::recvCutText()
598{
599 DPRINTF(VNC, "Received client copy buffer message\n");
600
601 ClientCutTextMessage cct;
599
600 pem.x = betoh(pem.x);
601 pem.y = betoh(pem.y);
602 DPRINTF(VNC, " -- pointer at x = %d y = %d buttons = %#x\n", pem.x, pem.y,
603 pem.button_mask);
604
605 if (mouse)
606 mouse->mouseAt(pem.x, pem.y, pem.button_mask);
607}
608
609void
610VncServer::recvCutText()
611{
612 DPRINTF(VNC, "Received client copy buffer message\n");
613
614 ClientCutTextMessage cct;
602 read1((uint8_t*)&cct, sizeof(ClientCutTextMessage));
615 if (!read1((uint8_t *)&cct, sizeof(ClientCutTextMessage)))
616 return;
603
604 char str[1025];
605 size_t data_len = betoh(cct.length);
606 DPRINTF(VNC, "String length %d\n", data_len);
607 while (data_len > 0) {
617
618 char str[1025];
619 size_t data_len = betoh(cct.length);
620 DPRINTF(VNC, "String length %d\n", data_len);
621 while (data_len > 0) {
608 size_t len;
609 size_t bytes_to_read = data_len > 1024 ? 1024 : data_len;
622 size_t bytes_to_read = data_len > 1024 ? 1024 : data_len;
610 len = read((uint8_t*)&str, bytes_to_read);
623 if (!read((uint8_t *)&str, bytes_to_read))
624 return;
611 str[bytes_to_read] = 0;
625 str[bytes_to_read] = 0;
612 assert(len >= data_len);
613 data_len -= len;
626 data_len -= bytes_to_read;
614 DPRINTF(VNC, "Buffer: %s\n", str);
615 }
616
617}
618
619
620void
621VncServer::sendFrameBufferUpdate()

--- 24 unchanged lines hidden (view full) ---

646 fbu.num_rects = htobe(fbu.num_rects);
647 fbr.x = htobe(fbr.x);
648 fbr.y = htobe(fbr.y);
649 fbr.width = htobe(fbr.width);
650 fbr.height = htobe(fbr.height);
651 fbr.encoding = htobe(fbr.encoding);
652
653 // send headers to client
627 DPRINTF(VNC, "Buffer: %s\n", str);
628 }
629
630}
631
632
633void
634VncServer::sendFrameBufferUpdate()

--- 24 unchanged lines hidden (view full) ---

659 fbu.num_rects = htobe(fbu.num_rects);
660 fbr.x = htobe(fbr.x);
661 fbr.y = htobe(fbr.y);
662 fbr.width = htobe(fbr.width);
663 fbr.height = htobe(fbr.height);
664 fbr.encoding = htobe(fbr.encoding);
665
666 // send headers to client
654 write(&fbu);
655 write(&fbr);
667 if (!write(&fbu) || !write(&fbr))
668 return;
656
657 assert(fb);
658
659 std::vector<uint8_t> line_buffer(pixelConverter.length * fb->width());
660 for (int y = 0; y < fb->height(); ++y) {
661 // Convert and send a line at a time
662 uint8_t *raw_pixel(line_buffer.data());
663 for (unsigned x = 0; x < fb->width(); ++x) {
664 pixelConverter.fromPixel(raw_pixel, fb->pixel(x, y));
665 raw_pixel += pixelConverter.length;
666 }
667
669
670 assert(fb);
671
672 std::vector<uint8_t> line_buffer(pixelConverter.length * fb->width());
673 for (int y = 0; y < fb->height(); ++y) {
674 // Convert and send a line at a time
675 uint8_t *raw_pixel(line_buffer.data());
676 for (unsigned x = 0; x < fb->width(); ++x) {
677 pixelConverter.fromPixel(raw_pixel, fb->pixel(x, y));
678 raw_pixel += pixelConverter.length;
679 }
680
668 write(line_buffer.data(), line_buffer.size());
681 if (!write(line_buffer.data(), line_buffer.size()))
682 return;
669 }
670}
671
672void
673VncServer::sendFrameBufferResized()
674{
675 assert(fb && dataFd > 0 && curState == NormalPhase);
676 DPRINTF(VNC, "Sending framebuffer resize\n");

--- 13 unchanged lines hidden (view full) ---

690 fbu.num_rects = htobe(fbu.num_rects);
691 fbr.x = htobe(fbr.x);
692 fbr.y = htobe(fbr.y);
693 fbr.width = htobe(fbr.width);
694 fbr.height = htobe(fbr.height);
695 fbr.encoding = htobe(fbr.encoding);
696
697 // send headers to client
683 }
684}
685
686void
687VncServer::sendFrameBufferResized()
688{
689 assert(fb && dataFd > 0 && curState == NormalPhase);
690 DPRINTF(VNC, "Sending framebuffer resize\n");

--- 13 unchanged lines hidden (view full) ---

704 fbu.num_rects = htobe(fbu.num_rects);
705 fbr.x = htobe(fbr.x);
706 fbr.y = htobe(fbr.y);
707 fbr.width = htobe(fbr.width);
708 fbr.height = htobe(fbr.height);
709 fbr.encoding = htobe(fbr.encoding);
710
711 // send headers to client
698 write(&fbu);
712 if (!write(&fbu))
713 return;
699 write(&fbr);
700
701 // No actual data is sent in this message
702}
703
704void
705VncServer::setDirty()
706{

--- 25 unchanged lines hidden ---
714 write(&fbr);
715
716 // No actual data is sent in this message
717}
718
719void
720VncServer::setDirty()
721{

--- 25 unchanged lines hidden ---