Coder Social home page Coder Social logo

node-x11's Introduction

node-x11

X11 protocol client for Node.js: implements the core X11 protocol, as well as Xrender, Damage, Composite, Big-Requests, Dpms, Screensaver, XFixes, Shape, XTest, XC-Misc, GLX, and Apple-WM extensions.

Gitter Build Status

Install

npm install x11

Windows users:

  1. install XMing or Cygwin/X
  2. get node-x11 copy (using git or from Github)

Example

Core requests usage:

var x11 = require('x11');

var Exposure = x11.eventMask.Exposure;
var PointerMotion = x11.eventMask.PointerMotion;

x11.createClient(function(err, display) {
  if (!err) {
    var X = display.client;
    var root = display.screen[0].root;
    var wid = X.AllocID();
    X.CreateWindow(
      wid,
      root, // new window id, parent
      0,
      0,
      500,
      500, // x, y, w, h
      0,
      0,
      0,
      0, // border, depth, class, visual
      { eventMask: Exposure | PointerMotion } // other parameters
    );
    X.MapWindow(wid);
    var gc = X.AllocID();
    X.CreateGC(gc, wid);
    var white = display.screen[0].white_pixel;
    var black = display.screen[0].black_pixel;
    cidBlack = X.AllocID();
    cidWhite = X.AllocID();
    X.CreateGC(cidBlack, wid, { foreground: black, background: white });
    X.CreateGC(cidWhite, wid, { foreground: white, background: black });
    X.on('event', function(ev) {
      if (ev.type == 12) {
        X.PolyFillRectangle(wid, cidWhite, [0, 0, 500, 500]);
        X.PolyText8(wid, cidBlack, 50, 50, ['Hello, Node.JS!']);
      }
    });
    X.on('error', function(e) {
      console.log(e);
    });
  } else {
    console.log(err);
  }
});

Screenshots

tetris game XRENDER gradients OpenGL glxgears OpenGL teapot

In use

  • ntk - higher level toolkit on top of X11
  • node-remote - media center controller
  • tiles - tiling window manager
  • vnc - vnc client.
  • node-ewmh - set of EWMH helpers.
  • OdieWM - window manager
  • Dbusmenu - unity global menu client.
  • AirWM - tiling window manager
  • npdf - pdf viewer
  • tinywm The famous TinyWM written in node.js
  • basedwm Infinite-desktop panning X window manager in LiveScript

X11 resources/documentation:

Other implementations

Server side (protocol + functionality) implementations for js + DOM

would be really great to make completely web based playground page, connecting node-x11 api to DOM based implementation

node-x11's People

Contributors

andrewstart avatar andrewswerlick avatar anko avatar aurium avatar bitdeli-chef avatar champii avatar danbulant avatar dominictarr avatar drom avatar froquede avatar gitter-badger avatar greenkeeper[bot] avatar jdomenechb avatar linuxenko avatar mat-sz avatar matoruru avatar megadonkey avatar mgechev avatar polpo avatar rosscomputerguy avatar santigimeno avatar sdumetz avatar sidorares avatar timroes avatar tiye avatar vird avatar wnayes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-x11's Issues

Question: how to create a transparent window

Hello Andrey,

I am trying to create a 'transparent' window which will not create any graphical content by itself, but will be used for more convenient geometry and z-index management for a set of hosted sub-windows in case creating some graphical content. This window should simply show and properly update the content underneath.

I'm not sure if this question is related to node-x11 or to X protocol itself, but I hope you could help me. This is what I do:

var x11 = require('x11');


x11.createClient(
    function(err, display) {
        if (!err) {
            // root window
            var X = display.client;
            var root = display.screen[0].root;
            var rootWindowId = X.AllocID();

            X.CreateWindow(
                rootWindowId, root,
                0, 0, 400, 400,
                0, 0, 0, 0,
                { backgroundPixel: display.screen[0].white_pixel }
            );
            X.MapWindow(rootWindowId);

            display.client.on( 'error', function(e) {
                console.log(e);
            });



            // container - this is the window I wish to be transparent
            var containerId = X.AllocID();
            X.CreateWindow(
                containerId, rootWindowId,
                100, 100, 200, 200,
                0, 0, 0, 0,
                {
//                    backgroundPixel: display.screen[0].white_pixel
                }
            );
            X.MapWindow(containerId);


        } else {
            console.log(err);
        }
    }
);

The root window is created as white, and the "container" takes the middle part. The content displayed inside the container is simply what was on that part of the screen before the window was created:

If I uncomment the white_pixel setting for the container, it will be rendered properly of course, but I need it to be transparent in case when there will be some graphical content under the container.

Thanks in advnace,
Dmitry

Damage.Destroy not work?

I use Damage.Create when receiving mapnotify, and use Damage.Destroy(damageId) later, but after that, I can still receive DamageNotify on that damage, or I shoud use other ways to destroy a damage?
And, I found that if I restart program, the damage seems not exists.
So, how to destroy a damage in program to prevent receive DamageNotify?

How can I listen to the root events?

I see the examples show how to listen to a specific window's events but is there a way to listen to the root window's events?

I need to manage global events.

Use consistent coding style

Hi,

This is more of a personal request.
The coding style is not consistent throughout the code and specially the use of tabs/spaces and different indentation values annoys me every time I read and try to modify the code. Would it be possible we define some basic guidelines: indentation, tabs/spaces, etc.? I would happily modify the code if we can agree on that.

Thanks in advance!

add xrender constants

  <!-- Disjoint* and Conjoint* are new in version 0.2 -->
  <!-- PDF blend modes are new in version 0.11 -->
  <enum name="PictOp">
    <item name="Clear" />
    <item name="Src" />
    <item name="Dst" />
    <item name="Over" />
    <item name="OverReverse" />
    <item name="In" />
    <item name="InReverse" />
    <item name="Out" />
    <item name="OutReverse" />
    <item name="Atop" />
    <item name="AtopReverse" />
    <item name="Xor" />
    <item name="Add" />
    <item name="Saturate" />

    <item name="DisjointClear"><value>16</value></item>
    <item name="DisjointSrc" />
    <item name="DisjointDst" />
    <item name="DisjointOver" />
    <item name="DisjointOverReverse" />
    <item name="DisjointIn" />
    <item name="DisjointInReverse" />
    <item name="DisjointOut" />
    <item name="DisjointOutReverse" />
    <item name="DisjointAtop" />
    <item name="DisjointAtopReverse" />
    <item name="DisjointXor" />

    <item name="ConjointClear"><value>32</value></item>
    <item name="ConjointSrc" />
    <item name="ConjointDst" />
    <item name="ConjointOver" />
    <item name="ConjointOverReverse" />
    <item name="ConjointIn" />
    <item name="ConjointInReverse" />
    <item name="ConjointOut" />
    <item name="ConjointOutReverse" />
    <item name="ConjointAtop" />
    <item name="ConjointAtopReverse" />
    <item name="ConjointXor" />

    <!-- PDF blend modes are new in version 0.11 -->
    <item name="Multiply"><value>48</value></item>
    <item name="Screen" />
    <item name="Overlay" />
    <item name="Darken" />
    <item name="Lighten" />
    <item name="ColorDodge" />
    <item name="ColorBurn" />
    <item name="HardLight" />
    <item name="SoftLight" />
    <item name="Difference" />
    <item name="Exclusion" />
    <item name="HSLHue" />
    <item name="HSLSaturation" />
    <item name="HSLColor" />
    <item name="HSLLuminosity" />
  </enum>

  <enum name="PolyEdge">
    <item name="Sharp" />
    <item name="Smooth" />
  </enum>

  <enum name="PolyMode">
    <item name="Precise" />
    <item name="Imprecise" />
  </enum>

  <enum name="CP">
    <item name="Repeat">          <bit>0</bit></item>
    <item name="AlphaMap">        <bit>1</bit></item>
    <item name="AlphaXOrigin">    <bit>2</bit></item>
    <item name="AlphaYOrigin">    <bit>3</bit></item>
    <item name="ClipXOrigin">     <bit>4</bit></item>
    <item name="ClipYOrigin">     <bit>5</bit></item>
    <item name="ClipMask">        <bit>6</bit></item>
    <item name="GraphicsExposure"><bit>7</bit></item>
    <item name="SubwindowMode">   <bit>8</bit></item>
    <item name="PolyEdge">        <bit>9</bit></item>
    <item name="PolyMode">        <bit>10</bit></item>
    <item name="Dither">          <bit>11</bit></item>
    <item name="ComponentAlpha">  <bit>12</bit></item>
  </enum>

  <enum name="SubPixel">
    <item name="Unknown" />
    <item name="HorizontalRGB" />
    <item name="HorizontalBGR" />
    <item name="VerticalRGB" />
    <item name="VerticalBGR" />
    <item name="None" />
  </enum>

  <!-- Extended repeat attributes introduced in 0.10 -->
  <enum name="Repeat">
    <item name="None" />
    <item name="Normal" />
    <item name="Pad" />
    <item name="Reflect" />
  </enum>

Cache already retrieved atom identifiers

Hi,

From what I've read, atom identifiers never change during the XServer lifetime. Would you consider a patch to cache the atom identifiers already retrieved by InternAtom to avoid redundant queries? In that case, would storing these values in X.atoms with the rest of standard atoms work for you?

Thanks!

[question] GrabButton

Hi again,

I'm still trying to get used to X11 rather than XCB. Reading both node-x11's source and the X protocol, I figured this should work:

var x11 = require( 'x11' );

x11.createClient( function( error, display ) { 
    var X = global.X = display.client;

    X.GrabButton( display.screen[0].root, true, x11.eventMask.ButtonPress | x11.eventMask.ButtonRelease | x11.eventMask.PointerMotion,
        1 /* Async */, 1 /* Async */, 0 /* None */, 0 /* None */, 1 << 3 /* Mod1 */, 1 );
} ).on( 'event', function( event ) { 
    console.log( event );
} );

By "work" I mean it should capture Mod1+Left click and log the event. But nothing is logged. The value for Mod1 comes from here as well as node-x11's source.

Sorry to misuse the issue system here, but the source is rather difficult to understand and documentation is sparse, so I'm sort of stuck here.

X.GetKeyboardMapping callback param list is null

I use node-x11 with xephyr, but the following code show that list is null;

require('x11').createClient({display: ":12"}, function(err, display) {
            var min = display.min_keycode; // is 8
            var max = display.max_keycode; // is 255
            display.client.GetKeyboardMapping(min, max-min, function(list){ 
                console.log(list); // out put is null
            });

what's wrong with my usage?

Getting error on running wm example

Hi. I'm getting an error running the wm example.

tom@laptom ~/Documents/Code9/window-manager
2014-15-24 18:15:27 ⚡ DISPLAY=:1 node foo.js 

/home/tom/Documents/Code9/window-manager/node_modules/x11/lib/ext/render.js:17
            display.client.seq2stack[display.client.seq_num] = err.stack;
                                                             ^
TypeError: Cannot set property '4' of undefined
    at captureStack (/home/tom/Documents/Code9/window-manager/node_modules/x11/lib/ext/render.js:17:62)
    at Object.ext.QueryPictFormat (/home/tom/Documents/Code9/window-manager/node_modules/x11/lib/ext/render.js:46:17)
    at /home/tom/Documents/Code9/window-manager/node_modules/x11/lib/ext/render.js:373:17
    at ReadFixedRequest.callback (/home/tom/Documents/Code9/window-manager/node_modules/x11/lib/xcore.js:493:21)
    at ReadFixedRequest.execute (/home/tom/Documents/Code9/window-manager/node_modules/x11/lib/unpackstream.js:41:10)
    at UnpackStream.resume (/home/tom/Documents/Code9/window-manager/node_modules/x11/lib/unpackstream.js:165:30)
    at UnpackStream.write (/home/tom/Documents/Code9/window-manager/node_modules/x11/lib/unpackstream.js:102:10)
    at Socket.<anonymous> (/home/tom/Documents/Code9/window-manager/node_modules/x11/lib/xcore.js:58:21)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:745:14)

tom@laptom ~/Documents/Code9/window-manager
2014-15-24 18:15:34 ⚡ 

I see this in the Xephyr output:

tom@laptom ~
2014-08-24 18:08:17 ⚡ Xephyr -screen 800x600 -nodri -br :1
Initializing built-in extension Generic Event Extension
Initializing built-in extension SHAPE
Initializing built-in extension MIT-SHM
2 XSELINUXs still allocated at resetutExtension
SCREEN: 0 objects of 256 bytes = 0 total bytes 0 private allocs
DEVICE: 0 objects of 32 bytes = 0 total bytes 0 private allocs
CLIENT: 0 objects of 168 bytes = 0 total bytes 0 private allocs
WINDOW: 0 objects of 56 bytes = 0 total bytes 0 private allocs
PIXMAP: 1 objects of 16 bytes = 16 total bytes 0 private allocs
GC: 0 objects of 16 bytes = 0 total bytes 0 private allocs
CURSOR: 1 objects of 8 bytes = 8 total bytes 0 private allocs
TOTAL: 2 objects, 24 bytes, 0 allocs
1 PIXMAPs still allocated at reset
PIXMAP: 1 objects of 16 bytes = 16 total bytes 0 private allocs
GC: 0 objects of 16 bytes = 0 total bytes 0 private allocs
CURSOR: 1 objects of 8 bytes = 8 total bytes 0 private allocs
TOTAL: 2 objects, 24 bytes, 0 allocs
1 CURSORs still allocated at reset
CURSOR: 1 objects of 8 bytes = 8 total bytes 0 private allocs
TOTAL: 1 objects, 8 bytes, 0 allocs
1 CURSOR_BITSs still allocated at reset
TOTAL: 0 objects, 0 bytes, 0 allocs
1 DAMAGEs still allocated at reset
TOTAL: 0 objects, 0 bytes, 0 allocs
2 XSELINUXs still allocated at reset
SCREEN: 0 objects of 256 bytes = 0 total bytes 0 private allocs
DEVICE: 0 objects of 32 bytes = 0 total bytes 0 private allocs
CLIENT: 0 objects of 168 bytes = 0 total bytes 0 private allocs
WINDOW: 0 objects of 56 bytes = 0 total bytes 0 private allocs
PIXMAP: 1 objects of 16 bytes = 16 total bytes 0 private allocs
GC: 0 objects of 16 bytes = 0 total bytes 0 private allocs
CURSOR: 1 objects of 8 bytes = 8 total bytes 0 private allocs
TOTAL: 2 objects, 24 bytes, 0 allocs
1 PIXMAPs still allocated at reset
PIXMAP: 1 objects of 16 bytes = 16 total bytes 0 private allocs
GC: 0 objects of 16 bytes = 0 total bytes 0 private allocs
CURSOR: 1 objects of 8 bytes = 8 total bytes 0 private allocs
TOTAL: 2 objects, 24 bytes, 0 allocs
1 CURSORs still allocated at reset
CURSOR: 1 objects of 8 bytes = 8 total bytes 0 private allocs
TOTAL: 1 objects, 8 bytes, 0 allocs
1 CURSOR_BITSs still allocated at reset
TOTAL: 0 objects, 0 bytes, 0 allocs
1 DAMAGEs still allocated at reset
TOTAL: 0 objects, 0 bytes, 0 allocs

grabbing/swallowing X11 apps - question

Advance apologies if this is not the right place to post this.

I am looking for a way to grab a native X11 application (say an xterm) into a node-webkit based UI. Was wondering if that's doable with node-x11 or some other variant? Appreciate any pointers. Thanks.

Rare exception handling GetProperty reply

Very rarely I'm receiving this exception:

Error: oob
at Buffer.slice (buffer.js:558:32)
at XClient.module.exports.GetProperty (/usr/share/smartion-node/node_modules/x11/lib/corereqs.js:409:28)
at ReadFixedRequest.XClient.expectReplyHeader as callback
at ReadFixedRequest.execute (/usr/share/smartion-node/node_modules/x11/lib/unpackstream.js:41:10)
at UnpackStream.resume (/usr/share/smartion-node/node_modules/x11/lib/unpackstream.js:165:30)
at UnpackStream.write (/usr/share/smartion-node/node_modules/x11/lib/unpackstream.js:102:10)
at Socket. (/usr/share/smartion-node/node_modules/x11/lib/xcore.js:57:21)
at Socket.EventEmitter.emit (events.js:96:17)
at Pipe.onread (net.js:397:14)

I don't find anything wrong in the code. Of course, I'll keep investigating, but is there anything in the code that draws your attention that could be causing this?

Thanks!

@sidorares

Implement GLX events

form mesa ./src/glx/glxext.c

/*
 * GLX events are a bit funky.  We don't stuff the X event code into
 * our user exposed (via XNextEvent) structure.  Instead we use the GLX
 * private event code namespace (and hope it doesn't conflict).  Clients
 * have to know that bit 15 in the event type field means they're getting
 * a GLX event, and then handle the various sub-event types there, rather
 * than simply checking the event code and handling it directly.
 */

static Bool
__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
{
     struct glx_display *glx_dpy = __glXInitialize(dpy);

   if (glx_dpy == NULL)
      return False;

   switch ((wire->u.u.type & 0x7f) - glx_dpy->codes->first_event) {
   case GLX_PbufferClobber:
   {
      GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event;
      xGLXPbufferClobberEvent *awire = (xGLXPbufferClobberEvent *)wire;
      aevent->event_type = awire->type;
      aevent->serial = awire->sequenceNumber;
      aevent->event_type = awire->event_type;
      aevent->draw_type = awire->draw_type;
      aevent->drawable = awire->drawable;
      aevent->buffer_mask = awire->buffer_mask;
      aevent->aux_buffer = awire->aux_buffer;
      aevent->x = awire->x;
      aevent->y = awire->y;
      aevent->width = awire->width;
      aevent->height = awire->height;
      aevent->count = awire->count;
      return True;
   }
   case GLX_BufferSwapComplete:
   {
      GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
      xGLXBufferSwapComplete2 *awire = (xGLXBufferSwapComplete2 *)wire;
      struct glx_drawable *glxDraw = GetGLXDrawable(dpy, awire->drawable);
      aevent->event_type = awire->event_type;
      aevent->drawable = awire->drawable;
      aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
      aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;

      if (!glxDraw)
         return False;

      if (awire->sbc < glxDraw->lastEventSbc)
         glxDraw->eventSbcWrap += 0x100000000;
      glxDraw->lastEventSbc = awire->sbc;
      aevent->sbc = awire->sbc + glxDraw->eventSbcWrap;
      return True;
   }
   default:
      /* client doesn't support server event */
      break;
   }

   return False;
}

GetImage returns error

code as following:

var x11 = require('x11');
x11.createClient({display: ":1"}, function(err, display) {
    var X = display.client;
    var root = display.screen[0].root;
    X.ChangeWindowAttributes(root, {
        eventMask: x11.eventMask.StructureNotify | x11.eventMask.SubstructureRedirect | x11.eventMask.SubstructureNotify | x11.eventMask.ProperityChange
    }, function(err) {
        if(err.error === 10) {
            console.log("Error: maybe another window manager had already ran?");
            process.exit(1);
        }
    });
    X.on('event', function(ev){
        console.log(ev);
        switch(ev.type){
            case 16: // CreateNotify
                break;
            case 20: //MapRequest
                X.GetGeometry(ev.wid, function(err, clientGeom) {
                    X.GetImage(2, ev.wid, 0, 0, clientGeom.width, clientGeom.height, 0xffffffff, function(d) {
                    });
                });
        }
    })
});

error:

{ type: 16,
  seq: 3,
  name: 'CreateNotify',
  parent: 365,
  wid: 4194314,
  x: 0,
  y: 150,
  width: 100,
  height: 1,
  borderWidth: 0,
  overrideRedirect: false,
  rawData: <Buffer 10 00 03 00 6d 01 00 00 0a 00 40 00 00 00 00 00 96 00 64 00 01 00 00 00 00 00 00 00 00 00 00 00> }
{ type: 20,
  seq: 3,
  name: 'MapRequest',
  parent: 365,
  wid: 4194314,
  rawData: <Buffer 14 00 03 00 6d 01 00 00 0a 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> }

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: Bad match
    at ReadFixedRequest.callback (/home/ubuntu/cw-ws/node_modules/x11/lib/xcore.js:429:29)
    at ReadFixedRequest.execute (/home/ubuntu/cw-ws/node_modules/x11/lib/unpackstream.js:41:10)
    at UnpackStream.resume (/home/ubuntu/cw-ws/node_modules/x11/lib/unpackstream.js:165:30)
    at UnpackStream.write (/home/ubuntu/cw-ws/node_modules/x11/lib/unpackstream.js:102:10)
    at Socket.<anonymous> (/home/ubuntu/cw-ws/node_modules/x11/lib/xcore.js:58:21)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)

createClient should fall back to TCP if Unix socket does not exist

Xlib and XCB fall back to using TCP on localhost if the Unix socket does not exist. node-x11 should do the same.

We've run into a few instances with users whose /tmp/.X11-unix/X* socket file has been deleted out from under them, but their X session appears to continue to work due to Xlib and XCB's falling back.

GetProperty logs errors

Is there any way to prevent it logging on error:

error { [Error: Bad window]
  error: 3,
  seq: 28,
  message: 'Bad window',
  badParam: 12585040,
  minorOpcode: 0,
  majorOpcode: 20 }

v1.0.3
Thanks!

CreateNotify wid is 0

The createNotify should return created window id, but it's 0. Is that right? Or I should use other ways to get the window id?

{ type: 16,
  seq: 3,
  name: 'CreateNotify',
  parent: 4194314,
  wid: 0,
  x: 150,
  y: 100,
  width: 1,
  height: 0,
  borderWidth: 0,
  overrideRedirect: false,
  rawData: <Buffer 10 00 03 00 6d 01 00 00 0a 00 40 00 00 00 00 00 96 00 64 00 01 00 00 00 00 00 00 00 00 00 00 00> }

Async GrabKey

I am trying something like X.GrabKey(root, 0, 0, 65, false, true); to capture space keypresses. How can I propagate keypress event to all system? Right now script is blocking space key, so the system doesn't see it.

Failed to pass keypress/release event to nw app

I use node-x11 to grab keyboard for a screensaver node-webkit app.I grabbed the keyboard and mouse event succeed, but only pointer events can delivery to my html input widget, the keypress/release not.

Below is my code:

        function grab_window(wid) {
            console.log("-----------grab window----------------");
            console.log(wid);
            var x11 = require('x11');
            x11.createClient(function(err, display) {
                var X = display.client;
                X.ChangeWindowAttributes(wid, { eventMask: x11.eventMask.ResizeRedirect|x11.eventMask.KeyPress|x11.eventMask.KeyRelease|x11.eventMask.StructureNotify|x11.eventMask.SubstructureNotify});
                X.LowerWindow(wid);
                X.GrabKeyboard(wid, false, 0, 1, 1);
                X.on('event', function(ev) {
                    console.log(ev.name);
                });
            });
        };

        var gui = require('nw.gui');
        var win = gui.Window.get();
        win.title = "cscreensaver";
        //win.enterKioskMode();
        onload = function () {
            win.setAlwaysOnTop(true);
            win.setShowInTaskbar(false);
            var child_process = require('child_process');
            var cmd = "xwininfo -name 'cscreensaver' -int |grep 'cscreensaver' | awk '{print $4}'";
            var wid = 0;
            child_process.exec(cmd, function(err, stdout, stderr) {
                wid = parseInt(stdout);
                win.show();
                grab_window(wid);
            });
        };

//code end

The '"console.log(ev.name);" can print the key event when I press my keyboard, but it can't go into my html input, how to solve this, thanks for any reply.

auto generate x protocol.

Andrey, You should be able to auto generate most of the bindings for the X protocol through. See libXCB for prior art. They have created and use a x protocol description written in xml to generate their bindings.

On that note I have been writing a wrapper for XCB using this idea. https://github.com/CrypticSwarm/XCBJS
So far I've only generated code for every Request, and Event but haven't yet for the Replies.

I believe that using a auto-generating the bindings is the way to go.

GetGeometry returns null

Testing with examples/screenshot.js:

$ xwininfo | grep id
xwininfo: Window id: 0x2c0007f "How can I listen to the root events? · Issue #69"
$ node node_modules/x11/examples/screenshot.js 0x2c0007f
0x2c0007f
/tmp/node_modules/x11/examples/screenshot.js:15
        width = clientGeom.width;
                          ^
TypeError: Cannot read property 'width' of null
    at /tmp/node_modules/x11/examples/screenshot.js:15:27
...
$ node node_modules/x11/examples/screenshot.js  # try on root
undefined
/tmp/node_modules/x11/examples/screenshot.js:15
        width = clientGeom.width;
                          ^
TypeError: Cannot read property 'width' of null
    at /tmp/node_modules/x11/examples/screenshot.js:15:27

add error parameter in requireExt callback

Currently if you require non-existent extension you'll get string as first parameter.

code like

conn.require('render', function(Render) {
})

should be changed to

conn.require('render', function(err, Render) {
})

Also might be useful to allow first parameter as array (maybe use different name for it) as it's very common to require 3-4 extensions at very beginning)

api proposal:

x.requreExtensions(['shape', 'randr', 'glx'], function(err, extension) {
  // again, what would be best way to report errors? all or nothing?
  extension.glx.CreateContext( ...)
}

Implementation is here:
https://github.com/sidorares/node-x11/blob/master/lib/xcore.js#L520

  • conn.require('name'... is based on node module system
  • we do module = require('ext/' + name); module.requireExt. E.i each extension implements its own 'require', including QueryExtension call, then populates result with methods, event parsers, error parsers and constats.

readDepths() hangs in Xvnc server

readDepths() hangs if I run node-x11 with an Xvnc server.

This is happening because on this server there are two 24-bit depths. So the Object.keys(depths).length == n_depths test fails even after we have read all the visuals for the depths, because depths[24] gets overwritten. Then the next bl.unpack() call hangs because there is no more data to read.

I can reproduce with TigerVNC server 1.3.1 on Fedora 21 and TigerVNC server 1.1.0 on CentOS 6.6.

auth: respect auth type

node-x11/lib/auth.js

Lines 36 to 42 in 0d7346f

cookie.type = buf.unpack('n')[0];
if (!typeToName[cookie.type]) {
console.warn('Unknown address type');
}
offset += 2;
//JSHint becomes angry when handleCookieProperty is declared inside loop
cookieProperties.forEach(handleCookieProperty);

depending on type semantics of address is different ( 4 bytes ip for 0=Internet, string for 256=Local etc )

return promises or thunks everywhere?

Since generators are enabled by default in iojs and easily accessible behind flag in 0.12 it might be good to allow to yield values imagine we can have

var co   = require('co');
var x11 = require('x11');
co(function*() {
   var X = yield x11.createClient();
   var root = X.display.screen[0].root;
   var XSS = display.client.require('screen-saver');
   console.log( 'idle time: %s ', (yield XSS.QueryInfo(root)).idle );
});

instead of

var x11 = require('x11');
x11.createClient(function(err, display) {
    var X = display.client;
    X.require('screen-saver', function(err, SS) {
        if (err) throw err;
        SS.QueryInfo(display.screen[0].root, function(err, info) {
           if (err) throw err; 
           console.log('Idle time', info.idle);
        });
    });
    X.on('error', console.error);
});

not sure if it's easy to make co throw correct exception with proper stack trace when there is error from request where non-error response is not sent normally ( see #85 )

NX and node-x11

Hi,
I'm trying to run an NX server that communicates with node-x11 as the NX client. A remote machine would communicate via HTML Canvas with the NX server.

I'm interested in your thoughts before diving into this. I appreciate any advice.

Thank you

Missing async handling (?)

If I call ChangeWindowAttributes, I can only define an error callback. Is there any way to wait for success? Currently, if I register as the window manager, I am forced to start managing windows before even knowing that no other window manager is active.

Raspbian CreatePicture problem

Hi;

I'm getting error this command;

Render.CreatePicture(pict, wid, Render.rgb24);

error message: Bad match

My system raspberry pi B+ and Raspbian Jezzy Lite.

Whats my problem ?

Thanks.

Question on 32-bit colors representation

I am trying to create a window with 32-bit color depth and set a background for it to a specified color. Investigating on how the 32-bit color is encoded with an integer, I finally came to the following function generating this number for me:

var color = function(a,r,g,b) {
    var d = 256;
    return a*d*d*d + r*d*d + g*d + b;
}

But the alpha channel value seems to be treated in a wired way. If I set the backgroundPixel value to color(0,0,0,255) ("transparent blue" or something like that), I expect the resulted window to be completely transparent: since the alpha channel value is set to 0, it should not matter which are the values of other channels. But the displayed window still reflects the blue channel value:

It could make sence meaning that it really shows the "transparent blue" color, and in order to get the really transparent color, I should set all the channels to 0.

Expected result seems to be achieved if I multiply the value of each channel with alpha channel, but I am not sure if such a solution is the correct one:

var color = function(a,r,g,b) {
    var a1 = a / 255;  // normalized alpha
    var ra = Math.floor(a1*r);
    var ga = Math.floor(a1*g);
    var ba = Math.floor(a1*b);
    var d = 256;
    return a*d*d*d + ra*d*d + ga*d + ba;
}

Where can I find an information on how the colors are encoded to make sure that my solution provides the "traditional" transparency logic?

Here is the full code of what I am doing to create a window:

var x11 = require('x11');


var color = function(a,r,g,b) {
    var d = 256;
    return a*d*d*d + r*d*d + g*d + b;
}

var color2 = function(a,r,g,b) {
    var a1 = a / 255;
    var ra = Math.floor(a1*r);
    var ga = Math.floor(a1*g);
    var ba = Math.floor(a1*b);
    var d = 256;
    return a*d*d*d + ra*d*d + ga*d + ba;
}



x11.createClient(
    function(err, display) {
        if (!err) {
            var visual = null;
            var depths = display.screen[0].depths[32];
            for (vid in depths) {
                if (depths[vid]['class'] === 4) {
                    visual = vid;
                    break;
                }
            }

            if (!visual) {
                console.log('No RGBA visual found');
                return;
            }

            var X = display.client;
            var root = display.screen[0].root;
            var rootWindowId = X.AllocID();

            var cmid = X.AllocID();
            X.CreateColormap(cmid, root, visual, 0);

            X.CreateWindow(
                rootWindowId, root,
                0, 0, 200, 200,  // x, y, width, height
                1,   // border
                32,  // depth
                1,   // class
                visual,
                {
                    backgroundPixel:  color(0,0,0,255),
                    colormap: cmid,
                    borderPixel: 0                    
                }
            );
            X.MapWindow(rootWindowId);

            display.client.on( 'error', function(e) {
                console.log(e);
            });
        } else {
            console.log(err);
        }
    }
);

question: send keyboard strokes to a window?

I notice there is a SendEvent function,
am wondering if it's possible to intercept keystrokes and send something different to a specific window?

chrome has very silly keyboard shortcuts: ctrl-fn-up/down goes to the left/right tab, and ctrl-fn-left/right goes to the top/bottom of the page... (of course, fn-up is pgup, so in a way it makes sense - but my muscles can't remember that)

Chrome has no way to reassign keyboard shortcuts, but can I work around this with x?

GetImage slow

I use GetImage to get the window pixmap, but it seems too slow, uses ablout 3.5s to callback. Is there any time consuming operations? Or should I use some flush functions?
code:

X.require('damage', function(err, Damage){
                        var damage = X.AllocID();
                        Damage.Create(damage, root, Damage.ReportLevel.NonEmpty);
                        X.on('event', function(ev){
                            console.log(ev);
                            if(ev.type == 16){
                                return;
                            }
                            if(ev.type == 19){
                                var pixmap = X.AllocID();
                                var damage = X.AllocID();
                                //Composite.NameWindowPixmap(ev.wid, pixmap);
                                Damage.Create(damage, ev.wid, Damage.ReportLevel.NonEmpty);
                            }
                            if(ev.damage){
                                console.log('start getimage:'+Date.now());
                                X.GetImage(2, ev.drawable, ev.area.x, ev.area.y, ev.area.w, ev.area.h, 0xffffffff, function(err, d) {
                                    console.log('end getimage:'+Date.now());
                                    if(err){
                                        console.log(err);
                                        return;
                                    }
                                    console.log(d);

                                });
                            }
                        })
                    })

result

start getimage:1443767202126
end getimage:1443767205641

OpenGL Fails

The OpenGL text applications like glxgears and glxdemo are working fine at my system but i cant run OpenGL with node-x11.
See this example output:

$ node examples/opengl/test1.js
{ [Error: Bad param value]
  error: 2,
  seq: 6,
  message: 'Bad param value',
  badParam: 0,
  minorOpcode: 3,
  majorOpcode: 154 }
{ [Error: GLX: Bad context]
  error: 169,
  seq: 7,
  message: 'GLX: Bad context',
  badParam: 75497474,
  minorOpcode: 5,
  majorOpcode: 154 }
/home/aurium/Projetos/node-x11/examples/opengl/test1.js:63
            gl.render(ctx);
               ^
TypeError: undefined is not a function
    at /home/aurium/Projetos/node-x11/examples/opengl/test1.js:63:16
    at ReadFixedRequest.callback (/home/aurium/Projetos/node-x11/lib/xcore.js:458:39)
    at ReadFixedRequest.execute (/home/aurium/Projetos/node-x11/lib/unpackstream.js:41:10)
    at UnpackStream.resume (/home/aurium/Projetos/node-x11/lib/unpackstream.js:165:30)
    at UnpackStream.write (/home/aurium/Projetos/node-x11/lib/unpackstream.js:102:10)
    at Socket.<anonymous> (/home/aurium/Projetos/node-x11/lib/xcore.js:63:21)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
    at Pipe.onread (net.js:538:20)

Any idea?
I'm not an OpenGL expert as other guys may not to be too. So, is it possible to add more tests and explained outputs to save us from ignorance? :-)

GetKeyBoardMapping returning incorrect results

For almost all the keys in my keyboard, GetKeyBoardMapping is returning an incorrect result. For most of the keys it's shifted one to the right. For some like the arrow keys there's no apparent pattern.

If need be I can email (or send via any other menas) a picture of my keyboard as well as the console output of the getkeyboardmapping.js test script for every key, pressed in order starting at the top left and moving down, skipping only the sleep and wake keys.

Failed to install 0.0.12 on Arch

I was trying to learn building a deskop environment.
But I'm only able to build demo in HTML at this moment.
That's why I tried node-x11 and maybe it's not related to the problem.

Failed to install 0.0.12 , but 0.0.11 successfully installed.

➤➤ npm install x11
npm http GET https://registry.npmjs.org/x11
npm http 304 https://registry.npmjs.org/x11
npm http GET https://registry.npmjs.org/x11/-/x11-0.0.12.tgz
npm http 404 https://registry.npmjs.org/x11/-/x11-0.0.12.tgz
npm ERR! fetch failed https://registry.npmjs.org/x11/-/x11-0.0.12.tgz
npm ERR! Error: 404 Not Found
npm ERR!     at null.<anonymous> (/usr/lib/node_modules/npm/lib/utils/fetch.js:47:16)
npm ERR!     at EventEmitter.emit (events.js:126:20)
npm ERR!     at WriteStream.flush (fs.js:1517:12)
npm ERR!     at fs.close (/usr/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:90:5)
npm ERR!     at Object.oncomplete (fs.js:297:15)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <[email protected]>

npm ERR! System Linux 3.6.6-1-ARCH
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install" "x11"
npm ERR! cwd /home/chen/code/x11-window
npm ERR! node -v v0.8.14
npm ERR! npm -v 1.1.65
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/chen/code/x11-window/npm-debug.log
npm ERR! not ok code 0
➤➤ npm install x11 -V
npm http GET https://registry.npmjs.org/x11
^C➤➤ npm install x11 --verbose
npm info it worked if it ends with ok
npm verb cli [ '/usr/bin/node', '/usr/bin/npm', 'install', 'x11', '--verbose' ]
npm info using [email protected]
npm info using [email protected]
npm verb read json /home/chen/code/x11-window/package.json
npm verb read json /home/chen/code/x11-window/node_modules/x11/package.json
npm verb read json /home/chen/code/x11-window/package.json
npm verb cache add [ 'x11', null ]
npm verb parsed url { pathname: 'x11', path: 'x11', href: 'x11' }
npm verb lock x11 /home/chen/.npm/5c939875-x11.lock
npm verb addNamed [ 'x11', '' ]
npm verb addNamed [ null, '' ]
npm verb lock x11@ /home/chen/.npm/76d4c307-x11.lock
npm verb url raw x11
npm verb url resolving [ 'https://registry.npmjs.org/', './x11' ]
npm verb url resolved https://registry.npmjs.org/x11
npm info trying registry request attempt 1 at 20:07:16
npm verb etag "DZBF9U7V1AMGHQAPSUKBB5HMZ"
npm http GET https://registry.npmjs.org/x11
npm http 304 https://registry.npmjs.org/x11
npm verb etag x11 from cache
npm verb addNamed [ 'x11', '0.0.12' ]
npm verb addNamed [ '0.0.12', '0.0.12' ]
npm verb lock [email protected] /home/chen/.npm/99c1b350-x11-0-0-12.lock
npm verb lock https://registry.npmjs.org/x11/-/x11-0.0.12.tgz /home/chen/.npm/b122725f-try-npmjs-org-x11-x11-0-0-12-tgz.lock
npm verb addRemoteTarball [ 'https://registry.npmjs.org/x11/-/x11-0.0.12.tgz',
npm verb addRemoteTarball   '7897e7227e705418c0c66c01a6dc1a71f0bb732f' ]
npm info retry fetch attempt 1 at 20:07:17
npm verb fetch to= /home/chen/tmp/npm-7535/1354104437759-0.6482729348354042/tmp.tgz
npm http GET https://registry.npmjs.org/x11/-/x11-0.0.12.tgz
npm http 404 https://registry.npmjs.org/x11/-/x11-0.0.12.tgz
npm ERR! fetch failed https://registry.npmjs.org/x11/-/x11-0.0.12.tgz
npm ERR! Error: 404 Not Found
npm ERR!     at null.<anonymous> (/usr/lib/node_modules/npm/lib/utils/fetch.js:47:16)
npm ERR!     at EventEmitter.emit (events.js:126:20)
npm ERR!     at WriteStream.flush (fs.js:1517:12)
npm ERR!     at fs.close (/usr/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:90:5)
npm ERR!     at Object.oncomplete (fs.js:297:15)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <[email protected]>

npm ERR! System Linux 3.6.6-1-ARCH
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install" "x11" "--verbose"
npm ERR! cwd /home/chen/code/x11-window
npm ERR! node -v v0.8.14
npm ERR! npm -v 1.1.65
npm verb exit [ 1, true ]
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/chen/code/x11-window/npm-debug.log
npm ERR! not ok code 0

➤➤ npm install [email protected]
npm http GET https://registry.npmjs.org/x11/0.0.11
npm http 304 https://registry.npmjs.org/x11/0.0.11
[email protected] node_modules/x11

PutImage return BadLength

Hi,

I get a BadLength error with PutImage()
In corereqs.js I removed the '1+' in '1+reqLen' and everithing worked !

Hope it help :)

xtest FakeInput logs undefined and <Buffer 00 00 ... 00 >

Is there any way to prevent it writing entries everytime I press a key ? Ta.

[andy@sandpit smoketest]$ node xtesttest.js 
{ present: 1,
  majorOpcode: 132,
  firstEvent: 0,
  firstError: 0,
  GetVersion: [Function],
  KeyPress: 2,
  KeyRelease: 3,
  ButtonPress: 4,
  ButtonRelease: 5,
  MotionNotify: 6,
  FakeInput: [Function] }
click
undefined
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>
undefined
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>
 click
 click
 undefined
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>
undefined
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>
^C[andy@sandpit smoketest]$ 

grab keyboard doesn't take effect, need some demo.

I want to write a screen locker program thats needs grab keyboard to inhibit other applications.
Below is my node js code, the problem is when press Alt + Tab, still can switch to other app.

var x11 = require('../../lib');
x11.createClient(function(err, display) {
    var X = display.client;
    var wid = X.AllocID();
    X.CreateWindow(wid, display.screen[0].root, -9, -9, 1, 1);
    X.ChangeWindowAttributes(wid, { eventMask: x11.eventMask.ResizeRedirect|x11.eventMask.KeyPress|x11.eventMask.KeyRelease|x11.eventMask.StructureNotify|x11.eventMask.SubstructureNotify});
    X.LowerWindow(wid);
    X.MapWindow(wid);
    //X.GrabPointer(wid, false, x11.eventMask.PointerMotion, 1, 1, wid, 0, Date.now());
    X.on('event', function(ev) {
        if (ev.type === 19) {
            console.log("------------finish map-------------------");
            X.GrabKeyboard(wid, false, new Date(), 1, 1);
            X.LowerWindow(wid);
        } else {
            console.log(ev.name);
        }
        if (ev.type == 2) {
            if (ev.keycode == 36) {
                X.terminate(); 
            } else {
                console.log(ev.keycode);
            }
        }
        if (ev.type == 18) {
            console.log("------------event unmap----------------");
        }
    });

    X.on('error', function(error) {
        console.log("-----------------error-------------------");
        console.log(error);
    });
});

But the coordiante C code works well, then how should I modify my js code, thanks for any reply.

Below is the c code:

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <stdio.h>

int main()
{
    Display *display;
    Window   window, rootwindow;
    XEvent   event;
    KeySym   escape;

    display = XOpenDisplay(NULL);
    rootwindow = DefaultRootWindow(display);
    window = XCreateWindow(display, rootwindow,
                           -99, -99, 1, 1, /* x, y, width, height */
                           0, 0, InputOnly, /* border, depth, class */
                           CopyFromParent, /* visual */
                           0, NULL); /* valuemask and attributes */

    XSelectInput(display, window, StructureNotifyMask | SubstructureRedirectMask | ResizeRedirectMask | KeyPressMask | KeyReleaseMask);
    XLowerWindow(display, window);
    XMapWindow(display, window);

    do {
        printf("----------------------event is not map------------------\n");
        XNextEvent(display, &event);
    } while (event.type != MapNotify);

    printf("----------------------now finish map------------------\n");
    XGrabKeyboard(display, window, False, GrabModeAsync, GrabModeAsync, CurrentTime);
    XLowerWindow(display, window);

    escape = XKeysymToKeycode(display, XK_Escape);
    printf("\nPress ESC to exit.\n\n");
    fflush(stdout);

    while (1) {

        XNextEvent(display, &event);

        if (event.type == KeyPress) {
            printf("KeyPress: keycode %u state %u\n", event.xkey.keycode, event.xkey.state);
            fflush(stdout);

        } else
        if (event.type == KeyRelease) {

            printf("KeyRelease: keycode %u state %u\n", event.xkey.keycode, event.xkey.state);
            fflush(stdout);

            if (event.xkey.keycode == escape)
                break;
        } else
        if (event.type == UnmapNotify) {
            printf("---------unmap----------\n");
            fflush(stdout);

            XUngrabKeyboard(display, CurrentTime);
            XDestroyWindow(display, window);
            XCloseDisplay(display);

            display = XOpenDisplay(NULL);
            rootwindow = DefaultRootWindow(display);
            window = XCreateWindow(display, rootwindow,
                                   -99, -99, 1, 1, /* x, y, width, height */
                                   0, 0, InputOnly, /* border, depth, class */
                                   CopyFromParent, /* visual */
                                   0, NULL); /* valuemask and attributes */

            XSelectInput(display, window, StructureNotifyMask | SubstructureRedirectMask | ResizeRedirectMask | KeyPressMask | KeyReleaseMask);
            XLowerWindow(display, window);
            XMapWindow(display, window);

            do {
                XNextEvent(display, &event);
            } while (event.type != MapNotify);

            XGrabKeyboard(display, window, False, GrabModeAsync, GrabModeAsync, CurrentTime);
            XLowerWindow(display, window);

            escape = XKeysymToKeycode(display, XK_Escape);

        } else {

            printf("Event type %d\n", event.type);
            fflush(stdout);
        }
    }

    XUngrabKeyboard(display, CurrentTime);

    XDestroyWindow(display, window);
    XCloseDisplay(display);
    return 0;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.