What is the difference between gi-cairo and cairo libraries - haskell

I making a program to draw some vector graphics on top of a GTK program written with Haskell.
I upgraded my program to the gi-gtk library in replacement of Gtk2Hs to benefit of Gtk3 and when I see tutorial/example about drawing in Gtk windows with cairo and/or diagram, both gi-cairo and cairo (from Gtk2Hs) are needed at the same time.
For an example I can see :
import GI.Gtk
import qualified GI.Cairo (Context(..))
import qualified Graphics.Rendering.Cairo as Cairo
import qualified Graphics.Rendering.Cairo.Internal as Cairo (Render(runRender))
import qualified Graphics.Rendering.Cairo.Types as Cairo (Cairo(Cairo))
and I don't understand why GI.Cairo (gi-cairo) and Graphics.Rendering.Cairo (cairo) must be imported at the same time.
Does GI.Cairo aim to replace Graphics.Rendering.Cairo or to complete it ?
Is Graphics.Rendering.Cairo still updated or is it a good idea to use another library ?
Any information/explanations about these two libraries would be helpful

TL;DR: treat anything based on GTK2HS as deprecated. Use things with the gi- prefix instead.
Originally there were the GTK2HS libraries, which were a manually written binding to GTK (I think, not sure about the details).
Part of this effort was a binding to the Cairo library. The Cairo functions all take a Cairo context object as an argument, which is used to carry state like the current colour and line style. The Haskell binding wraps this up using a Reader monad inside the Render newtype so you don't have to worry about the context object.
However maintaining this was slow and mandraulic, and there was an obvious better way: GTK has built-in support for other language bindings provided by metadata embedded in the source code. So it is perfectly possible to generate all the GTK bindings automatically, and also to extend this to other libraries which use the GTK metadata system. This is what gi-gtk and its relatives do.
Unfortunately Cairo doesn't work like that. It doesn't include the GTK metadata for the actual drawing API, so the gi-cairo interface is no use for anything.
For some time the only way around this was a manual bodge to bridge the gap between the gi-gtk family and the GTK2HS Cairo library, but no longer. Now there is a complete solution:
The gi-cairo-render library, which is essentially the same as the old GTK2HS library but using the gi-cairo version of the context object.
The associated gi-cairo-connector library which lets you switch between functions that require an explicit Cairo context object and functions that work in the Render monad.
You most often need an explicit Cairo context for drawing text using Pango. The Pango library has its own Context object (confusingly, both types are called Context and you have to import them qualified to disambiguate). You get the Pango context from a Cairo context using createContext, and to do this in the middle of a Render action you have to extract the current context from the Render monad using one of the Connector functions.
The code you have quoted is using the old manual bodge; the Render and runRender internal functions are used get at the Cairo context in the GTK2HS version of the Cairo binding. If you look at the code that calls these functions you will probably see it doing something unsafe with pointers to coerce between the GI.Cairo.Context type and Graphics.Rendering.Cairo.Types.Cairo context type, which both point to the same thing under the hood.

Related

What does a quoted string in the import syntax `import "cryptonite" Crypto.Hash` mean?

As stated in the title. There is a codebase, where I have seen the following syntax
import "cryptonite" Crypto.Hash
(Context, Digest, SHA256, hash, hashFinalize, hashInit,
hashUpdate)
This syntax doesn't seem to be mentioned on haskell wiki on imports.
What does the "cryptonite" string do here?
Where does this syntax come from?
Is is part of Haskell2010 and if it is so where in the language report is it mentioned?
This is extra syntax that is supported when using the PackageImports extension:
With the PackageImports extension, GHC allows import declarations to
be qualified by the package name that the module is intended to be
imported from. For example:
import "network" Network.Socket
would import the module Network.Socket
from the package network (any version). This may be used to
disambiguate an import when the same module is available from multiple
packages, or is present in both the current package being built and an
external package.
The special package name this can be used to refer to the current
package being built.
It occasionally happens that two packages export a module with the same name. For example both hashmap and unordered-containers export Data.HashSet. If both packages are installed, we want to disambiguate between the different packages. With this type of import, the author thus specifies that the Crypto.Hash module of the cryptonite needs to be used.
This is to to the best of my knowledge not standard Haskell (in the sense that other Haskell compilers do not have to support this, it seems not specified in the import statement section of the Haskell 2010 report), but a Glasgow Haskell compiler extension. Of course other compilers can support this as well, but a compiler without this extension, can still rightfully call itself a "Haskell compiler". In order to activate this extension, you need to compile with the -XPackageImports extension:
ghc -XPackageImports main.hs
This is a dynamic flag, and thus can be specified in the "pragma" of a Haskell source file as well.

How to do custom python imports?

Is there a way to have custom behaviour for import statements in Python? How? E.g.:
import "https://github.com/kennethreitz/requests"
import requests#2.11.1
import requests#7322a09379565bbeba9bb40000b41eab8856352e
Alternatively, in case this isn't possible... Can this be achieved in a standard way with function calls? How? E.g.:
import gitloader
repo = gitloader.repo("https://github.com/kennethreitz/requests")
requests = repo.from_commit("7322a09379565bbeba9bb40000b41eab8856352e")
There are two reasons for why I would like to do this. The first reason is convenience (Golang style imports). The second reason is that I need cryptographic verification of plugin modules for a project. I'm using Python 3.x
What you're essentially asking is customization of the import steps. This was made possible with PEP 302 which brought about certain hooks for for customization.
That PEP is currently not the source from which you should learn how importing works; rather, look at the documentation for the import statement for reference. There it states:
Python includes a number of default finders and importers. The first one knows how to locate built-in modules, and the second knows how to locate frozen modules. A third default finder searches an import path for modules. The import path is a list of locations that may name file system paths or zip files. It can also be extended to search for any locatable resource, such as those identified by URLs.
The import machinery is extensible, so new finders can be added to extend the range and scope of module searching.
In short, you'll need to define the appropriate finder (to find the modules you're looking for) and an appropriate loader for loading these.

How can I dynamically load a foreign library?

Is there a Haskell equivalent of POSIX' dlopen or Windows' LoadLibrary? All the FFI stuff only seems to work with libraries specified at link time.
A quick hoogling brings up System.Posix.DynamicLinker. You can also try the plugins package for more high-level stuff.
For Windows, there is System.Win32.DLL. The result of getProcAddress can be converted to a function pointer using castPtrToFunPtr.

What is imported using the Gjs imports statement?

If I'm looking at Gjs code and see this line near the beginning:
const Gio = imports.gi.Gio;
How can I know what methods, constants, events, etc. are on 'Gio' (without doing a Google search)? Is there a file somewhere on my installation that contains that information?
Obviously I'm asking for any 'imports' statement, not Gio specifically.
Some of imports statements import other javascript files:
imports.ui.* -> /usr/share/cinnamon/js/ui/*
imports.misc.* -> /usr/share/cinnamon/js/misc/*
imports.[cairo, dbus, format, gettext, jsUnit, lang, promise, signals] -> /usr/share/gjs-1.0/
For the imports.gi imports, Gnome Introspection is used to allow gjs to use C library.
So to get informations about those libraries I suggest you to look at the Gnome reference manuals:
Gio
Gtk
St
But to conclude, there is a huge lack of documentation and examples. That makes difficult to develop with gjs.
UPDATE
Here other useful links:
Seed documentation (seed is another javascript implementation for GNOME)
Gjs exemples
Since I got no answers I kept searching online and found this excellent blog post on how to generate HTML-formatted documentation from typelib files (such as Gio-2.0.typelib):
http://mathematicalcoffee.blogspot.com/2012/09/developing-gnome-shell-extensions_6.html

Where has hSetEncoding gone?

I was fairly sure that a while back GHC added the ability to explicitly set the character encoding on a Handle. However, when I look in System.IO, I don't see anything relating to character encodings. (I have Haskell Platform 2012.4.0.0)
Am I blind, or simply mistaken?
I investigated where the function is hiding.
Summary: Make sure to use System.IO from package base, not from package haskell2010.
Details: Hoogle tells me that there is System.IO.hSetEncoding in the latest base package.
http://www.haskell.org/hoogle/?hoogle=hSetEncoding
Checking the documentation about the Haskell platform 2012.4.0.0, I see a System.IO module from the haskell2010 package. And that module doesn't seem to contain hSetEncoding.
http://lambda.haskell.org/platform/doc/2012.4.0.0/ghc-doc/libraries/haskell2010-1.1.0.1/System-IO.html
But do not despair, there seems to also be the System.IO from base which contains hSetEncoding.
http://lambda.haskell.org/platform/doc/2012.4.0.0/ghc-doc/libraries/base-4.5.1.0/System-IO.html#v:hSetEncoding
So I guess you just have to make sure that you use the System.IO from base and not from haskell2010.
Oh my God!
OK, I just figured this out.
It appears that there are two packages that both export System.IO - the base package and the haskell2010 package.
The two versions of the module are different. Specifically, only the module from base has all the character encoding stuff in it.
When you go to the locally-installed module index, it only shows you the version of System.IO that's included in haskell2010 - without all the character encoding stuff.
It appears the only way to see the version from base is to click on some other module exported from base, then click "Contents", then navigate to System.IO from there. Then it shows you the correct module!
Counter-intuitive, much? o_O
OK, so I've found my function now, but man, Haddock should probably do a better job of handling this obscure edge-case...

Resources