Uses 1319K of libraries. Click here for Pure Java version (16630L/96K).
!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<Int> sentMouseButtons = syncSet(); transient L<MouseEvt> 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<MouseEvt> events = cloneAndClearAsLinkedList(this.events); final double scale = doubleRatio(dummyWidth, width); // drop old events (if network was down) new Set<Int> 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); } }
download show line numbers debug dex old transpilations
Travelled to 9 computer(s): bhatertpkbcr, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1019894 |
Snippet name: | Mini VNC [Dyn Module, control other computer's mouse & keyboard] |
Eternal ID of this version: | #1019894/69 |
Text MD5: | dca888f01a2eacaa81c5b255427115cb |
Transpilation MD5: | 2db594d1fc1c7a9e421ee8521b1e352c |
Author: | stefan |
Category: | javax / stefan's os |
Type: | JavaX source code (Dynamic Module) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2019-01-10 01:27:38 |
Source code size: | 4693 bytes / 130 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 515 / 4004 |
Version history: | 68 change(s) |
Referenced in: | #1020038 - Continuously Take Scaled Down Screenshot [doesn't save, just for image analysis] |