mozilla
Your Search Results

    Standard OS Libraries

    This article is in need of a technical review.

    This article gives the names of standard libraries that can be accessed with js-ctypes. These libraries are what enable js-ctypes to work. The alternative 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 already available on the operating system for you. 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 allows you to find out what types to give to values/arguments by supplying links to the documentation of the OS libraries.

    Windows

    Windows has many Standard OS Libraries. The most common, 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 comes shipped by default with all installations of Windows operating systems since Win98. It's also known as WinAPI32 or just 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 wouldn't 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();
    

    Resources for WinAPI

    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.

    X11

    X11 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 X11; at the time of this writing, the latest version is 4.4.0. Information on all releases can be found on its official page X11 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: X11 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();
    

    Resources for X11

    Mac OS X

    Mac OS X has two categories of C-based API (Carbon, Core Foundation) and Objective-C based API (Cocoa).

    Note: You cannot use Carbon routines from your add-on; Firefox is a 64-bit application, and you cannot use Carbon from 64-bit code.

    Core Foundation

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

    The CoreGraphics framework is based on CoreFoundation framework, including CoreGraphics etc. The release, string, etc. comes from CoreFoundation.

    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();
    

    Resources for Core Foundation

    Cocoa

    To call Objective-C based API from ctypes, use the 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 by the 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,
                                            "...");
    
    // loc = [NSEvent mouseLocation]
    let NSEvent = objc_getClass("NSEvent");
    let mouseLocation = sel_registerName("mouseLocation");
    let loc = objc_msgSend_NSPoint(NSEvent, mouseLocation);
    
    Components.utils.reportError(loc);
    
    objc.close();
    

    Resources for Cocoa

    See Also

    Document Tags and Contributors

    Contributors to this page: Sheppy, arlolra, jswisher, arai, kscarfone, r_boy_, Noitidart
    Last updated by: kscarfone,