Your Search Results

    Standard OS Libraries

    This article is in need of a technical review.

    This article here gives the names of standard libraries that can be accesed with js-ctypes. These libraries are what enable js-ctypes to work. The altnerative to standard libraries is creating your own DLL (for Windows) or SO (for Linux) file with C functions that can be called from your add-on with js-ctypes. The DLL/SO/etc file you make must be shipped with your add-on. Standard libraries offer the advantage of not having to ship anything. They are available on operating system for you alreayd. You just need to supply the path to appropriate files and set up the proper types of values/arguments in the js-ctypes code. This article you to find out what types to give to values/arguments by suppling links to documentation of the OS libraries.

    Windows

    Windows has many Standard OS Libraries. The most common and found on all Windows OS version is "WinAPI". Windows also has the "WinAPILists" and ".NET Framework" (I'm not sure if it can be accessed JSCtypes but probably). A complete list of Windows APIs can be found at the MSDN API Index

    WinAPI

    This is the one that is most commonly used by js-ctypes. This is comes shipped default with all installations of Windows operating systems since Win98. It's also known as WinAPI32 or just WinAPI. On StackOverflow the relavent tag is "winapi". A list of all the functions available through this API can be found at the MSDN WinAPI Index. For finding out the values and types of arguments and returns of the functions you want to use from this API you must visit the functions page on this linked MSDN site, it will give you all that information.

    Example: GetCursorPos

    I wanted to get the mouse cursor position without using a MouseMove listener as this is a high overhead event listener. So I went to the MSDN WinAPI Index page and then went to the "Cursors" category and came across GetCursorPos. I then searched it on MSDN and saw that it needed the user32.dll. (MSDN - GetCursorPos)

    This example was created on Windows XP SP2. It is a full working example, just copy & paste it to try it out.

    Components.utils.import("resource://gre/modules/ctypes.jsm");
    var lib = ctypes.open("user32.dll");
    
    /* Declare the signature of the function we are going to call */
    /* note: if you go to GetCursorPos page on MSDN it says that x and y are
     * type Long, and in data types Long on MSDN it says it's a 64-byte signed
     * integer, so before ctypes.int I was trying ctypes.int64_t
     * but it wouldnt work, no clue why ctypes.int was the solution */
    var struct_Point = new ctypes.StructType("Point", [
      {"x": ctypes.int},
      {"y": ctypes.int}
    ]);
    
    var GetCursorPos = lib.declare('GetCursorPos',
        ctypes.winapi_abi,
        ctypes.bool,
        struct_Point.ptr
    );
    
    /* Use it like this */
    var point = new struct_Point;
    var ret = GetCursorPos(point.address());
    
    Components.utils.reportError(ret);
    Components.utils.reportError(point);
    
    lib.close();
    

    Linux

    On Linux, libraries will be typically found as .so files. One library that Linux uses, and that can be used through js-ctypes is XFree86.

    XFree86

    XFree86 runs primarily on UNIX®and UNIX-like operating systems like Linux, all of the BSD variants, Sun Solaris both native 32 and 64 bit support, Solaris x86, Mac OS X (via Darwin) as well as other platforms like OS/2 and Cygwin. There are updates that happen to XFree86, at the time of this writing, the latest version is 4.4.0. Information on all releases can be found on it's official page XFree86 Resources. Syntax and variable types are found on the documentation pages linked from this page. For example the documentation for v4.4.0 is seen here: XFree86[tm] Manual pages: Section 3

    Example: XQueryPointer

    Get mouse cursor position and some extra information. Documentation on this function is found at XFree86 :: XQueryPointer(3X11) Manual Page.

    Components.utils.import("resource://gre/modules/ctypes.jsm");
    let X11 = ctypes.open("libX11.so.6");
    let Display_ptr = ctypes.voidptr_t;
    let XOpenDisplay = X11.declare("XOpenDisplay",
        ctypes.default_abi,
        Display_ptr,
        ctypes.char.ptr
    );
    let Window = ctypes.int;
    let XRootWindow = X11.declare("XRootWindow",
        ctypes.default_abi,
        Window,
        Display_ptr,
        ctypes.int
    );
    let XQueryPointer = X11.declare("XQueryPointer",
        ctypes.default_abi,
        ctypes.bool,
        Display_ptr,
        Window,
        Window.ptr,
        Window.ptr,
        ctypes.int.ptr,
        ctypes.int.ptr,
        ctypes.int.ptr,
        ctypes.int.ptr,
        ctypes.unsigned_int.ptr
    );
    let XCloseDisplay = X11.declare("XCloseDisplay",
        ctypes.default_abi,
        ctypes.int,
        Display_ptr
    );
    
    let display = XOpenDisplay(null);
    let rootWindow = XRootWindow(display, 0);
    
    let root = new Window();
    let child = new Window();
    let rootX = new ctypes.int();
    let rootY = new ctypes.int();
    let windowX = new ctypes.int();
    let windowY = new ctypes.int();
    let mask = new ctypes.unsigned_int();
    
    XQueryPointer(display,
        rootWindow,
        root.address(),
        child.address(),
        rootX.address(),
        rootY.address(),
        windowX.address(),
        windowY.address(),
        mask.address()
    );
    
    XCloseDisplay(display);
    
    Components.utils.reportError(rootX.value + "," + rootY.value);
    
    X11.close();
    

    Mac OS X

    Mac OS X has two way to call Standard OS Library, C-based API (Carbon, Core Graphics, etc) and Objective-C based API (Cocoa).

    Core Graphics

    To learn about all the Mac OS X APIs and which library file you will need to call, go to Mac Developer Library website and find the function then scroll down to "Declared In" section, and find which Framework contains the header file.

    Example: CGEventGetLocation

    For example, CGEventGetLocation function is declared in CGEvent.h header file, which is contained in CoreGraphics.framework. so /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics is the library path to pass to ctypes.open function call.

    Components.utils.import("resource://gre/modules/ctypes.jsm");
    let CoreGraphics = ctypes.open("/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics");
    let CoreFoundation = ctypes.open("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation");
    
    let CGEventRef = ctypes.voidptr_t;
    let CGEventSourceRef = ctypes.voidptr_t;
    let CGEventCreate = CoreGraphics.declare("CGEventCreate",
                                             ctypes.default_abi,
                                             CGEventRef,
                                             CGEventSourceRef);
    let CGFloat = ctypes.float64_t;
    let CGPoint = new ctypes.StructType("CGPoint",
                                         [ { "x" : CGFloat },
                                           { "y" : CGFloat } ]);
    let CGEventGetLocation = CoreGraphics.declare("CGEventGetLocation",
                                                  ctypes.default_abi,
                                                  CGPoint,
                                                  CGEventRef);
    let CFTypeRef = ctypes.voidptr_t;
    let CFRelease = CoreFoundation.declare("CFRelease",
                                           ctypes.default_abi,
                                           ctypes.void_t,
                                           CGEventRef);
    
    let event = CGEventCreate(null);
    let cursor = CGEventGetLocation(event);
    
    CFRelease(event);
    
    Components.utils.reportError(cursor);
    
    CoreGraphics.close();
    CoreFoundation.close();
    

    Cocoa

    To call Objective-C based API from ctypes, use following functions in libobjc.dylib:

    • objc_getClass to get Class
    • sel_registerName to register selector name
    • objc_msgSend and some variants to send message to class and instance

    You can get any Objective-C class by calling objc_msgSend..

    Objective-C code can be translated into C code in following rule:

    // Objective-C code
    NSEvent loc = [NSEvent mouseLocation];
    
    // pseudo C code
    NSEvent loc = (NSPoint)objc_msgSend(objc_getClass("NSEvent"),
                                        sel_registerName("mouseLocation"));
    

    Example: [NSEvent mouseLocation]

    Components.utils.import("resource://gre/modules/ctypes.jsm");
    let objc = ctypes.open(ctypes.libraryName("objc"));
    
    let id = ctypes.voidptr_t;
    let SEL = ctypes.voidptr_t;
    let objc_getClass = objc.declare("objc_getClass",
                                     ctypes.default_abi,
                                     id,
                                     ctypes.char.ptr);
    let sel_registerName = objc.declare("sel_registerName",
                                        ctypes.default_abi,
                                        SEL,
                                        ctypes.char.ptr);
    let objc_msgSend = objc.declare("objc_msgSend",
                                    ctypes.default_abi,
                                    id,
                                    id,
                                    SEL,
                                    "...");
    let CGFloat = ctypes.float64_t;
    let NSPoint = new ctypes.StructType("NSPoint",
                                        [ { "x" : CGFloat },
                                          { "y" : CGFloat } ]);
    // note: [NSEvent mouseLocation] returns NSPoint struct,
    // which is small enough to return in register,
    // so we don't need to use objc_msgSend_stret.
    let objc_msgSend_NSPoint = objc.declare("objc_msgSend",
                                            ctypes.default_abi,
                                            NSPoint,
                                            id,
                                            SEL,
                                            "...");
    
    // pool = [[NSAutoreleasePool alloc] init]
    let NSAutoreleasePool = objc_getClass("NSAutoreleasePool");
    let alloc = sel_registerName("alloc");
    let init = sel_registerName("init");
    let pool = objc_msgSend(objc_msgSend(NSAutoreleasePool, alloc), init);
    
    // loc = [NSEvent mouseLocation]
    let NSEvent = objc_getClass("NSEvent");
    let mouseLocation = sel_registerName("mouseLocation");
    let loc = objc_msgSend_NSPoint(NSEvent, mouseLocation);
    
    // [pool mouseLocation]
    let release = sel_registerName("release");
    objc_msgSend(pool, release);
    
    Components.utils.reportError(loc);
    
    objc.close();
    

    Document Tags and Contributors

    Tags:
    Contributors to this page: jswisher, arai, r_boy_, Noitidart
    Last updated by: Noitidart,