├── .gitattributes ├── .gitignore ├── BcmHost.lua ├── DisplayManX.lua ├── Drawing.lua ├── EventLoop.lua ├── GLES2Man.lua ├── GLESMan.lua ├── IOAlertEmitter.lua ├── Keyboard.lua ├── Mouse.lua ├── OpenVG.lua ├── OpenVGApp.lua ├── OpenVG_Utils.lua ├── README.md ├── TVService.lua ├── bcm_host.lua ├── common.lua ├── connection.lua ├── ctest.lua ├── docs └── event-codes.txt ├── egl.lua ├── egl_utils.lua ├── eglplatform.lua ├── experimental ├── Application.lua ├── MouseInteractor.lua ├── OMX.lua ├── OMX_Core.lua ├── OMX_IVCommon.lua ├── OMX_Index.lua ├── OMX_Other.lua ├── OMX_Types.lua ├── OMX_Video.lua ├── ev.lua ├── ev_utils.lua ├── font.lua ├── freetype.lua ├── freetype_utils.lua ├── graphics_x_private.lua ├── ilclient.lua ├── ilcore.lua ├── libev.lua ├── metadata_fourcc.lua ├── test_libev.lua ├── test_video.lua ├── vc_vchi_gencmd_c.lua ├── vc_vchi_gencmd_h.lua └── vgft.lua ├── gl.lua ├── gl2.lua ├── gl2ext.lua ├── glext.h ├── gpio.lua ├── include ├── constants-arm.lua ├── constants-mips.lua ├── constants-ppc.lua ├── constants-x64.lua ├── constants-x86.lua ├── constants.lua ├── headers-x64.lua ├── headers-x86.lua ├── headers.lua ├── ioctl.lua └── types.lua ├── input.lua ├── khrplatform.lua ├── libc.lua ├── message.lua ├── nl.lua ├── rpiui.lua ├── strict.lua ├── syscall.lua ├── test_snapshot.lua ├── tests ├── Djenne_128_128.raw ├── Gaudi_128_128.raw ├── Lucca_128_128.raw ├── PGMCodec.lua ├── PSLoader.lua ├── cube_texture_and_coords.lua ├── luaunit.lua ├── media │ ├── desktop.mp4 │ └── desktop.ppm ├── snapper.lua ├── test.lua ├── test_App_Watcher.lua ├── test_bcm_host.lua ├── test_bit.c ├── test_blink1.lua ├── test_bouncing_square.lua ├── test_dispmanx.lua ├── test_egl.lua ├── test_egl_vg_window.lua ├── test_egl_window.lua ├── test_egles_basic.lua ├── test_enumdispman.lua ├── test_event_emitter.lua ├── test_event_loop.lua ├── test_followmouse.lua ├── test_input.c ├── test_input.lua ├── test_keyboard.lua ├── test_keyboard_emitter.lua ├── test_mouse.lua ├── test_moveview.lua ├── test_picast.lua ├── test_snapshot.lua ├── test_syscall.lua ├── test_tiger.lua ├── test_triangle.lua ├── test_window_basic.lua └── tiger.lua ├── vc_cec.lua ├── vc_cecservice.lua ├── vc_display_types.lua ├── vc_dispmanx.lua ├── vc_dispmanx_types.lua ├── vc_dispservice_x_defs.lua ├── vc_hdmi.lua ├── vc_hdmi_property.lua ├── vc_image_types.lua ├── vc_sdtv.lua ├── vc_tvservice.lua ├── vc_tvservice_defs.lua ├── vcgencmd.lua ├── vchi.lua ├── vchi_cfg.lua ├── vchi_cfg_internal.lua ├── vchi_common.lua ├── vchi_mh.lua ├── vcos.lua ├── vcos_assert.lua ├── vcos_init.lua ├── vcos_platform.lua ├── vcos_platform_types.lua ├── vcos_semaphore.lua ├── vcos_types.lua ├── vgext.lua └── vgu.lua /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | experimental/test.h264 2 | 3 | ################# 4 | ## Eclipse 5 | ################# 6 | 7 | *.pydevproject 8 | .project 9 | .metadata 10 | bin/ 11 | tmp/ 12 | *.tmp 13 | *.bak 14 | *.swp 15 | *~.nib 16 | local.properties 17 | .classpath 18 | .settings/ 19 | .loadpath 20 | 21 | # External tool builders 22 | .externalToolBuilders/ 23 | 24 | # Locally stored "Eclipse launch configurations" 25 | *.launch 26 | 27 | # CDT-specific 28 | .cproject 29 | 30 | # PDT-specific 31 | .buildpath 32 | 33 | 34 | ################# 35 | ## Visual Studio 36 | ################# 37 | 38 | ## Ignore Visual Studio temporary files, build results, and 39 | ## files generated by popular Visual Studio add-ons. 40 | 41 | # User-specific files 42 | *.suo 43 | *.user 44 | *.sln.docstates 45 | 46 | # Build results 47 | [Dd]ebug/ 48 | [Rr]elease/ 49 | *_i.c 50 | *_p.c 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.vspscc 65 | .builds 66 | *.dotCover 67 | 68 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 69 | #packages/ 70 | 71 | # Visual C++ cache files 72 | ipch/ 73 | *.aps 74 | *.ncb 75 | *.opensdf 76 | *.sdf 77 | 78 | # Visual Studio profiler 79 | *.psess 80 | *.vsp 81 | 82 | # ReSharper is a .NET coding add-in 83 | _ReSharper* 84 | 85 | # Installshield output folder 86 | [Ee]xpress 87 | 88 | # DocProject is a documentation generator add-in 89 | DocProject/buildhelp/ 90 | DocProject/Help/*.HxT 91 | DocProject/Help/*.HxC 92 | DocProject/Help/*.hhc 93 | DocProject/Help/*.hhk 94 | DocProject/Help/*.hhp 95 | DocProject/Help/Html2 96 | DocProject/Help/html 97 | 98 | # Click-Once directory 99 | publish 100 | 101 | # Others 102 | [Bb]in 103 | [Oo]bj 104 | sql 105 | TestResults 106 | *.Cache 107 | ClientBin 108 | stylecop.* 109 | ~$* 110 | *.dbmdl 111 | Generated_Code #added for RIA/Silverlight projects 112 | 113 | # Backup & report files from converting an old project file to a newer 114 | # Visual Studio version. Backup files are not needed, because we have git ;-) 115 | _UpgradeReport_Files/ 116 | Backup*/ 117 | UpgradeLog*.XML 118 | 119 | 120 | 121 | ############ 122 | ## Windows 123 | ############ 124 | 125 | # Windows image file caches 126 | Thumbs.db 127 | 128 | # Folder config file 129 | Desktop.ini 130 | 131 | 132 | ############# 133 | ## Python 134 | ############# 135 | 136 | *.py[co] 137 | 138 | # Packages 139 | *.egg 140 | *.egg-info 141 | dist 142 | build 143 | eggs 144 | parts 145 | bin 146 | var 147 | sdist 148 | develop-eggs 149 | .installed.cfg 150 | 151 | # Installer logs 152 | pip-log.txt 153 | 154 | # Unit test / coverage reports 155 | .coverage 156 | .tox 157 | 158 | #Translations 159 | *.mo 160 | 161 | #Mr Developer 162 | .mr.developer.cfg 163 | 164 | # Mac crap 165 | .DS_Store 166 | -------------------------------------------------------------------------------- /BcmHost.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | local host = require "bcm_host" 5 | 6 | 7 | local bcm_host_lib = ffi.load("bcm_host"); 8 | 9 | --[[ 10 | The bcm_host_init() function must be called 11 | before any other functions in the library can be 12 | utilized. This will be done automatically 13 | if the developer does: 14 | require "bcm_host" 15 | --]] 16 | 17 | bcm_host_lib.bcm_host_init(); 18 | 19 | 20 | 21 | 22 | 23 | local GetDisplaySize = function(display_number) 24 | display_number = display_number or 0 25 | local pWidth = ffi.new("uint32_t[1]"); 26 | local pHeight = ffi.new("uint32_t[1]"); 27 | 28 | local err = lib.graphics_get_display_size(display_number, pWidth, pHeight); 29 | 30 | -- Return immediately if there was an error 31 | if err ~= 0 then 32 | return false, err 33 | end 34 | 35 | return pWidth[0], pHeight[0]; 36 | end 37 | 38 | return { 39 | -- Libraries 40 | Lib = lib, 41 | bcm_host_lib = bcm_host_lib, 42 | 43 | GetDisplaySize = GetDisplaySize, 44 | } 45 | -------------------------------------------------------------------------------- /Drawing.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | local bit = require "bit" 3 | local bor = bit.bor 4 | 5 | local EGL = require "egl_utils" 6 | 7 | local OpenVG = require "OpenVG" 8 | local OpenVGUtils = require "OpenVG_Utils" 9 | 10 | 11 | -- Color functions 12 | -- 13 | -- 14 | 15 | -- RGB returns a solid color from a RGB triple 16 | function RGB(r, g, b, color) 17 | return RGBA(r, g, b, 1.0, color); 18 | end 19 | 20 | 21 | -- RGBA fills a color vectors from a RGBA quad. 22 | function RGBA(r, g, b, a, color) 23 | if (r > 255) then 24 | r = 0; 25 | end 26 | if (g > 255) then 27 | g = 0; 28 | end 29 | if (b > 255) then 30 | b = 0; 31 | end 32 | if (a < 0.0 or a > 1.0) then 33 | a = 1.0; 34 | end 35 | 36 | color[0] = r / 255.0; 37 | color[1] = g / 255.0; 38 | color[2] = b / 255.0; 39 | color[3] = a; 40 | 41 | return color 42 | end 43 | 44 | 45 | 46 | 47 | local Renderer = {} 48 | local Renderer_mt = { 49 | __index = Renderer, 50 | } 51 | 52 | function Renderer.new(display, width, height) 53 | local self = { 54 | Display = display; 55 | Width = width; 56 | Height = height; 57 | TransformStack = {}; 58 | } 59 | 60 | setmetatable(self, Renderer_mt); 61 | 62 | --[[ 63 | self.SansTypeface = loadfont(DejaVuSans_glyphPoints, 64 | DejaVuSans_glyphPointIndices, 65 | DejaVuSans_glyphInstructions, 66 | DejaVuSans_glyphInstructionIndices, 67 | DejaVuSans_glyphInstructionCounts, 68 | DejaVuSans_glyphAdvances, DejaVuSans_characterMap, DejaVuSans_glyphCount); 69 | 70 | self.SerifTypeface = loadfont(DejaVuSerif_glyphPoints, 71 | DejaVuSerif_glyphPointIndices, 72 | DejaVuSerif_glyphInstructions, 73 | DejaVuSerif_glyphInstructionIndices, 74 | DejaVuSerif_glyphInstructionCounts, 75 | DejaVuSerif_glyphAdvances, DejaVuSerif_characterMap, DejaVuSerif_glyphCount); 76 | 77 | self.MonoTypeface = loadfont(DejaVuSansMono_glyphPoints, 78 | DejaVuSansMono_glyphPointIndices, 79 | DejaVuSansMono_glyphInstructions, 80 | DejaVuSansMono_glyphInstructionIndices, 81 | DejaVuSansMono_glyphInstructionCounts, 82 | DejaVuSansMono_glyphAdvances, DejaVuSansMono_characterMap, DejaVuSansMono_glyphCount); 83 | --]] 84 | 85 | return self 86 | end 87 | 88 | 89 | -- Start begins the picture, clearing a rectangular region with a specified color 90 | function Renderer:Begin() 91 | 92 | local color = ffi.new("VGfloat[4]", 255, 255, 255, 1); 93 | EGL.Lib.vgSetfv(ffi.C.VG_CLEAR_COLOR, 4, color); 94 | EGL.Lib.vgClear(0, 0, self.Width, self.Height); 95 | 96 | color[0] = 0; 97 | color[1] = 0; 98 | color[2] = 0; 99 | self:SetFill(color); 100 | self:SetStrokeColor(color); 101 | self:StrokeWidth(0); 102 | 103 | EGL.Lib.vgLoadIdentity(); 104 | end 105 | 106 | -- End checks for errors, and renders to the display 107 | function Renderer:End() 108 | --assert(EGL.Lib.vgGetError() == ffi.C.VG_NO_ERROR); 109 | self.Display:SwapBuffers(); 110 | --assert(EGL.Lib.eglGetError() == EGL.EGL_SUCCESS); 111 | end 112 | 113 | function Renderer:Flush() 114 | EGL.Lib.vgFlush(); 115 | end 116 | 117 | function Renderer:Finish() 118 | EGL.Lib.vgFinish(); 119 | end 120 | 121 | 122 | 123 | -- 124 | -- Transformations 125 | -- 126 | 127 | function Renderer:PushTransform() 128 | local mTrans = ffi.new("VGfloat[9]"); 129 | EGL.Lib.vgGetMatrix(mTrans); 130 | table.insert(self.TransformStack, mTrans); 131 | end 132 | 133 | function Renderer:PopTransform() 134 | if #self.TransformStack < 1 then 135 | return 136 | end 137 | 138 | local mTrans = self.TransformStack[#self.TransformStack]; 139 | table.remove(self.TransformStack, #self.TransformStack); 140 | 141 | EGL.Lib.vgLoadMatrix(mTrans); 142 | end 143 | 144 | -- Translate the coordinate system to x,y 145 | function Renderer:Translate(x, y) 146 | EGL.Lib.vgTranslate(x, y); 147 | end 148 | 149 | -- Rotate around angle r 150 | function Renderer:Rotate(r) 151 | EGL.Lib.vgRotate(r); 152 | end 153 | 154 | -- Shear shears the x coordinate by x degrees, the y coordinate by y degrees 155 | function Renderer:Shear(x, y) 156 | EGL.Lib.vgShear(x, y) 157 | end 158 | 159 | -- Scale scales by x, y 160 | function Renderer:Scale(x, y) 161 | EGL.Lib.vgScale(x, y); 162 | end 163 | 164 | -- 165 | -- Style functions 166 | -- 167 | 168 | -- setfill sets the fill color 169 | function Renderer:SetFill(color) 170 | local fillPaint, err = OpenVGUtils.Paint(); 171 | if not fillPaint then 172 | print("SetFill Failed: ", err); 173 | return false; 174 | end 175 | 176 | fillPaint:SetType(ffi.C.VG_PAINT_TYPE_COLOR); 177 | fillPaint:SetColor(color); 178 | fillPaint:SetModes(ffi.C.VG_FILL_PATH); 179 | end 180 | 181 | -- setstroke sets the stroke color 182 | function Renderer:SetStrokeColor(color) 183 | local strokePaint = OpenVGUtils.Paint(); 184 | strokePaint:SetType(ffi.C.VG_PAINT_TYPE_COLOR); 185 | strokePaint:SetColor(color); 186 | strokePaint:SetModes(ffi.C.VG_STROKE_PATH); 187 | end 188 | 189 | 190 | -- StrokeWidth sets the stroke width 191 | function Renderer:StrokeWidth(width) 192 | EGL.Lib.vgSetf(ffi.C.VG_STROKE_LINE_WIDTH, width); 193 | EGL.Lib.vgSeti(ffi.C.VG_STROKE_CAP_STYLE, ffi.C.VG_CAP_BUTT); 194 | EGL.Lib.vgSeti(ffi.C.VG_STROKE_JOIN_STYLE, ffi.C.VG_JOIN_MITER); 195 | end 196 | 197 | 198 | -- Fill sets the fillcolor, defined as a RGBA quad. 199 | function Renderer:Fill(r, g, b, a) 200 | local color = ffi.new("VGfloat[4]") 201 | RGBA(r, g, b, a, color); 202 | self:SetFill(color); 203 | end 204 | 205 | function Renderer:SetStroke(r,g,b,a) 206 | local color = ffi.new("VGfloat[4]") 207 | RGBA(r, g, b, a, color); 208 | self:SetStrokeColor(color); 209 | end 210 | 211 | -- clear the screen to a background color 212 | function Renderer:Background(r, g, b) 213 | self:Fill(r, g, b, 1); 214 | self:Rect(0, 0,self.Width, self.Height); 215 | end 216 | 217 | 218 | --[[ 219 | Shape drawing functions 220 | --]] 221 | 222 | -- Line makes a line from (x1,y1) to (x2,y2) 223 | function Renderer:Line(x1, y1, x2, y2) 224 | OpenVGUtils.Paths.Line(x1, y1, x2, y2):Draw(); 225 | end 226 | 227 | -- interleave interleaves arrays of x, y into a single array 228 | function interleave(x, y, n, points) 229 | while (n>0) do 230 | points[0] = x[0]; 231 | points = points + 1; 232 | points[0] = y[0]; 233 | points = points + 1; 234 | x = x + 1; 235 | y = y + 1; 236 | n = n - 1 237 | end 238 | end 239 | 240 | -- poly makes either a polygon or polyline 241 | function poly(x, y, n, flag) 242 | flag = flag or bor(ffi.C.VG_FILL_PATH, ffi.C.VG_STROKE_PATH); 243 | 244 | local points = ffi.new("VGfloat[?]", n * 2); 245 | 246 | interleave(x, y, n, points); 247 | 248 | OpenVGUtils.Paths.Poly(points, n):Draw(flag); 249 | end 250 | 251 | -- Polygon makes a filled polygon with vertices in x, y arrays 252 | function Renderer:Polygon(x, y, n) 253 | poly(x, y, n, ffi.C.VG_FILL_PATH); 254 | end 255 | 256 | -- Polyline makes a polyline with vertices at x, y arrays 257 | function Renderer:Polyline(x, y, n) 258 | poly(x, y, n, ffi.C.VG_STROKE_PATH); 259 | end 260 | 261 | 262 | -- makecurve makes path data using specified segments and coordinates 263 | function drawcurve(segments, coords) 264 | local path = OpenVGUtils.Path(); 265 | EGL.Lib.vgAppendPathData(path, 2, segments, coords); 266 | path:Draw(); 267 | end 268 | 269 | -- CBezier makes a quadratic bezier curve 270 | function Renderer:Cbezier(sx, sy, cx, cy, px, py, ex, ey) 271 | local segments = ffi.new("VGubyte[2]", ffi.C.VG_MOVE_TO_ABS, ffi.C.VG_CUBIC_TO); 272 | local coords = ffi.new("VGfloat[8]", sx, sy, cx, cy, px, py, ex, ey); 273 | drawcurve(segments, coords); 274 | end 275 | 276 | -- QBezier makes a quadratic bezier curve 277 | function Renderer:Qbezier(sx, sy, cx, cy, ex, ey) 278 | local segments = ffi.new("VGubyte[2]", ffi.C.VG_MOVE_TO_ABS, ffi.C.VG_QUAD_TO); 279 | local coords = ffi.new("VGfloat[6]", sx, sy, cx, cy, ex, ey); 280 | drawcurve(segments, coords); 281 | end 282 | 283 | 284 | -- Rect makes a rectangle at the specified location and dimensions 285 | function Renderer:Rect(x, y, w, h) 286 | OpenVGUtils.Paths.Rect(x,y,w,h):Draw(); 287 | end 288 | 289 | -- Roundrect makes an rounded rectangle at the specified location and dimensions 290 | function Renderer:Roundrect(x, y, w, h, rw, rh) 291 | OpenVGUtils.Paths.Roundrect(x,y,w,h, rw, rh):Draw(); 292 | end 293 | 294 | -- Ellipse makes an ellipse at the specified location and dimensions 295 | function Renderer:Ellipse(x, y, w, h) 296 | OpenVGUtils.Paths.Ellipse(x,y,w,h):Draw(); 297 | end 298 | 299 | -- Circle makes a circle at the specified location and dimensions 300 | function Renderer:Circle(x, y, r) 301 | self:Ellipse(x, y, r, r); 302 | end 303 | 304 | -- Arc makes an elliptical arc at the specified location and dimensions 305 | function Arc(x, y, w, h, sa, aext) 306 | OpenVGUtils.Paths.Arc(x,y,w,h,sa,aext):Draw(); 307 | end 308 | 309 | 310 | return Renderer; 311 | -------------------------------------------------------------------------------- /EventLoop.lua: -------------------------------------------------------------------------------- 1 | local IOAlertEmitter = require "IOAlertEmitter" 2 | 3 | local EventLoop = { 4 | MaxEvents = 16, 5 | } 6 | local EventLoop_mt = { 7 | __index = EventLoop, 8 | } 9 | 10 | EventLoop.new = function(timeout, maxevents) 11 | maxevents = maxevents or EventLoop.MaxEvents 12 | 13 | local obj = { 14 | Observers = {}, 15 | Emitter = IOAlertEmitter.new(timeout, maxevents), 16 | Running = false; 17 | } 18 | 19 | setmetatable(obj, EventLoop_mt); 20 | 21 | return obj; 22 | end 23 | 24 | 25 | EventLoop.AddObservable = function(self, observable, observer) 26 | observer = observer or observable 27 | self.Observers[observable.AlertHandle:getfd()] = observer; 28 | 29 | return self.Emitter:AddAlertable(observable.AlertHandle, observer.OnAlert, observable.WhichAlerts); 30 | end 31 | 32 | EventLoop.Halt = function(self) 33 | self.Running = false; 34 | end 35 | 36 | EventLoop.OnPollEnd = function(self, alerts, count) 37 | if alerts and count > 0 then 38 | for i=0,count-1 do 39 | --print("Event: ", alerts[i].data.fd, alerts[i].events); 40 | 41 | -- get the appropriate observer 42 | local observer = self.Observers[alerts[i].data.fd]; 43 | if observer and observer.OnAlert then 44 | observer:OnAlert(self, alerts[i].data.fd, alerts[i].events) 45 | end 46 | end 47 | end 48 | end 49 | 50 | 51 | EventLoop.Run = function(self, timeout) 52 | timeout = timeout or 0 53 | 54 | self.Running = true; 55 | 56 | while self.Running do 57 | if self.OnPollBegin then 58 | self.OnPollBegin(self) 59 | end 60 | 61 | local alerts, count = self.Emitter:EPollWait() 62 | 63 | 64 | if self.OnPollEnd then 65 | self.OnPollEnd(self, alerts, count) 66 | end 67 | 68 | 69 | -- Allow some idle work to occur 70 | if self.OnIdle then 71 | self.OnIdle(self) 72 | end 73 | end 74 | end 75 | 76 | 77 | return EventLoop; 78 | -------------------------------------------------------------------------------- /GLES2Man.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | require "gl2" 4 | --require "gl2ext" 5 | 6 | local gl = ffi.load( "GLESv2" ) 7 | 8 | 9 | 10 | function GetFunctionProtoName(fname) 11 | local upname = fname:upper(); 12 | local protoname = string.format("PFN%sPROC", upname); 13 | 14 | return protoname; 15 | end 16 | 17 | function CastFunctionPointer(fname, funcptr) 18 | local protoname = GetFunctionProtoName(fname); 19 | local castfunc = ffi.cast(protoname, funcptr); 20 | 21 | return castfunc; 22 | end 23 | 24 | function GetWglFunction(fname) 25 | local funcptr = gl.wglGetProcAddress(fname); 26 | 27 | if funcptr == nil then 28 | return nil 29 | end 30 | 31 | local castfunc = CastFunctionPointer(fname, funcptr); 32 | 33 | return castfunc; 34 | end 35 | 36 | 37 | 38 | 39 | OglMan={ 40 | Lib = gl; 41 | } 42 | OglMan_mt = { 43 | __index = function(tbl, key) 44 | local funcptr = GetWglFunction(key) 45 | 46 | -- Set the function into the table of 47 | -- known functions, so next time around, 48 | -- it this code will not need to execute 49 | rawset(tbl, key, funcptr) 50 | 51 | return funcptr; 52 | end, 53 | 54 | --[[ 55 | __newindex = function(tbl, idx, value) 56 | if idx == "Execute" then 57 | rawset(tbl, idx, value) 58 | end 59 | end, 60 | --]] 61 | } 62 | 63 | setmetatable(OglMan, OglMan_mt) 64 | 65 | 66 | 67 | --[[ 68 | Convenience aliases 69 | --]] 70 | 71 | 72 | --[[ 73 | glActiveTexture = gl.glActiveTexture; 74 | glAttachShader = gl.glAttachShader; 75 | 76 | glBegin = gl.glBegin; 77 | glBlendFunc = gl.glBlendFunc; 78 | glClear = gl.glClear; 79 | glClearColor = gl.glClearColor; 80 | 81 | function glClearDepth (depth) 82 | gl.glClearDepth(depth); 83 | end 84 | 85 | function glColor(...) 86 | local arg={...}; 87 | if #arg == 3 then 88 | gl.glColor3d(arg[1], arg[2], arg[3]); 89 | elseif #arg == 4 then 90 | gl.glColor4d(arg[1], arg[2], arg[3], arg[4]); 91 | elseif #arg == 2 then 92 | gl.glColor4d(arg[1], arg[1], arg[1], arg[2]); 93 | elseif #arg == 1 then 94 | if type(arg[1] == "number") then 95 | gl.glColor3d(arg[1], arg[1], arg[1]); 96 | elseif type(arg[1]) == "table" then 97 | if #arg[1] == 3 then 98 | gl.glColor3d(arg[1], arg[2], arg[3]); 99 | elseif #arg[1] == 4 then 100 | gl.glColor4d(arg[1], arg[2], arg[3], arg[4]); 101 | end 102 | end 103 | end 104 | end 105 | 106 | glColor3f = gl.glColor3f; 107 | glColor4f = gl.glColor4f; 108 | 109 | glColorMaterial = gl.glColorMaterial; 110 | 111 | glCullFace = gl.glCullFace; 112 | 113 | glDeleteLists = gl.glDeleteLists; 114 | 115 | glDepthFunc = gl.glDepthFunc; 116 | 117 | glDepthRange = gl.glDepthRange; 118 | 119 | glDisable = gl.glDisable; 120 | glEnable = gl.glEnable; 121 | 122 | glDrawPixels = gl.glDrawPixels; 123 | 124 | glEnd = gl.glEnd; 125 | glEndList = gl.glEndList; 126 | 127 | glFinish = gl.glFinish; 128 | glFlush = gl.glFlush; 129 | 130 | glGenLists = gl.glGenLists; 131 | 132 | glGetError = gl.glGetError; 133 | glHint = gl.glHint; 134 | glLineWidth = gl.glLineWidth; 135 | 136 | glLoadIdentity = gl.glLoadIdentity; 137 | glMatrixMode = gl.glMatrixMode; 138 | glPopMatrix = gl.glPopMatrix; 139 | glPushMatrix = gl.glPushMatrix; 140 | 141 | glOrtho = gl.glOrtho; 142 | glFrustum = gl.glFrustum; 143 | 144 | glPixelStorei = gl.glPixelStorei; 145 | 146 | glPointSize = gl.glPointSize; 147 | 148 | glPolygonMode = gl.glPolygonMode; 149 | 150 | 151 | 152 | 153 | function glRasterPos(x, y) 154 | gl.glRasterPos2d(x, y); 155 | end 156 | 157 | glRasterPos2i = gl.glRasterPos2i; 158 | 159 | 160 | function glRotate(angle, x, y, z) 161 | gl.glRotated(angle, x, y, z); 162 | end 163 | 164 | glRotatef = gl.glRotatef; 165 | 166 | 167 | function glScale(x, y, z) 168 | gl.glScaled (x, y, z); 169 | end 170 | 171 | glScalef = gl.glScalef; 172 | 173 | glShadeModel = gl.glShadeModel; 174 | 175 | 176 | function glTexCoord(s, t, r, q) 177 | gl.glTexCoord2d(s, t); 178 | end 179 | 180 | glTexCoord2f = glTexCoord; 181 | glTexCoord2d = gl.glTexCoord2d; 182 | 183 | 184 | function glTranslate(x, y, z) 185 | gl.glTranslated(x, y, z); 186 | end 187 | 188 | glTranslatef = gl.glTranslatef; 189 | 190 | 191 | function glVertex(...) 192 | local arg={...}; 193 | if #arg == 3 then 194 | gl.glVertex3d(arg[1], arg[2], arg[3]); 195 | elseif #arg == 4 then 196 | gl.glVertex4d(arg[1], arg[2], arg[3], arg[4]); 197 | elseif #arg == 1 then 198 | if type(arg[1]) == "table" then 199 | if #arg[1] == 3 then 200 | gl.glVertex3d(arg[1], arg[2], arg[3]); 201 | elseif #arg[1] == 4 then 202 | gl.glVertex4d(arg[1], arg[2], arg[3], arg[4]); 203 | end 204 | end 205 | end 206 | end 207 | 208 | glVertex2f = gl.glVertex2f; 209 | glVertex3f = gl.glVertex3f; 210 | glVertex4f = gl.glVertex4f; 211 | 212 | glVertex2d = gl.glVertex2d; 213 | 214 | glViewport = gl.glViewport; 215 | --]] 216 | 217 | 218 | 219 | return OglMan; 220 | -------------------------------------------------------------------------------- /IOAlertEmitter.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | local S = require "syscall" 4 | local UI = require "input" 5 | 6 | local IOAlertEmitter = {} 7 | local IOAlertEmitter_mt = { 8 | __index = IOAlertEmitter, 9 | } 10 | 11 | function IOAlertEmitter.new(timeout, maxevents) 12 | timeout = timeout or -1 13 | maxevents = maxevents or 16 14 | 15 | local handle, err = S.epoll_create(); 16 | if not handle then 17 | return false, err 18 | end 19 | 20 | local eventBuffer = S.t.epoll_events(maxevents) 21 | 22 | local obj = { 23 | AlertHandle = handle, 24 | MaxEvents = maxevents, 25 | EventBuffer = eventBuffer, 26 | Timeout = timeout, 27 | } 28 | 29 | setmetatable(obj, IOAlertEmitter_mt); 30 | 31 | return obj; 32 | end 33 | 34 | 35 | 36 | --[[ 37 | event must have the following: 38 | Descriptor - file descriptor 39 | actions - bitwise OR of actions to observe 40 | --]] 41 | 42 | function IOAlertEmitter:AddAlertable(fd, onactivity, whichalerts) 43 | if not fd then 44 | return false, "IOAlertEmitter:AddAlertable(), no descriptor specified" 45 | end 46 | 47 | whichalerts = whichalerts or S.c.POLL.RDNORM; 48 | 49 | local event = S.t.epoll_event(); 50 | event.events = whichalerts; 51 | event.data.fd = fd:getfd(); 52 | 53 | return S.epoll_ctl(self.AlertHandle, S.c.EPOLL_CTL.ADD, event.data.fd, event); 54 | end 55 | 56 | function IOAlertEmitter:AddObserver(observer) 57 | local event = S.t.epoll_event(); 58 | event.events = observer.actions; 59 | event.data.fd = observer.Descriptor:getfd(); 60 | 61 | return S.epoll_ctl(self.AlertHandle, S.c.EPOLL_CTL.ADD, event.data.fd, event); 62 | end 63 | 64 | function IOAlertEmitter:RemoveObserver(observer) 65 | return S.epoll_ctl(self.AlertHandle, S.c.EPOLL_CTL.DEL, observer.fd, nil); 66 | end 67 | 68 | function IOAlertEmitter:EPollWait() 69 | local ret = S.C.epoll_wait(self.AlertHandle:getfd(), self.EventBuffer, self.MaxEvents, self.Timeout) 70 | if ret == -1 then 71 | return nil, S.t.error() 72 | end 73 | 74 | return self.EventBuffer, ret 75 | end 76 | 77 | function IOAlertEmitter:Wait(timeout, events, maxevents) 78 | timeout = timeout or 0; 79 | if not maxevents then 80 | events = self.EventBuffer; 81 | maxevents = self.MaxEvents; 82 | end 83 | 84 | return S.epoll_wait(self.AlertHandle, events, maxevents, timeout); 85 | end 86 | 87 | return IOAlertEmitter; 88 | -------------------------------------------------------------------------------- /Keyboard.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | local bit = require "bit" 3 | local band = bit.band 4 | local lshift = bit.lshift 5 | 6 | 7 | local S = require "syscall" 8 | local UI = require "input" 9 | 10 | 11 | 12 | 13 | local Keyboard = {} 14 | local Keyboard_mt = { 15 | __index = Keyboard, 16 | } 17 | 18 | 19 | Keyboard.new = function(handlers, devicename) 20 | devicename = devicename or "/dev/input/event0"; 21 | 22 | -- Create Actual Device Handle 23 | local devicefd, err = S.open(devicename, S.c.O.RDWR); 24 | if not devicefd then 25 | return false, err 26 | end 27 | 28 | local obj = handlers or {} 29 | obj.DeviceDescriptor = devicefd; 30 | obj.AlertHandle = devicefd; 31 | obj.WhichAlerts = S.c.POLL.RDNORM; 32 | 33 | setmetatable(obj, Keyboard_mt) 34 | 35 | return obj 36 | end 37 | 38 | 39 | 40 | Keyboard.OnAlert = function(self, loop, fd, events) 41 | --print("Keyboard.OnAlert: ", fd, events); 42 | 43 | -- Read the keyboard device 44 | local event = input_event(); 45 | local bytesread, err = S.read(fd, event, ffi.sizeof(event)); 46 | 47 | if not bytesread then 48 | return false, err 49 | end 50 | 51 | if event.type == EV_MSC then 52 | if event.code == MSC_SCAN then 53 | --print("MSC_SCAN: ", string.format("0x%x",event.value)); 54 | else 55 | --print("MSC: ", event.code, event.value); 56 | end 57 | elseif event.type == EV_KEY then 58 | if event.value == 1 and self.OnKeyDown then 59 | self:OnKeyDown(event.code); 60 | elseif event.value == 0 and self.OnKeyUp then 61 | self:OnKeyUp(event.code); 62 | elseif event.value == 2 and self.OnKeyRepeat then 63 | self:OnKeyRepeat(event.code, 1); 64 | end 65 | else 66 | --print("EVENT TYPE: ", UI.EventTypes[event.type][2], "CODE:",event.code, "VALUE: ", string.format("0x%x",event.value)); 67 | end 68 | end 69 | 70 | --[[ 71 | Get the current state of all the keys 72 | What is returned is a bitfield with KEY_MAX entries 73 | You can find out the state of any key by checking to 74 | see if the appropriate bit is set. 75 | --]] 76 | Keyboard.GetKeys = function(self) 77 | -- Maybe this buffer should be allocated 78 | -- only once, and simply zeroed for each call 79 | local key_b = ffi.new("unsigned char [?]",KEY_MAX/8 + 1); 80 | 81 | success, err = S.ioctl(self.AlertHandle:getfd(), EVIOCGKEY(ffi.sizeof(key_b)), key_b); 82 | 83 | if not success then 84 | return false, err 85 | end 86 | 87 | return key_b; 88 | end 89 | 90 | Keyboard.IsKeyPressed = function(self, keycode) 91 | local keys, err = self:GetKeys() 92 | 93 | if not keys then 94 | return false, err 95 | end 96 | 97 | return test_bit(keycode, keys); 98 | end 99 | 100 | --[[ 101 | Return the state of all the LEDs on the keyboard 102 | --]] 103 | Keyboard.GetLEDs = function(self) 104 | end 105 | 106 | Keyboard.SetLED = function(self, whichled, state) 107 | local event = input_event(); 108 | event.type = EV_LED; 109 | event.code = whichled; 110 | 111 | if state then 112 | event.value = 1; 113 | else 114 | event.value = 0; 115 | end 116 | 117 | return self.AlertHandle:write(event, ffi.sizeof(event)); 118 | end 119 | 120 | Keyboard.SetCapsLock = function(self, state) 121 | self:SetLED(LED_CAPSL, state) 122 | end 123 | 124 | Keyboard.SetNumLock = function(self, state) 125 | self:SetLED(LED_NUML, state) 126 | end 127 | 128 | Keyboard.SetScrollLock = function(self, state) 129 | self:SetLED(LED_SCROLLL, state) 130 | end 131 | 132 | return Keyboard; 133 | 134 | -------------------------------------------------------------------------------- /Mouse.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | local bit = require "bit" 3 | local band = bit.band 4 | local lshift = bit.lshift 5 | 6 | 7 | local S = require "syscall" 8 | local UI = require "input" 9 | 10 | local test_bit = function(yalv, abs_b) 11 | return (band(ffi.cast("const uint8_t *",abs_b)[yalv/8], lshift(1, yalv%8)) > 0) 12 | end 13 | 14 | 15 | local Mouse = {} 16 | local Mouse_mt = { 17 | __index = Mouse, 18 | } 19 | 20 | 21 | Mouse.new = function(handlers, devicename) 22 | devicename = devicename or "/dev/input/event2"; 23 | 24 | -- Create Actual Device Handle 25 | local devicefd, err = S.open(devicename, S.c.O.RDONLY); 26 | if not devicefd then 27 | return false, err 28 | end 29 | 30 | local obj = handlers or {} 31 | obj.DeviceDescriptor = devicefd; 32 | obj.AlertHandle = devicefd; 33 | obj.WhichAlerts = S.c.POLL.RDNORM; 34 | 35 | setmetatable(obj, Mouse_mt) 36 | 37 | return obj 38 | end 39 | 40 | 41 | 42 | Mouse.OnAlert = function(self, loop, fd, events) 43 | --print("Mouse.OnAlert: ", fd, events); 44 | 45 | -- Read the mouse device 46 | local event = input_event(); 47 | local bytesread, err = S.read(fd, event, ffi.sizeof(event)); 48 | 49 | if not bytesread then 50 | return false, err 51 | end 52 | 53 | if event.type == EV_SYN then 54 | -- do nothing 55 | elseif event.type == EV_MSC then 56 | -- do nothing 57 | -- probably MSC_SCAN, which is manufacturer scancode? 58 | elseif event.type == EV_REL then 59 | -- relative movement 60 | -- CODE == REL_X (x-axis) 61 | -- CODE == REL_Y (y-axis) 62 | -- CODE == REL_WHEEL (mouse wheel) 63 | -- VALUE > 0 forward 64 | -- VALUE < 0 backward 65 | if event.code == REL_WHEEL then 66 | self:HandleWheel(event.value); 67 | else 68 | self:HandleMove(event.code, event.value); 69 | end 70 | elseif event.type == EV_KEY then 71 | self:HandleButton(event.code, event.value); 72 | else 73 | print("MOUSE UKNOWN EVENT TYPE: ", UI.EventTypes[event.type][2], "CODE:",event.code, "VALUE: ", string.format("%d",event.value)); 74 | end 75 | 76 | 77 | end 78 | 79 | --[[ 80 | 81 | BTN_LEFT 82 | BTN_RIGHT 83 | BTN_MIDDLE 84 | BTN_SIDE 85 | BTN_EXTRA 86 | BTN_FORWARD 87 | BTN_BACK 88 | BTN_TASK 89 | VALUE: 0 -> release 90 | VALUE: 1 -> pressed 91 | 92 | --]] 93 | Mouse.HandleButton = function(self, button, value) 94 | 95 | --print("HandleButton: ", string.format("0x%x",button), value); 96 | 97 | if value == 1 and self.OnButtonPressed then 98 | self.OnButtonPressed(self, button) 99 | end 100 | 101 | if value == 0 and self.OnButtonReleased then 102 | self.OnButtonReleased(self, button) 103 | end 104 | end 105 | 106 | Mouse.HandleMove = function(self, axis, value) 107 | if self.OnMouseMove then 108 | self.OnMouseMove(self, axis, value) 109 | end 110 | end 111 | 112 | Mouse.HandleWheel = function(self, value) 113 | if self.OnMouseWheel then 114 | self.OnMouseWheel(self, value) 115 | end 116 | end 117 | 118 | 119 | --[[ 120 | Get the current state of all the keys 121 | What is returned is a bitfield with KEY_MAX entries 122 | You can find out the state of any key by checking to 123 | see if the appropriate bit is set. 124 | --]] 125 | Mouse.GetKeys = function(self) 126 | -- Maybe this buffer should be allocated 127 | -- only once, and simply zeroed for each call 128 | local key_b = ffi.new("unsigned char [?]",KEY_MAX/8 + 1); 129 | 130 | success, err = S.ioctl(self.AlertHandle:getfd(), EVIOCGKEY(ffi.sizeof(key_b)), key_b); 131 | 132 | if not success then 133 | return false, err 134 | end 135 | 136 | return key_b; 137 | end 138 | 139 | Mouse.IsKeyPressed = function(self, keycode) 140 | local keys, err = self:GetKeys() 141 | 142 | if not keys then 143 | return false, err 144 | end 145 | 146 | return test_bit(keycode, keys); 147 | end 148 | 149 | 150 | 151 | 152 | return Mouse; 153 | 154 | -------------------------------------------------------------------------------- /OpenVGApp.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | local C = ffi.C; 4 | local bit = require "bit" 5 | local bor = bit.bor 6 | local band = bit.band 7 | 8 | 9 | -- Bring in the necessary UI stuff 10 | local rpiui = require "rpiui" 11 | local DMX = require "DisplayManX" 12 | 13 | local Keyboard = require "Keyboard" 14 | local Mouse = require ("Mouse"); 15 | local EventLoop = require "EventLoop" 16 | 17 | local GLES = rpiui.GLES; 18 | local EGL = rpiui.EGL; 19 | local OpenVG = rpiui.OpenVG; 20 | local egl = require "egl" 21 | local VG = EGL.Lib; 22 | 23 | 24 | 25 | OpenVGApp = { 26 | -- Setup Display object 27 | Display = DMX.DMXDisplay(); 28 | 29 | -- Setup the event loop stuff 30 | Loop = EventLoop.new(15); 31 | } 32 | 33 | OpenVGApp.init = function(width, height, x, y) 34 | width = width or 640; 35 | height = height or 480; 36 | 37 | 38 | 39 | -- Add the keyboard 40 | OpenVGApp.Keyboard = Keyboard.new(); 41 | OpenVGApp.Keyboard.OnKeyUp = OpenVGApp.KeyUp; 42 | OpenVGApp.Keyboard.OnKeyDown = OpenVGApp.KeyDown; 43 | OpenVGApp.Loop:AddObservable(OpenVGApp.Keyboard); 44 | 45 | -- Add the mouse 46 | OpenVGApp.Mouse, err = Mouse.new(); 47 | 48 | if OpenVGApp.Mouse then 49 | OpenVGApp.Mouse.OnButtonPressed = OpenVGApp.MouseDown; 50 | OpenVGApp.Mouse.OnButtonReleased = OpenVGApp.MouseUp; 51 | OpenVGApp.Mouse.OnMouseMove = OpenVGApp.MouseMove; 52 | OpenVGApp.Mouse.OnMouseWheel = OpenVGApp.MouseWheel; 53 | OpenVGApp.Loop:AddObservable(OpenVGApp.Mouse); 54 | end 55 | 56 | -- Other interesting things with the loop 57 | OpenVGApp.Loop.OnIdle = OpenVGApp.Idle; 58 | 59 | -- Create the Main Window 60 | OpenVGApp.Window = EGL.Window.new(width, height, x,y, nil, EGL.EGL_OPENVG_API); 61 | 62 | return OpenVGApp; 63 | end 64 | 65 | 66 | OpenVGApp.Render = function(self) 67 | if self.OnRender then 68 | self.OnRender(self) 69 | end 70 | end 71 | 72 | OpenVGApp.Idle = function(loop) 73 | if OpenVGApp.OnIdle then 74 | OpenVGApp.OnIdle(OpenVGApp); 75 | end 76 | end 77 | 78 | OpenVGApp.KeyDown = function(kbd, keycode) 79 | if OpenVGApp.OnKeyDown then 80 | OpenVGApp.OnKeyDown(kbd, keycode); 81 | end 82 | end 83 | 84 | OpenVGApp.KeyUp = function(kbd, keycode) 85 | -- Halt the loop if they press the "Esc" key 86 | if OpenVGApp.OnKeyUp then 87 | OpenVGApp.OnKeyUp(kbd, keycode); 88 | else 89 | if keycode == KEY_ESC then 90 | OpenVGApp:Stop(); 91 | end 92 | end 93 | end 94 | 95 | -- Mouse Events 96 | OpenVGApp.MouseDown = function(mouse, button) 97 | if OpenVGApp.OnMouseDown then 98 | OpenVGApp.OnMouseDown(mouse, button); 99 | end 100 | end 101 | 102 | OpenVGApp.MouseUp = function(mouse, button) 103 | if OpenVGApp.OnMouseUp then 104 | OpenVGApp.OnMouseUp(mouse, button); 105 | end 106 | end 107 | 108 | OpenVGApp.MouseMove = function(mouse, axis, value) 109 | if OpenVGApp.OnMouseMove then 110 | OpenVGApp.OnMouseMove(mouse, axis, value); 111 | end 112 | end 113 | 114 | OpenVGApp.MouseWheel = function(mouse, value) 115 | if OpenVGApp.OnMouseWheel then 116 | OpenVGApp.OnMouseWheel(mouse, value); 117 | end 118 | end 119 | 120 | 121 | 122 | -- Application Control 123 | 124 | OpenVGApp.Stop = function(self) 125 | OpenVGApp.Loop:Halt(); 126 | end 127 | 128 | OpenVGApp.Run = function(self) 129 | OpenVGApp.Loop:Run(15); 130 | end 131 | 132 | return OpenVGApp 133 | -------------------------------------------------------------------------------- /OpenVG_Utils.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | local bit = require "bit" 4 | local bor = bit.bor 5 | 6 | require "OpenVG" 7 | 8 | local OpenVG = { 9 | Lib = ffi.load "OpenVG"; 10 | } 11 | 12 | 13 | ffi.cdef[[ 14 | typedef struct { 15 | VGPaint Handle; 16 | } OVGPaint; 17 | 18 | typedef struct { 19 | VGPath Handle; 20 | } OVGPath; 21 | ]] 22 | 23 | --[[ 24 | Paint object 25 | --]] 26 | Paint = ffi.typeof("OVGPaint") 27 | Paint_mt = { 28 | __new = function(ct, paintMode) 29 | local handle 30 | 31 | if not paintMode then 32 | handle = OpenVG.Lib.vgCreatePaint(); 33 | else 34 | handle = OpenVG.Lib.vgGetPaint(paintMode); 35 | end 36 | 37 | if handle == VG_INVALID_HANDLE then 38 | return nil 39 | end 40 | 41 | local obj = ffi.new(ct, handle); 42 | return obj 43 | end, 44 | 45 | __gc = function(self) 46 | OpenVG.Lib.vgDestroyPaint(self.Handle); 47 | end, 48 | 49 | __index = { 50 | SetModes = function(self, paintModes) 51 | OpenVG.Lib.vgSetPaint(self.Handle, paintModes); 52 | end, 53 | 54 | SetColor = function(self, rgba) 55 | --OpenVG.Lib.vgSetColor(self.Handle, rgba); 56 | OpenVG.Lib.vgSetParameterfv(self.Handle, ffi.C.VG_PAINT_COLOR, 4, rgba); 57 | end, 58 | 59 | GetColor = function(self) 60 | return OpenVG.Lib.vgGetColor(self.Handle); 61 | end, 62 | 63 | SetPattern = function(self, pattern) 64 | OpenVG.Lib.vgPaintPattern(self.Handle, pattern); 65 | end, 66 | 67 | SetType = function(self, pType) 68 | OpenVG.Lib.vgSetParameteri(self.Handle, ffi.C.VG_PAINT_TYPE, pType); 69 | end, 70 | }, 71 | } 72 | Paint = ffi.metatype(Paint, Paint_mt); 73 | 74 | 75 | 76 | --[[ 77 | Paths 78 | --]] 79 | 80 | Path = ffi.typeof("OVGPath"); 81 | Path_mt = { 82 | __new = function(ct, pathFormat, datatype, scale, bias, segmentCapacityHint, coordCapacityHint, capabilities) 83 | pathFormat = pathFormat or VG_PATH_FORMAT_STANDARD; 84 | datatype = datatype or ffi.C.VG_PATH_DATATYPE_F 85 | scale = scale or 1 86 | bias = bias or 0 87 | segmentCapacityHint = segmentCapacityHint or 0 88 | coordCapacityHint = coordCapacityHint or 0 89 | capabilities = capabilities or ffi.C.VG_PATH_CAPABILITY_ALL 90 | 91 | local handle = OpenVG.Lib.vgCreatePath(pathFormat, datatype, scale, bias, segmentCapacityHint, coordCapacityHint, capabilities); 92 | --print("Path Handle: ", handle); 93 | 94 | local obj = ffi.new(ct, handle); 95 | return obj 96 | end, 97 | 98 | __gc = function(self) 99 | OpenVG.Lib.vgDestroyPath(self.Handle); 100 | end, 101 | 102 | __index = { 103 | Clear = function(self, capabilities) 104 | capabilities = capabilities or ffi.C.VG_PATH_CAPABILITY_ALL 105 | 106 | OpenVG.Lib.vgClearPath(self.Handle, capabilities); 107 | end, 108 | 109 | RemoveCapabilities = function(self, capabilities) 110 | capabilities = capabilities or ffi.C.VG_PATH_CAPABILITY_ALL 111 | 112 | OpenVG.Lib.vgRemovePathCapabilities(self.Handle, capabilities); 113 | end, 114 | 115 | GetCapabilities = function(self) 116 | return OpenVG.Lib.vgGetPathCapabilities(self.Handle); 117 | end, 118 | 119 | AppendPath = function(self, path) 120 | OpenVG.Lib.vgAppendPath(self.Handle, path.Handle); 121 | end, 122 | 123 | AppendPathData = function(self, numSegments, pathSegments, pathData) 124 | OpenVG.Lib.vgAppendPathData(self.Handle, numSegments, pathSegments, pathData); 125 | end, 126 | 127 | ModifyPathCoords = function(self, startIndex, numSegments, pathData) 128 | OpenVG.Lib.vgModifyPathCoords(self.Handle, startIndex, numSegments, pathData); 129 | end, 130 | 131 | TransformPath = function(self, srcPath) 132 | OpenVG.Lib.vgTransformPath(self.Handle, srcPath.Handle); 133 | end, 134 | 135 | InterpolatePath = function(self, startPath, endPath, amount) 136 | return OpenVG.Lib.vgInterpolatePath(self.Handle, startPath.Handle, endPath.Handle, amount); 137 | end, 138 | 139 | PathLength = function(self, startSegment, numSegments) 140 | return OpenVG.Lib.vgPathLength(self.Handle, startSegment, numSegments); 141 | end, 142 | 143 | PointAlongPath = function(self, startSegment, numSegments, distance) 144 | local x = ffi.new("VGfloat[1]"); 145 | local y = ffi.new("VGFloat[1]"); 146 | local tangentX = ffi.new("VGFloat[1]"); 147 | local tangentY = ffi.new("VGFloat[1]"); 148 | 149 | OpenVG.Lib.vgPointAlongPath(self.Handle, startSegment, numSegments, distance, 150 | x, y, tangentX, tangentY); 151 | return x[0], y[0], tangentX[0], tangentY[0]; 152 | end, 153 | 154 | Bounds = function(self) 155 | local minX = ffi.new("VGfloat[1]"); 156 | local minY = ffi.new("VGfloat[1]"); 157 | local width = ffi.new("VGfloat[1]"); 158 | local height = ffi.new("VGfloat[1]"); 159 | 160 | OpenVG.Lib.vgPathBounds(self.Handle, 161 | minX, minY, 162 | width, height); 163 | return minX[0], minY[0], width[0], height[0]; 164 | end, 165 | 166 | TransformedBounds = function(self) 167 | local minX = ffi.new("VGfloat[1]"); 168 | local minY = ffi.new("VGfloat[1]"); 169 | local width = ffi.new("VGfloat[1]"); 170 | local height = ffi.new("VGfloat[1]"); 171 | 172 | OpenVG.Lib.vgPathTransformedBounds(self.Handle, minX, minY, width, height); 173 | 174 | return minX[0], minY[0], width[0], height[0]; 175 | end, 176 | 177 | Draw = function(self, paintModes) 178 | paintModes = paintModes or bor(ffi.C.VG_FILL_PATH, ffi.C.VG_STROKE_PATH) 179 | OpenVG.Lib.vgDrawPath(self.Handle, paintModes); 180 | return self; 181 | end, 182 | 183 | 184 | 185 | }, 186 | } 187 | Path = ffi.metatype(Path, Path_mt); 188 | 189 | 190 | 191 | --[[ 192 | Shapes 193 | 194 | A simple factory to create various types of path 195 | objects. 196 | --]] 197 | local Paths = { 198 | Line = function(x1, y1, x2, y2) 199 | local path = Path(); 200 | OpenVG.Lib.vguLine(path.Handle, x1, y1, x2, y2); 201 | 202 | return path; 203 | end, 204 | 205 | -- poly makes either a polygon or polyline 206 | Poly = function(points, n) 207 | local path = Path(); 208 | OpenVG.Lib.vguPolygon(path.Handle, points, n, ffi.C.VG_FALSE); 209 | return path; 210 | end, 211 | 212 | -- Rect makes a rectangle at the specified location and dimensions 213 | Rect = function(x, y, w, h) 214 | local path = Path(); 215 | OpenVG.Lib.vguRect(path.Handle, x, y, w, h); 216 | return path 217 | end, 218 | 219 | -- Roundrect makes an rounded rectangle at the specified location and dimensions 220 | Roundrect = function(x, y, w, h, rw, rh) 221 | local path = Path(); 222 | OpenVG.Lib.vguRoundRect(path.Handle, x, y, w, h, rw, rh); 223 | return path; 224 | end, 225 | 226 | -- Ellipse makes an ellipse at the specified location and dimensions 227 | Ellipse = function(x, y, w, h) 228 | local path = Path(); 229 | OpenVG.Lib.vguEllipse(path.Handle, x, y, w, h); 230 | return path; 231 | end, 232 | 233 | -- Arc makes an elliptical arc at the specified location and dimensions 234 | Arc = function(x, y, w, h, sa, aext) 235 | local path = Path(); 236 | OpenVG.Lib.vguArc(path.Handle, x, y, w, h, sa, aext, ffi.C.VGU_ARC_OPEN); 237 | return path; 238 | end, 239 | } 240 | 241 | return { 242 | Lib = OpenVG.Lib; 243 | 244 | Path = Path; 245 | Paths = Paths; 246 | Paint = Paint; 247 | 248 | } 249 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LJIT2RPi 2 | LuaJIT FFI Interop to Raspberry Pi 3 | 4 | Provides basic access to various Raspberry Pi libraries. 5 | 6 | The Raspberry Pi is basically a Linux machine, with some specialized libraries. Gaining access to the core Linux routines is best 7 | achieved by using the ljsyscall project. 8 | 9 | This project contains an earlier version of ljsyscall, as well as wrappers for the Pi specific libraries, particularly 10 | related to low level graphics. 11 | -------------------------------------------------------------------------------- /TVService.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | local host = require "BcmHost" 5 | 6 | local bcm_host_lib = ffi.load("bcm_host") 7 | local vcos_lib = ffi.load("vcos") 8 | local vchi_lib = ffi.load("vchiq_arm") 9 | 10 | require "vc_tvservice" 11 | 12 | local TVService = { 13 | init = function(initialize_instance, connections, num_connections) 14 | local result = bcm_host_lib.vc_vchi_tv_init(initialise_instance, connections, num_connections ); 15 | return result == 0 or false, result; 16 | end, 17 | 18 | stop = function() 19 | bcm_host_lib.vc_vchi_tv_stop( void ); 20 | return true; 21 | end, 22 | 23 | register_callback = function(callback, callback_data) 24 | bcm_host_lib.vc_tv_register_callback(callback, callback_data); 25 | return true; 26 | end, 27 | 28 | unregister_callback = function(callback) 29 | bcm_host_lib.vc_tv_unregister_callback(callback); 30 | return true; 31 | end, 32 | 33 | enable_copyprotect = function(cp_mode, timeout) 34 | local result = bcm_host_lib.vc_tv_enable_copyprotect(cp_mode, timeout); 35 | return result == 0 or false, result; 36 | end, 37 | 38 | disable_copyprotect = function() 39 | local result = bcm_host_lib.vc_tv_disable_copyprotect( ); 40 | return result == 0 or false, result; 41 | end, 42 | 43 | show_info = function(show) 44 | local result = bcm_host_lib.vc_tv_show_info(show); 45 | return result == 0 or false, result; 46 | end, 47 | 48 | get_state = function(tvstate) 49 | local result = bcm_host_lib.vc_tv_get_state(tvstate); 50 | return result == 0 or false, result; 51 | end, 52 | 53 | power_off = function() 54 | local result = bcm_host_lib.vc_tv_power_off(); 55 | return result == 0 or false, result; 56 | end, 57 | 58 | test_mode_start = function(colour, test_mode) 59 | local result = bcm_host_lib.vc_tv_test_mode_start(colour, test_mode); 60 | return result == 0 or false, result; 61 | end, 62 | 63 | test_mode_stop = function() 64 | local result = bcm_host_lib.vc_tv_test_mode_stop(); 65 | return result == 0 or false, result; 66 | end, 67 | 68 | notification_name = function(reason) 69 | local result = bcm_host_lib.vc_tv_notifcation_name(reason); 70 | if result ~= nil then 71 | return ffi.string(result) 72 | end 73 | 74 | return false 75 | end, 76 | 77 | -- SDTV Specific Routines 78 | sdtv_power_on = function(mode, options) 79 | local status = bcm_host_lib.vc_tv_sdtv_power_on(mode, options); 80 | return result == 0 or false, result; 81 | end, 82 | 83 | --[[ 84 | // HDMI Specific Routines 85 | int vc_tv_hdmi_power_on_preferred( void ); 86 | 87 | int vc_tv_hdmi_power_on_preferred_3d( void ); 88 | 89 | int vc_tv_hdmi_power_on_best(uint32_t width, uint32_t height, uint32_t frame_rate, 90 | HDMI_INTERLACED_T scan_mode, EDID_MODE_MATCH_FLAG_T match_flags); 91 | 92 | int vc_tv_hdmi_power_on_best_3d(uint32_t width, uint32_t height, uint32_t frame_rate, 93 | HDMI_INTERLACED_T scan_mode, EDID_MODE_MATCH_FLAG_T match_flags); 94 | 95 | int vc_tv_hdmi_power_on_explicit(HDMI_MODE_T mode, HDMI_RES_GROUP_T group, uint32_t code); 96 | 97 | int vc_tv_hdmi_get_supported_modes(HDMI_RES_GROUP_T group, 98 | TV_SUPPORTED_MODE_T *supported_modes, 99 | uint32_t max_supported_modes, 100 | HDMI_RES_GROUP_T *preferred_group, 101 | uint32_t *preferred_mode); 102 | 103 | 104 | int vc_tv_hdmi_mode_supported(HDMI_RES_GROUP_T group, uint32_t mode); 105 | 106 | int vc_tv_hdmi_audio_supported(uint32_t audio_format, uint32_t num_channels, EDID_AudioSampleRate fs, uint32_t bitrate); 107 | 108 | int vc_tv_hdmi_get_av_latency( void ); 109 | 110 | int vc_tv_hdmi_set_hdcp_key(const uint8_t *key); 111 | 112 | int vc_tv_hdmi_set_hdcp_revoked_list(const uint8_t *list, uint32_t num_keys); 113 | 114 | int vc_tv_hdmi_set_spd(const char *manufacturer, const char *description, HDMI_SPD_TYPE_CODE_T type); 115 | 116 | int vc_tv_hdmi_set_display_options(HDMI_ASPECT_T aspect, uint32_t left_bar_width, uint32_t right_bar_width, uint32_t top_bar_height, uint32_t bottom_bar_height, uint32_t overscan_flags); 117 | 118 | int vc_tv_hdmi_ddc_read(uint32_t offset, uint32_t length, uint8_t *buffer); 119 | 120 | int vc_tv_hdmi_set_attached(uint32_t attached); 121 | 122 | int vc_tv_hdmi_set_property(uint32_t property, uint32_t param1, uint32_t param2); 123 | 124 | int vc_tv_hdmi_get_property(uint32_t property, uint32_t *param1, uint32_t *param2); 125 | --]] 126 | } 127 | 128 | 129 | 130 | local function tvservice_init() 131 | pvchi_instance = ffi.new("VCHI_INSTANCE_T[1]"); 132 | pvchi_connections = ffi.new("VCHI_CONNECTION_T *[1]"); 133 | 134 | -- Assume bcm_host_init() has already been called 135 | -- bcm_host_init(); 136 | 137 | -- initialise vcos/vchi 138 | --ffi.C.vcos_init(); 139 | 140 | local result = vchi_lib.vchi_initialise(pvchi_instance) 141 | if result ~= VCHIQ_SUCCESS then 142 | return false, result 143 | end 144 | vchi_instance = pvchi_instance[0]; 145 | 146 | -- create a vchi connection 147 | result = vchi_lib.vchi_connect( nil, 0, vchi_instance ) 148 | if result ~= 0 then 149 | return false, result; 150 | end 151 | 152 | -- connect to tvservice 153 | result = vchi_lilb.vc_vchi_tv_init( vchi_instance, pvchi_connections, 1) 154 | if result ~= 0 then 155 | return false, result 156 | end 157 | end 158 | 159 | 160 | tvservice_init(); 161 | 162 | return TVService; 163 | -------------------------------------------------------------------------------- /bcm_host.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | ffi.cdef [[ 5 | void bcm_host_init(void); 6 | void bcm_host_deinit(void); 7 | 8 | int32_t graphics_get_display_size( const uint16_t display_number, uint32_t *width, uint32_t *height); 9 | ]] 10 | 11 | require "libc" 12 | 13 | require "vc_dispmanx" 14 | require "vc_tvservice" 15 | require "vcgencmd" 16 | 17 | --[[ 18 | 19 | require "interface/vmcs_host/vc_cec" 20 | require "interface/vmcs_host/vc_cecservice" 21 | --]] 22 | 23 | 24 | 25 | return { 26 | 27 | } 28 | -------------------------------------------------------------------------------- /common.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | ffi.cdef[[ 4 | typedef int bool_t; 5 | ]] 6 | -------------------------------------------------------------------------------- /ctest.lua: -------------------------------------------------------------------------------- 1 | -- generate C test file to check type sizes etc 2 | 3 | local S = require "syscall" 4 | local ffi = require "ffi" 5 | 6 | local s, t = S.s, S.t 7 | 8 | -- TODO fix these, various naming issues 9 | S.ctypes["struct linux_dirent64"] = nil 10 | S.ctypes["struct statfs64"] = nil 11 | S.ctypes["struct flock64"] = nil 12 | S.ctypes["struct stat64"] = nil 13 | S.ctypes["struct fdb_entry"] = nil 14 | S.ctypes["struct seccomp_data"] = nil 15 | S.ctypes["sighandler_t"] = nil 16 | S.ctypes["struct rlimit64"] = nil 17 | S.ctypes["struct mq_attr"] = nil 18 | 19 | -- fixes for constants 20 | S.__WALL = S.WALL; S.WALL = nil 21 | S.__WCLONE = S.WCLONE; S.WCLONE = nil 22 | 23 | -- remove seccomp for now as no support on the ARM box 24 | for k, _ in pairs(S) do 25 | if k:sub(1, 8) == 'SECCOMP_' then S[k] = nil end 26 | end 27 | 28 | -- fake constants 29 | S.MS_RO = nil 30 | S.MS_RW = nil 31 | S.IFF_ALL = nil 32 | S.IFF_NONE = nil 33 | 34 | -- TODO find the headers/flags for these if exist, or remove 35 | S.SA_RESTORER = nil 36 | S.AF_DECNET = nil 37 | S.SIG_HOLD = nil 38 | S.NOTHREAD = nil 39 | S.RTF_PREFIX_RT = nil 40 | S.RTF_EXPIRES = nil 41 | S.RTF_ROUTEINFO = nil 42 | S.RTF_ANYCAST = nil 43 | 44 | -- include kitchen sink, garbage can etc 45 | print [[ 46 | #include "assert.h" 47 | 48 | #define _GNU_SOURCE 49 | #define __USE_GNU 50 | #define _FILE_OFFSET_BITS 64 51 | #define _LARGE_FILES 1 52 | #define __USE_FILE_OFFSET64 53 | 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include 81 | #include 82 | #include 83 | #include 84 | #include 85 | #include 86 | #include 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | #include 101 | 102 | int main(int argc, char **argv) { 103 | ]] 104 | 105 | -- iterate over S.ctypes 106 | for k, v in pairs(S.ctypes) do 107 | print("assert(sizeof(" .. k .. ") == " .. ffi.sizeof(v) .. ");") 108 | end 109 | 110 | -- test all the constants 111 | 112 | for k, v in pairs(S) do 113 | if type(S[k]) == "number" then 114 | print("assert(" .. k .. " == " .. v .. ");") 115 | end 116 | end 117 | 118 | -- TODO test error codes 119 | 120 | print [[ 121 | } 122 | ]] 123 | 124 | -------------------------------------------------------------------------------- /egl_utils.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | local bit = require "bit" 4 | local lshift = bit.lshift 5 | 6 | local DMX = require "DisplayManX" 7 | local EGL = require "egl" 8 | local vgu = require "vgu" 9 | 10 | 11 | EGL.Lib = ffi.load("EGL"); 12 | 13 | 14 | local EglDisplay = {} 15 | local EglDisplay_mt = { 16 | __index = EglDisplay, 17 | } 18 | 19 | EglDisplay.new = function(api, dispid) 20 | local dpy 21 | 22 | if not dispid then 23 | dpy = EGL.Lib.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); 24 | else 25 | return nil 26 | end 27 | 28 | local obj = { 29 | Handle = dpy; 30 | } 31 | 32 | setmetatable(obj, EglDisplay_mt); 33 | 34 | obj:Initialize(); 35 | 36 | --print("BINDING TO API: ", api); 37 | if api then 38 | -- api = api or EGL.EGL_OPENVG_API 39 | assert(obj:BindToAPI(api), "Could not bind to API"); 40 | end 41 | assert(obj:ChooseConfig(), "Could not choose config"); 42 | assert(obj:CreateContext(), "Could not create context"); 43 | 44 | return obj 45 | end 46 | 47 | EglDisplay.free = function(self) 48 | local res = EGL.Lib.eglTerminate(self.Handle); 49 | end 50 | 51 | --[[ 52 | Various Attributes 53 | --]] 54 | EglDisplay.ClientAPIs = function(self) 55 | return ffi.string(EGL.Lib.eglQueryString(self.Handle, EGL.EGL_CLIENT_APIS)); 56 | end 57 | 58 | EglDisplay.CurrentAPI = function(self) 59 | return EGL.Lib.eglQueryAPI(); 60 | end 61 | 62 | EglDisplay.Vendor = function(self) 63 | return ffi.string(EGL.Lib.eglQueryString(self.Handle, EGL.EGL_VENDOR)); 64 | end 65 | 66 | 67 | EglDisplay.Extensions = function(self) 68 | return ffi.string(EGL.Lib.eglQueryString(self.Handle, EGL.EGL_EXTENSIONS)); 69 | end 70 | 71 | 72 | --[[ 73 | Meat and potatoes 74 | --]] 75 | EglDisplay.Initialize = function(self) 76 | local pmajor = ffi.new("EGLint[1]"); 77 | local pminor = ffi.new("EGLint[1]"); 78 | local res = EGL.Lib.eglInitialize(self.Handle, nil, nil); 79 | assert(res ~= EGL.EGL_FALSE); 80 | 81 | return self, pmajor[0], pminor[0]; 82 | end 83 | 84 | EglDisplay.BindToAPI = function(self, api) 85 | api = api or EGL.EGL_OPENVG_API 86 | 87 | local res = EGL.Lib.eglBindAPI(api); 88 | 89 | if res == EGL_FALSE then 90 | return nil 91 | end 92 | 93 | return self 94 | end 95 | 96 | EglDisplay.ChooseConfig = function(self, attribute_list) 97 | attribute_list = attribute_list or ffi.new("EGLint[11]", 98 | EGL.EGL_RED_SIZE, 8, 99 | EGL.EGL_GREEN_SIZE, 8, 100 | EGL.EGL_BLUE_SIZE, 8, 101 | EGL.EGL_ALPHA_SIZE, 8, 102 | EGL.EGL_SURFACE_TYPE, EGL.EGL_WINDOW_BIT, 103 | EGL.EGL_NONE); 104 | 105 | local pconfig = ffi.new("EGLConfig[10]"); 106 | local pnum_config = ffi.new("EGLint[1]"); 107 | 108 | local res = EGL.Lib.eglChooseConfig(self.Handle, attribute_list, pconfig, 10, pnum_config); 109 | 110 | assert(res == EGL.EGL_TRUE); 111 | 112 | local num_config = pnum_config[0] 113 | print("EglDisplay.ChooseConfig(): num: ", num_config); 114 | 115 | self.Config = pconfig[0]; 116 | 117 | return self.Config; 118 | end 119 | 120 | EglDisplay.CreateContext = function(self, config) 121 | config = config or self.Config 122 | 123 | local ctx = EGL.Lib.eglCreateContext(self.Handle, config, EGL.EGL_NO_CONTEXT, nil); 124 | self.Context = ctx; 125 | return ctx; 126 | end 127 | 128 | 129 | EglDisplay.CreateWindowSurface = function(self, nativewindow, config) 130 | config = config or self.Config 131 | 132 | local srf = EGL.Lib.eglCreateWindowSurface(self.Handle, config, nativewindow, nil); 133 | self.Surface = srf 134 | 135 | return srf; 136 | end 137 | 138 | 139 | 140 | EglDisplay.CreateWindow = function(self, width, height, config) 141 | config = config or self.config 142 | 143 | return EGLWindow.new(self, width , height) 144 | end 145 | 146 | EglDisplay.MakeCurrent = function(self, surface, context) 147 | surface = surface or self.Surface; 148 | context = context or self.Context; 149 | 150 | -- connect the context to the surface 151 | local res = EGL.Lib.eglMakeCurrent(self.Handle, surface, surface, context); 152 | return res 153 | end 154 | 155 | EglDisplay.SwapBuffers = function(self, surface) 156 | surface = surface or self.Surface; 157 | local res = EGL.Lib.eglSwapBuffers(self.Handle, surface); 158 | 159 | return res; 160 | end 161 | 162 | 163 | 164 | 165 | 166 | --[[ 167 | Representation of a window 168 | --]] 169 | --[[ 170 | Create a native window. This is essentially 171 | the lowest level window 'handle'. EGL then 172 | uses this handle to create a managed 'window'. 173 | --]] 174 | 175 | local function createNativeView(dmxdisplay, width, height, x, y, level) 176 | x = x or 0 177 | y = y or 0 178 | level = level or 0 179 | 180 | local dst_rect = VC_RECT_T(x,y,width, height); 181 | local src_rect = VC_RECT_T(0,0, lshift(width, 16), lshift(height,16)); 182 | 183 | --local alpha = VC_DISPMANX_ALPHA_T(ffi.C.DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,255,0); 184 | --local view = dmxdisplay:CreateElement(dst_rect, nil, src_rect, 0, DISPMANX_PROTECTION_NONE, alpha); 185 | --local view = dmxdisplay:CreateElement(dst_rect, nil, src_rect); 186 | local view = dmxdisplay:CreateView(width, height, x,y, level); 187 | 188 | assert(view, "FAILURE: Did not create element"); 189 | 190 | -- create an EGL window surface 191 | local nativewindow = ffi.new("EGL_DISPMANX_WINDOW_T"); 192 | nativewindow.element = view.Surface.Handle; 193 | nativewindow.width = width; 194 | nativewindow.height = height; 195 | 196 | return nativewindow, view; 197 | end 198 | 199 | 200 | local EGLWindow = {} 201 | local EGLWindow_mt = { 202 | __index = EGLWindow, 203 | } 204 | 205 | EGLWindow.new = function(width, height, x, y, config, api) 206 | x = x or 0 207 | y = y or 0 208 | config = config or {background = {153, 153, 153}}; 209 | 210 | local obj = { 211 | X = x; 212 | Y = y; 213 | Width = width; 214 | Height = height; 215 | } 216 | 217 | -- Create the display object 218 | obj.Display = EglDisplay.new(api); 219 | 220 | -- create nativewindow 221 | local dmxdisplay = DMX.DMXDisplay(); 222 | obj.NativeWindow, obj.NativeView = createNativeView(dmxdisplay, width, height, x, y); 223 | 224 | -- create window surface 225 | obj.Surface = obj.Display:CreateWindowSurface(obj.NativeWindow); 226 | obj.Display:MakeCurrent(); 227 | 228 | setmetatable(obj, EGLWindow_mt); 229 | 230 | if config.background then 231 | obj:SetBackgroundColor(config.background[1], config.background[2], config.background[3], config.background[3]); 232 | end 233 | 234 | obj:Clear(); 235 | obj:SwapBuffers(); 236 | 237 | return obj 238 | end 239 | 240 | EGLWindow.Clear = function(self) 241 | glClear(GL_COLOR_BUFFER_BIT); 242 | end 243 | 244 | EGLWindow.SetBackgroundColor = function(self, red, green, blue, alpha) 245 | alpha = alpha or 1.0; 246 | 247 | glClearColor(red/256, green/256, blue/256, alpha); 248 | 249 | end 250 | 251 | EGLWindow.SwapBuffers = function(self) 252 | self.Display:SwapBuffers(); 253 | end 254 | 255 | EGLWindow.MoveTo = function(self, x, y) 256 | self.NativeView:MoveTo(x,y); 257 | self.X = x; 258 | self.Y = y; 259 | 260 | --self:SwapBuffers(); 261 | end 262 | 263 | 264 | 265 | 266 | EGL.Display = EglDisplay 267 | EGL.Window = EGLWindow; 268 | 269 | return EGL 270 | 271 | --[[ 272 | return { 273 | Lib = EGL.Lib, 274 | Display = EglDisplay, 275 | Window = EGLWindow, 276 | } 277 | --]] 278 | -------------------------------------------------------------------------------- /eglplatform.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | local ffi = require "ffi" 5 | 6 | require "khrplatform" 7 | 8 | 9 | ffi.cdef[[ 10 | typedef void *EGLNativeDisplayType; 11 | typedef void *EGLNativePixmapType; 12 | typedef void *EGLNativeWindowType; 13 | ]] 14 | 15 | 16 | require "bcm_host" 17 | 18 | 19 | ffi.cdef[[ 20 | typedef struct { 21 | DISPMANX_ELEMENT_HANDLE_T element; 22 | int width; /* This is necessary because dispmanx elements are not queriable. */ 23 | int height; 24 | } EGL_DISPMANX_WINDOW_T; 25 | 26 | 27 | 28 | /* EGL 1.2 types, renamed for consistency in EGL 1.3 */ 29 | typedef EGLNativeDisplayType NativeDisplayType; 30 | typedef EGLNativePixmapType NativePixmapType; 31 | typedef EGLNativeWindowType NativeWindowType; 32 | ]] 33 | 34 | ffi.cdef[[ 35 | /* Define EGLint. This must be a signed integral type large enough to contain 36 | * all legal attribute names and values passed into and out of EGL, whether 37 | * their type is boolean, bitmask, enumerant (symbolic constant), integer, 38 | * handle, or other. While in general a 32-bit integer will suffice, if 39 | * handles are 64 bit types, then EGLint should be defined as a signed 64-bit 40 | * integer type. 41 | */ 42 | typedef khronos_int32_t EGLint; 43 | ]] 44 | 45 | -------------------------------------------------------------------------------- /experimental/Application.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | local ev = require "ev_utils" 5 | local S = require "syscall" 6 | local UI = require "input" 7 | 8 | Application = { 9 | IdleWatchers = {}, 10 | MouseWatchers = {}, 11 | KeyboardWatchers = {}, 12 | TimerWatchers = {}, 13 | SocketWatchers = {}, 14 | FileWatchers = {}, 15 | } 16 | 17 | -- Create the primary application event loop 18 | Application.Loop = ev.ev_loop(); 19 | 20 | Application.AddIdleObserver = function(onactivity) 21 | local watcher = ev.ev_idle(onactivity); 22 | table.insert(Application.IdleWatchers, {watcher}); 23 | end 24 | 25 | Application.AddKeyboardObserver = function(onactivity, devicename) 26 | devicename = devicename or "/dev/input/event0" 27 | local fd, err = S.open(devicename, "O_RDONLY"); 28 | if not fd then 29 | return false, err 30 | end 31 | 32 | local watcher = ev.ev_io(onactivity, fd:getfd(), ffi.C.EV_READ); 33 | table.insert(Application.KeyboardWatchers, {watcher, fd}); 34 | 35 | return true; 36 | end 37 | 38 | 39 | Application.AddMouseObserver = function(onactivity, devicename) 40 | devicename = devicename or "/dev/input/event1" 41 | local fd = S.open(devicename, "O_RDONLY"); 42 | if not fd then 43 | return false, err 44 | end 45 | 46 | local watcher = ev.ev_io(onactivity, fd:getfd(), ffi.C.EV_READ); 47 | table.insert(Application.MouseWatchers, {watcher, fd}); 48 | 49 | return true; 50 | end 51 | 52 | Application.AddTimerObserver = function(onactivity, after, interval) 53 | local watcher = ev.ev_timer(onactivity, after, interval); 54 | table.insert(Application.TimerWatchers, {watcher}); 55 | 56 | return true; 57 | end 58 | 59 | Application.Run = function() 60 | -- Start the various watchers 61 | -- Start Mouse Watchers 62 | for i,watcher in ipairs(Application.MouseWatchers) do 63 | watcher[1]:start(Application.Loop); 64 | end 65 | 66 | -- Start Keyboard Watchers 67 | for i,watcher in ipairs(Application.KeyboardWatchers) do 68 | watcher[1]:start(Application.Loop); 69 | end 70 | 71 | -- Start Socket Watchers 72 | for i,watcher in ipairs(Application.SocketWatchers) do 73 | watcher[1]:start(Application.Loop); 74 | end 75 | 76 | -- Start File Watchers 77 | for i,watcher in ipairs(Application.FileWatchers) do 78 | watcher[1]:start(Application.Loop); 79 | end 80 | 81 | -- Start Timer Watchers 82 | for i,watcher in ipairs(Application.TimerWatchers) do 83 | watcher[1]:start(Application.Loop); 84 | end 85 | 86 | -- Start the idle watchers 87 | for i,watcher in ipairs(Application.IdleWatchers) do 88 | watcher[1]:start(Application.Loop); 89 | end 90 | 91 | Application.Loop:run(); 92 | end 93 | 94 | Application.Finish = function() 95 | Application.Loop:halt(); 96 | end 97 | 98 | return Application 99 | -------------------------------------------------------------------------------- /experimental/MouseInteractor.lua: -------------------------------------------------------------------------------- 1 | 2 | MouseInteractor = {} 3 | MouseInteractor_mt = { 4 | __index = MouseInteractor, 5 | } 6 | 7 | 8 | MouseInteractor.new = function(devicename) 9 | local obj = { 10 | MouseDeviceName = devicename, 11 | MouseInteractors = {}, 12 | MouseMovers = {}, 13 | MouseDowners = {}, 14 | MouseUppers = {}, 15 | } 16 | setmetatable(obj, MouseInteractor_mt); 17 | 18 | return obj; 19 | end 20 | 21 | MouseInteractor.OnDeviceReadyForRead = function(self) 22 | -- read from the device 23 | end 24 | 25 | MouseInteractor.OnMouseMove = function(self, x, y, flags, device) 26 | for i,interactor in ipairs(self.MouseInteractors) do 27 | observer:OnMouseMove(x, y, flags, device) 28 | end 29 | 30 | for i,mover in ipairs(self.MouseMovers) do 31 | mover(x,y,flags, device) 32 | end 33 | end 34 | 35 | MouseInteractor.OnMouseDown = function(self, x, y, button, flags, device) 36 | for i,downer in ipairs(self.MouseDowners) do 37 | downer(x, y, button, flags, device) 38 | end 39 | end 40 | 41 | MouseInteractor.OnMouseUp = function(self, x, y, button, flags, device) 42 | for i,upper in ipairs(self.MouseUppers) do 43 | upper(x, y, button, flags, device) 44 | end 45 | end 46 | 47 | 48 | MouseInteractor.AddMouseInteractor = function(self, observer) 49 | table.insert(self.MouseInteractors, observer) 50 | 51 | return true 52 | end 53 | 54 | MouseInteractor.Add 55 | -------------------------------------------------------------------------------- /experimental/OMX.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | local OMXVideo = require "OMX_Video" 4 | --require "OMX_Audio" 5 | local OMXOther = require "OMX_Other" 6 | 7 | 8 | OMX = {} 9 | OMX_mt = { 10 | __index = OMX, 11 | } 12 | -------------------------------------------------------------------------------- /experimental/freetype_utils.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | local lib = ffi.load("libfreetype.so.6") 4 | require "freetype" 5 | 6 | return { 7 | Native = lib, 8 | } 9 | -------------------------------------------------------------------------------- /experimental/libev.lua: -------------------------------------------------------------------------------- 1 | -- LuaJIT binding to libev (http://libev.schmorp.de/) 2 | -- 3 | -- uses almost-identical API to lua-ev (https://github.com/brimworks/lua-ev) 4 | -- 5 | -- Author: Evan Wies 6 | -- 7 | 8 | local ffi = require('ffi') 9 | 10 | local bit = require("bit") 11 | local band, bor = bit.band, bit.bor 12 | 13 | 14 | 15 | -- extracted from preprocessing 16 | ffi.cdef[[ 17 | 18 | /* eventmask, revents, events... */ 19 | enum { 20 | EV_UNDEF = 0xFFFFFFFF, /* guaranteed to be invalid */ 21 | EV_NONE = 0x00, /* no events */ 22 | EV_READ = 0x01, /* ev_io detected read will not block */ 23 | EV_WRITE = 0x02, /* ev_io detected write will not block */ 24 | EV__IOFDSET = 0x80, /* internal use only */ 25 | EV_IO = EV_READ, /* alias for type-detection */ 26 | EV_TIMER = 0x00000100, /* timer timed out */ 27 | EV_PERIODIC = 0x00000200, /* periodic timer timed out */ 28 | EV_SIGNAL = 0x00000400, /* signal was received */ 29 | EV_CHILD = 0x00000800, /* child/pid had status change */ 30 | EV_STAT = 0x00001000, /* stat data changed */ 31 | EV_IDLE = 0x00002000, /* event loop is idling */ 32 | EV_PREPARE = 0x00004000, /* event loop about to poll */ 33 | EV_CHECK = 0x00008000, /* event loop finished poll */ 34 | EV_EMBED = 0x00010000, /* embedded event loop needs sweep */ 35 | EV_FORK = 0x00020000, /* event loop resumed in child */ 36 | EV_CLEANUP = 0x00040000, /* event loop resumed in child */ 37 | EV_ASYNC = 0x00080000, /* async intra-loop signal */ 38 | EV_CUSTOM = 0x01000000, /* for use by user code */ 39 | EV_ERROR = 0x80000000 /* sent when an error occurs */ 40 | }; 41 | 42 | /* flag bits for ev_default_loop and ev_loop_new */ 43 | enum { 44 | /* the default */ 45 | EVFLAG_AUTO = 0x00000000U, /* not quite a mask */ 46 | /* flag bits */ 47 | EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */ 48 | EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */ 49 | /* debugging/feature disable */ 50 | EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */ 51 | EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */ 52 | EVFLAG_NOSIGMASK = 0x00400000U /* avoid modifying the signal mask */ 53 | }; 54 | 55 | /* method bits to be ored together */ 56 | enum { 57 | EVBACKEND_SELECT = 0x00000001U, /* about anywhere */ 58 | EVBACKEND_POLL = 0x00000002U, /* !win */ 59 | EVBACKEND_EPOLL = 0x00000004U, /* linux */ 60 | EVBACKEND_KQUEUE = 0x00000008U, /* bsd */ 61 | EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */ 62 | EVBACKEND_PORT = 0x00000020U, /* solaris 10 */ 63 | EVBACKEND_ALL = 0x0000003FU, /* all known backends */ 64 | EVBACKEND_MASK = 0x0000FFFFU /* all future backends */ 65 | }; 66 | 67 | typedef double ev_tstamp; 68 | 69 | ev_tstamp ev_time (void); 70 | void ev_sleep (ev_tstamp delay); /* sleep for a while */ 71 | 72 | /* ev_run flags values */ 73 | enum { 74 | EVRUN_NOWAIT = 1, /* do not block/wait */ 75 | EVRUN_ONCE = 2 /* block *once* only */ 76 | }; 77 | 78 | /* ev_break how values */ 79 | enum { 80 | EVBREAK_CANCEL = 0, /* undo unloop */ 81 | EVBREAK_ONE = 1, /* unloop once */ 82 | EVBREAK_ALL = 2 /* unloop all loops */ 83 | }; 84 | 85 | typedef struct ev_loop ev_loop; 86 | 87 | typedef struct ev_watcher 88 | { 89 | int active; 90 | int pending; 91 | int priority; 92 | void *data; 93 | void (*cb)(struct ev_loop *loop, struct ev_watcher *w, int revents); 94 | } ev_watcher; 95 | 96 | typedef struct ev_watcher_list 97 | { 98 | int active; 99 | int pending; 100 | int priority; 101 | void *data; 102 | void (*cb)(struct ev_loop *loop, struct ev_watcher_list *w, int revents); 103 | struct ev_watcher_list *next; 104 | } ev_watcher_list; 105 | 106 | typedef struct ev_watcher_time 107 | { 108 | int active; 109 | int pending; 110 | int priority; 111 | void *data; 112 | void (*cb)(struct ev_loop *loop, struct ev_watcher_time *w, int revents); 113 | ev_tstamp at; 114 | } ev_watcher_time; 115 | 116 | typedef struct ev_io 117 | { 118 | int active; 119 | int pending; 120 | int priority; 121 | void *data; 122 | void (*cb)(struct ev_loop *loop, struct ev_io *w, int revents); 123 | struct ev_watcher_list *next; 124 | int fd; 125 | int events; 126 | } ev_io; 127 | 128 | typedef struct ev_timer 129 | { 130 | int active; 131 | int pending; 132 | int priority; 133 | void *data; 134 | void (*cb)(struct ev_loop *loop, struct ev_timer *w, int revents); 135 | ev_tstamp at; 136 | ev_tstamp repeat_; 137 | } ev_timer; 138 | 139 | typedef struct ev_periodic 140 | { 141 | int active; 142 | int pending; 143 | int priority; 144 | void *data; 145 | void (*cb)(struct ev_loop *loop, struct ev_periodic *w, int revents); 146 | ev_tstamp at; 147 | ev_tstamp offset; 148 | ev_tstamp interval; 149 | ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now); 150 | } ev_periodic; 151 | 152 | typedef struct ev_signal 153 | { 154 | int active; 155 | int pending; 156 | int priority; 157 | void *data; 158 | void (*cb)(struct ev_loop *loop, struct ev_signal *w, int revents); 159 | struct ev_watcher_list *next; 160 | int signum; 161 | } ev_signal; 162 | 163 | typedef struct ev_child 164 | { 165 | int active; 166 | int pending; 167 | int priority; 168 | void *data; 169 | void (*cb)(struct ev_loop *loop, struct ev_child *w, int revents); 170 | struct ev_watcher_list *next; 171 | int flags; 172 | int pid; 173 | int rpid; 174 | int rstatus; 175 | } ev_child; 176 | 177 | typedef struct ev_idle 178 | { 179 | int active; 180 | int pending; 181 | int priority; 182 | void *data; 183 | void (*cb)(struct ev_loop *loop, struct ev_idle *w, int revents); 184 | } ev_idle; 185 | 186 | typedef struct ev_prepare 187 | { 188 | int active; int pending; int priority; void *data; void (*cb)(struct ev_loop *loop, struct ev_prepare *w, int revents); 189 | } ev_prepare; 190 | 191 | typedef struct ev_check 192 | { 193 | int active; int pending; int priority; void *data; void (*cb)(struct ev_loop *loop, struct ev_check *w, int revents); 194 | } ev_check; 195 | 196 | typedef struct ev_fork 197 | { 198 | int active; int pending; int priority; void *data; void (*cb)(struct ev_loop *loop, struct ev_fork *w, int revents); 199 | } ev_fork; 200 | 201 | typedef struct ev_cleanup 202 | { 203 | int active; int pending; int priority; void *data; void (*cb)(struct ev_loop *loop, struct ev_cleanup *w, int revents); 204 | } ev_cleanup; 205 | 206 | typedef struct ev_embed 207 | { 208 | int active; int pending; int priority; void *data; void (*cb)(struct ev_loop *loop, struct ev_embed *w, int revents); 209 | struct ev_loop *other; 210 | ev_io io; 211 | ev_prepare prepare; 212 | ev_check check; 213 | ev_timer timer; 214 | ev_periodic periodic; 215 | ev_idle idle; 216 | ev_fork fork; 217 | ev_cleanup cleanup; 218 | } ev_embed; 219 | 220 | typedef int sig_atomic_t; 221 | typedef struct ev_async 222 | { 223 | int active; int pending; int priority; void *data; void (*cb)(struct ev_loop *loop, struct ev_async *w, int revents); 224 | sig_atomic_t volatile sent; 225 | } ev_async; 226 | 227 | 228 | int ev_version_major (void); 229 | int ev_version_minor (void); 230 | 231 | 232 | 233 | void ev_signal_start (struct ev_loop *loop, ev_signal *w); 234 | void ev_signal_stop (struct ev_loop *loop, ev_signal *w); 235 | 236 | struct ev_loop *ev_default_loop (unsigned int flags ); 237 | struct ev_loop *ev_loop_new (unsigned int flags ); 238 | ev_tstamp ev_now (struct ev_loop *loop); 239 | void ev_loop_destroy (struct ev_loop *loop); 240 | unsigned int ev_iteration (struct ev_loop *loop); 241 | unsigned int ev_depth (struct ev_loop *loop); 242 | 243 | void ev_io_start (struct ev_loop *loop, ev_io *w); 244 | void ev_io_stop (struct ev_loop *loop, ev_io *w); 245 | 246 | void ev_run (struct ev_loop *loop, int flags ); 247 | void ev_break (struct ev_loop *loop, int how ); 248 | void ev_suspend (struct ev_loop *loop); 249 | void ev_resume (struct ev_loop *loop); 250 | int ev_clear_pending (struct ev_loop *loop, void *w); 251 | 252 | void ev_timer_start (struct ev_loop *loop, ev_timer *w); 253 | void ev_timer_stop (struct ev_loop *loop, ev_timer *w); 254 | void ev_timer_again (struct ev_loop *loop, ev_timer *w); 255 | ev_tstamp ev_timer_remaining (struct ev_loop *loop, ev_timer *w); 256 | 257 | void ev_idle_start (struct ev_loop *loop, ev_idle *w); 258 | void ev_idle_stop (struct ev_loop *loop, ev_idle *w); 259 | 260 | ]] 261 | 262 | 263 | -------------------------------------------------------------------------------- /experimental/metadata_fourcc.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | ffi.cdef[[ 5 | /****************************************************************************** 6 | Definition of 4CCs assigned to metadata items. This list acts more as a 7 | central repository of 4CCs for different metadata items so as to avoid clashes. 8 | They are not otherwise necessary for library to function correctly. 9 | ******************************************************************************/ 10 | 11 | /* 12 | Note: Multi-character constants are not valid C and although supported by 13 | some compilers such as Metaware, they are ambiguous in how they should be 14 | packed into a long due to endian-ness (and also due to size for 2 and 3 15 | character constants). 16 | */ 17 | 18 | typedef enum { 19 | 20 | METADATA_CDI = ('C'<<24)+('D'<<16)+('M'<<8)+('D'), // 'CDMD' struct CDI_METADATA_T in /middleware/camplus/cdi/cdi.h 21 | METADATA_CAM_CAL = ('C'<<24)+('C'<<16)+('A'<<8)+('L'), // 'CCAL' struct CAMERA_CALIBRATION_METADATA_T in /middleware/camplus/cdi/cdi.h 22 | METADATA_TIMING = ('T'<<24)+('I'<<16)+('M'<<8)+('E'), // 'TIME' struct TIMING_METADATA_T in /middleware/camplus/cdi/cdi.h 23 | METADATA_CDI_FILE = ( 0 <<24)+('C'<<16)+('D'<<8)+('F'), // '\x00CDF' struct CDI_FILE_METADATA_T in /middleware/camplus/cdi/cdi_file.h 24 | METADATA_CDI_RAW = ('C'<<24)+('D'<<16)+('R'<<8)+('W'), // 'CDRW' struct CDI_FILE_RAW_METADATA_T in /middleware/camplus/cdi/cdi_file_raw.h 25 | METADATA_STABILISE = ('S'<<24)+('T'<<16)+('A'<<8)+('B'), // 'STAB' struct GLOBAL_MOTION_VECTOR_T in /middleware/camplus/sw/stabilise/stabilise.h 26 | METADATA_LOCAL_MV1 = ('L'<<24)+('M'<<16)+('V'<<8)+('1'), // 'LMV1' struct ALL_LOCAL_MOTION_VECTORS_T in /middleware/camplus/sw/stabilise/stabilise.h 27 | METADATA_LOCAL_MV2 = ('L'<<24)+('M'<<16)+('V'<<8)+('2'), // 'LMV2' struct ALL_LOCAL_MOTION_VECTORS_T in /middleware/camplus/sw/stabilise/stabilise.h 28 | METADATA_TUNER_AGC = ( 0 <<24)+('A'<<16)+('G'<<8)+('C'), // '\x00AGC' struct ISP_AGC_METADATA_T in /middleware/ISP/tuner/isp_tuner_ctrl.h 29 | METADATA_AGC_DEBUG = ('A'<<24)+('G'<<16)+('C'<<8)+('D'), // 'AGCD' struct ISP_TUNER_BRCM_AGC_DEBUG_T in /middleware/ISP/tuner/isp_tuner_agc.h 30 | METADATA_FOCUS_REGION = ('F'<<24)+('R'<<16)+('G'<<8)+('N'), // 'FRGN' struct ISP_TUNER_BRCM_AF_STATISTICS_PARAMS_T in /middleware/ISP/tuner/isp_tuner_brcm_common.h 31 | METADATA_FOCUS_WOI = ('F'<<24)+('W'<<16)+('O'<<8)+('I'), // 'FWOI' struct ISP_WOI_METADATA_T in /middleware/ISP/tuner/isp_tuner_ctrl.h 32 | METADATA_AUTOFOCUS = ( 0 <<24)+( 0 <<16)+('A'<<8)+('F'), // '\x00\x00AF' struct ISP_AF_METADATA_T in /middleware/ISP/tuner/isp_tuner_ctrl.h 33 | METADATA_EV = ('E'<<24)+('V'<<16)+('M'<<8)+('D'), // 'EVMD' struct ISP_TUNER_BRCM_EV_METADATA_T in /middleware/ISP/tuner/isp_tuner_brcm_common.h 34 | METADATA_ISP = ('I'<<24)+('S'<<16)+('P'<<8)+('M'), // 'ISPM' struct ISP_ISP_METADATA_T in /middleware/ISP/tuner/isp_tuner_ctrl.h 35 | METADATA_FACETRACKING = ('F'<<24)+('A'<<16)+('C'<<8)+('E'), // 'FACE' struct FACE_METADATA_T defined in /middleware/camplus/sw/face_metadata.h 36 | METADATA_ANTISHAKE = ('S'<<24)+('H'<<16)+('A'<<8)+('K'), // 'SHAK' struct SHAKE_METADATA_T defined in /middleware/camplus/sw/shake_metadata.h 37 | METADATA_RER = ( 0 <<24)+('R'<<16)+('E'<<8)+('R'), // '\x00RER' struct RER_METADATA_T defined in /middleware/camplus/sw/rer_metadata.h 38 | METADATA_SCENEDETECTION = ( 0 <<24)+('A'<<16)+('S'<<8)+('D'), // '\x00ASD' struct ASD_METADATA_T defined in /middleware/camplus/sw/asd_metadata.h 39 | METADATA_TUNER_SYNC = ('S'<<24)+('Y'<<16)+('N'<<8)+('C'), // 'SYNC' NULL data, just adds the item header. 40 | METADATA_DARK_FRAME_CORRECT = ('D'<<24)+('F'<<16)+('R'<<8)+('C'), // 'DFRC' 5 byte literal string "dfrc" 41 | METADATA_DARK_FRAME_SUB = ('D'<<24)+('F'<<16)+('S'<<8)+('B'), // 'DFSB' 3 byte literal string "on" 42 | METADATA_ABL = ( 0 <<24)+('A'<<16)+('B'<<8)+('L'), // '\x00ABL' struct ISP_TUNER_BRCM_BLACK_LEVEL_ABL_T defined in /middleware/ISP/tuner/isp_tuner_brcm_black_level.h 43 | METADATA_DRC = ( 0 <<24)+('D'<<16)+('R'<<8)+('C'), // 'DRC' struct DRC_METADATA_T defined in /middleware/camplus/sw/drc/drc.h 44 | METADATA_REGISTRATION = ( 0 <<24)+('R'<<16)+('E'<<8)+('G'), // 'REG' struct REGISTRATION_OFFSETS_T defined in /middleware/camplus/sw/registration/registration.h 45 | METADATA_RAW_CAPTURE = ('R'<<24)+('W'<<16)+('M'<<8)+('D'), // 'RWMD' struct RAW_CAPTURE_METADATA_T defined in /middleware/camplus/sw/raw_metadata.h 46 | // structure definitions for IL metadata are 47 | // in middleware/openmaxil/headers/ilmetadata.h 48 | METADATA_IL_CAMERA_NAME = ('I'<<24)+('L'<<16)+('C'<<8)+('A'), // 'ILCA' 49 | METADATA_IL_CROP_RECTANGLE = ('I'<<24)+('L'<<16)+('C'<<8)+('R'), // 'ILCR' 50 | METADATA_IL_PIXEL_ASPECT_RATIO = ('I'<<24)+('L'<<16)+('P'<<8)+('A'), // 'ILPA' 51 | 52 | METADATA_TUNER_FLASH_MONITOR = ('F'<<24)+('L'<<16)+('M'<<8)+('N'), // 'FLMN' Flash monitor - type ISP_TUNER_BRCM_FLASH_MONITOR_T from isp_tuner_brcm.h 53 | 54 | 55 | // VoWIFI video analysis 56 | METADATA_SPATIAL_ACT_A = ( 'S'<<24)+('P'<<16)+('T'<<8)+('A'), // 'SPTA' : SPATIAL_ACTIVITY_METADATA_T defined in /middleware/camplus/sw/perceptual/spatial_activity.h 57 | METADATA_TEMPORAL_ACT_A = ( 'T'<<24)+('M'<<16)+('P'<<8)+('A'), // 'TMPA' : TEMPORAL_ACTIVITY_METADATA_T defined in /middleware/camplus/sw/perceptual/temporal_activity.h 58 | METADATA_FILMGRAIN_NOISE_A = ( 'F'<<24)+('G'<<16)+('N'<<8)+('A'), // 'FGNA' : FILMGRAIN_NOISE_METADATA_T defined in /middleware/camplus/sw/perceptual/filmgrain_noise.h 59 | METADATA_COLORSPACE_A = ( 'C'<<24)+('L'<<16)+('R'<<8)+('A'), // 'CLRA' : COLORSPACE_METADATA_T defined in /middleware/camplus/sw/perceptual/colorspace.h 60 | METADATA_FLAT_AREA_A = ( 'F'<<24)+('L'<<16)+('T'<<8)+('A'), // 'FLTA' : FLAT_AREA_METADATA_T defined in /middleware/camplus/sw/perceptual/flatarea.h 61 | METADATA_STILL_AREA_A = ( 'S'<<24)+('T'<<16)+('L'<<8)+('A'), // 'STLA' : FLAT_AREA_METADATA_T defined in /middleware/camplus/sw/perceptual/stillarea.h 62 | METADATA_DDITHER_A = ( 'D'<<24)+('D'<<16)+('T'<<8)+('A'), // 'DDTA' : DDITHER_METADATA_T defined in /middleware/camplus/sw/perceptual/... 63 | 64 | METADATA_HDR = ( 0 <<24)+( 'H'<<16)+('D'<<8)+('R'), // 'HDR' : HDR_METADATA_T defined in /middleware/camplus/sw/hdr/hdr_metadata.h 65 | 66 | METADATA_UNKNOWN = ('U'<<24)+('N'<<16)+('K'<<8)+('N') // 'UNKN' 67 | 68 | } METADATA_CODE_T; 69 | 70 | ]] 71 | -------------------------------------------------------------------------------- /experimental/test_libev.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | local ev = require "ev_utils" 5 | local S = require "syscall" 6 | local UI = require "input" 7 | 8 | --print("EV Version: ", ev.version()); 9 | 10 | local loop = ev.ev_loop(); -- ev.Loop(); 11 | 12 | assert(loop, "event loop not created"); 13 | 14 | 15 | --[[ 16 | Callback functions 17 | --]] 18 | 19 | function OnTimeout(loop, ...) 20 | print("OnTimeout: ", loop:iteration()); 21 | end 22 | 23 | function OnIdle(loop, ...) 24 | print("Idling"); 25 | end 26 | 27 | 28 | 29 | --[[ 30 | Event type: 31 | EV_KEY 32 | EV_MSC 33 | 34 | value: 35 | 0 == keyup 36 | 1 == keydown 37 | --]] 38 | 39 | function OnKey(loop, w, revents) 40 | local event = input_event(); 41 | local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 42 | 43 | 44 | if event.type == EV_MSC then 45 | if event.code == MSC_SCAN then 46 | --print("MSC_SCAN: ", string.format("0x%x",event.value)); 47 | else 48 | --print("MSC: ", event.code, event.value); 49 | end 50 | elseif event.type == EV_KEY then 51 | if event.value == 1 then 52 | print("KEYDOWN: ", event.code); 53 | elseif event.value == 0 then 54 | print("KEYUP: ", event.code); 55 | 56 | if event.code == KEY_ESC then 57 | loop:halt(); 58 | return false; 59 | end 60 | 61 | elseif event.value == 2 then 62 | print("KEYREP: ", event.code); 63 | end 64 | else 65 | --print("EVENT TYPE: ", UI.EventTypes[event.type][2], "CODE:",event.code, "VALUE: ", string.format("0x%x",event.value)); 66 | end 67 | end 68 | 69 | function OnTTY(loop, w, revents) 70 | local bufflen = 10; 71 | local buff = ffi.new("char[?]", bufflen); 72 | 73 | local bytesread = S.read(w.fd, buff, bufflen); 74 | print("TTY: ", ffi.string(buff, bytesread)); 75 | 76 | end 77 | 78 | function OnMouse(loop, w, revents) 79 | --print("OnMouse: ", w, revents); 80 | local event = input_event(); 81 | local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 82 | 83 | print("MOUSE: ", event.type, event.code, event.value); 84 | end 85 | 86 | 87 | --[[ 88 | Create Observers 89 | --]] 90 | 91 | local idler = ev.ev_idle(OnIdle); 92 | --idler:start(loop, true); 93 | 94 | local timer = ev.ev_timer(OnTimeout, 1, 2) 95 | --timer:start(loop, true); 96 | 97 | -- Keyboard Tracking 98 | local fd = S.open("/dev/input/event0", "O_RDONLY"); 99 | local kfd = fd:getfd(); 100 | print("FD: ", fd, kfd); 101 | local iowatcher = ev.ev_io(OnKey, kfd, ffi.C.EV_READ); 102 | iowatcher:start(loop, true); 103 | 104 | function watchtty(filename) 105 | local tty, err = S.open("/dev/tty0", "O_RDONLY"); 106 | if not tty then 107 | print("TTY ERROR: ", err); 108 | return false 109 | end 110 | 111 | local ttyfd = tty:getfd(); 112 | print("TTY FD: ", ttyfd); 113 | local ttywatcher = ev.ev_io(OnTTY, ttyfd, ffi.C.EV_READ); 114 | ttywatcher:start(loop, true); 115 | end 116 | 117 | -- Mouse Tracking 118 | local fd = S.open("/dev/input/event1", "O_RDONLY"); 119 | local mfd = fd:getfd(); 120 | local mousewatcher = ev.ev_io(OnMouse, mfd, ffi.C.EV_READ); 121 | --mousewatcher:start(loop, true); 122 | 123 | 124 | -- Run the loop 125 | print(loop:run()); 126 | 127 | print("Loop Running"); 128 | -------------------------------------------------------------------------------- /experimental/vc_vchi_gencmd_h.lua: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012, Broadcom Europe Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of the copyright holder nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef VC_VCHI_GENCMD_H 29 | #define VC_VCHI_GENCMD_H 30 | #include "vchost_config.h" 31 | #include "interface/vchi/vchi.h" 32 | #include "interface/vcos/vcos.h" //for VCHPRE_ abd VCHPOST_ macro's for func declaration 33 | 34 | /* Initialise general command service. Returns it's interface number. This initialises 35 | the host side of the interface, it does not send anything to VideoCore. */ 36 | 37 | VCHPRE_ int VCHPOST_ vc_gencmd_init(void); 38 | 39 | VCHPRE_ void VCHPOST_ vc_vchi_gencmd_init(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ); 40 | 41 | 42 | /* Stop the service from being used. */ 43 | 44 | VCHPRE_ void VCHPOST_ vc_gencmd_stop(void); 45 | 46 | /* Functions to support videocore suspend/resume for cases where vc_gencmd_send expects a response to 47 | * ensure videocore is not shut down (done internally in vc_gencmd / vc_gencmd_until) */ 48 | 49 | VCHPRE_ int VCHPOST_ use_gencmd_service(void); 50 | VCHPRE_ int VCHPOST_ release_gencmd_service(void); 51 | 52 | /****************************************************************************** 53 | Send commands to VideoCore. 54 | These all return 0 for success. They return VC_MSGFIFO_FIFO_FULL if there is 55 | insufficient space for the whole message in the fifo, and none of the message is 56 | sent. 57 | ******************************************************************************/ 58 | 59 | /* send command to general command serivce */ 60 | VCHPRE_ int VCHPOST_ vc_gencmd_send( const char *format, ... ); 61 | 62 | /* get resonse from general command serivce */ 63 | VCHPRE_ int VCHPOST_ vc_gencmd_read_response(char *response, int maxlen); 64 | 65 | /* convenience function to send command and receive the response */ 66 | VCHPRE_ int VCHPOST_ vc_gencmd(char *response, int maxlen, const char *format, ...); 67 | 68 | /****************************************************************************** 69 | Utilities to help interpret the responses. 70 | ******************************************************************************/ 71 | 72 | /* Read the value of a property=value type pair from a string (typically VideoCore's 73 | response to a general command). Return non-zero if found. */ 74 | VCHPRE_ int VCHPOST_ vc_gencmd_string_property(char *text, const char *property, char **value, int *length); 75 | 76 | /* Read the numeric value of a property=number field from a response string. Return 77 | non-zero if found. */ 78 | VCHPRE_ int VCHPOST_ vc_gencmd_number_property(char *text, const char *property, int *number); 79 | 80 | /* Send a command until the desired response is received, the error message is detected, or the timeout */ 81 | VCHPRE_ int VCHPOST_ vc_gencmd_until( char *cmd, 82 | const char *property, 83 | char *value, 84 | const char *error_string, 85 | int timeout); 86 | 87 | 88 | #endif -------------------------------------------------------------------------------- /gpio.lua: -------------------------------------------------------------------------------- 1 | -- Raspberry Pi GPIO module. 2 | -- Written by Mike Pall. Public domain. 3 | 4 | 5 | local error, tostring, setmt = error, tostring, setmetatable 6 | local bit = require("bit") 7 | local band, bor, shl, shr = bit.band, bit.bor, bit.lshift, bit.rshift 8 | 9 | local ffi = require("ffi") 10 | local C = ffi.C 11 | 12 | require "syscall" 13 | 14 | 15 | local function gpio_open() 16 | local fd = C.open("/dev/mem", 2, 0) 17 | if fd < 0 then 18 | error("You must be root to control the GPIO pins on the Raspberry Pi") 19 | end 20 | local gp = ffi.cast("volatile int32_t *", 21 | C.mmap(nil, 4096, 3, 1, fd, 0x20200000)) 22 | C.close(fd) 23 | if ffi.cast("intptr_t", gp) == -1 then 24 | error("Mapping of GPIO registers failed") 25 | end 26 | return gp 27 | end 28 | 29 | local gp = ffi.gc(gpio_open(), function(gp) 30 | -- Restore default values. 31 | gp[0] = 0x00040000; gp[1] = 0x00064000; gp[2] = 0x00000000 32 | gp[10] = 0x03e6cf93 33 | C.munmap(ffi.cast("void *", gp), 4096) 34 | end) 35 | 36 | module(...) 37 | 38 | -- WARNING: You may only use one of the following raw pin numbers! 39 | -- 0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25 40 | -- These correspond to the BCM2835 GPIO numbering scheme. 41 | 42 | -- Set direction of raw GPIO pin. 0 = input, 1 = output. 43 | local function _rawdir(pin, dir) 44 | local idx = pin % 10 45 | local reg = (pin - idx) / 10 46 | gp[reg] = bor(band(gp[reg], shl(7, idx*3)), shl(dir, idx*3)) 47 | end 48 | rawdir = _rawdir 49 | 50 | -- Turn raw GPIO output pin on. 51 | function rawon(pin) 52 | gp[7] = shl(1, pin) 53 | end 54 | 55 | -- Turn raw GPIO output pin off. 56 | function rawoff(pin) 57 | gp[10] = shl(1, pin) 58 | end 59 | 60 | -- Get state of raw GPIO input pin. 61 | function rawin(pin) 62 | return band(shr(gp[13], pin), 1) 63 | end 64 | 65 | -- User-level (non-raw) GPIO API. The numbers correspond to the numbering 66 | -- on the GPIO connector drawing: http://elinux.org/File:GPIOs.png 67 | -- Input/output direction is automatically selected. 68 | 69 | local function pinerror(t, i) 70 | error("bad GPIO pin number "..tostring(i), 2) 71 | end 72 | local rawmap = {[0]=17, 18, 21, 22, 23, 24, 25, 4} 73 | local inmap = setmt({[0]=-1,-1,-1,-1,-1,-1,-1,-1}, {__index=pinerror}) 74 | local outmap = setmt({[0]=-1,-1,-1,-1,-1,-1,-1,-1}, {__index=pinerror}) 75 | 76 | pin = setmt({}, { 77 | __index = function(t, i) 78 | local pin = inmap[i] 79 | if pin < 0 then 80 | pin = rawmap[i]; inmap[i] = pin; outmap[i] = -1; _rawdir(pin, 0) 81 | end 82 | return band(shr(gp[13], pin), 1) 83 | end, 84 | __newindex = function(t, i, v) 85 | local pin = outmap[i] 86 | if pin < 0 then 87 | pin = rawmap[i]; outmap[i] = pin; inmap[i] = -1; _rawdir(pin, 1) 88 | end 89 | gp[10-band(v, 1)*3] = shl(1, pin) 90 | end, 91 | }) 92 | 93 | function msleep(ms) 94 | C.poll(nil, 0, ms) 95 | end 96 | 97 | -------------------------------------------------------------------------------- /include/constants-arm.lua: -------------------------------------------------------------------------------- 1 | -- arm specific constants 2 | 3 | local ffi = require "ffi" 4 | 5 | assert(ffi.abi("eabi"), "only support eabi for arm") 6 | 7 | local octal = function (s) return tonumber(s, 8) end 8 | 9 | local arch = {} 10 | 11 | arch.SYS = { 12 | mknod = 14, 13 | getpid = 20, 14 | acct = 51, 15 | ustat = 62, 16 | stat = 106, 17 | fstat = 108, 18 | lstat = 107, 19 | clone = 120, 20 | _llseek = 140, 21 | getdents = 141, 22 | getcwd = 183, 23 | stat64 = 195, 24 | lstat64 = 196, 25 | fstat64 = 197, 26 | getdents64 = 217, 27 | readahead = 225, 28 | setxattr = 226, 29 | lsetxattr = 227, 30 | fsetxattr = 228, 31 | getxattr = 229, 32 | lgetxattr = 230, 33 | fgetxattr = 231, 34 | listxattr = 232, 35 | llistxattr = 233, 36 | flistxattr = 234, 37 | removexattr = 235, 38 | lremovexattr = 236, 39 | fremovexattr = 237, 40 | io_setup = 243, 41 | io_destroy = 244, 42 | io_getevents = 245, 43 | io_submit = 246, 44 | io_cancel = 247, 45 | clock_settime = 262, 46 | clock_gettime = 263, 47 | clock_getres = 264, 48 | clock_nanosleep = 265, 49 | mknodat = 324, 50 | fstatat64 = 327, 51 | splice = 340, 52 | sync_file_range = 341, 53 | tee = 342, 54 | vmsplice = 343, 55 | timerfd_create = 350, 56 | fallocate = 352, 57 | timerfd_settime = 353, 58 | timerfd_gettime = 354, 59 | pipe2 = 359, 60 | setns = 375, 61 | } 62 | 63 | -- TODO cleanup to return table 64 | arch.oflags = function(c) 65 | c.O_DIRECTORY = octal('040000') 66 | c.O_NOFOLLOW = octal('0100000') 67 | c.O_DIRECT = octal('0200000') 68 | end 69 | 70 | return arch 71 | 72 | -------------------------------------------------------------------------------- /include/constants-ppc.lua: -------------------------------------------------------------------------------- 1 | -- ppc specific code 2 | 3 | error("ppc support is coming soon") 4 | 5 | local arch = {} 6 | 7 | arch.socketoptions = function(c) 8 | error("ppc socketoptions need to be set") 9 | end 10 | 11 | return arch 12 | 13 | -------------------------------------------------------------------------------- /include/headers-x64.lua: -------------------------------------------------------------------------------- 1 | -- x64 specific definitions 2 | 3 | local ffi = require "ffi" 4 | 5 | local arch = {} 6 | 7 | arch.epoll = function() 8 | ffi.cdef[[ 9 | struct epoll_event { 10 | uint32_t events; /* Epoll events */ 11 | epoll_data_t data; /* User data variable */ 12 | } __attribute__ ((packed)); 13 | ]] 14 | end 15 | 16 | return arch 17 | 18 | -------------------------------------------------------------------------------- /include/headers-x86.lua: -------------------------------------------------------------------------------- 1 | -- x86 specific definitions 2 | 3 | local ffi = require "ffi" 4 | 5 | local arch = {} 6 | 7 | arch.sigaction = function() 8 | ffi.cdef[[ 9 | struct sigaction { 10 | union { 11 | sighandler_t sa_handler; 12 | void (*sa_sigaction)(int, struct siginfo *, void *); 13 | }; 14 | sigset_t sa_mask; 15 | unsigned long sa_flags; 16 | void (*sa_restorer)(void); 17 | }; 18 | ]] 19 | end 20 | 21 | return arch 22 | 23 | -------------------------------------------------------------------------------- /include/ioctl.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | local bit = require "bit" 4 | local band = bit.band 5 | local bor = bit.bor 6 | local lshift = bit.lshift 7 | local rshift = bit.rshift 8 | 9 | --[[ 10 | * ioctl command encoding: 32 bits total, command in lower 16 bits, 11 | * size of the parameter structure in the lower 14 bits of the 12 | * upper 16 bits. 13 | * Encoding the size of the parameter structure in the ioctl request 14 | * is useful for catching programs compiled with old versions 15 | * and to avoid overwriting user space outside the user buffer area. 16 | * The highest 2 bits are reserved for indicating the ``access mode''. 17 | * NOTE: This limits the max parameter size to 16kB -1 ! 18 | --]] 19 | 20 | --[[ 21 | * The following is for compatibility across the various Linux 22 | * platforms. The generic ioctl numbering scheme doesn't really enforce 23 | * a type field. De facto, however, the top 8 bits of the lower 16 24 | * bits are indeed used as a type field, so we might just as well make 25 | * this explicit here. Please be sure to use the decoding macros 26 | * below from now on. 27 | --]] 28 | 29 | _IOC_NRBITS = 8; 30 | _IOC_TYPEBITS = 8; 31 | 32 | --[[ 33 | * Let any architecture override either of the following before 34 | * including this file. 35 | --]] 36 | 37 | _IOC_SIZEBITS = 14; 38 | _IOC_DIRBITS = 2 39 | 40 | _IOC_NRMASK = (lshift(1, _IOC_NRBITS)-1) 41 | _IOC_TYPEMASK = (lshift(1, _IOC_TYPEBITS)-1) 42 | _IOC_SIZEMASK = (lshift(1, _IOC_SIZEBITS)-1) 43 | _IOC_DIRMASK = (lshift(1, _IOC_DIRBITS)-1) 44 | 45 | _IOC_NRSHIFT = 0 46 | _IOC_TYPESHIFT = (_IOC_NRSHIFT+_IOC_NRBITS) 47 | _IOC_SIZESHIFT = (_IOC_TYPESHIFT+_IOC_TYPEBITS) 48 | _IOC_DIRSHIFT = (_IOC_SIZESHIFT+_IOC_SIZEBITS) 49 | 50 | --[[ 51 | * Direction bits, which any architecture can choose to override 52 | * before including this file. 53 | --]] 54 | 55 | _IOC_NONE = 0 56 | _IOC_WRITE = 1 57 | _IOC_READ = 2 58 | 59 | _IOC = function(dir,type,nr,size) 60 | return bor(lshift(dir, _IOC_DIRSHIFT), 61 | lshift(type, _IOC_TYPESHIFT), 62 | lshift(nr, _IOC_NRSHIFT), 63 | lshift(size, _IOC_SIZESHIFT)) 64 | end 65 | 66 | _IOC_TYPECHECK = function(t) 67 | return ffi.sizeof(t) 68 | end 69 | 70 | -- used to create numbers 71 | _IO = function(type,nr) return _IOC(_IOC_NONE,(type),nr,0) end 72 | _IOR = function(type,nr,size) return _IOC(_IOC_READ,(type),nr,(_IOC_TYPECHECK(size))) end 73 | _IOW = function(type,nr,size) return _IOC(_IOC_WRITE,(type),nr,(_IOC_TYPECHECK(size))) end 74 | _IOWR = function(type,nr,size) return _IOC(bor(_IOC_READ,_IOC_WRITE),(type),nr,(_IOC_TYPECHECK(size))) end 75 | _IOR_BAD = function(type,nr,size) return _IOC(_IOC_READ,(type),nr,ffi.sizeof(size)) end 76 | _IOW_BAD = function(type,nr,size) return _IOC(_IOC_WRITE,(type),nr,ffi.sizeof(size)) end 77 | _IOWR_BAD= function(type,nr,size) return _IOC(bor(_IOC_READ, _IOC_WRITE),(type),nr,ffi.sizeof(size)) end 78 | 79 | -- used to decode ioctl numbers.. 80 | _IOC_DIR = function(nr) return band(rshift(nr, _IOC_DIRSHIFT), _IOC_DIRMASK) end 81 | _IOC_TYPE= function(nr) return band(rshift(nr, _IOC_TYPESHIFT), _IOC_TYPEMASK) end 82 | _IOC_NR = function(nr) return band(rshift(nr, _IOC_NRSHIFT), _IOC_NRMASK) end 83 | _IOC_SIZE= function(nr) return band(rshift(nr, _IOC_SIZESHIFT), _IOC_SIZEMASK) end 84 | 85 | -- ...and for the drivers/sound files... 86 | 87 | IOC_IN = lshift(_IOC_WRITE, _IOC_DIRSHIFT) 88 | IOC_OUT = lshift(_IOC_READ, _IOC_DIRSHIFT) 89 | IOC_INOUT = lshift(bor(_IOC_WRITE,_IOC_READ), _IOC_DIRSHIFT) 90 | IOCSIZE_MASK = lshift(_IOC_SIZEMASK, _IOC_SIZESHIFT) 91 | IOCSIZE_SHIFT = (_IOC_SIZESHIFT) 92 | 93 | -------------------------------------------------------------------------------- /khrplatform.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | local ffi = require "ffi" 5 | 6 | ffi.cdef[[ 7 | typedef int32_t khronos_int32_t; 8 | typedef uint32_t khronos_uint32_t; 9 | typedef int64_t khronos_int64_t; 10 | typedef uint64_t khronos_uint64_t; 11 | ]] 12 | 13 | KHRONOS_SUPPORT_INT64 = true; 14 | KHRONOS_SUPPORT_FLOAT = true; 15 | 16 | 17 | 18 | ffi.cdef[[ 19 | /* 20 | * Types that are (so far) the same on all platforms 21 | */ 22 | typedef signed char khronos_int8_t; 23 | typedef unsigned char khronos_uint8_t; 24 | typedef signed short int khronos_int16_t; 25 | typedef unsigned short int khronos_uint16_t; 26 | typedef signed long int khronos_intptr_t; 27 | typedef unsigned long int khronos_uintptr_t; 28 | typedef signed long int khronos_ssize_t; 29 | typedef unsigned long int khronos_usize_t; 30 | ]] 31 | 32 | if KHRONOS_SUPPORT_FLOAT then 33 | ffi.cdef[[ 34 | typedef float khronos_float_t; 35 | ]] 36 | end 37 | 38 | if KHRONOS_SUPPORT_INT64 then 39 | ffi.cdef[[ 40 | /* Time types 41 | * 42 | * These types can be used to represent a time interval in nanoseconds or 43 | * an absolute Unadjusted System Time. Unadjusted System Time is the number 44 | * of nanoseconds since some arbitrary system event (e.g. since the last 45 | * time the system booted). The Unadjusted System Time is an unsigned 46 | * 64 bit value that wraps back to 0 every 584 years. Time intervals 47 | * may be either signed or unsigned. 48 | */ 49 | typedef khronos_uint64_t khronos_utime_nanoseconds_t; 50 | typedef khronos_int64_t khronos_stime_nanoseconds_t; 51 | ]] 52 | end 53 | 54 | ffi.cdef[[ 55 | /* 56 | * Dummy value used to pad enum types to 32 bits. 57 | */ 58 | static const int KHRONOS_MAX_ENUM = 0x7FFFFFFF; 59 | 60 | 61 | /* 62 | * Enumerated boolean type 63 | * 64 | * Values other than zero should be considered to be true. Therefore 65 | * comparisons should not be made against KHRONOS_TRUE. 66 | */ 67 | typedef enum { 68 | KHRONOS_FALSE = 0, 69 | KHRONOS_TRUE = 1, 70 | KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM 71 | } khronos_boolean_enum_t; 72 | ]] 73 | 74 | --[[ 75 | /* 76 | ** Copyright (c) 2008-2009 The Khronos Group Inc. 77 | ** 78 | ** Permission is hereby granted, free of charge, to any person obtaining a 79 | ** copy of this software and/or associated documentation files (the 80 | ** "Materials"), to deal in the Materials without restriction, including 81 | ** without limitation the rights to use, copy, modify, merge, publish, 82 | ** distribute, sublicense, and/or sell copies of the Materials, and to 83 | ** permit persons to whom the Materials are furnished to do so, subject to 84 | ** the following conditions: 85 | ** 86 | ** The above copyright notice and this permission notice shall be included 87 | ** in all copies or substantial portions of the Materials. 88 | ** 89 | ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 90 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 91 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 92 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 93 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 94 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 95 | ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 96 | */ 97 | --]] 98 | -------------------------------------------------------------------------------- /libc.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | ffi.cdef[[ 4 | int sleep(int millis); 5 | //int nanosleep(const struct timespec *req, struct timespec *rem); 6 | 7 | int open(const char *path, int flags, int mode); 8 | int close(int fd); 9 | size_t write(int fildes, const void *buf, size_t nbytes); 10 | 11 | void *mmap(void *addr, size_t length, int prot, int flags, int fd, size_t ofs); 12 | int munmap(void *addr, size_t length); 13 | int poll(struct pollfd *fds, unsigned long nfds, int timeout); 14 | 15 | void * malloc(size_t size); 16 | void free(void *ptr); 17 | void * calloc(size_t nmemb, size_t size); 18 | void * realloc(void *ptr, size_t size); 19 | ]] 20 | -------------------------------------------------------------------------------- /rpiui.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | local BCMHost = require "BcmHost" 5 | 6 | 7 | local vchiq_arm_Lib = ffi.load("vchiq_arm"); 8 | 9 | --[[ 10 | GLESv2 must be loaded before EGL or there will be 11 | an error: 12 | /opt/vc/lib/libEGL.so: undefined symbol: glPointSizePointerOES 13 | 14 | this symbol is located in the libGLESv2.so library, thus it needs 15 | to be loaded first. 16 | --]] 17 | local GLESv1 = require "GLESMan" 18 | --local GLESv2 = require "GLES2Man"; 19 | 20 | local EGL = require "egl_utils"; 21 | 22 | 23 | local OpenVG = require "OpenVG_Utils"; 24 | 25 | --local mmal_Lib = ffi.load("mmal"); 26 | --local openmaxil_Lib = ffi.load("openmaxil"); 27 | --local WFC_Lib = ffi.load("WFC"); 28 | 29 | 30 | return { 31 | -- Modules 32 | BCMHost = BCMHost; 33 | 34 | GLES = GLESv1; 35 | -- GLES2 = GLESv2; 36 | 37 | EGL = EGL; 38 | OpenVG = OpenVG; 39 | } 40 | -------------------------------------------------------------------------------- /strict.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- strict.lua 3 | -- checks uses of undeclared global variables 4 | -- All global variables must be 'declared' through a regular assignment 5 | -- (even assigning nil will do) in a main chunk before being used 6 | -- anywhere or assigned to inside a function. 7 | -- 8 | 9 | local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget 10 | 11 | local mt = getmetatable(_G) 12 | if mt == nil then 13 | mt = {} 14 | setmetatable(_G, mt) 15 | end 16 | 17 | mt.__declared = {} 18 | 19 | local function what () 20 | local d = getinfo(3, "S") 21 | return d and d.what or "C" 22 | end 23 | 24 | mt.__newindex = function (t, n, v) 25 | if not mt.__declared[n] then 26 | local w = what() 27 | if w ~= "main" and w ~= "C" then 28 | error("assign to undeclared variable '"..n.."'", 2) 29 | end 30 | mt.__declared[n] = true 31 | end 32 | rawset(t, n, v) 33 | end 34 | 35 | mt.__index = function (t, n) 36 | if not mt.__declared[n] and what() ~= "C" then 37 | error("variable '"..n.."' is not declared", 2) 38 | end 39 | return rawget(t, n) 40 | end 41 | 42 | -------------------------------------------------------------------------------- /test_snapshot.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | local DMX = require "DisplayManX" 4 | 5 | local Display = DMXDisplay(); 6 | Display:SetBackground(0,0,0); 7 | 8 | local screenWidth, screenHeight = Display:GetSize(); 9 | local ratio = screenWidth / screenHeight; 10 | local displayHeight = 320; 11 | local displayWidth = 640; 12 | --local displayHeight = 70; 13 | --local displayWidth = displayHeight * ratio; 14 | 15 | 16 | -- Create the view that will display the snapshot 17 | local displayView = Display:CreateView( 18 | displayWidth, displayHeight, 19 | 0, screenHeight-displayHeight-1, 20 | 0, ffi.C.VC_IMAGE_RGB888) 21 | 22 | 23 | 24 | 25 | local function WritePPM(filename, pixbuff) 26 | local r, c, val; 27 | 28 | local fp = io.open(filename, "wb") 29 | if not fp then 30 | return false 31 | end 32 | 33 | local header = string.format("P6\n%d %d\n255\n", pixbuff.Width, pixbuff.Height) 34 | fp:write(header); 35 | 36 | for row=0,pixbuff.Height-1 do 37 | local dataPtr = ffi.cast("char *",pixbuff.Data) + pixbuff.Pitch*row 38 | local data = ffi.string(dataPtr, pixbuff.Width*3); 39 | fp:write(data); 40 | end 41 | 42 | fp:close(); 43 | end 44 | 45 | 46 | -- Do the snapshot 47 | displayView:Hide(); 48 | Display:Snapshot(displayView.Resource); 49 | displayView:Show(); 50 | 51 | 52 | local pixeldata, err = displayView.Resource:ReadPixelData(); 53 | if pixeldata then 54 | -- Write the data out 55 | local filename = "~/desktop.ppm" 56 | print("Writing: ", filename); 57 | 58 | WritePPM(filename, pixeldata); 59 | end 60 | 61 | ffi.C.sleep(5); 62 | 63 | 64 | -------------------------------------------------------------------------------- /tests/Djenne_128_128.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wiladams/LJIT2RPi/df1345d87f511846479cb6ef240033360a433ed2/tests/Djenne_128_128.raw -------------------------------------------------------------------------------- /tests/Gaudi_128_128.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wiladams/LJIT2RPi/df1345d87f511846479cb6ef240033360a433ed2/tests/Gaudi_128_128.raw -------------------------------------------------------------------------------- /tests/Lucca_128_128.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wiladams/LJIT2RPi/df1345d87f511846479cb6ef240033360a433ed2/tests/Lucca_128_128.raw -------------------------------------------------------------------------------- /tests/PGMCodec.lua: -------------------------------------------------------------------------------- 1 | 2 | function WritePGM(fp, pixbuff) 3 | local r, c, val; 4 | 5 | local header = string.format("P5\n%d %d\n255\n", pixbuff.Width, pixbuff.Height) 6 | fp:write(header); 7 | 8 | for r = 0, pixbuff.Height-1 do 9 | for c = 0, pixbuff.Width-1 do 10 | local offset = (r*pixbuff.Width)+c 11 | local pix = pixbuff.Data[offset]:ToArray(); 12 | fp:write(pix); 13 | end 14 | end 15 | end 16 | 17 | 18 | 19 | function WritePPM(fp, pixbuff) 20 | local r, c, val; 21 | 22 | local header = string.format("P6\n%d %d\n255\n", pixbuff.Width, pixbuff.Height) 23 | fp:write(header); 24 | 25 | for r = 0, pixbuff.Height-1 do 26 | for c = 0, pixbuff.Width-1 do 27 | local offset = (r*pixbuff.Width)+c 28 | local pix = pixbuff.Data[offset]:ToArray(); 29 | fp:write(pix); 30 | end 31 | end 32 | end 33 | 34 | 35 | function WritePNMFile(filename, pixbuff, routine) 36 | local fp = io.open(filename, "wb") 37 | if fp then 38 | routine(fp, pixbuff) 39 | end 40 | fp:close() 41 | end 42 | 43 | 44 | return { 45 | WritePGM = WritePGM, 46 | WritePPM = WritePPM, 47 | WritePNM = WritePNMFile, 48 | } 49 | 50 | -------------------------------------------------------------------------------- /tests/PSLoader.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | local bit = require "bit" 3 | local bor = bit.bor 4 | local band = bit.band 5 | 6 | 7 | local rpiui = require "rpiui" 8 | local EGL = rpiui.EGL; 9 | local VG = EGL.Lib; 10 | 11 | ffi.cdef[[ 12 | typedef struct 13 | { 14 | VGFillRule m_fillRule; 15 | VGPaintMode m_paintMode; 16 | VGCapStyle m_capStyle; 17 | VGJoinStyle m_joinStyle; 18 | float m_miterLimit; 19 | float m_strokeWidth; 20 | VGPaint m_fillPaint; 21 | VGPaint m_strokePaint; 22 | VGPath m_path; 23 | } PathData; 24 | 25 | 26 | ]] 27 | 28 | PS = {} 29 | PS_mt = { 30 | __index = PS; 31 | } 32 | 33 | 34 | PS.construct = function(commands, commandCount, points, pointCount) 35 | 36 | local ps = { 37 | m_paths = {}; 38 | m_numPaths = 0; 39 | } 40 | setmetatable(ps, PS_mt); 41 | 42 | local p = 0; 43 | local c = 0; 44 | local i = 0; 45 | local paths = 0; 46 | local maxElements = 0; 47 | 48 | while(c < commandCount) do 49 | local elements; 50 | local e; 51 | c = c+4; 52 | p = p+8; 53 | elements = points[p]; 54 | p = p + 1; 55 | assert(elements > 0); 56 | if(elements > maxElements) then 57 | maxElements = elements; 58 | end 59 | 60 | e = 0; 61 | while (e 0); 180 | startp = p; 181 | 182 | e = 0; 183 | while (e 0) then 233 | 234 | VG.vgSetf(ffi.C.VG_STROKE_LINE_WIDTH, ps.m_paths[i].m_strokeWidth); 235 | VG.vgSeti(ffi.C.VG_STROKE_CAP_STYLE, ps.m_paths[i].m_capStyle); 236 | VG.vgSeti(ffi.C.VG_STROKE_JOIN_STYLE, ps.m_paths[i].m_joinStyle); 237 | VG.vgSetf(ffi.C.VG_STROKE_MITER_LIMIT, ps.m_paths[i].m_miterLimit); 238 | VG.vgSetPaint(ps.m_paths[i].m_strokePaint, ffi.C.VG_STROKE_PATH); 239 | end 240 | 241 | VG.vgDrawPath(ps.m_paths[i].m_path, ps.m_paths[i].m_paintMode); 242 | i = i + 1; 243 | end 244 | --assert(tonumber(VG.vgGetError()) == tonumber(ffi.C.VG_NO_ERROR)); 245 | end 246 | 247 | return PS 248 | -------------------------------------------------------------------------------- /tests/cube_texture_and_coords.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | -- Spatial coordinates for the cube 5 | 6 | quadx = ffi.new("GLbyte[?]", 6*4*3, { 7 | -- FRONT 8 | -10, -10, 10, 9 | 10, -10, 10, 10 | -10, 10, 10, 11 | 10, 10, 10, 12 | 13 | -- BACK 14 | -10, -10, -10, 15 | -10, 10, -10, 16 | 10, -10, -10, 17 | 10, 10, -10, 18 | 19 | -- LEFT 20 | -10, -10, 10, 21 | -10, 10, 10, 22 | -10, -10, -10, 23 | -10, 10, -10, 24 | 25 | -- RIGHT 26 | 10, -10, -10, 27 | 10, 10, -10, 28 | 10, -10, 10, 29 | 10, 10, 10, 30 | 31 | -- TOP 32 | -10, 10, 10, 33 | 10, 10, 10, 34 | -10, 10, -10, 35 | 10, 10, -10, 36 | 37 | -- BOTTOM 38 | -10, -10, 10, 39 | -10, -10, -10, 40 | 10, -10, 10, 41 | 10, -10, -10, 42 | }); 43 | 44 | -- Texture coordinates for the quad. 45 | texCoords = ffi.new("GLfloat[?]", 6 * 4 * 2, { 46 | 0, 0, 47 | 0, 1, 48 | 1, 0, 49 | 1, 1, 50 | 51 | 0, 0, 52 | 0, 1, 53 | 1, 0, 54 | 1, 1, 55 | 56 | 0, 0, 57 | 0, 1, 58 | 1, 0, 59 | 1, 1, 60 | 61 | 0, 0, 62 | 0, 1, 63 | 1, 0, 64 | 1, 1, 65 | 66 | 0, 0, 67 | 0, 1, 68 | 1, 0, 69 | 1, 1, 70 | 71 | 0, 0, 72 | 0, 1, 73 | 1, 0, 74 | 1, 1 75 | }); 76 | 77 | -- Colors are invisible when textures appear on all 6 faces. 78 | -- If textures are disabled, e.g. by commenting out glEnable(GL_TEXTURE_2D), 79 | -- the colours will appear. 80 | 81 | colorsf = ffi.new("float[?]", 6*4*4, { 82 | 1, 0, 0, 1, --red 83 | 1, 0, 0, 1, 84 | 1, 0, 0, 1, 85 | 1, 0, 0, 1, 86 | 87 | 0, 1, 0, 1, -- blue 88 | 0, 1, 0, 1, 89 | 0, 1, 0, 1, 90 | 0, 1, 0, 1, 91 | 92 | 0, 0, 1, 1, -- green 93 | 0, 0, 1, 1, 94 | 0, 0, 1, 1, 95 | 0, 0, 1, 1, 96 | 97 | 0, 0.5, 0.5, 1, -- teal 98 | 0, 0.5, 0.5, 1, 99 | 0, 0.5, 0.5, 1, 100 | 0, 0.5, 0.5, 1, 101 | 102 | 0.5, 0.5, 0, 1, -- yellow 103 | 0.5, 0.5, 0, 1, 104 | 0.5, 0.5, 0, 1, 105 | 0.5, 0.5, 0, 1, 106 | 107 | 0.5, 0, 0.5, 1, -- purple 108 | 0.5, 0, 0.5, 1, 109 | 0.5, 0, 0.5, 1, 110 | 0.5, 0, 0.5, 1 111 | }); 112 | -------------------------------------------------------------------------------- /tests/media/desktop.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wiladams/LJIT2RPi/df1345d87f511846479cb6ef240033360a433ed2/tests/media/desktop.mp4 -------------------------------------------------------------------------------- /tests/media/desktop.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wiladams/LJIT2RPi/df1345d87f511846479cb6ef240033360a433ed2/tests/media/desktop.ppm -------------------------------------------------------------------------------- /tests/snapper.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | 5 | local Keyboard = require "Keyboard" 6 | local EventLoop = require "EventLoop" 7 | 8 | local DMX = require "DisplayManX" 9 | 10 | local Display = DMXDisplay(); 11 | --Display:SetBackground(0,0,0); 12 | 13 | local screenWidth, screenHeight = Display:GetSize(); 14 | 15 | local displayHeight = screenHeight; 16 | local displayWidth = screenWidth; 17 | 18 | 19 | -- Setup an event loop and keyboard 20 | local loop = EventLoop.new(); 21 | local kbd = Keyboard.new(); 22 | 23 | 24 | 25 | local function WritePPM(filename, pixbuff) 26 | local r, c, val; 27 | 28 | local fp = io.open(filename, "wb") 29 | if not fp then 30 | return false 31 | end 32 | 33 | local header = string.format("P6\n%d %d\n255\n", pixbuff.Width, pixbuff.Height) 34 | fp:write(header); 35 | 36 | for row=0,pixbuff.Height-1 do 37 | local dataPtr = ffi.cast("char *",pixbuff.Data) + pixbuff.Pitch*row 38 | local data = ffi.string(dataPtr, pixbuff.Width*3); 39 | fp:write(data); 40 | end 41 | 42 | fp:close(); 43 | end 44 | 45 | local function TakeSnapshot() 46 | -- Create resource used for capturing screen 47 | local resource = DMXResource(displayWidth, displayHeight, ffi.C.VC_IMAGE_RGB888); 48 | 49 | -- Do the snapshot 50 | Display:Snapshot(resource); 51 | 52 | 53 | local pixeldata, err = resource:ReadPixelData(); 54 | if pixeldata then 55 | -- Write the data out 56 | local filename = "media/desktop.ppm" 57 | 58 | WritePPM(filename, pixeldata); 59 | end 60 | 61 | print("File Written: ", filename); 62 | end 63 | 64 | 65 | OnKeyUp = function(kbd, keycode) 66 | if keycode == KEY_SYSRQ then 67 | TakeSnapshot(); 68 | end 69 | 70 | -- Halt the loop if they press the "Esc" key 71 | if keycode == KEY_ESC then 72 | loop:Halt(); 73 | end 74 | end 75 | 76 | 77 | 78 | -- Setup some keyboard with event handlers 79 | kbd.OnKeyUp = OnKeyUp; 80 | 81 | loop:AddObservable(kbd); 82 | 83 | loop:Run(15); 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /tests/test.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | print("Arch: ", ffi.arch); 4 | print("EABI: ", ffi.abi("eabi")); 5 | 6 | -------------------------------------------------------------------------------- /tests/test_App_Watcher.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | 5 | local app = require "Application"; 6 | 7 | local S = require "syscall" 8 | 9 | 10 | --[[ 11 | Callback functions 12 | --]] 13 | 14 | function OnTimer(loop, ...) 15 | print("OnTimer: ", loop:iteration()); 16 | end 17 | 18 | function OnIdle(loop, ...) 19 | print("Idling"); 20 | end 21 | 22 | 23 | 24 | --[[ 25 | Event type: 26 | EV_KEY 27 | EV_MSC 28 | 29 | value: 30 | 0 == keyup 31 | 1 == keydown 32 | --]] 33 | 34 | function OnKey(loop, w, revents) 35 | local event = input_event(); 36 | local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 37 | 38 | 39 | if event.type == EV_MSC then 40 | if event.code == MSC_SCAN then 41 | --print("MSC_SCAN: ", string.format("0x%x",event.value)); 42 | else 43 | --print("MSC: ", event.code, event.value); 44 | end 45 | elseif event.type == EV_KEY then 46 | if event.value == 1 then 47 | print("KEYDOWN: ", event.code); 48 | elseif event.value == 0 then 49 | print("KEYUP: ", event.code); 50 | 51 | if event.code == KEY_ESC then 52 | loop:halt(); 53 | return false; 54 | end 55 | 56 | elseif event.value == 2 then 57 | print("KEYREP: ", event.code); 58 | end 59 | else 60 | --print("EVENT TYPE: ", UI.EventTypes[event.type][2], "CODE:",event.code, "VALUE: ", string.format("0x%x",event.value)); 61 | end 62 | end 63 | 64 | function OnMouse(loop, w, revents) 65 | --print("OnMouse: ", w, revents); 66 | local event = input_event(); 67 | local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 68 | 69 | print("MOUSE: ", event.type, event.code, event.value); 70 | end 71 | 72 | 73 | --[[ 74 | Create Observers 75 | --]] 76 | 77 | --app.AddIdleObserver(OnIdle); 78 | 79 | -- Timer Observer 80 | app.AddTimerObserver(OnTimer, 1, 3); 81 | 82 | -- Keyboard Tracking 83 | app.AddKeyboardObserver(OnKey); 84 | 85 | -- Mouse Tracking 86 | --app.AddMouseObserver(OnMouse); 87 | 88 | 89 | -- Run the Application 90 | app.Run(); 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /tests/test_bcm_host.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | 5 | 6 | local bcm = require "BcmHost" 7 | 8 | 9 | print(bcm.GetDisplaySize()); 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/test_bit.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define test_bit(yalv, abs_b) ((((char *)abs_b)[yalv/8] & (1< 0) 5 | 6 | int printBits(int value) 7 | { 8 | int i; 9 | 10 | for (i=32;i>=0;i--) 11 | { 12 | printf("%d",test_bit(i, &value)); 13 | } 14 | printf("\n"); 15 | } 16 | 17 | int main(void) 18 | { 19 | int abs_b = 0x05; 20 | 21 | printBits(0x01); 22 | printBits(0x03); 23 | printBits(0x05); 24 | printBits(0x0f); 25 | printBits(0xff); 26 | printBits(0x7f); 27 | printBits(0x80); 28 | printBits(0x8000); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /tests/test_blink1.lua: -------------------------------------------------------------------------------- 1 | -- Simple example for Raspberry Pi GPIO module. 2 | -- Blinks GPIO 0 (LED + resistor to 0V) and shows input status of GPIO 6. 3 | -- Written by Mike Pall. Public domain. 4 | 5 | local gpio = require("rpi.gpio") 6 | 7 | for i=1,10 do 8 | print("GPIO 6:", gpio.pin[6]) 9 | gpio.pin[0] = 1 10 | gpio.msleep(100) 11 | gpio.pin[0] = 0 12 | gpio.msleep(100) 13 | end 14 | 15 | -------------------------------------------------------------------------------- /tests/test_bouncing_square.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | 5 | local app = require "Application"; 6 | 7 | local S = require "syscall" 8 | 9 | 10 | --[[ 11 | Callback functions 12 | --]] 13 | 14 | function OnTimer(loop, ...) 15 | print("OnTimer: ", loop:iteration()); 16 | end 17 | 18 | function OnIdle(loop, ...) 19 | print("Idling"); 20 | end 21 | 22 | 23 | 24 | --[[ 25 | Event type: 26 | EV_KEY 27 | EV_MSC 28 | 29 | value: 30 | 0 == keyup 31 | 1 == keydown 32 | --]] 33 | 34 | function OnKey(loop, w, revents) 35 | local event = input_event(); 36 | local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 37 | 38 | 39 | if event.type == EV_MSC then 40 | if event.code == MSC_SCAN then 41 | --print("MSC_SCAN: ", string.format("0x%x",event.value)); 42 | else 43 | --print("MSC: ", event.code, event.value); 44 | end 45 | elseif event.type == EV_KEY then 46 | if event.value == 1 then 47 | print("KEYDOWN: ", event.code); 48 | elseif event.value == 0 then 49 | print("KEYUP: ", event.code); 50 | 51 | if event.code == KEY_ESC then 52 | loop:halt(); 53 | return false; 54 | end 55 | 56 | elseif event.value == 2 then 57 | print("KEYREP: ", event.code); 58 | end 59 | else 60 | --print("EVENT TYPE: ", UI.EventTypes[event.type][2], "CODE:",event.code, "VALUE: ", string.format("0x%x",event.value)); 61 | end 62 | end 63 | 64 | function OnMouse(loop, w, revents) 65 | --print("OnMouse: ", w, revents); 66 | local event = input_event(); 67 | local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 68 | 69 | print("MOUSE: ", event.type, event.code, event.value); 70 | end 71 | 72 | 73 | --[[ 74 | Create Observers 75 | --]] 76 | 77 | --app.AddIdleObserver(OnIdle); 78 | 79 | -- Timer Observer 80 | app.AddTimerObserver(OnTimer, 1, 0.5); 81 | 82 | -- Keyboard Tracking 83 | app.AddKeyboardObserver(OnKey); 84 | 85 | -- Mouse Tracking 86 | --app.AddMouseObserver(OnMouse); 87 | 88 | 89 | -- Run the Application 90 | app.Run(); 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /tests/test_dispmanx.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | -- A simple demo using dispmanx to display an overlay 4 | 5 | local ffi = require "ffi" 6 | local bit = require "bit" 7 | local bnot = bit.bnot 8 | local band = bit.band 9 | local bor = bit.bor 10 | local rshift = bit.rshift 11 | local lshift = bit.lshift 12 | 13 | local DMX = require "DisplayManX" 14 | 15 | 16 | -- This is a very simple graphics rendering routine. 17 | -- It will fill in a rectangle, and that's it. 18 | function FillRect( pbuff, x, y, w, h, val) 19 | local dataPtr = ffi.cast("uint8_t *", pbuff.Data); 20 | 21 | local row; 22 | local col; 23 | for row=y, y+h-1 do 24 | local rowPtr = ffi.cast("int16_t *", (dataPtr + (pbuff.Pitch*row))); 25 | for col=x, x+w-1 do 26 | rowPtr[col] = val; 27 | end 28 | end 29 | end 30 | 31 | -- Setup the display 32 | width = 400 33 | height = 200 34 | 35 | -- Get a connection to the display 36 | local Display = DMXDisplay(); 37 | Display:SetBackground(125, 65, 65); 38 | 39 | local info = Display:GetInfo(); 40 | 41 | print(string.format("Display is %d x %d", info.width, info.height) ); 42 | 43 | -- Create an image to be displayed 44 | local pbuff = DMX.DMXPixelData(width, height); 45 | 46 | --FillRect( pbuff, 0, 0, width, height, 0xffff ); 47 | FillRect( pbuff, 0, 0, width, height, 0xF800 ); 48 | FillRect( pbuff, 20, 20, width - 40, height - 40, 0x07E0 ); 49 | FillRect( pbuff, 40, 40, width - 80, height - 80, 0x001F ); 50 | 51 | 52 | -- local alpha = VC_DISPMANX_ALPHA_T( bor(ffi.C.DISPMANX_FLAGS_ALPHA_FROM_SOURCE, ffi.C.DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS), 120, 0 ); 53 | mainView = Display:CreateView(width, height, 0, info.height-height, nil, nil, 0.5); 54 | mainView:CopyPixelBuffer(pbuff, 0, 0, width, height); 55 | 56 | ffi.C.sleep( 2 ) 57 | 58 | -- Copy a different picture 59 | FillRect( pbuff, 0, 0, width, height, 0xffff ); 60 | mainView:CopyPixelBuffer(pbuff, 0, 0, width, height); 61 | 62 | ffi.C.sleep( 2 ) 63 | 64 | 65 | -------------------------------------------------------------------------------- /tests/test_egl.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | local bit = require "bit" 4 | local bor = bit.bor 5 | local lshift = bit.lshift; 6 | 7 | 8 | 9 | local rpiui = require "rpiui" 10 | 11 | local GLES = rpiui.GLES; 12 | local EGL = rpiui.EGL; 13 | local OpenVG = rpiui.OpenVG; 14 | local egl = require "egl" 15 | 16 | 17 | local screenWidth = 640; 18 | local screenHeight = 480; 19 | 20 | print("EGL API: ", EGL.EGL_OPENVG_API); 21 | 22 | local mainWindow = EGL.Window.new(screenWidth, screenHeight, nil, EGL.EGL_OPENVG_API); 23 | --local mainWindow = EGL.Window.new(screenWidth, screenHeight, nil, EGL.EGL_OPENGLES_API); 24 | --local mainWindow = EGL.Window.new(screenWidth, screenHeight, nil); 25 | 26 | local RenderClass = require"Drawing" 27 | 28 | 29 | print("-- EGL --"); 30 | print("Vendor: ", mainWindow.Display:Vendor()); 31 | print("ClientAPIs: ", mainWindow.Display:ClientAPIs()); 32 | print(string.format("Current API: 0x%x", mainWindow.Display:CurrentAPI())); 33 | print("Extensions: "); 34 | print(mainWindow.Display:Extensions()); 35 | 36 | -- Create the renderer so we can do some drawing 37 | local Renderer = RenderClass.new(mainWindow.Display, screenWidth, screenHeight); 38 | 39 | 40 | 41 | local drawLines = function() 42 | --Renderer:Begin(); 43 | Renderer:StrokeWidth(1); 44 | Renderer:SetStroke(250,250,250,1); 45 | Renderer:Line(1,1, screenWidth/2, screenHeight/2); 46 | --Renderer:End(); 47 | end 48 | 49 | local drawRectangles = function(count) 50 | count = count or 100; 51 | 52 | 53 | --Renderer:Begin(); 54 | for i=1,count do 55 | local width = math.random(10,250); 56 | local height = math.random(10,250); 57 | local x = math.random(0,screenWidth -1-width); 58 | local y = math.random(0,screenHeight - 1-height); 59 | 60 | local red = math.random(0,255); 61 | local green = math.random(0,255); 62 | local blue = math.random(0,255); 63 | 64 | Renderer:Fill(red, green, blue, 1); 65 | --print(x,y,width, height, ": ", red, green, blue); 66 | Renderer:Rect(x,y,width,height); 67 | end 68 | --Renderer:End(); 69 | 70 | end 71 | 72 | local drawEllipses = function() 73 | Renderer:PushTransform(); 74 | 75 | --Renderer:Begin(); 76 | Renderer:Translate(screenWidth/2, screenHeight/2); 77 | Renderer:Fill(44, 77, 232, 1); -- Big blue marble 78 | Renderer:Circle(0, 0, screenHeight/2); -- The "world" 79 | --Renderer:End(); 80 | 81 | Renderer:PopTransform(); 82 | end 83 | 84 | local tick = function(ticker, tickCount) 85 | print("Tick: ", tickCount); 86 | 87 | 88 | Renderer:Begin(); 89 | Renderer:Background(0, 0, 0); -- Black background 90 | 91 | drawRectangles(255); 92 | drawEllipses(); 93 | drawLines(); 94 | Renderer:End(); 95 | end 96 | 97 | 98 | glViewport(0,0,screenWidth,screenHeight); 99 | glMatrixMode(GL_PROJECTION); 100 | glLoadIdentity(); 101 | 102 | local ratio = screenWidth/screenHeight; 103 | glFrustumf(-ratio, ratio, -1, 1, 1, 10); 104 | 105 | 106 | -- Now, finally do some drawing 107 | --tick(RealDisplay, 1); 108 | 109 | 110 | -- Sleep for a few seconds so we can see the results 111 | local seconds = 3 112 | print( string.format("Sleeping for %d seconds...", seconds )); 113 | ffi.C.sleep( seconds ) 114 | 115 | -------------------------------------------------------------------------------- /tests/test_egl_vg_window.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | local bit = require "bit" 4 | local bor = bit.bor 5 | local lshift = bit.lshift; 6 | 7 | 8 | 9 | local rpiui = require "rpiui" 10 | 11 | local GLES = rpiui.GLES; 12 | local EGL = rpiui.EGL; 13 | local OpenVG = rpiui.OpenVG; 14 | local egl = require "egl" 15 | 16 | 17 | local screenWidth = 640; 18 | local screenHeight = 480; 19 | 20 | 21 | local mainWindow = EGL.Window.new(screenWidth, screenHeight, nil, EGL.EGL_OPENVG_API); 22 | --local mainWindow = EGL.Window.new(screenWidth, screenHeight, nil, EGL.EGL_OPENGLES_API); 23 | --local mainWindow = EGL.Window.new(screenWidth, screenHeight, nil); 24 | 25 | local RenderClass = require"Drawing" 26 | 27 | 28 | print("-- EGL --"); 29 | print("Vendor: ", mainWindow.Display:Vendor()); 30 | print("ClientAPIs: ", mainWindow.Display:ClientAPIs()); 31 | print(string.format("Current API: 0x%x", mainWindow.Display:CurrentAPI())); 32 | print("Extensions: "); 33 | print(mainWindow.Display:Extensions()); 34 | 35 | -- Create the renderer so we can do some drawing 36 | local Renderer = RenderClass.new(mainWindow.Display, screenWidth, screenHeight); 37 | 38 | 39 | 40 | local drawLines = function() 41 | --Renderer:Begin(); 42 | Renderer:StrokeWidth(1); 43 | Renderer:SetStroke(250,250,250,1); 44 | Renderer:Line(1,1, screenWidth/2, screenHeight/2); 45 | --Renderer:End(); 46 | end 47 | 48 | local drawRectangles = function(count) 49 | count = count or 100; 50 | 51 | 52 | --Renderer:Begin(); 53 | for i=1,count do 54 | local width = math.random(10,250); 55 | local height = math.random(10,250); 56 | local x = math.random(0,screenWidth -1-width); 57 | local y = math.random(0,screenHeight - 1-height); 58 | 59 | local red = math.random(0,255); 60 | local green = math.random(0,255); 61 | local blue = math.random(0,255); 62 | 63 | Renderer:Fill(red, green, blue, 1); 64 | --print(x,y,width, height, ": ", red, green, blue); 65 | Renderer:Rect(x,y,width,height); 66 | end 67 | --Renderer:End(); 68 | 69 | end 70 | 71 | local drawEllipses = function() 72 | Renderer:PushTransform(); 73 | 74 | --Renderer:Begin(); 75 | Renderer:Translate(screenWidth/2, screenHeight/2); 76 | Renderer:Fill(44, 77, 232, 1); -- Big blue marble 77 | Renderer:Circle(0, 0, screenHeight/2); -- The "world" 78 | --Renderer:End(); 79 | 80 | Renderer:PopTransform(); 81 | end 82 | 83 | local tick = function(ticker, tickCount) 84 | print("Tick: ", tickCount); 85 | 86 | 87 | Renderer:Begin(); 88 | Renderer:Background(0, 0, 0); -- Black background 89 | 90 | drawRectangles(255); 91 | drawEllipses(); 92 | drawLines(); 93 | Renderer:End(); 94 | end 95 | 96 | 97 | glViewport(0,0,screenWidth,screenHeight); 98 | glMatrixMode(GL_PROJECTION); 99 | glLoadIdentity(); 100 | 101 | local ratio = screenWidth/screenHeight; 102 | glFrustumf(-ratio, ratio, -1, 1, 1, 10); 103 | 104 | 105 | -- Now, finally do some drawing 106 | tick(RealDisplay, 1); 107 | 108 | 109 | -- Sleep for a few seconds so we can see the results 110 | local seconds = 3 111 | print( string.format("Sleeping for %d seconds...", seconds )); 112 | ffi.C.sleep( seconds ) 113 | 114 | -------------------------------------------------------------------------------- /tests/test_egl_window.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | local rpiui = require "rpiui" 5 | 6 | local EGL = rpiui.EGL 7 | 8 | -- Setup window 9 | local mainWindow = EGL.Window.new(640, 480, {background = {153, 153, 153}}); 10 | 11 | -- Sleep for a second so we can see the results 12 | local seconds = 5 13 | print( string.format("Sleeping for %d seconds...", seconds )); 14 | ffi.C.sleep( seconds ) 15 | 16 | -------------------------------------------------------------------------------- /tests/test_egles_basic.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | -- A rotating cube rendered with OpenGL|ES. Three images used as textures on the cube faces. 4 | 5 | local ffi = require "ffi" 6 | local bit = require "bit" 7 | local lshift = bit.lshift 8 | local rshift = bit.rshift 9 | 10 | local DMX = require "DisplayManX" 11 | 12 | local rpiui = require "rpiui" 13 | 14 | local GLES = rpiui.GLES 15 | local EGL = rpiui.EGL 16 | local OpenVG = rpiui.OpenVG; 17 | 18 | 19 | 20 | --local egldisplay = EGL.Display.new(EGL.EGL_OPENGL_ES_API); 21 | local egldisplay = EGL.Display.new(); 22 | assert(egldisplay, "EglDisplay not created"); 23 | 24 | local dmxdisplay = DMX.DMXDisplay(); 25 | assert(dmxdisplay, "Could not initialize DMXDisplay"); 26 | 27 | 28 | local screenWidth = 320; 29 | local screenHeight = 240; 30 | 31 | 32 | local IMAGE_SIZE = 128; 33 | 34 | --[[ 35 | /*********************************************************** 36 | * Name: init_ogl 37 | * 38 | * Arguments: 39 | * CUBE_STATE_T *state - holds OGLES model info 40 | * 41 | * Description: Sets the display, OpenGL|ES context and screen stuff 42 | * 43 | * Returns: void 44 | * 45 | ***********************************************************/ 46 | --]] 47 | 48 | function createNativeWindow(dmxdisplay, width, height) 49 | 50 | local dst_rect = VC_RECT_T(0,0,width, height); 51 | local src_rect = VC_RECT_T(0,0, lshift(width, 16), lshift(height,16)); 52 | 53 | --local alpha = VC_DISPMANX_ALPHA_T(ffi.C.DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,255,0); 54 | --local dmxview = dmxdisplay:CreateElement(dst_rect, nil, src_rect, 0, DISPMANX_PROTECTION_NONE, alpha); 55 | local dmxview = dmxdisplay:CreateElement(dst_rect, nil, src_rect); 56 | assert(dmxview, "FAILURE: Did not create dmxview"); 57 | 58 | -- create an EGL window surface 59 | local nativewindow = ffi.new("EGL_DISPMANX_WINDOW_T"); 60 | nativewindow.element = dmxview.Handle; 61 | nativewindow.width = width; 62 | nativewindow.height = height; 63 | 64 | return nativewindow; 65 | end 66 | 67 | 68 | function init_ogl(state) 69 | 70 | -- Get size of the display window 71 | state.screen_width, state.screen_height = dmxdisplay:GetSize(); 72 | state.screen_width = screenWidth; 73 | state.screen_height = screenHeight; 74 | print("SCREEN SIZE: ", state.screen_width, state.screen_height); 75 | 76 | -- Setup the EGL Display 77 | state.display = egldisplay; 78 | 79 | state.nativewindow = createNativeWindow(dmxdisplay, state.screen_width, state.screen_height); 80 | state.surface = egldisplay:CreateWindowSurface(state.nativewindow); 81 | print("SURFACE: ", state.surface); 82 | 83 | -- connect the context to the surface 84 | state.display:MakeCurrent(); 85 | 86 | -- Set background color and clear buffers 87 | glClearColor(0.15, 0.25, 0.35, 1.0); 88 | glClear( GL_COLOR_BUFFER_BIT ); 89 | glClear( GL_DEPTH_BUFFER_BIT ); 90 | end 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | --[[ 99 | *********************************************************** 100 | * Name: init_model_proj 101 | * 102 | * Arguments: 103 | * CUBE_STATE_T *state - holds OGLES model info 104 | * 105 | * Description: Sets the OpenGL|ES model to default values 106 | * 107 | * Returns: void 108 | * 109 | ********************************************************** 110 | --]] 111 | function init_model_proj(state) 112 | 113 | local nearp = 1.0; 114 | local farp = 500.0; 115 | local hht; 116 | local hwd; 117 | 118 | glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); 119 | 120 | glViewport(0, 0, state.screen_width, state.screen_height); 121 | 122 | glMatrixMode(GL_PROJECTION); 123 | glLoadIdentity(); 124 | 125 | hht = nearp * math.tan(45.0 / 2.0 / 180.0 * math.pi); 126 | hwd = hht * state.screen_width / state.screen_height; 127 | 128 | glFrustumf(-hwd, hwd, -hht, hht, nearp, farp); 129 | 130 | 131 | reset_model(state); 132 | end 133 | 134 | 135 | 136 | 137 | --[[ 138 | /*********************************************************** 139 | * Name: redraw_scene 140 | * 141 | * Arguments: 142 | * CUBE_STATE_T *state - holds OGLES model info 143 | * 144 | * Description: Draws the model and calls eglSwapBuffers 145 | * to render to screen 146 | * 147 | * Returns: void 148 | * 149 | ***********************************************************/ 150 | --]] 151 | function redraw_scene(state) 152 | 153 | -- Start with a clear screen 154 | glClear( GL_COLOR_BUFFER_BIT ); 155 | glClear( GL_DEPTH_BUFFER_BIT ); 156 | 157 | glFlush(); 158 | 159 | print("SWAP: ", state.display:SwapBuffers()); 160 | end 161 | 162 | 163 | 164 | -- ============================================================================== 165 | 166 | function main() 167 | -- Clear application state 168 | local state = { 169 | distance_inc = 0, 170 | } 171 | 172 | -- Start OGLES 173 | init_ogl(state); 174 | 175 | redraw_scene(state); 176 | 177 | redraw_scene(state); 178 | 179 | -- Sleep for a second so we can see the results 180 | local seconds = 5 181 | print( string.format("Sleeping for %d seconds...", seconds )); 182 | ffi.C.sleep( seconds ) 183 | 184 | return 0; 185 | end 186 | 187 | main(); 188 | -------------------------------------------------------------------------------- /tests/test_enumdispman.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | 3 | local DMX = require "DisplayManX" 4 | 5 | 6 | function test_image_formats() 7 | local result, err = DMX.query_image_formats(); 8 | 9 | print("Result: ", result, err); 10 | 11 | if result then 12 | print("Formats: ", result, ffi.sizeof(result)); 13 | 14 | 15 | for i=0,16 do 16 | print(string.format("0x%x",result[i])); 17 | end 18 | end 19 | end 20 | 21 | function test_display_info() 22 | local display = DMX.display_open(); 23 | 24 | local info = DMX.get_info(display); 25 | 26 | print("Info: ", info); 27 | print("Size: ", info.width, info.height); 28 | print("Transform: ", info.transform); 29 | print("Input Format: ", info.input_format); 30 | end 31 | 32 | 33 | test_display_info(); -------------------------------------------------------------------------------- /tests/test_event_emitter.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | 5 | local S = require "syscall" 6 | local UI = require "input" 7 | local IOAlertEmitter = require "IOAlertEmitter" 8 | 9 | 10 | 11 | 12 | --[[ 13 | Callback functions 14 | --]] 15 | 16 | function OnIdle(loop, ...) 17 | print("Idling"); 18 | end 19 | 20 | 21 | 22 | --[[ 23 | Event type: 24 | EV_KEY 25 | EV_MSC 26 | 27 | value: 28 | 0 == keyup 29 | 1 == keydown 30 | --]] 31 | 32 | function OnKey(loop, observer) 33 | local event = input_event(); 34 | --local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 35 | local bytesread = observer.Descriptor:read(event, ffi.sizeof(event)); 36 | 37 | if event.type == EV_MSC then 38 | if event.code == MSC_SCAN then 39 | --print("MSC_SCAN: ", string.format("0x%x",event.value)); 40 | else 41 | --print("MSC: ", event.code, event.value); 42 | end 43 | elseif event.type == EV_KEY then 44 | if event.value == 1 then 45 | print("KEYDOWN: ", event.code); 46 | elseif event.value == 0 then 47 | print("KEYUP: ", event.code); 48 | 49 | if event.code == KEY_ESC then 50 | loop:halt(); 51 | return false; 52 | end 53 | 54 | elseif event.value == 2 then 55 | print("KEYREP: ", event.code); 56 | end 57 | else 58 | --print("EVENT TYPE: ", UI.EventTypes[event.type][2], "CODE:",event.code, "VALUE: ", string.format("0x%x",event.value)); 59 | end 60 | end 61 | 62 | function OnMouse(loop, w, revents) 63 | --print("OnMouse: ", w, revents); 64 | local event = input_event(); 65 | local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 66 | 67 | print("MOUSE: ", event.type, event.code, event.value); 68 | end 69 | 70 | local Observers = {} 71 | 72 | AddKeyboardObserver = function(emitter, onactivity, devicename) 73 | devicename = devicename or "/dev/input/event0" 74 | local fd, err = S.open(devicename, S.c.O.RDONLY); 75 | if not fd then 76 | return false, err 77 | end 78 | 79 | print("DEVICE: ", devicename); 80 | print("FD: ", fd:getfd()); 81 | 82 | local observer = { 83 | Descriptor = fd, 84 | actions = S.c.POLL.RDNORM, 85 | Callback = onactivity}; 86 | 87 | Observers[fd:getfd()] = observer; 88 | 89 | emitter:AddObserver(observer) 90 | 91 | return observer; 92 | end 93 | 94 | --[[ 95 | Create Observers 96 | --]] 97 | 98 | local emitter = IOAlertEmitter.new(); 99 | 100 | assert(emitter, "Did not create alert emitter"); 101 | 102 | local keyObserver = AddKeyboardObserver(emitter, OnKey); 103 | 104 | --[[ 105 | -- Timer Observer 106 | --AddTimerObserver(emitter, OnTimer, 1, 3); 107 | 108 | -- Mouse Tracking 109 | AddMouseObserver(emitter, OnMouse); 110 | --]] 111 | 112 | 113 | -- Run a loop 114 | local timeout = 500 115 | while true do 116 | local ret, err = emitter:Wait(timeout); 117 | 118 | --print(ret, type(ret), err); 119 | if ret then 120 | for i=1,#ret do 121 | print("Event: ", ret[i].fd, ret[i].events); 122 | -- get the appropriate observer 123 | local observer = Observers[ret[i].fd]; 124 | if observer and observer.Callback then 125 | observer.Callback(emitter, observer) 126 | end 127 | end 128 | end 129 | --OnIdle(); 130 | end 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /tests/test_event_loop.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | local bit = require "bit" 5 | local band = bit.band 6 | local lshift = bit.lshift 7 | 8 | local Keyboard = require "Keyboard" 9 | local EventLoop = require "EventLoop" 10 | 11 | test_bit = function(yalv, abs_b) 12 | return (band(ffi.cast("const uint8_t *",abs_b)[yalv/8], lshift(1, yalv%8)) > 0) 13 | end 14 | 15 | --[[ 16 | React to Keyboard activity 17 | --]] 18 | OnKeyDown = function(kbd, keycode) 19 | keys,err = kbd:GetKeys(); 20 | if not keys then 21 | print("GetKeys Error: ", err); 22 | end 23 | 24 | if kbd:IsKeyPressed(KEY_LEFTSHIFT) then 25 | print("LSHIFT"); 26 | elseif kbd:IsKeyPressed(KEY_RIGHTSHIFT) then 27 | print("RSHIFT"); 28 | else 29 | print("KEYDOWN: ", keycode); 30 | end 31 | end 32 | 33 | OnKeyUp = function(kbd, keycode) 34 | keys,err = kbd:GetKeys(); 35 | if not keys then 36 | print("GetKeys Error: ", err); 37 | end 38 | 39 | if kbd:IsKeyPressed(KEY_LEFTSHIFT) then 40 | print("LSHIFT"); 41 | end 42 | 43 | if kbd:IsKeyPressed(KEY_RIGHTSHIFT) then 44 | print("RSHIFT"); 45 | end 46 | 47 | print("KEYUP: ", keycode); 48 | 49 | 50 | -- Halt the loop if they press the "Esc" key 51 | if keycode == KEY_ESC then 52 | loop:Halt(); 53 | end 54 | end 55 | 56 | OnKeyRepeat = function(kbd, keycode, count) 57 | print("KEYREP: ", keycode, count); 58 | end 59 | 60 | 61 | -- Setup an event loop and keyboard 62 | loop = EventLoop.new(); 63 | local kbd = Keyboard.new(); 64 | 65 | -- Setup some keyboard with event handlers 66 | kbd.OnKeyDown = OnKeyDown; 67 | kbd.OnKeyUp = OnKeyUp; 68 | kbd.OnKeyRepeat = OnKeyRepeat; 69 | 70 | loop:AddObservable(kbd); 71 | 72 | loop:Run(15); 73 | 74 | --[[ 75 | print("Type of _IOC: ", type(_IOC)); 76 | print("Type of EVIOCGKEY: ", type(EVIOCGKEY)); 77 | local key_b = ffi.new("unsigned char [?]",KEY_MAX/8 + 1); 78 | print("Size of key_b: ", ffi.sizeof(key_b)); 79 | print("VALUE of EVIOCGKEY(): ", string.format("0x%x",EVIOCGKEY(ffi.sizeof(key_b)))); 80 | --]] 81 | -------------------------------------------------------------------------------- /tests/test_followmouse.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | -- Bring in the necessary UI stuff 4 | local OpenVGApp = require "OpenVGApp" 5 | 6 | local viewWidth = 32; 7 | local viewHeight = 32; 8 | 9 | 10 | local app = OpenVGApp.init(viewWidth, viewHeight, 10, 10); 11 | local screenWidth, screenHeight = OpenVGApp.Display:GetSize(); 12 | 13 | local midScreenX = screenWidth/2; 14 | local midScreenY = screenHeight/2; 15 | 16 | -- Place the window in the center of the screen 17 | local startx = midScreenX - viewWidth; 18 | local starty = midScreenY - viewHeight; 19 | 20 | local mouseX = midScreenX; 21 | local mouseY = midScreenY; 22 | 23 | app.Window:MoveTo(startx, starty); 24 | 25 | 26 | app.OnMouseMove = function(mouse, axis, value) 27 | -- print("Move: ", axis, value); 28 | 29 | if axis == REL_X then 30 | mouseX = mouseX + value; 31 | if mouseX < 0 then mouseX = 0; end 32 | if mouseX >= screenWidth-viewWidth then mouseX = screenWidth-1-viewWidth; end 33 | elseif axis == REL_Y then 34 | mouseY = mouseY + value; 35 | if mouseY < 0 then mouseY = 0; end 36 | if mouseY >= screenHeight-viewHeight then mouseY = screenHeight-1-viewHeight; end 37 | end 38 | 39 | -- Move the window 40 | app.Window:MoveTo(mouseX, mouseY); 41 | end 42 | 43 | app:Run(); 44 | 45 | 46 | -------------------------------------------------------------------------------- /tests/test_keyboard.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | local bit = require "bit" 5 | local band = bit.band 6 | local lshift = bit.lshift 7 | 8 | local Keyboard = require "Keyboard" 9 | local EventLoop = require "EventLoop" 10 | 11 | test_bit = function(yalv, abs_b) 12 | return (band(ffi.cast("const uint8_t *",abs_b)[yalv/8], lshift(1, yalv%8)) > 0) 13 | end 14 | 15 | --[[ 16 | React to Keyboard activity 17 | --]] 18 | OnKeyDown = function(kbd, keycode) 19 | keys,err = kbd:GetKeys(); 20 | if not keys then 21 | print("GetKeys Error: ", err); 22 | end 23 | 24 | if kbd:IsKeyPressed(KEY_LEFTSHIFT) then 25 | print("LSHIFT"); 26 | elseif kbd:IsKeyPressed(KEY_RIGHTSHIFT) then 27 | print("RSHIFT"); 28 | else 29 | print("KEYDOWN: ", keycode); 30 | end 31 | end 32 | 33 | local scrolllock = false; 34 | local capslock = false; 35 | local numlock = false; 36 | 37 | local function setLEDs(kbd) 38 | kbd:SetScrollLock(scrolllock); 39 | kbd:SetCapsLock(capslock); 40 | kbd:SetNumLock(numlock); 41 | end 42 | 43 | OnKeyUp = function(kbd, keycode) 44 | keys,err = kbd:GetKeys(); 45 | if not keys then 46 | print("GetKeys Error: ", err); 47 | end 48 | 49 | 50 | -- Halt the loop if they press the "Esc" key 51 | if keycode == KEY_ESC then 52 | return loop:Halt(); 53 | end 54 | 55 | 56 | -- Check the state of a couple of keys 57 | if kbd:IsKeyPressed(KEY_LEFTSHIFT) then 58 | print("LSHIFT"); 59 | end 60 | 61 | if kbd:IsKeyPressed(KEY_RIGHTSHIFT) then 62 | print("RSHIFT"); 63 | end 64 | 65 | -- Toggle LEDs 66 | if keycode == KEY_S then 67 | scrolllock = not scrolllock 68 | end 69 | if keycode == KEY_C then 70 | capslock = not capslock 71 | end 72 | if keycode == KEY_N then 73 | numlock = not numlock 74 | end 75 | 76 | 77 | setLEDs(kbd); 78 | 79 | print("KEYUP: ", keycode); 80 | end 81 | 82 | OnKeyRepeat = function(kbd, keycode, count) 83 | print("KEYREP: ", keycode, count); 84 | end 85 | 86 | 87 | -- Setup an event loop and keyboard 88 | loop = EventLoop.new(); 89 | 90 | -- Setup some keyboard with event handlers 91 | local handlers = { 92 | OnKeyDown = OnKeyDown; 93 | OnKeyUp = OnKeyUp; 94 | OnKeyRepeat = OnKeyRepeat; 95 | } 96 | local kbd = Keyboard.new(handlers); 97 | 98 | setLEDs(kbd); 99 | 100 | loop:AddObservable(kbd); 101 | 102 | loop:Run(15); 103 | 104 | 105 | -------------------------------------------------------------------------------- /tests/test_keyboard_emitter.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | 5 | local S = require "syscall" 6 | local UI = require "input" 7 | local Keyboard = require "Keyboard" 8 | 9 | 10 | 11 | 12 | --[[ 13 | Callback functions 14 | --]] 15 | 16 | 17 | 18 | 19 | --[[ 20 | Event type: 21 | EV_KEY 22 | EV_MSC 23 | 24 | value: 25 | 0 == keyup 26 | 1 == keydown 27 | --]] 28 | 29 | function OnKey(loop, observer) 30 | local event = input_event(); 31 | --local bytesread = S.read(w.fd, event, ffi.sizeof(event)); 32 | local bytesread = observer.Descriptor:read(event, ffi.sizeof(event)); 33 | 34 | if event.type == EV_MSC then 35 | if event.code == MSC_SCAN then 36 | --print("MSC_SCAN: ", string.format("0x%x",event.value)); 37 | else 38 | --print("MSC: ", event.code, event.value); 39 | end 40 | elseif event.type == EV_KEY then 41 | if event.value == 1 then 42 | print("KEYDOWN: ", event.code); 43 | elseif event.value == 0 then 44 | print("KEYUP: ", event.code); 45 | 46 | if event.code == KEY_ESC then 47 | loop:halt(); 48 | return false; 49 | end 50 | 51 | elseif event.value == 2 then 52 | print("KEYREP: ", event.code); 53 | end 54 | else 55 | --print("EVENT TYPE: ", UI.EventTypes[event.type][2], "CODE:",event.code, "VALUE: ", string.format("0x%x",event.value)); 56 | end 57 | end 58 | 59 | 60 | 61 | --[[ 62 | Create Keyboard Device 63 | --]] 64 | local kbd = Keyboard.new(); 65 | 66 | 67 | -- Run a loop 68 | local timeout = 500 69 | while true do 70 | local ret, err = kbd:Step(); 71 | end 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /tests/test_mouse.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | local bit = require "bit" 5 | local band = bit.band 6 | local lshift = bit.lshift 7 | 8 | local Mouse = require "Mouse" 9 | local EventLoop = require "EventLoop" 10 | local loop = EventLoop.new(); 11 | 12 | test_bit = function(yalv, abs_b) 13 | return (band(ffi.cast("const uint8_t *",abs_b)[yalv/8], lshift(1, yalv%8)) > 0) 14 | end 15 | 16 | 17 | local ButtonNames = { 18 | [BTN_LEFT] = "LEFT"; 19 | [BTN_MIDDLE] = "MIDDLE"; 20 | [BTN_RIGHT] = "RIGHT"; 21 | } 22 | 23 | local GetButtonName = function(id) 24 | return ButtonNames[id] or tostring(id); 25 | end 26 | 27 | function OnButtonPressed(mouse, button) 28 | print("PRESSED: ", GetButtonName(button)); 29 | end 30 | 31 | function OnButtonReleased(mouse, button) 32 | print("RELEASED: ", GetButtonName(button)); 33 | 34 | if button == 289 then 35 | loop:Halt(); 36 | end 37 | end 38 | 39 | function OnMouseWheel(mouse, value) 40 | print("WHEEL: ", value); 41 | end 42 | 43 | function OnMouseMove(mouse, axis, value) 44 | print("AXIS: ", axis, "Amount: ", value); 45 | end 46 | 47 | 48 | -- Setup some keyboard with event handlers 49 | local handlers = { 50 | OnButtonPressed = OnButtonPressed; 51 | OnButtonReleased = OnButtonReleased; 52 | OnMouseWheel = OnMouseWheel; 53 | OnMouseMove = OnMouseMove; 54 | } 55 | local mouse = Mouse.new(handlers); 56 | 57 | print("Mouse: ", mouse); 58 | 59 | loop:AddObservable(mouse, mouse); 60 | 61 | loop:Run(15); 62 | 63 | 64 | -------------------------------------------------------------------------------- /tests/test_moveview.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | local DMX = require "DisplayManX" 5 | 6 | local Display = DMX.DMXDisplay(); 7 | 8 | local screenWidth, screenHeight = Display:GetSize(); 9 | local ratio = screenWidth / screenHeight; 10 | local displayHeight = 320; 11 | local displayWidth = 640; 12 | 13 | 14 | -- Create resource used for capturing screen 15 | local resource = DMXResource(displayWidth, displayHeight); 16 | 17 | -- Do the snapshot 18 | Display:Snapshot(resource); 19 | 20 | -- Get the pixel data so it can be copied 21 | -- to multiple views 22 | local pixeldata, err = resource:ReadPixelData(); 23 | 24 | 25 | local viewCount = 20 26 | local views = {} 27 | 28 | for i=1,viewCount do 29 | local x = math.random(0,screenWidth -1); 30 | local y = math.random(0,screenHeight - 1); 31 | 32 | --print(string.format("[%d, %d]", x, y)); 33 | 34 | x = x - displayWidth/2 35 | if x < 0 then 36 | x = 0 37 | elseif x > screenWidth-1 - (displayWidth/2)+1 then 38 | x = screenWidth-1-displayWidth 39 | end 40 | 41 | y = y - displayHeight/2 42 | if y < 0 then 43 | y = 0 44 | elseif y > screenHeight-1 - (displayHeight/2)+1 then 45 | y = screenHeight-1-displayHeight 46 | end 47 | 48 | print(string.format("[%d, %d]", x, y)); 49 | 50 | local view = Display:CreateView(displayWidth, displayHeight, x, y) 51 | view:CopyPixelBuffer(pixeldata); 52 | table.insert(views, view); 53 | 54 | -- Wait a bit 55 | ffi.C.sleep(1); 56 | end 57 | 58 | ffi.C.sleep(3); 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /tests/test_picast.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | local DMX = require "DisplayManX" 5 | 6 | local Display = DMXDisplay(); 7 | local screenWidth, screenHeight = Display:GetSize(); 8 | local ratio = screenWidth / screenHeight; 9 | local displayHeight = 320; 10 | local displayWidth = 640; 11 | --local displayHeight = 70; 12 | --local displayWidth = displayHeight * ratio; 13 | 14 | 15 | 16 | 17 | 18 | 19 | local function WritePPM(filename, pixbuff) 20 | local r, c, val; 21 | 22 | local fp = io.open(filename, "wb") 23 | if not fp then 24 | return false 25 | end 26 | 27 | local header = string.format("P6\n%d %d\n255\n", pixbuff.Width, pixbuff.Height) 28 | fp:write(header); 29 | 30 | for row=0,pixbuff.Height-1 do 31 | local dataPtr = ffi.cast("char *",pixbuff.Data) + pixbuff.Pitch*row 32 | local data = ffi.string(dataPtr, pixbuff.Width*3); 33 | fp:write(data); 34 | end 35 | 36 | fp:close(); 37 | end 38 | 39 | 40 | 41 | -- Create the resource that will be used 42 | -- to copy the screen into. Do this so that 43 | -- we can reuse the same chunk of memory 44 | local resource = DMXResource(displayWidth, displayHeight, ffi.C.VC_IMAGE_RGB888); 45 | 46 | local p_rect = VC_RECT_T(0,0,displayWidth, displayHeight); 47 | local pixdata = resource:CreateCompatiblePixmap(displayWidth, displayHeight); 48 | 49 | local framecount = 120 50 | 51 | 52 | for i=1,framecount do 53 | -- Do the snapshot 54 | Display:Snapshot(resource); 55 | 56 | 57 | local pixeldata, err = resource:ReadPixelData(pixdata, p_rect); 58 | if pixeldata then 59 | -- Write the data out 60 | local filename = string.format("screencast/desktop_%06d.ppm", i); 61 | print("Writing: ", filename); 62 | 63 | WritePPM(filename, pixeldata); 64 | end 65 | 66 | --ffi.C.sleep(1); 67 | end 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /tests/test_snapshot.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | local DMX = require "DisplayManX" 5 | 6 | local Display = DMXDisplay(); 7 | Display:SetBackground(0,0,0); 8 | 9 | local screenWidth, screenHeight = Display:GetSize(); 10 | local ratio = screenWidth / screenHeight; 11 | local displayHeight = 320; 12 | local displayWidth = 640; 13 | --local displayHeight = 70; 14 | --local displayWidth = displayHeight * ratio; 15 | 16 | 17 | -- Create the view that will display the snapshot 18 | local displayView = Display:CreateView( 19 | displayWidth, displayHeight, 20 | 0, screenHeight-displayHeight-1, 21 | 0, ffi.C.VC_IMAGE_RGB888) 22 | 23 | 24 | 25 | 26 | local function WritePPM(filename, pixbuff) 27 | local r, c, val; 28 | 29 | local fp = io.open(filename, "wb") 30 | if not fp then 31 | return false 32 | end 33 | 34 | local header = string.format("P6\n%d %d\n255\n", pixbuff.Width, pixbuff.Height) 35 | fp:write(header); 36 | 37 | for row=0,pixbuff.Height-1 do 38 | local dataPtr = ffi.cast("char *",pixbuff.Data) + pixbuff.Pitch*row 39 | local data = ffi.string(dataPtr, pixbuff.Width*3); 40 | fp:write(data); 41 | end 42 | 43 | fp:close(); 44 | end 45 | 46 | 47 | -- Do the snapshot 48 | displayView:Hide(); 49 | Display:Snapshot(displayView.Resource); 50 | displayView:Show(); 51 | 52 | 53 | local pixeldata, err = displayView.Resource:ReadPixelData(); 54 | if pixeldata then 55 | -- Write the data out 56 | local filename = "desktop.ppm" 57 | print("Writing: ", filename); 58 | 59 | WritePPM(filename, pixeldata); 60 | end 61 | 62 | ffi.C.sleep(5); 63 | 64 | 65 | -------------------------------------------------------------------------------- /tests/test_tiger.lua: -------------------------------------------------------------------------------- 1 | -- #!/usr/local/bin/luajit 2 | 3 | package.path = package.path..";../?.lua" 4 | 5 | local ffi = require "ffi" 6 | local C = ffi.C; 7 | local bit = require "bit" 8 | local bor = bit.bor 9 | local band = bit.band 10 | 11 | 12 | -- Bring in the necessary UI stuff 13 | 14 | local OpenVGApp = require "OpenVGApp" 15 | 16 | 17 | local rpiui = require "rpiui" 18 | local EGL = rpiui.EGL; 19 | local OpenVG = rpiui.OpenVG; 20 | local VG = EGL.Lib; 21 | local PS = require "PSLoader"; 22 | 23 | 24 | local viewWidth = 640; 25 | local viewHeight = 480; 26 | 27 | 28 | 29 | local app = OpenVGApp.init(viewWidth, viewHeight, 10, 10); 30 | 31 | local screenWidth, screenHeight = app.Display:GetSize(); 32 | 33 | local tigerModel = require "tiger"; 34 | local tigerscene = { 35 | Width = viewWidth; 36 | Height = viewHeight; 37 | rotateN = 0.0; 38 | rotateFactor = 3; 39 | ClearColor = ffi.new("VGfloat[4]", 1,1,1,1); 40 | 41 | Elements = { 42 | PS.construct(tigerModel.Commands, tigerModel.CommandCount, tigerModel.Points, tigerModel.PointCount); 43 | } 44 | } 45 | 46 | 47 | 48 | --[[ 49 | Render 50 | --]] 51 | local function renderbegin(vgapp, scene) 52 | VG.vgSetfv(ffi.C.VG_CLEAR_COLOR, 4, scene.ClearColor); 53 | VG.vgClear(0, 0, scene.Width, scene.Height); 54 | 55 | VG.vgLoadIdentity(); 56 | end 57 | 58 | local function renderend(vgapp, scene) 59 | vgapp.Window:SwapBuffers(); -- force EGL to recognize resize 60 | end 61 | 62 | local function render(vgapp, scene) 63 | renderbegin(vgapp, scene); 64 | 65 | VG.vgTranslate(scene.Width * 0.5, scene.Height * 0.5); 66 | VG.vgRotate(scene.rotateN); 67 | VG.vgTranslate(-scene.Width * 0.5, -scene.Height * 0.5); 68 | 69 | for _, element in ipairs(scene.Elements) do 70 | local scale = scene.Width / (tigerModel.MaxX - tigerModel.MinX); 71 | VG.vgScale(scale, scale); 72 | VG.vgTranslate(-tigerModel.MinX, -tigerModel.MinY + 0.5 * (scene.Height / scale - (tigerModel.MaxY - tigerModel.MinY))); 73 | element:render(); 74 | --assert(tonumber(VG.vgGetError()) == tonumber(ffi.C.VG_NO_ERROR)); 75 | end 76 | 77 | renderend(vgapp, scene); 78 | end 79 | 80 | 81 | 82 | app.OnIdle = function(vgapp) 83 | --print("DoIdle"); 84 | render(vgapp, tigerscene); 85 | tigerscene.rotateN = tigerscene.rotateN + (1.0 * tigerscene.rotateFactor); 86 | end 87 | 88 | local XIncrement = 5; 89 | local YIncrement = 5; 90 | 91 | app.OnKeyUp = function(kbd, keycode) 92 | --print("KEY: ", keycode); 93 | 94 | -- Halt the loop if they press the "Esc" key 95 | if keycode == KEY_ESC then 96 | return app:Stop(); 97 | end 98 | 99 | local x = app.Window.X 100 | local y = app.Window.Y; 101 | 102 | -- Move the window around the screen 103 | -- using the keyboard arrow keys 104 | if keycode == KEY_RIGHT then 105 | x = app.Window.X + XIncrement; 106 | end 107 | 108 | if keycode == KEY_LEFT then 109 | x = app.Window.X - XIncrement; 110 | end 111 | 112 | if keycode == KEY_HOME then 113 | x = 0 114 | end 115 | 116 | if keycode == KEY_END then 117 | x = screenWidth - app.Window.Width; 118 | end 119 | 120 | if keycode == KEY_UP then 121 | y = y - YIncrement; 122 | end 123 | 124 | if keycode == KEY_DOWN then 125 | y = y + YIncrement 126 | end 127 | 128 | if keycode == KEY_PAGEUP then 129 | y = 0; 130 | end 131 | 132 | if keycode == KEY_PAGEDOWN then 133 | y = screenHeight - app.Window.Height 134 | end 135 | 136 | -- Move the window 137 | app.Window:MoveTo(x,y); 138 | 139 | -- Change direction of rotation when space 140 | -- bar is pressed 141 | if keycode == KEY_SPACE then 142 | tigerscene.rotateFactor = -1 * tigerscene.rotateFactor; 143 | end 144 | end 145 | 146 | 147 | app:Run(); 148 | -------------------------------------------------------------------------------- /tests/test_window_basic.lua: -------------------------------------------------------------------------------- 1 | package.path = package.path..";../?.lua" 2 | 3 | local ffi = require "ffi" 4 | 5 | local rpiui = require "rpiui" 6 | 7 | local EGL = rpiui.EGL 8 | 9 | 10 | -- Setup window 11 | local mainWindow = EGL.Window.new(640, 480, {background = {153, 153, 153}}); 12 | 13 | 14 | -- Sleep for a second so we can see the results 15 | local seconds = 5 16 | print( string.format("Sleeping for %d seconds...", seconds )); 17 | ffi.C.sleep( seconds ) 18 | 19 | -------------------------------------------------------------------------------- /vc_display_types.lua: -------------------------------------------------------------------------------- 1 | 2 | -- Common image types used by the vc_image library. 3 | local ffi = require "ffi" 4 | 5 | ffi.cdef[[ 6 | //enums of display input format 7 | typedef enum 8 | { 9 | VCOS_DISPLAY_INPUT_FORMAT_INVALID = 0, 10 | VCOS_DISPLAY_INPUT_FORMAT_RGB888, 11 | VCOS_DISPLAY_INPUT_FORMAT_RGB565 12 | } VCOS_DISPLAY_INPUT_FORMAT_T; 13 | 14 | 15 | typedef VCOS_DISPLAY_INPUT_FORMAT_T DISPLAY_INPUT_FORMAT_T; 16 | 17 | // Enum determining how image data for 3D displays has to be supplied 18 | typedef enum 19 | { 20 | DISPLAY_3D_UNSUPPORTED = 0, // default 21 | DISPLAY_3D_INTERLEAVED, // For autosteroscopic displays 22 | DISPLAY_3D_SBS_FULL_AUTO, // Side-By-Side, Full Width (also used by some autostereoscopic displays) 23 | DISPLAY_3D_SBS_HALF_HORIZ, // Side-By-Side, Half Width, Horizontal Subsampling (see HDMI spec) 24 | DISPLAY_3D_FORMAT_MAX 25 | } DISPLAY_3D_FORMAT_T; 26 | 27 | //enums of display types 28 | typedef enum 29 | { 30 | DISPLAY_INTERFACE_MIN, 31 | DISPLAY_INTERFACE_SMI, 32 | DISPLAY_INTERFACE_DPI, 33 | DISPLAY_INTERFACE_DSI, 34 | DISPLAY_INTERFACE_LVDS, 35 | DISPLAY_INTERFACE_MAX 36 | 37 | } DISPLAY_INTERFACE_T; 38 | 39 | /* display dither setting, used on B0 */ 40 | typedef enum { 41 | DISPLAY_DITHER_NONE = 0, /* default if not set */ 42 | DISPLAY_DITHER_RGB666 = 1, 43 | DISPLAY_DITHER_RGB565 = 2, 44 | DISPLAY_DITHER_RGB555 = 3, 45 | DISPLAY_DITHER_MAX 46 | } DISPLAY_DITHER_T; 47 | 48 | //info struct 49 | typedef struct 50 | { 51 | //type 52 | DISPLAY_INTERFACE_T type; 53 | //width / height 54 | uint32_t width; 55 | uint32_t height; 56 | //output format 57 | DISPLAY_INPUT_FORMAT_T input_format; 58 | //interlaced? 59 | uint32_t interlaced; 60 | /* output dither setting (if required) */ 61 | DISPLAY_DITHER_T output_dither; 62 | /* Pixel frequency */ 63 | uint32_t pixel_freq; 64 | /* Line rate in lines per second */ 65 | uint32_t line_rate; 66 | // Format required for image data for 3D displays 67 | DISPLAY_3D_FORMAT_T format_3d; 68 | } DISPLAY_INFO_T; 69 | 70 | ]] 71 | -------------------------------------------------------------------------------- /vc_dispmanx.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | -- Display manager service API 5 | 6 | require "vcos" 7 | require "vc_image_types" 8 | require "vc_dispservice_x_defs" 9 | require "vc_dispmanx_types" 10 | require "vchi" 11 | 12 | ffi.cdef[[ 13 | // Same function as above, to aid migration of code. 14 | int vc_dispman_init( void ); 15 | 16 | // Stop the service from being used 17 | void vc_dispmanx_stop( void ); 18 | 19 | // Set the entries in the rect structure 20 | int vc_dispmanx_rect_set( VC_RECT_T *rect, uint32_t x_offset, uint32_t y_offset, uint32_t width, uint32_t height ); 21 | 22 | // Resources 23 | // Create a new resource 24 | DISPMANX_RESOURCE_HANDLE_T vc_dispmanx_resource_create( VC_IMAGE_TYPE_T type, uint32_t width, uint32_t height, uint32_t *native_image_handle ); 25 | 26 | // Write the bitmap data to VideoCore memory 27 | int vc_dispmanx_resource_write_data( DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type, int src_pitch, void * src_address, const VC_RECT_T * rect ); 28 | int vc_dispmanx_resource_write_data_handle( DISPMANX_RESOURCE_HANDLE_T res, VC_IMAGE_TYPE_T src_type, int src_pitch, VCHI_MEM_HANDLE_T handle, uint32_t offset, const VC_RECT_T * rect ); 29 | int vc_dispmanx_resource_read_data(DISPMANX_RESOURCE_HANDLE_T handle, 30 | const VC_RECT_T* p_rect, 31 | void * dst_address, 32 | uint32_t dst_pitch ); 33 | // Delete a resource 34 | int vc_dispmanx_resource_delete( DISPMANX_RESOURCE_HANDLE_T res ); 35 | 36 | // Displays 37 | // Opens a display on the given device 38 | DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open( uint32_t device ); 39 | 40 | // Opens a display on the given device in the request mode 41 | DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open_mode( uint32_t device, uint32_t mode ); 42 | 43 | // Open an offscreen display 44 | DISPMANX_DISPLAY_HANDLE_T vc_dispmanx_display_open_offscreen( DISPMANX_RESOURCE_HANDLE_T dest, VC_IMAGE_TRANSFORM_T orientation ); 45 | 46 | // Change the mode of a display 47 | int vc_dispmanx_display_reconfigure( DISPMANX_DISPLAY_HANDLE_T display, uint32_t mode ); 48 | 49 | // Sets the desstination of the display to be the given resource 50 | int vc_dispmanx_display_set_destination( DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_RESOURCE_HANDLE_T dest ); 51 | 52 | // Set the background colour of the display 53 | int vc_dispmanx_display_set_background( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_DISPLAY_HANDLE_T display, 54 | uint8_t red, uint8_t green, uint8_t blue ); 55 | // get the width, height, frame rate and aspect ratio of the display 56 | int vc_dispmanx_display_get_info( DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_MODEINFO_T * pinfo ); 57 | 58 | // Closes a display 59 | int vc_dispmanx_display_close( DISPMANX_DISPLAY_HANDLE_T display ); 60 | 61 | // Updates 62 | // Start a new update, DISPMANX_NO_HANDLE on error 63 | DISPMANX_UPDATE_HANDLE_T vc_dispmanx_update_start( int32_t priority ); 64 | 65 | // Add an elment to a display as part of an update 66 | DISPMANX_ELEMENT_HANDLE_T vc_dispmanx_element_add ( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_DISPLAY_HANDLE_T display, 67 | int32_t layer, const VC_RECT_T *dest_rect, DISPMANX_RESOURCE_HANDLE_T src, 68 | const VC_RECT_T *src_rect, DISPMANX_PROTECTION_T protection, 69 | VC_DISPMANX_ALPHA_T *alpha, 70 | DISPMANX_CLAMP_T *clamp, DISPMANX_TRANSFORM_T transform ); 71 | // Change the source image of a display element 72 | int vc_dispmanx_element_change_source( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element, 73 | DISPMANX_RESOURCE_HANDLE_T src ); 74 | // Change the layer number of a display element 75 | int vc_dispmanx_element_change_layer ( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element, 76 | int32_t layer ); 77 | // Signal that a region of the bitmap has been modified 78 | int vc_dispmanx_element_modified( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element, const VC_RECT_T * rect ); 79 | 80 | // Remove a display element from its display 81 | int vc_dispmanx_element_remove( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_ELEMENT_HANDLE_T element ); 82 | 83 | // Ends an update 84 | int vc_dispmanx_update_submit( DISPMANX_UPDATE_HANDLE_T update, DISPMANX_CALLBACK_FUNC_T cb_func, void *cb_arg ); 85 | 86 | // End an update and wait for it to complete 87 | int vc_dispmanx_update_submit_sync( DISPMANX_UPDATE_HANDLE_T update ); 88 | 89 | // Query the image formats supported in the VMCS build 90 | int vc_dispmanx_query_image_formats( uint32_t *supported_formats ); 91 | 92 | //New function added to VCHI to change attributes, set_opacity does not work there. 93 | int vc_dispmanx_element_change_attributes( DISPMANX_UPDATE_HANDLE_T update, 94 | DISPMANX_ELEMENT_HANDLE_T element, 95 | uint32_t change_flags, 96 | int32_t layer, 97 | uint8_t opacity, 98 | const VC_RECT_T *dest_rect, 99 | const VC_RECT_T *src_rect, 100 | DISPMANX_RESOURCE_HANDLE_T mask, 101 | VC_IMAGE_TRANSFORM_T transform ); 102 | 103 | //xxx hack to get the image pointer from a resource handle, will be obsolete real soon 104 | uint32_t vc_dispmanx_resource_get_image_handle( DISPMANX_RESOURCE_HANDLE_T res); 105 | 106 | //Call this instead of vc_dispman_init 107 | void vc_vchi_dispmanx_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ); 108 | 109 | // Take a snapshot of a display in its current state. 110 | // This call may block for a time; when it completes, the snapshot is ready. 111 | int vc_dispmanx_snapshot( DISPMANX_DISPLAY_HANDLE_T display, 112 | DISPMANX_RESOURCE_HANDLE_T snapshot_resource, 113 | VC_IMAGE_TRANSFORM_T transform ); 114 | ]] 115 | 116 | -------------------------------------------------------------------------------- /vc_dispmanx_types.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | -- Typedefs and enums for the VideoCore III Display Manager 5 | 6 | 7 | 8 | require "vc_image_types" 9 | require "vc_display_types" 10 | 11 | ffi.cdef[[ 12 | /* Opaque handles */ 13 | typedef uint32_t DISPMANX_DISPLAY_HANDLE_T; 14 | typedef uint32_t DISPMANX_UPDATE_HANDLE_T; 15 | typedef uint32_t DISPMANX_ELEMENT_HANDLE_T; 16 | typedef uint32_t DISPMANX_RESOURCE_HANDLE_T; 17 | 18 | typedef uint32_t DISPMANX_PROTECTION_T; 19 | ]] 20 | 21 | DISPMANX_DISPLAY_HANDLE_T = ffi.typeof("DISPMANX_DISPLAY_HANDLE_T"); 22 | DISPMANX_UPDATE_HANDLE_T = ffi.typeof("DISPMANX_UPDATE_HANDLE_T"); 23 | DISPMANX_ELEMENT_HANDLE_T = ffi.typeof("DISPMANX_ELEMENT_HANDLE_T"); 24 | DISPMANX_RESOURCE_HANDLE_T = ffi.typeof("DISPMANX_RESOURCE_HANDLE_T"); 25 | 26 | DISPMANX_NO_HANDLE =0 27 | 28 | DISPMANX_PROTECTION_MAX =0x0f 29 | DISPMANX_PROTECTION_NONE =0 30 | DISPMANX_PROTECTION_HDCP =11 -- Derived from the WM DRM levels, 101-300 31 | 32 | 33 | 34 | --[[ 35 | Default display IDs. 36 | Note: if you overwrite with your own dispmanx_platfrom_init function, you 37 | should use IDs you provided during dispmanx_display_attach. 38 | --]] 39 | 40 | DISPMANX_ID_MAIN_LCD =0; 41 | DISPMANX_ID_AUX_LCD =1; 42 | DISPMANX_ID_HDMI =2; 43 | DISPMANX_ID_SDTV =3; 44 | 45 | ffi.cdef[[ 46 | /* Return codes. Nonzero ones indicate failure. */ 47 | typedef enum { 48 | DISPMANX_SUCCESS = 0, 49 | DISPMANX_INVALID = -1 50 | /* XXX others TBA */ 51 | } DISPMANX_STATUS_T; 52 | 53 | typedef enum { 54 | /* Bottom 2 bits sets the orientation */ 55 | DISPMANX_NO_ROTATE = 0, 56 | DISPMANX_ROTATE_90 = 1, 57 | DISPMANX_ROTATE_180 = 2, 58 | DISPMANX_ROTATE_270 = 3, 59 | 60 | DISPMANX_FLIP_HRIZ = 1 << 16, 61 | DISPMANX_FLIP_VERT = 1 << 17 62 | } DISPMANX_TRANSFORM_T; 63 | 64 | typedef enum { 65 | /* Bottom 2 bits sets the alpha mode */ 66 | DISPMANX_FLAGS_ALPHA_FROM_SOURCE = 0, 67 | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS = 1, 68 | DISPMANX_FLAGS_ALPHA_FIXED_NON_ZERO = 2, 69 | DISPMANX_FLAGS_ALPHA_FIXED_EXCEED_0X07 = 3, 70 | 71 | DISPMANX_FLAGS_ALPHA_PREMULT = 1 << 16, 72 | DISPMANX_FLAGS_ALPHA_MIX = 1 << 17 73 | } DISPMANX_FLAGS_ALPHA_T; 74 | 75 | typedef struct { 76 | DISPMANX_FLAGS_ALPHA_T flags; 77 | uint32_t opacity; 78 | VC_IMAGE_T *mask; 79 | } DISPMANX_ALPHA_T; 80 | 81 | typedef struct { 82 | DISPMANX_FLAGS_ALPHA_T flags; 83 | uint32_t opacity; 84 | DISPMANX_RESOURCE_HANDLE_T mask; 85 | } VC_DISPMANX_ALPHA_T; /* for use with vmcs_host */ 86 | ]] 87 | 88 | DISPMANX_ALPHA_T = ffi.typeof("DISPMANX_ALPHA_T"); 89 | VC_DISPMANX_ALPHA_T = ffi.typeof("VC_DISPMANX_ALPHA_T"); 90 | 91 | 92 | ffi.cdef[[ 93 | typedef enum { 94 | DISPMANX_FLAGS_CLAMP_NONE = 0, 95 | DISPMANX_FLAGS_CLAMP_LUMA_TRANSPARENT = 1, 96 | //DISPMANX_FLAGS_CLAMP_TRANSPARENT = 2, 97 | DISPMANX_FLAGS_CLAMP_REPLACE = 3, 98 | DISPMANX_FLAGS_CLAMP_CHROMA_TRANSPARENT = 2, 99 | DISPMANX_FLAGS_CLAMP_TRANSPARENT = 3, 100 | } DISPMANX_FLAGS_CLAMP_T; 101 | 102 | typedef enum { 103 | DISPMANX_FLAGS_KEYMASK_OVERRIDE = 1, 104 | DISPMANX_FLAGS_KEYMASK_SMOOTH = 1 << 1, 105 | DISPMANX_FLAGS_KEYMASK_CR_INV = 1 << 2, 106 | DISPMANX_FLAGS_KEYMASK_CB_INV = 1 << 3, 107 | DISPMANX_FLAGS_KEYMASK_YY_INV = 1 << 4 108 | } DISPMANX_FLAGS_KEYMASK_T; 109 | 110 | typedef union { 111 | struct { 112 | uint8_t yy_upper; 113 | uint8_t yy_lower; 114 | uint8_t cr_upper; 115 | uint8_t cr_lower; 116 | uint8_t cb_upper; 117 | uint8_t cb_lower; 118 | } yuv; 119 | struct { 120 | uint8_t red_upper; 121 | uint8_t red_lower; 122 | uint8_t blue_upper; 123 | uint8_t blue_lower; 124 | uint8_t green_upper; 125 | uint8_t green_lower; 126 | } rgb; 127 | } DISPMANX_CLAMP_KEYS_T; 128 | 129 | typedef struct { 130 | DISPMANX_FLAGS_CLAMP_T mode; 131 | DISPMANX_FLAGS_KEYMASK_T key_mask; 132 | DISPMANX_CLAMP_KEYS_T key_value; 133 | uint32_t replace_value; 134 | } DISPMANX_CLAMP_T; 135 | 136 | typedef struct { 137 | int32_t width; 138 | int32_t height; 139 | VC_IMAGE_TRANSFORM_T transform; 140 | DISPLAY_INPUT_FORMAT_T input_format; 141 | } DISPMANX_MODEINFO_T; 142 | ]] 143 | 144 | ffi.cdef[[ 145 | /* Update callback. */ 146 | typedef void (*DISPMANX_CALLBACK_FUNC_T)(DISPMANX_UPDATE_HANDLE_T u, void * arg); 147 | 148 | /* Pluggable display interface */ 149 | 150 | typedef struct tag_DISPMANX_DISPLAY_FUNCS_T { 151 | // Get essential HVS configuration to be passed to the HVS driver. Options 152 | // is any combination of the following flags: HVS_ONESHOT, HVS_FIFOREG, 153 | // HVS_FIFO32, HVS_AUTOHSTART, HVS_INTLACE; and if HVS_FIFOREG, one of; 154 | // { HVS_FMT_RGB888, HVS_FMT_RGB565, HVS_FMT_RGB666, HVS_FMT_YUV }. 155 | int32_t (*get_hvs_config)(void *instance, uint32_t *pchan, 156 | uint32_t *poptions, DISPLAY_INFO_T *info, 157 | uint32_t *bg_colour, uint32_t *test_mode); 158 | 159 | // Get optional HVS configuration for gamma tables, OLED matrix and dither controls. 160 | // Set these function pointers to NULL if the relevant features are not required. 161 | int32_t (*get_gamma_params)(void * instance, 162 | int32_t gain[3], int32_t offset[3], int32_t gamma[3]); 163 | int32_t (*get_oled_params)(void * instance, uint32_t * poffsets, 164 | uint32_t coeffs[3]); 165 | int32_t (*get_dither)(void * instance, uint32_t * dither_depth, uint32_t * dither_type); 166 | 167 | // Get mode information, which may be returned to the applications as a courtesy. 168 | // Transform should be set to 0, and {width,height} should be final dimensions. 169 | int32_t (*get_info)(void * instance, DISPMANX_MODEINFO_T * info); 170 | 171 | // Inform driver that the application refcount has become nonzero / zero 172 | // These callbacks might perhaps be used for backlight and power management. 173 | int32_t (*open)(void * instance); 174 | int32_t (*close)(void * instance); 175 | 176 | // Display list updated callback. Primarily of use to a "one-shot" display. 177 | // For convenience of the driver, we pass the register address of the HVS FIFO. 178 | void (*dlist_updated)(void * instance, volatile uint32_t * fifo_reg); 179 | 180 | // End-of-field callback. This may occur in an interrupt context. 181 | void (*eof_callback)(void * instance); 182 | 183 | // Return screen resolution format 184 | DISPLAY_INPUT_FORMAT_T (*get_input_format)(void * instance); 185 | 186 | int32_t (*suspend_resume)(void *instance, int up); 187 | 188 | DISPLAY_3D_FORMAT_T (*get_3d_format)(void * instance); 189 | } DISPMANX_DISPLAY_FUNCS_T; 190 | ]] 191 | 192 | -------------------------------------------------------------------------------- /vc_dispservice_x_defs.lua: -------------------------------------------------------------------------------- 1 | local ffi = require "ffi" 2 | local bit = require "bit" 3 | local bnot = bit.bnot 4 | local band = bit.band 5 | 6 | -- Display service command enumeration. 7 | 8 | 9 | require "vc_image_types" 10 | 11 | HOST_PITCH_ALIGNMENT = 4 12 | 13 | -- Round up to the nearest multiple of 16 14 | PAD16 = function(x) 15 | return band(x + (VC_INTERFACE_BLOCK_SIZE-1), bnot(VC_INTERFACE_BLOCK_SIZE-1)) 16 | end 17 | 18 | -- The max length for an effect name 19 | DISPMANX_MAX_EFFECT_NAME = 28 20 | 21 | ffi.cdef[[ 22 | 23 | // Should really use the VC_IMAGE_TYPE_T, but this one has been extended 24 | // to force it up to 32-bits... 25 | typedef enum { 26 | // Values initially chosen to match VC_IMAGE_TYPE_T to aid debugging 27 | // This is now a mandatory constraint 28 | VC_FORMAT_RGB565 = VC_IMAGE_RGB565, 29 | VC_FORMAT_YUV420 = VC_IMAGE_YUV420, 30 | VC_FORMAT_RGB888 = VC_IMAGE_RGB888, 31 | VC_FORMAT_RGBA32 = VC_IMAGE_RGBA32, 32 | VC_FORMAT_RGBA565 = VC_IMAGE_RGBA565, 33 | VC_FORMAT_RGBA16 = VC_IMAGE_RGBA16, 34 | VC_FORMAT_TF_RGBA32 = VC_IMAGE_TF_RGBA32, 35 | VC_FORMAT_TF_RGBA16 = VC_IMAGE_TF_RGBA16, 36 | VC_FORMAT_TF_RGB565 = VC_IMAGE_TF_RGB565, 37 | VC_FORMAT_BGR888 = VC_IMAGE_BGR888, 38 | VC_FORMAT_BGR888_NP = VC_IMAGE_BGR888_NP, 39 | 40 | VC_FORMAT_ARGB8888 = VC_IMAGE_ARGB8888, 41 | VC_FORMAT_XRGB8888 = VC_IMAGE_XRGB8888, 42 | 43 | /* To force 32-bit storage, enabling use in structures over-the-wire */ 44 | VC_FORMAT_RANGE_MAX = 0x7FFFFFFF 45 | } VC_IMAGE_FORMAT_T; 46 | ]] 47 | 48 | VC_DISPMAN_ROT0 = VC_IMAGE_ROT0; 49 | VC_DISPMAN_ROT90 = VC_IMAGE_ROT90; 50 | VC_DISPMAN_ROT180 = VC_IMAGE_ROT180; 51 | VC_DISPMAN_ROT270 = VC_IMAGE_ROT270; 52 | VC_DISPMAN_MIRROR_ROT0 = VC_IMAGE_MIRROR_ROT0; 53 | VC_DISPMAN_MIRROR_ROT90 = VC_IMAGE_MIRROR_ROT90; 54 | VC_DISPMAN_MIRROR_ROT180 = VC_IMAGE_MIRROR_ROT180; 55 | VC_DISPMAN_MIRROR_ROT270 = VC_IMAGE_MIRROR_ROT270; 56 | VC_DISPMAN_TRANSFORM_T = VC_IMAGE_TRANSFORM_T; 57 | 58 | ffi.cdef[[ 59 | typedef enum { 60 | VC_RESOURCE_TYPE_HOST, 61 | VC_RESOURCE_TYPE_VIDEOCORE, 62 | VC_RESOURCE_TYPE_VIDEOCORE_UNCACHED, 63 | } VC_RESOURCE_TYPE_T; 64 | 65 | typedef struct { 66 | uint8_t type; // VC_IMAGE_FORMAT_T 67 | uint32_t width; // width in pixels 68 | uint32_t height; // height in pixels 69 | uint32_t pitch; // pitch of image_data array in *bytes* 70 | uint32_t size; // number of *bytes* available in the image_data arry 71 | uint32_t pointer; // pointer for image_data - this allows the object to be cast to a VC_IMAGE_T on the VIDEOCORE side 72 | } VC_IMAGE_PARAM_T; 73 | 74 | typedef enum { 75 | VC_DISPMANX_GET_DEVICES = 0, 76 | VC_DISPMANX_GET_DEVICE_NAME, 77 | VC_DISPMANX_GET_MODES, 78 | VC_DISPMANX_GET_MODE_INFO, 79 | VC_DISPMANX_DISPLAY_QUERY_IMAGE_FORMATS, 80 | // Resources 81 | VC_DISPMANX_RESOURCE_CREATE, 82 | VC_DISPMANX_RESOURCE_WRITE_DATA, 83 | VC_DISPMANX_RESOURCE_DELETE, 84 | // Displays 85 | VC_DISPMANX_DISPLAY_OPEN, 86 | VC_DISPMANX_DISPLAY_OPEN_MODE, 87 | VC_DISPMANX_DISPLAY_OPEN_OFFSCREEN, 88 | VC_DISPMANX_DISPLAY_RECONFIGURE, 89 | VC_DISPMANX_DISPLAY_SET_DESTINATION, 90 | VC_DISPMANX_DISPLAY_SET_BACKGROUND, 91 | VC_DISPMANX_DISPLAY_GET_INFO, 92 | VC_DISPMANX_DISPLAY_CLOSE, 93 | // Updates 94 | VC_DISPMANX_UPDATE_START, 95 | VC_DISPMANX_ELEMENT_ADD, 96 | VC_DISPMANX_ELEMENT_CHANGE_SOURCE, 97 | VC_DISPMANX_ELEMENT_MODIFIED, 98 | VC_DISPMANX_ELEMENT_REMOVE, 99 | VC_DISPMANX_UPDATE_SUBMIT, 100 | VC_DISPMANX_UPDATE_SUBMIT_SYNC, 101 | // Miscellaneous 102 | VC_DISPMANX_SNAPSHOT, 103 | // new features - add to end of list 104 | VC_CMD_END_OF_LIST 105 | } VC_CMD_CODE_T; 106 | ]] 107 | 108 | ffi.cdef[[ 109 | /* The table of functions executed for each command. */ 110 | 111 | typedef void (*INTERFACE_EXECUTE_FN_T)(int, int); 112 | 113 | //extern INTERFACE_EXECUTE_FN_T interface_execute_fn[]; 114 | ]] 115 | 116 | ffi.cdef[[ 117 | static const int DISPMANX_MAX_HOST_DEVICES = 8; 118 | static const int DISPMANX_MAX_DEVICE_NAME_LEN = 16; 119 | 120 | //Parameter sets for dispservice commands 121 | 122 | typedef struct { 123 | int32_t response; 124 | uint32_t ndevices; 125 | uint32_t dummy[2]; 126 | uint8_t names[DISPMANX_MAX_HOST_DEVICES][DISPMANX_MAX_DEVICE_NAME_LEN]; 127 | } DISPMANX_GET_DEVICES_RESP_T; 128 | 129 | typedef struct { 130 | uint32_t device; 131 | uint32_t dummy[3]; //Pad to multiple of 16 bytes 132 | } DISPMANX_GET_MODES_PARAM_T; 133 | 134 | typedef struct { 135 | uint32_t display; 136 | uint32_t mode; 137 | uint32_t dummy[2]; //Pad to multiple of 16 bytes 138 | } DISPMANX_GET_MODE_INFO_PARAM_T; 139 | 140 | typedef struct { 141 | uint32_t type; 142 | uint32_t width; 143 | uint32_t height; 144 | uint32_t dummy[1]; // Pad to multiple of 16 bytes 145 | } DISPMANX_RESOURCE_CREATE_PARAM_T; 146 | 147 | typedef struct { 148 | // This will be needed when we change to vchi. 149 | int junk; // empty structure not allowed 150 | } DISPMANX_RESOURCE_WRITE_DATA_PARAM_T; 151 | 152 | typedef struct { 153 | uint32_t handle; 154 | uint32_t dummy[3]; //Pad to multiple of 16 bytes 155 | } DISPMANX_RESOURCE_DELETE_PARAM_T; 156 | 157 | typedef struct { 158 | uint32_t device; 159 | uint32_t dummy[3]; 160 | } DISPMANX_DISPLAY_OPEN_PARAM_T; 161 | 162 | typedef struct { 163 | uint32_t device; 164 | uint32_t mode; 165 | uint32_t dummy[2]; 166 | } DISPMANX_DISPLAY_OPEN_MODE_PARAM_T; 167 | 168 | typedef struct { 169 | uint32_t dest; 170 | uint32_t orientation; 171 | uint32_t dummy[2]; 172 | } DISPMANX_DISPLAY_OPEN_OFFSCREEN_PARAM_T; 173 | 174 | typedef struct { 175 | uint32_t display; 176 | uint32_t dest; 177 | uint32_t dummy[2]; 178 | } DISPMANX_DISPLAY_SET_DESTINATION_PARAM_T; 179 | 180 | typedef struct { 181 | uint32_t display; 182 | uint32_t update; 183 | uint32_t colour; 184 | uint32_t dummy; 185 | } DISPMANX_DISPLAY_SET_BACKGROUND_PARAM_T; 186 | 187 | typedef struct { 188 | uint32_t display; 189 | uint32_t dummy[3]; 190 | } DISPMANX_DISPLAY_GET_INFO_PARAM_T; 191 | 192 | typedef struct { 193 | uint32_t read_response; 194 | int32_t width; 195 | int32_t height; 196 | int32_t aspect_pixwidth; 197 | int32_t aspect_pixheight; 198 | int32_t fieldrate_num; 199 | int32_t fieldrate_denom; 200 | int32_t fields_per_frame; 201 | uint32_t transform; 202 | uint32_t dummy[3]; 203 | } DISPMANX_DISPLAY_GET_INFO_RESP_T; 204 | 205 | typedef struct { 206 | int32_t priority; 207 | uint32_t dummy[3]; 208 | } DISPMANX_UPDATE_START_PARAM_T; 209 | 210 | typedef struct { 211 | uint32_t update; 212 | uint32_t display; 213 | int32_t layer; 214 | uint32_t transform; 215 | uint32_t src_resource; 216 | uint16_t dest_x; 217 | uint16_t dest_y; 218 | uint16_t dest_width; 219 | uint16_t dest_height; 220 | uint16_t src_x; 221 | uint16_t src_y; 222 | uint16_t src_width; 223 | uint16_t src_height; 224 | uint32_t flags; 225 | uint32_t opacity; 226 | uint32_t mask_resource; 227 | // already 16 byte aligned 228 | } DISPMANX_ELEMENT_ADD_PARAM_T; 229 | 230 | typedef struct { 231 | uint32_t update; 232 | uint32_t element; 233 | uint32_t src_resource; 234 | uint32_t dummy; // pad to 16 bytes 235 | } DISPMANX_ELEMENT_CHANGE_SOURCE_PARAM_T; 236 | 237 | typedef struct { 238 | uint32_t update; 239 | uint32_t element; 240 | uint16_t x; 241 | uint16_t y; 242 | uint16_t width; 243 | uint16_t height; 244 | } DISPMANX_ELEMENT_MODIFIED_PARAM_T; 245 | 246 | typedef struct { 247 | uint32_t update; 248 | uint32_t element; 249 | uint32_t dummy[2]; 250 | } DISPMANX_ELEMENT_REMOVE_PARAM_T; 251 | 252 | typedef struct { 253 | uint32_t update; 254 | uint32_t dummy[3]; 255 | } DISPMANX_UPDATE_SUBMIT_PARAM_T; 256 | 257 | typedef struct { 258 | uint32_t update; 259 | uint32_t dummy[3]; 260 | } DISPMANX_UPDATE_SUBMIT_SYNC_PARAM_T; 261 | 262 | typedef struct { 263 | uint32_t display; 264 | uint32_t snapshot_resource; 265 | uint32_t transform; 266 | uint32_t dummy[1]; 267 | } DISPMANX_DISPLAY_SNAPSHOT_PARAM_T; 268 | ]] 269 | 270 | --[=[ 271 | ffi.cdef[[ 272 | /* Image transformations. These must match the DISPMAN and Media Player versions */ 273 | 274 | static const int TRANSFORM_HFLIP = 0x01; 275 | static const int TRANSFORM_VFLIP = 0x02; 276 | static const int TRANSFORM_TRANSPOSE = 0x04; 277 | ]] 278 | --]=] 279 | 280 | TRANSFORM_HFLIP = 0x01; 281 | TRANSFORM_VFLIP = 0x02; 282 | TRANSFORM_TRANSPOSE = 0x04; 283 | 284 | -------------------------------------------------------------------------------- /vc_hdmi_property.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | --[[ 5 | /* 6 | * This file contains all the properties one can set in HDMI 7 | * Each property has up to two parameters corresponding to list of enums one can set via 8 | * the set/get property function from TV service (HOST) or HDMI middleware API (Videocore) 9 | * Each property also has a default value for these parameters. Please refer to 10 | * individual properties for details. 11 | */ 12 | --]] 13 | 14 | ffi.cdef[[ 15 | /** 16 | * Property type 17 | */ 18 | typedef enum { 19 | HDMI_PROPERTY_PIXEL_ENCODING = 0, /**< Set pixel encoding, value of property is HDMI_PIXEL_ENCODING_T, default is RGB full range (unless it is not supported) */ 20 | HDMI_PROPERTY_PIXEL_CLOCK_TYPE = 1, /**< See HDMI_PIXEL_CLOCK_TYPE_T, default is HDMI_PIXEL_CLOCK_TYPE_PAL */ 21 | HDMI_PROPERTY_CONTENT_TYPE = 2, /**< Set content type flag EDID_ContentType_T */ 22 | HDMI_PROPERTY_FUZZY_MATCH = 3, /**< disable (0 - default) or enable (1) fuzzy format match */ 23 | //More properties to be added here 24 | HDMI_PROPERTY_MAX /**< place holder */ 25 | } HDMI_PROPERTY_T; 26 | 27 | /** 28 | * PIXEL_ENCODING: param1: encoding type, param2: n/a 29 | * Setting encoding type is subjected to support in EDID 30 | */ 31 | typedef enum { 32 | HDMI_PIXEL_ENCODING_RGB_LIMITED = 0, /** 6 | 7 | ffi.cdef[[ 8 | typedef int32_t VCHI_MEM_HANDLE_T; 9 | ]] 10 | 11 | VCHI_MEM_HANDLE_INVALID = false 12 | 13 | 14 | -------------------------------------------------------------------------------- /vcos.lua: -------------------------------------------------------------------------------- 1 | 2 | --[[ 3 | ============================================================================= 4 | VideoCore OS Abstraction Layer - public header file 5 | =============================================================================*/ 6 | --]] 7 | 8 | local ffi = require "ffi" 9 | 10 | --[[ 11 | \file vcos.h 12 | 13 | This is the top level header file. Clients include this. It pulls in the platform-specific 14 | header file (vcos_platform.h) together with header files defining the expected APIs, such 15 | as vcos_mutex.h, vcos_semaphore.h, etc. It is also possible to include these header files 16 | directly. 17 | 18 | --]] 19 | 20 | 21 | require "vcos_assert" 22 | require "vcos_types" 23 | require "vcos_platform" 24 | require "vcos_init" 25 | --require "vcos_semaphore" 26 | 27 | --[[ 28 | require "vcos_thread" 29 | require "vcos_mutex" 30 | require "vcos_mem" 31 | require "vcos_logging" 32 | require "vcos_string" 33 | require "vcos_event" 34 | require "vcos_thread_attr" 35 | require "vcos_tls" 36 | require "vcos_reentrant_mutex" 37 | require "vcos_named_semaphore" 38 | require "vcos_quickslow_mutex" 39 | --]] 40 | 41 | --[[ 42 | -- Headers with predicates 43 | require "../vcos/vcos_event_flags.h" 44 | require "../vcos/vcos_queue.h" 45 | require "../vcos/vcos_legacy_isr.h" 46 | require "../vcos/vcos_timer.h" 47 | require "../vcos/vcos_mempool.h" 48 | require "../vcos/vcos_isr.h" 49 | require "../vcos/vcos_atomic_flags.h" 50 | require "../vcos/vcos_once.h" 51 | require "../vcos/vcos_blockpool.h" 52 | require "../vcos/vcos_file.h" 53 | require "../vcos/vcos_cfg.h" 54 | require "../vcos/vcos_cmd.h" 55 | --]] 56 | 57 | 58 | local vcos_Lib = ffi.load("vcos"); 59 | local result = vcos_Lib.vcos_init(); 60 | print("VCOS INIT: ", result); 61 | 62 | return { 63 | Lib = vcos_Lib; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /vcos_init.lua: -------------------------------------------------------------------------------- 1 | 2 | local ffi = require "ffi" 3 | 4 | 5 | --[[ 6 | ============================================================================= 7 | VideoCore OS Abstraction Layer - initialization routines 8 | ============================================================================= 9 | --]] 10 | 11 | 12 | require "vcos_types" 13 | require "vcos_platform" 14 | 15 | ffi.cdef[[ 16 | /** \file 17 | * 18 | * Some OS support libraries need some initialization. To support this, call 19 | * vcos_init() function at the start of day; vcos_deinit() at the end. 20 | */ 21 | 22 | /** 23 | * vcos initialization. Call this function before using other vcos functions. 24 | * Calls can be nested within the same process; they are reference counted so 25 | * that only a call from uninitialized state has any effect. 26 | * @note On platforms/toolchains that support it, gcc's constructor attribute or 27 | * similar is used to invoke this function before main() or equivalent. 28 | * @return Status of initialisation. 29 | */ 30 | VCOS_STATUS_T vcos_init(void); 31 | 32 | /** 33 | * vcos deinitialization. Call this function when vcos is no longer required, 34 | * in order to free resources. 35 | * Calls can be nested within the same process; they are reference counted so 36 | * that only a call that decrements the reference count to 0 has any effect. 37 | * @note On platforms/toolchains that support it, gcc's destructor attribute or 38 | * similar is used to invoke this function after exit() or equivalent. 39 | * @return Status of initialisation. 40 | */ 41 | void vcos_deinit(void); 42 | 43 | /** 44 | * Acquire global lock. This must be available independent of vcos_init()/vcos_deinit(). 45 | */ 46 | void vcos_global_lock(void); 47 | 48 | /** 49 | * Release global lock. This must be available independent of vcos_init()/vcos_deinit(). 50 | */ 51 | void vcos_global_unlock(void); 52 | 53 | /** Pass in the argv/argc arguments passed to main() */ 54 | void vcos_set_args(int argc, const char **argv); 55 | 56 | /** Return argc. */ 57 | int vcos_get_argc(void); 58 | 59 | /** Return argv. */ 60 | const char ** vcos_get_argv(void); 61 | 62 | ]] 63 | 64 | 65 | --[[ 66 | Copyright (c) 2012, Broadcom Europe Ltd 67 | All rights reserved. 68 | 69 | Redistribution and use in source and binary forms, with or without 70 | modification, are permitted provided that the following conditions are met: 71 | * Redistributions of source code must retain the above copyright 72 | notice, this list of conditions and the following disclaimer. 73 | * Redistributions in binary form must reproduce the above copyright 74 | notice, this list of conditions and the following disclaimer in the 75 | documentation and/or other materials provided with the distribution. 76 | * Neither the name of the copyright holder nor the 77 | names of its contributors may be used to endorse or promote products 78 | derived from this software without specific prior written permission. 79 | 80 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 81 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 82 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 83 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 84 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 85 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 86 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 87 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 88 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 89 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 90 | --]] 91 | -------------------------------------------------------------------------------- /vcos_platform_types.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | --[[ 4 | ============================================================================= 5 | VideoCore OS Abstraction Layer - platform-specific types and defines 6 | ============================================================================= 7 | --]] 8 | 9 | --[[ 10 | #include /* for PRId64, PRIi64, etc */ 11 | #include 12 | 13 | #define VCOSPRE_ extern 14 | #define VCOSPOST_ 15 | 16 | #if defined(__GNUC__) && (( __GNUC__ > 2 ) || (( __GNUC__ == 2 ) && ( __GNUC_MINOR__ >= 3 ))) 17 | #define VCOS_FORMAT_ATTR_(ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK) __attribute__ ((format (ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK))) 18 | #else 19 | #define VCOS_FORMAT_ATTR_(ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK) 20 | #endif 21 | 22 | /*#define VCOS_BKPT vcos_abort() */ 23 | 24 | #define VCOS_ASSERT_LOGGING = true 25 | #define VCOS_ASSERT_LOGGING_DISABLE = false 26 | 27 | extern void 28 | vcos_pthreads_logging_assert(const char *file, const char *func, unsigned int line, const char *fmt, ...); 29 | 30 | #define VCOS_ASSERT_MSG(...) ((VCOS_ASSERT_LOGGING && !VCOS_ASSERT_LOGGING_DISABLE) ? vcos_pthreads_logging_assert(__FILE__, __func__, __LINE__, __VA_ARGS__) : (void)0) 31 | --]] 32 | 33 | --[[ 34 | #define VCOS_INLINE_BODIES 35 | #define VCOS_INLINE_DECL extern __inline__ 36 | #define VCOS_INLINE_IMPL static __inline__ 37 | --]] 38 | 39 | PRId64 ="lld"; 40 | PRIi64 ="lli"; 41 | PRIo64 ="llo"; 42 | PRIu64 ="llu"; 43 | PRIx64 ="llx"; 44 | 45 | --[[ 46 | Copyright (c) 2012, Broadcom Europe Ltd 47 | All rights reserved. 48 | 49 | Redistribution and use in source and binary forms, with or without 50 | modification, are permitted provided that the following conditions are met: 51 | * Redistributions of source code must retain the above copyright 52 | notice, this list of conditions and the following disclaimer. 53 | * Redistributions in binary form must reproduce the above copyright 54 | notice, this list of conditions and the following disclaimer in the 55 | documentation and/or other materials provided with the distribution. 56 | * Neither the name of the copyright holder nor the 57 | names of its contributors may be used to endorse or promote products 58 | derived from this software without specific prior written permission. 59 | 60 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 61 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 62 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 63 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 64 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 65 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 66 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 67 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 68 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 69 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 70 | --]] 71 | -------------------------------------------------------------------------------- /vcos_semaphore.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | --[[ 4 | ============================================================================= 5 | VideoCore OS Abstraction Layer - public header file 6 | ============================================================================= 7 | --]] 8 | 9 | local ffi = require "ffi" 10 | 11 | require "vcos_types" 12 | require "pthreads/vcos_platform" 13 | 14 | 15 | ffi.cdef[[ 16 | /** 17 | * \file vcos_semaphore.h 18 | * 19 | * \section sem Semaphores 20 | * 21 | * This provides counting semaphores. Semaphores are not re-entrant. On sensible 22 | * operating systems a semaphore can always be posted but can only be taken in 23 | * thread (not interrupt) context. Under Nucleus, a LISR cannot post a semaphore, 24 | * although it would not be hard to lift this restriction. 25 | * 26 | * \subsection timeout Timeout 27 | * 28 | * On both Nucleus and ThreadX a semaphore can be taken with a timeout. This is 29 | * not supported by VCOS because it makes the non-timeout code considerably more 30 | * complicated (and hence slower). In the unlikely event that you need a timeout 31 | * with a semaphore, and you cannot simply redesign your code to avoid it, use 32 | * an event flag (vcos_event_flags.h). 33 | * 34 | * \subsection sem_nucleus Changes from Nucleus: 35 | * 36 | * Semaphores are always "FIFO" - i.e. sleeping threads are woken in FIFO order. That's 37 | * because: 38 | * \arg there's no support for NU_PRIORITY in threadx (though it can be emulated, slowly) 39 | * \arg we don't appear to actually consciously use it - for example, Dispmanx uses 40 | * it, but all threads waiting are the same priority. 41 | * 42 | */ 43 | 44 | /** 45 | * \brief Create a semaphore. 46 | * 47 | * Create a semaphore. 48 | * 49 | * @param sem Pointer to memory to be initialized 50 | * @param name A name for this semaphore. The name may be truncated internally. 51 | * @param count The initial count for the semaphore. 52 | * 53 | * @return VCOS_SUCCESS if the semaphore was created. 54 | * 55 | */ 56 | VCOS_STATUS_T vcos_semaphore_create(VCOS_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count); 57 | 58 | /** 59 | * \brief Wait on a semaphore. 60 | * 61 | * There is no timeout option on a semaphore, as adding this will slow down 62 | * implementations on some platforms. If you need that kind of behaviour, use 63 | * an event group. 64 | * 65 | * On most platforms this always returns VCOS_SUCCESS, and so would ideally be 66 | * a void function, however some platforms allow a wait to be interrupted so 67 | * it remains non-void. 68 | * 69 | * @param sem Semaphore to wait on 70 | * @return VCOS_SUCCESS - semaphore was taken. 71 | * VCOS_EAGAIN - could not take semaphore 72 | * 73 | */ 74 | VCOS_STATUS_T vcos_semaphore_wait(VCOS_SEMAPHORE_T *sem); 75 | 76 | /** 77 | * \brief Try to wait for a semaphore. 78 | * 79 | * Try to obtain the semaphore. If it is already taken, return VCOS_TIMEOUT. 80 | * @param sem Semaphore to wait on 81 | * @return VCOS_SUCCESS - semaphore was taken. 82 | * VCOS_EAGAIN - could not take semaphore 83 | */ 84 | VCOS_STATUS_T vcos_semaphore_trywait(VCOS_SEMAPHORE_T *sem); 85 | 86 | /** 87 | * \brief Post a semaphore. 88 | * 89 | * @param sem Semaphore to wait on 90 | */ 91 | VCOS_STATUS_T vcos_semaphore_post(VCOS_SEMAPHORE_T *sem); 92 | 93 | /** 94 | * \brief Delete a semaphore, releasing any resources consumed by it. 95 | * 96 | * @param sem Semaphore to wait on 97 | */ 98 | void vcos_semaphore_delete(VCOS_SEMAPHORE_T *sem); 99 | ]] 100 | 101 | --[[ 102 | Copyright (c) 2012, Broadcom Europe Ltd 103 | All rights reserved. 104 | 105 | Redistribution and use in source and binary forms, with or without 106 | modification, are permitted provided that the following conditions are met: 107 | * Redistributions of source code must retain the above copyright 108 | notice, this list of conditions and the following disclaimer. 109 | * Redistributions in binary form must reproduce the above copyright 110 | notice, this list of conditions and the following disclaimer in the 111 | documentation and/or other materials provided with the distribution. 112 | * Neither the name of the copyright holder nor the 113 | names of its contributors may be used to endorse or promote products 114 | derived from this software without specific prior written permission. 115 | 116 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 117 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 118 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 119 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY 120 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 121 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 122 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 123 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 124 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 125 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 126 | --]] 127 | -------------------------------------------------------------------------------- /vgu.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | /* $Revision: 6810 $ on $Date:: 2008-10-29 15:31:37 +0100 #$ */ 3 | --]] 4 | 5 | --[[ 6 | VGU 1.1 API. 7 | --]] 8 | 9 | local ffi = require "ffi" 10 | 11 | require "OpenVG" 12 | 13 | local VGU = { 14 | VGU_VERSION_1_0 = 1; 15 | VGU_VERSION_1_1 = 2; 16 | } 17 | 18 | 19 | ffi.cdef[[ 20 | typedef enum { 21 | VGU_NO_ERROR = 0, 22 | VGU_BAD_HANDLE_ERROR = 0xF000, 23 | VGU_ILLEGAL_ARGUMENT_ERROR = 0xF001, 24 | VGU_OUT_OF_MEMORY_ERROR = 0xF002, 25 | VGU_PATH_CAPABILITY_ERROR = 0xF003, 26 | VGU_BAD_WARP_ERROR = 0xF004, 27 | 28 | VGU_ERROR_CODE_FORCE_SIZE = VG_MAX_ENUM 29 | } VGUErrorCode; 30 | 31 | typedef enum { 32 | VGU_ARC_OPEN = 0xF100, 33 | VGU_ARC_CHORD = 0xF101, 34 | VGU_ARC_PIE = 0xF102, 35 | 36 | VGU_ARC_TYPE_FORCE_SIZE = VG_MAX_ENUM 37 | } VGUArcType; 38 | 39 | VGUErrorCode vguLine(VGPath path, VGfloat x0, VGfloat y0, VGfloat x1, VGfloat y1); 40 | VGUErrorCode vguPolygon(VGPath path, const VGfloat * points, VGint count, VGboolean closed); 41 | VGUErrorCode vguRect(VGPath path, VGfloat x, VGfloat y, VGfloat width, VGfloat height); 42 | VGUErrorCode vguRoundRect(VGPath path, VGfloat x, VGfloat y, VGfloat width, VGfloat height, VGfloat arcWidth, VGfloat arcHeight); 43 | VGUErrorCode vguEllipse(VGPath path, VGfloat cx, VGfloat cy, VGfloat width, VGfloat height); 44 | VGUErrorCode vguArc(VGPath path, 45 | VGfloat x, VGfloat y, 46 | VGfloat width, VGfloat height, 47 | VGfloat startAngle, VGfloat angleExtent, 48 | VGUArcType arcType); 49 | 50 | VGUErrorCode vguComputeWarpQuadToSquare(VGfloat sx0, VGfloat sy0, 51 | VGfloat sx1, VGfloat sy1, 52 | VGfloat sx2, VGfloat sy2, 53 | VGfloat sx3, VGfloat sy3, 54 | VGfloat * matrix); 55 | 56 | VGUErrorCode vguComputeWarpSquareToQuad(VGfloat dx0, VGfloat dy0, 57 | VGfloat dx1, VGfloat dy1, 58 | VGfloat dx2, VGfloat dy2, 59 | VGfloat dx3, VGfloat dy3, 60 | VGfloat * matrix); 61 | 62 | VGUErrorCode vguComputeWarpQuadToQuad(VGfloat dx0, VGfloat dy0, 63 | VGfloat dx1, VGfloat dy1, 64 | VGfloat dx2, VGfloat dy2, 65 | VGfloat dx3, VGfloat dy3, 66 | VGfloat sx0, VGfloat sy0, 67 | VGfloat sx1, VGfloat sy1, 68 | VGfloat sx2, VGfloat sy2, 69 | VGfloat sx3, VGfloat sy3, 70 | VGfloat * matrix); 71 | ]] 72 | 73 | return VGU 74 | --------------------------------------------------------------------------------