Warning: session_start(): open(/var/lib/php/sessions/sess_te3nt31ec7au5fvjvh2m36td81, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
// TODO (rare case): send pending mouse up on disable
// TODO: move to machine-to-machine chat
srecord MouseEvt(bool mouseDown, int button, DoublePt p) {
long time = sysNow();
}
compact module MiniVNC > DynImageSurface {
bool enabled, usePossiblyBrokenVersion = true, runInBackground;
S computerID;
int width = 512;
double videoInterval = 2, mouseInterval = 0.1;
transient int discardEventsAfter = 10000;
transient int dummyWidth = 100000;
transient DoublePt mousePosition;
transient Set sentMouseButtons = syncSet();
transient L events = syncList();
transient DoublePt sentMousePosition;
transient Q sendQ;
S switchableFields() { ret "usePossiblyBrokenVersion runInBackground"; }
start {
dm_requireModule("#1016578/AllOnlineComputers");
sendQ = dm_startQ();
doEvery(videoInterval, r grab);
doEvery(mouseInterval, r moveMouse);
}
visualize {
JComponent c = super.visualize();
enableDoubleBuffering();
imageSurfaceOnMouseMoveOrDrag_double(imageSurface, voidfunc(DoublePt p) { mousePosition = p });
disableImageSurfaceSelector(imageSurface);
setFocusable(imageSurface, true);
makePopupMenuConditional(imageSurface, func -> bool { enabled });
addKeyListener(imageSurface, new KeyAdapter {
public void keyReleased(final KeyEvent evt) {
print("key up (mod=" + evt.getModifiers() + "): " + evt);
if (actuallyEnabled()) sendQ.add(r {
dm_evalOnOtherMachine(computerID, "robot_keyPressAndReleaseWithModifiers(" + evt.getKeyCode() + ", " + evt.getModifiers() + ")")
});
}
});
addMouseListener(imageSurface, new MouseAdapter {
public void mousePressed(MouseEvent evt) {
imageSurface.grabFocus();
impl(evt, true);
}
void impl(MouseEvent evt, bool down) {
if (!actuallyEnabled()) return;
int mask = mouseButtonMaskForRobot(evt.getButton());
print("mask: " + mask);
events.add(MouseEvt(down, mask, imageSurface_doublePtFromEvent(imageSurface, evt)));
}
public void mouseReleased(MouseEvent evt) {
impl(evt, false);
}
});
ret northAndCenterWithMargins(vstackWithSpacing(
centerAndEastWithMargins(
withLabel("Computer to control:", dm_onlineComputerSelectorComboBox(dm_fieldLiveValue('computerID))), dm_fieldCheckBox('enabled)),
jRightAlignedLine(jLabel("Resize to width (pixels):"), jMinWidth(100, jLiveValueIntTextField(dm_fieldLiveValue('width))))),
c);
}
bool actuallyEnabled() {
ret enabled && possibleComputerID(computerID) && dm_isVisible();
}
bool actuallyEnabledAndInFocus() {
ret actuallyEnabled() && (runInBackground || dm_osInForeground());
}
void grab enter {
if (!actuallyEnabledAndInFocus()) ret;
time "Get Screenshot" {
setImage(dm_scaledDownScreenshotFromOtherMachine(computerID, width, +usePossiblyBrokenVersion));
}
}
void moveMouse enter {
if (!actuallyEnabled()) {
sentMousePosition = null; sentMouseButtons.clear(); ret;
}
LinkedList events = cloneAndClearAsLinkedList(this.events);
final double scale = doubleRatio(dummyWidth, width);
// drop old events (if network was down)
new Set sendMouseUp;
while (nempty(events) && elapsedMS(first(events).time) >= discardEventsAfter) {
if (!first(events).mouseDown) sendMouseUp.add(first(events).button); // don't drop that
popFirst(events);
}
for (int button : sendMouseUp)
dm_evalOnOtherMachine(computerID, "robot_mouseUp(" + button + ")");
// send mouse click/release events
for (MouseEvt e : events) {
dm_evalOnOtherMachine(computerID,
"robot_mouseButtonPressOrRelease_scaled(" + e.mouseDown + ", " + e.button + ", " + scaleInt(e.p.x, scale) + ", " + scaleInt(e.p.y, scale) + ", " + dummyWidth + ")");
sentMousePosition = e.p;
addOrRemove(sentMouseButtons, e.button, e.mouseDown);
}
// send mouse position
DoublePt p = mousePosition;
if (neq(p, sentMousePosition)) {
sentMousePosition = p;
if (p != null) {
time "Move Mouse On Other Machine" {
dm_evalOnOtherMachine(computerID, "dm_moveMouseImmediate_direct_scaled(" + scaleInt(p.x, scale) + ", " + scaleInt(p.y, scale) + ", " + dummyWidth + ")");
}
}
}
}
enhanceFrame {
dm_doubleFieldMenuItem(f, 'videoInterval, formTitle := "Update image every n seconds", onSet := rThread dm_reload);
}
}