Permalink
Browse files

new file: EventLoop.lua

	new file:   IOAlertEmitter.lua
	new file:   Keyboard.lua
	modified:   tests/test_event_emitter.lua
	new file:   tests/test_event_loop.lua
	new file:   tests/test_keyboard_emitter.lua
	new file:   tests/test_snapshot.lua
  • Loading branch information...
1 parent ffcbb9b commit 0fa278ab08e005d0c50f1ba6360314227b41dd75 @Wiladams committed Nov 5, 2012
Showing with 323 additions and 49 deletions.
  1. +53 −0 EventLoop.lua
  2. +66 −0 IOAlertEmitter.lua
  3. +42 −0 Keyboard.lua
  4. +4 −49 tests/test_event_emitter.lua
  5. +20 −0 tests/test_event_loop.lua
  6. +74 −0 tests/test_keyboard_emitter.lua
  7. +64 −0 tests/test_snapshot.lua
View
@@ -0,0 +1,53 @@
+local IOAlertEmitter = require "IOAlertEmitter"
+
+local EventLoop = {}
+local EventLoop_mt = {
+ __index = EventLoop,
+}
+
+EventLoop.new = function()
+ local obj = {
+ Observers = {},
+ Emitter = IOAlertEmitter.new(),
+ }
+
+ setmetatable(obj, EventLoop_mt);
+
+ return obj;
+end
+
+
+EventLoop.AddEmitter = function(self, emitter, observer)
+ observer = observer or emitter
+ self.Observers[emitter.AlertHandle:getfd()] = observer;
+
+ return self.Emitter:AddAlertable(emitter.AlertHandle, observer.OnAlert, emitter.WhichAlerts);
+end
+
+EventLoop.Run = function(self, timeout)
+ timeout = timeout or 0
+
+ while true do
+ local alerts, err = self.Emitter:Wait(timeout)
+
+ if alerts and #alerts > 0 then
+ for i=1,#alerts do
+ --print("Event: ", alerts[i].fd, alerts[i].events);
+
+ -- get the appropriate observer
+ local observer = self.Observers[alerts[i].fd];
+ if observer and observer.OnAlert then
+ observer:OnAlert(alerts[i])
+ end
+ end
+ end
+
+ -- Allow some idle work to occur
+ if self.OnIdle then
+ self.OnIdle()
+ end
+ end
+end
+
+
+return EventLoop;
View
@@ -0,0 +1,66 @@
+local ffi = require "ffi"
+
+local S = require "syscall"
+local UI = require "input"
+
+local IOAlertEmitter = {}
+local IOAlertEmitter_mt = {
+ __index = IOAlertEmitter,
+}
+
+function IOAlertEmitter.new()
+ local handle, err = S.epoll_create();
+ if not handle then
+ return false, err
+ end
+
+ local obj = {
+ AlertHandle = handle,
+ }
+
+ setmetatable(obj, IOAlertEmitter_mt);
+
+ return obj;
+end
+
+
+
+--[[
+ event must have the following:
+ Descriptor - file descriptor
+ actions - bitwise OR of actions to observe
+--]]
+
+function IOAlertEmitter:AddAlertable(fd, onactivity, whichalerts)
+ if not fd then
+ return false, "IOAlertEmitter:AddAlertable(), no descriptor specified"
+ end
+
+ whichalerts = whichalerts or S.c.POLL.RDNORM;
+
+ local event = S.t.epoll_event();
+ event.events = whichalerts;
+ event.data.fd = fd:getfd();
+
+ return S.epoll_ctl(self.AlertHandle, S.c.EPOLL_CTL.ADD, event.data.fd, event);
+end
+
+function IOAlertEmitter:AddObserver(observer)
+ local event = S.t.epoll_event();
+ event.events = observer.actions;
+ event.data.fd = observer.Descriptor:getfd();
+
+ return S.epoll_ctl(self.AlertHandle, S.c.EPOLL_CTL.ADD, event.data.fd, event);
+end
+
+function IOAlertEmitter:RemoveObserver(observer)
+ return S.epoll_ctl(self.AlertHandle, S.c.EPOLL_CTL.DEL, observer.fd, nil);
+end
+
+function IOAlertEmitter:Wait(timeout, events, maxevents)
+ timeout = timeout or 0
+
+ return S.epoll_wait(self.AlertHandle, events, maxevents, timeout);
+end
+
+return IOAlertEmitter;
View
@@ -0,0 +1,42 @@
+local ffi = require "ffi"
+
+local S = require "syscall"
+local UI = require "input"
+
+local Keyboard = {}
+local Keyboard_mt = {
+ __index = Keyboard,
+}
+
+
+Keyboard.new = function(devicename)
+ devicename = devicename or "/dev/input/event0";
+
+ -- Create Actual Device Handle
+ local devicefd, err = S.open(devicename, S.c.O.RDONLY);
+ if not devicefd then
+ return false, err
+ end
+
+ local obj = {
+ DeviceDescriptor = devicefd,
+ AlertHandle = devicefd,
+ WhichAlerts = S.c.POLL.RDNORM,
+ }
+
+ setmetatable(obj, Keyboard_mt)
+
+ return obj
+end
+
+Keyboard.OnAlert = function(self, alert)
+ -- fd, events
+ print("Keyboard.OnAlert: ", alert);
+
+ -- Read the keyboard device
+ local event = input_event();
+ local bytesread = S.read(alert.fd, event, ffi.sizeof(event));
+
+end
+
+return Keyboard;
@@ -4,56 +4,9 @@ local ffi = require "ffi"
local S = require "syscall"
local UI = require "input"
+local IOAlertEmitter = require "IOAlertEmitter"
-IOEventEmitter = {}
-IOEventEmitter_mt = {
- __index = IOEventEmitter,
-}
-function IOEventEmitter.new()
- local handle, err = S.epoll_create();
- if not handle then
- return false, err
- end
-
- local obj = {
- Handle = handle,
- }
-
- setmetatable(obj, IOEventEmitter_mt);
-
- return obj;
-
-end
-
-
-function IOEventEmitter:ModifyDescriptor(fd)
- return S.epoll_ctl(self.Handle, S.c.EPOLL_CTL.MOD, fd, event);
-end
-
-function IOEventEmitter:Wait(timeout, events, maxevents)
- timeout = timeout or 0
-
- return S.epoll_wait(self.Handle, events, maxevents, timeout);
-end
-
---[[
- event must have the following:
- Descriptor - file descriptor
- actions - bitwise OR of actions to observe
---]]
-
-function IOEventEmitter:AddObserver(observer)
- local event = S.t.epoll_event();
- event.events = observer.actions;
- event.data.fd = observer.Descriptor:getfd();
-
- return S.epoll_ctl(self.Handle, S.c.EPOLL_CTL.ADD, event.data.fd, event);
-end
-
-function IOEventEmitter:RemoveObserver(observer)
- return S.epoll_ctl(self.Handle, S.c.EPOLL_CTL.DEL, observer.fd, nil);
-end
--[[
@@ -142,7 +95,9 @@ end
Create Observers
--]]
-local emitter = IOEventEmitter.new();
+local emitter = IOAlertEmitter.new();
+
+assert(emitter, "Did not create alert emitter");
local keyObserver = AddKeyboardObserver(emitter, OnKey);
View
@@ -0,0 +1,20 @@
+package.path = package.path..";../?.lua"
+
+local Keyboard = require "Keyboard"
+local EventLoop = require "EventLoop"
+
+
+--[[
+ Create Keyboard Device
+--]]
+local loop = EventLoop.new();
+local kbd = Keyboard.new();
+
+
+print("AddEmitter: ", loop:AddEmitter(kbd));
+
+loop:Run(15);
+
+
+
+
@@ -0,0 +1,74 @@
+package.path = package.path..";../?.lua"
+
+local ffi = require "ffi"
+
+local S = require "syscall"
+local UI = require "input"
+local Keyboard = require "Keyboard"
+
+
+
+
+--[[
+ Callback functions
+--]]
+
+
+
+
+--[[
+ Event type:
+ EV_KEY
+ EV_MSC
+
+ value:
+ 0 == keyup
+ 1 == keydown
+--]]
+
+function OnKey(loop, observer)
+ local event = input_event();
+ --local bytesread = S.read(w.fd, event, ffi.sizeof(event));
+ local bytesread = observer.Descriptor:read(event, ffi.sizeof(event));
+
+ if event.type == EV_MSC then
+ if event.code == MSC_SCAN then
+ --print("MSC_SCAN: ", string.format("0x%x",event.value));
+ else
+ --print("MSC: ", event.code, event.value);
+ end
+ elseif event.type == EV_KEY then
+ if event.value == 1 then
+ print("KEYDOWN: ", event.code);
+ elseif event.value == 0 then
+ print("KEYUP: ", event.code);
+
+ if event.code == KEY_ESC then
+ loop:halt();
+ return false;
+ end
+
+ elseif event.value == 2 then
+ print("KEYREP: ", event.code);
+ end
+ else
+ --print("EVENT TYPE: ", UI.EventTypes[event.type][2], "CODE:",event.code, "VALUE: ", string.format("0x%x",event.value));
+ end
+end
+
+
+
+--[[
+ Create Keyboard Device
+--]]
+local kbd = Keyboard.new();
+
+
+-- Run a loop
+local timeout = 500
+while true do
+ local ret, err = kbd:Step();
+end
+
+
+
View
@@ -0,0 +1,64 @@
+package.path = package.path..";../?.lua"
+
+local ffi = require "ffi"
+local DMX = require "DisplayManX"
+
+local Display = DMXDisplay();
+Display:SetBackground(0,0,0);
+
+local screenWidth, screenHeight = Display:GetSize();
+local ratio = screenWidth / screenHeight;
+local displayHeight = 320;
+local displayWidth = 640;
+--local displayHeight = 70;
+--local displayWidth = displayHeight * ratio;
+
+
+-- Create the view that will display the snapshot
+local displayView = Display:CreateView(
+ displayWidth, displayHeight,
+ 0, screenHeight-displayHeight-1,
+ 0, ffi.C.VC_IMAGE_RGB888)
+
+
+
+
+local function WritePPM(filename, pixbuff)
+ local r, c, val;
+
+ local fp = io.open(filename, "wb")
+ if not fp then
+ return false
+ end
+
+ local header = string.format("P6\n%d %d\n255\n", pixbuff.Width, pixbuff.Height)
+ fp:write(header);
+
+ for row=0,pixbuff.Height-1 do
+ local dataPtr = ffi.cast("char *",pixbuff.Data) + pixbuff.Pitch*row
+ local data = ffi.string(dataPtr, pixbuff.Width*3);
+ fp:write(data);
+ end
+
+ fp:close();
+end
+
+
+-- Do the snapshot
+displayView:Hide();
+Display:Snapshot(displayView.Resource);
+displayView:Show();
+
+
+local pixeldata, err = displayView.Resource:ReadPixelData();
+if pixeldata then
+ -- Write the data out
+ local filename = "desktop.ppm"
+ print("Writing: ", filename);
+
+ WritePPM(filename, pixeldata);
+end
+
+ffi.C.sleep(5);
+
+

0 comments on commit 0fa278a

Please sign in to comment.