#include <output.h>
#include <fb.h>
+#include "../aseg-paging/keyboard.h"
+
#include "lwip/tcp.h"
#include "rfb.h"
break;
}
- /* potential FALL THROUGH */
-
+ /* FALL THROUGH to SST_NEEDS_UPDATE*/
case SST_NEEDS_UPDATE:
outputf("RFB send: sending header");
/* Send a header */
- state->frame_bytes = fb->curmode.xres * fb->curmode.yres * 3; /* XXX */
+ state->frame_bytes = fb->curmode.xres * fb->curmode.yres * fb->curmode.bytestride;
hdr.msgtype = 0;
hdr.nrects = htons(1);
hdr.xpos = htons(0);
hdr.width = htons(fb->curmode.xres);
hdr.height = htons(fb->curmode.yres);
hdr.enctype = htonl(0);
- tcp_write(pcb, &hdr, sizeof(hdr), 0);
- tcp_output(pcb);
+ tcp_write(pcb, &hdr, sizeof(hdr), TCP_WRITE_FLAG_COPY);
state->update_pos = 0;
state->send_state = SST_SENDING;
- /* FALL THROUGH */
-
+ /* FALL THROUGH to SST_SENDING*/
case SST_SENDING:
- left = state->frame_bytes - state->update_pos;
+ while (1) {
+ left = state->frame_bytes - state->update_pos;
- if (left > tcp_sndbuf(pcb)) {
- sndlength = tcp_sndbuf(pcb);
- } else {
- sndlength = left;
- }
+ if (left == 0) {
+ state->send_state = SST_IDLE;
+ break;
+ }
+
+ if (left > 8192) /* Sounds good enough to me. */
+ left = 8192;
- do {
- err = tcp_write(pcb, fb->fbaddr + state->update_pos, sndlength, 0);
- if (err == ERR_MEM) {
- outputf("RFB: ERR_MEM sending %d", sndlength);
- sndlength /= 2;
+ sndlength = left;
+ do {
+ err = tcp_write(pcb, fb->fbaddr + state->update_pos, sndlength, TCP_WRITE_FLAG_COPY /* The card can't DMA from there. */);
+ if (err == ERR_MEM) /* Back down until lwip says we've got space. */
+ sndlength /= 2;
+ } while (err == ERR_MEM && sndlength > 1);
+
+ if (err != ERR_OK) {
+ if (err != ERR_MEM)
+ outputf("RFB: send error %d", err);
+
+ /* We'll just give up for now and come back when we have space later. */
+ break;
}
- } while (err == ERR_MEM && sndlength > 1);
- if (err == ERR_OK) {
- outputf("RFB: sent %d", sndlength);
state->update_pos += sndlength;
- } else {
- outputf("RFB: send error %d", err);
- }
- tcp_output(pcb);
-
- if (state->update_pos == state->frame_bytes) {
- state->send_state = SST_IDLE;
+ if (tcp_sndbuf(pcb) == 0) {
+ break;
+ }
}
break;
}
+
+ if (tcp_output(pcb) != ERR_OK)
+ outputf("RFB: tcp_output bailed in send_fsm?");
}
static err_t rfb_sent(void *arg, struct tcp_pcb *pcb, uint16_t len) {
state->state = ST_MAIN;
outputf("RFB: Sending server info", state->version);
- tcp_write(pcb, &server_info, sizeof(server_info), 0);
+ tcp_write(pcb, &server_info, sizeof(server_info), TCP_WRITE_FLAG_COPY);
tcp_output(pcb);
return OK;
for (i = 0; i < ntohs(req->num); i++) {
outputf("RFB: Encoding: %d", ntohl(req->encodings[i]));
/* XXX ... */
-
}
state->readpos += pktsize;
case KEY_EVENT:
if (state->writepos < sizeof(struct key_event_pkt))
return NEEDMORE;
- outputf("RFB: Key");
- /* XXX stub */
+ struct key_event_pkt * p = (struct key_event_pkt *)state->data;
+
+ outputf("RFB: Key: %d (%c)", htonl(p->keysym), (htonl(p->keysym) & 0xFF));
+ kbd_inject_keysym(htonl(p->keysym), p->downflag);
state->readpos += sizeof(struct key_event_pkt);
return OK;
case OK:
outputf("RFB FSM: ok");
- /* Might as well send now... */
+ /* Kick off a send. */
if (state->send_state == SST_IDLE
&& state->update_requested) {
send_fsm(pcb, state);