Initial commit

This commit is contained in:
Chris 2016-12-26 20:54:28 +01:00
commit f9c2f8f543
8 changed files with 259 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/vendor

17
composer.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "noccylabs/x11",
"description": "Interact with windows on Linux/X11",
"type": "library",
"license": "GPL-3.0",
"authors": [
{
"name": "Christopher Vagnetoft",
"email": "cvagnetoft@gmail.com"
}
],
"autoload": {
"psr-4": {
"NoccyLabs\\X11\\": "src/"
}
}
}

20
examples/find_windows.php Normal file
View File

@ -0,0 +1,20 @@
<?php
require_once __DIR__."/../vendor/autoload.php";
use NoccyLabs\X11\WindowList;
// Create a list of all windows
$windows = new WindowList();
$windows->dump();
// Select all the windows with a title matching *code*
$windows = $windows->visible()->find("*code*");
$windows->dump();
// Grab the first window
$window = $windows->first();
$window->dump();
// Focus the window and simulate F1 being pressed
$window->focus()->sendKeys("F1");

View File

@ -0,0 +1,11 @@
<?php
require_once __DIR__."/../vendor/autoload.php";
use NoccyLabs\X11\WindowSelector;
$selector = new WindowSelector();
printf("Click a window to select it...\n");
$window = $selector->select();
$window->dump();

8
examples/self_keys.php Normal file
View File

@ -0,0 +1,8 @@
<?php
require_once __DIR__."/../vendor/autoload.php";
use NoccyLabs\X11\Window;
$me = new Window();
$me->sendKeys("l s Return", true);

97
src/Window.php Normal file
View File

@ -0,0 +1,97 @@
<?php
namespace NoccyLabs\X11;
class Window
{
protected $windowId;
protected $windowTitle;
protected $isVisible;
public function __construct($id=null)
{
if (!$id) { $id = (int)exec("xdotool getactivewindow"); }
$this->windowId = $id;
$this->readWindowInfo();
}
private function readWindowInfo()
{
exec("xwininfo -id {$this->windowId} -all -children", $output, $status);
foreach ($output as $line) {
if (preg_match('/^(.+?): (.+?)$/', trim($line), $match)) {
switch ($match[1]) {
case 'xwininfo':
if (preg_match('/Window id: .+? "(.+?)"/', $match[2], $m)) {
$this->windowTitle = $m[1];
}
break;
case 'Map State':
$this->isVisible = ($match[2]=='IsViewable');
break;
default:
//printf("[%s]->'%s'\n", $match[1], $match[2]);
}
}
}
//printf("---\n");
}
public function getId()
{
return hexdec($this->windowId);
}
public function isVisible()
{
return $this->isVisible;
}
public function getWindowTitle()
{
return $this->windowTitle;
}
public function sendKeys($keys, $forceFocus=false)
{
if ($forceFocus) {
$this->focus();
$cmdl = sprintf("xdotool key %s", $keys);
} else {
$cmdl = sprintf("xdotool key --delay 100 --window %d %s", $this->windowId, $keys);
}
echo "$ {$cmdl}\n";
exec($cmdl);
return $this;
}
public function focus()
{
$cmdl = sprintf("xdotool windowfocus %d", $this->windowId);
echo "$ {$cmdl}\n";
exec($cmdl);
return $this;
}
public function activate()
{
$cmdl = sprintf("xdotool windowactivate %d", $this->windowId);
echo "$ {$cmdl}\n";
exec($cmdl);
return $this;
}
public function dump()
{
printf("Window: (id=0x%08x)\n Title: %s\n Visible: %s\n",
$this->windowId,
$this->windowTitle,
$this->isVisible?'true':'false'
);
}
}

88
src/WindowList.php Normal file
View File

@ -0,0 +1,88 @@
<?php
namespace NoccyLabs\X11;
use IteratorAggregate;
use ArrayIterator;
use Countable;
class WindowList implements IteratorAggregate, Countable
{
private $windows = [];
public function __construct(array $windows=null)
{
if (null === $windows) {
$this->readRootWindowTree();
} elseif (is_array($windows)) {
$this->windows = $windows;
}
}
public function getIterator()
{
return new ArrayIterator($this->windows);
}
public function count()
{
return count($this->windows);
}
private function readRootWindowTree()
{
exec("xwininfo -root -tree", $output, $status);
$this->windows = [];
foreach ($output as $line) {
if (preg_match('/^\s+0x([0-9a-f]+?) (.+?)\: \((.+?)\)/', $line, $match)) {
$this->windows[] = new Window(hexdec($match[1]));
}
}
}
public function find($title)
{
$found = [];
foreach ($this->windows as $window) {
if (fnmatch($title, $window->getWindowTitle(), FNM_CASEFOLD)) {
$found[] = $window;
}
}
return new WindowList($found);
}
public function findByClass($class)
{
$found = [];
return new WindowList($found);
}
public function getRootWindow()
{
}
public function visible()
{
$found = [];
foreach ($this->windows as $window) {
if ($window->isVisible())
$found[] = $window;
}
return new WindowList($found);
}
public function first()
{
return count($this->windows)?$this->windows[0]:null;
}
public function dump()
{
printf("WindowList: (count=%d)\n", count($this));
foreach ($this as $window) {
printf(" 0x%08x: %s %s\n", $window->getId(), $window->getWindowTitle(), $window->isVisible()?'(Visible)':'');
}
}
}

17
src/WindowSelector.php Normal file
View File

@ -0,0 +1,17 @@
<?php
namespace NoccyLabs\X11;
class WindowSelector
{
public function select()
{
$id = exec("xdotool selectwindow");
if (is_numeric($id)) {
return new Window($id);
}
return null;
}
}