 Hello everyone, my name is Pranab and today I'm going to talk about how you can integrate your applications with a widget that resides in a LibreOffice repository, but many of you might not be knowing. So I work for Collabra and so let's start. So this is a rough outline that I would be talking on. First of all, I would be giving a brief introduction to LibreOffice kit, which is probably repeating and you would be getting to know about it in various LibreOffice online talks that would be tomorrow or day after tomorrow. After that, I would give an introduction to GObject, what exactly it is, and the GObject introspection magic that we use in the widget, which makes it possible to use the widget from many of the languages. And then I would give an introduction to the widget finally. So first we would get to know about the prerequisites, which are LibreOffice kit, GObject and GObject introspection. And after that we would dive into the widget, which is actually a GObject. And then I have like I created a few examples in different languages such as JavaScript or Python, so that you can use the widget from any of these languages. But there are other possibilities also, like for example you can use it from Perl or any other language for which there are GObject introspection bindings available there. And we have also managed to integrate this widget with Grom documents. So I would give you a demo also showing the integration with Grom documents. So Grom documents is currently using this widget behind the scenes from GNOME 3.2 or release onwards. So okay, so first thing about LibreOffice kit, what exactly it is, and how it is making things possible, how this widget is built on it, and how many of the cool products that we have like LibreOffice online and other things are built on this. So this slide is probably repeated because LibreOffice kit has been discussed several times in last year conferences also. And I actually also gave a lightning talk on this topic last year, but there have been a lot of improvements since the last year on this widget. So I decided to do a full-fledged talk on this because like we finally managed to merge the work with Grom documents in January this year. So that's why this full-fledged talk on the complete topic. So LibreOffice kit is a very simple CC++ API for LibreOffice. It like exposes the core value of LibreOffice. So you can access the file format filters through it. You have the main thing is about the tile rendering. So it converts the whole document into separate tiles. And those tiles are then transported from the back end to the front end. And you can use these tiles to form a complete document view on the front-end side in any language. It also exposes an API for making additions to the document. And you can make selections to the document. And so like you can do all kind of things that you can expect to be on a full-fledged desktop version of LibreOffice. So yeah, it's a very simple header-only API. So you don't need any linking. You are supposed to just hash include the header and then call a function which will deal open the LibreOffice shared object in the back end and hence will interact with the LibreOffice code internally. So as I already mentioned, there are many cool tools that are currently using LibreOffice kit. So LibreOffice Online, for example, is using LibreOffice kit. And the Android viewer that we have on the Play Store is using LibreOffice kit. And there is this tool for conversion of documents from one format to another. This is also using LibreOffice kit. And finally, this widget that I am talking about is also using LibreOffice kit in the back end. So let's talk a bit more about tile rendering, what exactly it is. So tile rendering is like converting your document into pixels. So this LibreOffice kit API exposes this functionality that you can access the whole document in form of tiles, in form of pixels. And then you can show these pixels on the front end and it would be like a complete document. So for example, I have screenshot the main function which is responsible for tile rendering through LibreOffice kit API. So as you can see, it accepts the coordinates of tile that you want LibreOffice kit to render for you. And it will give you a bitmap buffer rendering with 32-bit RGBA color space. And then you can use that buffer on the front end size and do a lot of stuff with it, whatever you want. So the communication that is happening here is the first communication is between the client and Allocore. As you might already have guessed, it just uses the API to talk to Allocore. So like your mouse events, your keyboard events, and are converted into these document coordinates. And along with the payload, they are forwarded to the core. And core, which is running in headless mode behind the scenes, is would be intercepting these events and make changes to it and then would interact with the client. The communication between the client and the Allocore is through API and then core also interacts with client through a mechanism that we would see in the next slides. You can also send your UNO commands to the back end from the front end. You just need to invoke a function in LibreOffice kit API. And you can do all sorts of stuff. So I'm just mentioning the most important things that are required for editing and making selections and all that stuff. For example, mouse events, keyboard events, so that you can interact with your document. Yeah, so this second communication is between the LibreOffice core and the client. So during when a new client initializes the widget, then it registers different kind of callbacks on it. So for example, when you have not opened any document, then you register a callback, which is a global callback. And so yeah, so this is registered on the main LibreOffice kit instance and you and like whenever LibreOffice core have to tell some global error message to the client, then it just invokes this global callback that is registered with it during the client initialization. And the other kind of callback is document callback. This is registered when you have already opened the document. So on the LibreOffice kit document instance, and it will tell you about the changes that have been made to the document so that client can make adjustments. For example, it will, whenever a selection changes in the backend, then it will tell the frontend that okay, the new selection coordinates are this and this, and you need to create an overlay over your document on the frontend size and show the user with this much selection on the document. So this kind of stuff is supported by document callback and the other callback which is, which is there to support the collaborative editing that we have in LibreOffice online now is a view callback. This is registered per view. So when you open a document and you can have different views viewing the same document. So each view registers their different view callback and so these are like callbacks which are called on different views separately, not on the document. So yeah, so we have only three kind of callbacks right now through which the core can communicate with the client. As mentioned before, tile invalidation, text selection, and visible cursor information, all this kind of stuff is communicated to the client through the medium of these callbacks. The global callback is responsible for like stuff which is related to, related directly to the document so that, for example, whenever you load a document, then it will tell you the status indicator callbacks. So like document has been loaded 10%, 20%, or 90%. So this kind of stuff is handled by global callback and yeah, and if a document is protected with a password or something, then LibreOffice core will let the client know about that a password has been set for this document and you need to provide a password if you want to open the document. So this kind of stuff is also supported through global callback because these are directly related to the document. So that was all about LibreOffice kit and now I will talk a little bit about GObject, what exactly it is and how this widget that I would be talking about is a GObject class. So a semi-object oriented programming is kind of already possible in C. So for example, Glib core uses it, but there are no modern useful features if you want to do that through C. So that's really difficult, but we have GObject over rescue. So Glib is actually made of three different kind of libraries. It's a set of libraries. So the first library that comes under Glib is Glib core and it contains common utility functions and data structure handling and all that kind of stuff. It uses a semi-object oriented kind of programming in the Glib core and GObject heavily uses this Glib core library and it creates a framework so that you can do some object oriented programming in C language using this GObject library. So it has the support for event-driven programming and event and all other object oriented features that we have. For example, it will give you inheritance virtual functions and all that stuff in C itself. So yeah, GIO is another such library which comes under Glib and it depends on GObject and Glib core both. So yeah, oh yeah, I already told most of things about it here. So yeah, it provides inheritance virtual functions and interfaces, reference counting signals and all that kind of stuff that you can imagine modern programming language using modern programming language will provide. But the negative side of it is that you have to use a lot of boilerplate code to support these OOP features. So you will often see these widgets written using these widgets using GObject classes have these lot of boilerplate codes because you need to support these OOP features somehow. And there is no multiple inheritance possible in GObject. So yeah, much like Java. So now let's talk about GObject introspection. It is the magic that we are using for making the library to be used from many of the languages. For example you can have your client in JavaScript, you can have your client in Perl, Python or any such languages which GObject introspection supports. So you don't have to write your client in C or C++, you can have your client in any of these languages. It's a middleware layer between GObject classes and the language bindings. So it's actually a set of tools to collect and extend GAPI metadata for GObject classes. So like it has a scanner with it which parses the C source files and generate a format which we call GIR. This GIR format contains all the metadata about your widget written in C and then there is a compiler which compiles this GIR file into a binary efficient disk format which we call type lib file. So because the thing we use it is we use it because the C syntax is insufficient for these language bindings because there is no way to transmit the information about ownership and dynamically allocated content. For example I have pasted this code from the widget and as you can see there are annotations which are written in bracket. So for example the first parameter of the function is ppath and the nullable thing that you can see in front of it is actually the information that will be used for creating the GIR format I discussed earlier. So for example in this case nullable means that you can set this parameter as null. You don't have to pass something always. You can just call the function with null parameter there. And yeah so this is a very small list among hundreds of annotations that is supported by G object introspection. One thing that we need to take care of here is because this annotation information is embedded into the comments so if you change the comment then it will just change the GIR introspection format that is generated. So it's not like you can change the comment to anything else and expect the API to be stable. It will just break everything. So you need to be very careful about these comments, about these annotations because these comments are read by the GIR scanner and so you need to be very consistent with the comments also which is unlike the case with programming in other programming in LibreOffice score where if you change the comment then at least it won't break the API. So yeah so like this is a very small list among many annotations that is supported. So for example if you have an annotation in front of a parameter which says transfer none then it means that the parameter that you are passing is like yeah sorry yeah. So yeah here we can see in front of return there is transfer none. So it means that the parameter that the object which is returned is not supposed to be freed so this information, this metadata information is embedded into the GIR format so that language bindings can use it and they can know that okay I don't need to free what is returned to me. So the other annotations are like transfer container which means that okay you can free the container but not the elements you don't need to care about freeing the elements you just need to care about freeing the container and if you have something like transfer full it means that you need to release the container as well the elements. So similarly we already saw about the nullable annotation which is used in front of parameters. So yeah now coming to the point which is this is the name of the widget and now we already know what LibreOffice kit is, what G object is, what G object introspection is. So lock doc view is a G object in simple words it's a G object class and since it's a G object class it's written in it's written following the G object code conventions so that the GIR scanner can run on that source file and can create a different GIR format XML file and that file will be read by different language bindings and hence you would be able to have your client in many different languages. So yeah it actually wraps the LibreOffice kit in a G object and it exposes all the functionality of this LibreOffice kit as a G object library the library is LibreOffice kit gtk.so. So a few more things about the internal structure of the widget so we do all the heavy lifting in a separate thread so because for UI applications it is necessary that it is responsive all the times you don't want that whenever you do some operation on the front end size then it hangs so like that would be a very bad user experience so because responsiveness is very necessary we do all the interaction with LibreOffice core in a separate thread and for example whenever we have to render some tiles we just dedicate the task to a separate thread and that thread is responsible for rendering the tile in the back end and whenever tile rendering is finished it just tells the widget that ok tile is rendered and you can now show this buffer on the front end. So this is a diagram that I came up with so you can see the lock doc view widget which is assigning the task to a dedicated thread and that dedicated thread is then interacting with LibreOffice core and LibreOffice core is interacting with the widget again through different callbacks those callbacks are fired on the S office thread but those callbacks which are fired on the S office thread are then forwarded to the widget's internal callback implementation because you need because as soon as something is changed as soon as for example let's say that LibreOffice core says you to change some selection coordinates that ok selection coordinate has been changed so you need to render the overlay differently on the front end so you need to make some changes to the widget and to make some changes on the widget you need to come to the main thread you cannot make the changes to the widget from the S office thread so what we do here is we forward those callbacks to the widget's internal implementation and this widget's internal callback implementation are on the main thread so now since we are in the main thread we can make changes to the widget so like every callback on the S office thread is mapped to every callback in the widget's internal implementation and then there's a small tile buffer class which is responsible for buffering of tiles so that if there are no changes you don't have to go all the way to LibreOffice core and ask it to render a tile again and then give it back to the client you can just poke the buffer and if the tile is there you can just return it so like I've come up with a few examples for example in JavaScript and Python where I can show the interaction going on so yeah yeah so like I just wrote this small client in JavaScript yeah so like 40 lines through which you can integrate LibreOffice in your application so you can launch it easily like this and it will open the LibreOffice in a different window so and then you can scroll it and then you can also edit it make selections and all that kind of stuff but since this is a minimal example you can here only view the document and cannot edit it because but editing is very simple and you can just extend the example here and if we do the same so yeah so the next line that I just wrote few hours ago is this something written in Python and yeah this is the same kind of thing you just have LibreOffice embedded inside the inside the client written in Python and you can access all the functionality of LibreOffice from this thing so yeah so these were like a few of the examples that I created for the demonstration purposes but it's like very much possible to write your client in other languages also you can use Perl you can use Lua you can use or you can have a look at the list of geo object introspection bindings available out there and can have your clients in any of the languages you want and access this LibreOffice functionality in your application so just a real-life example that I have is now is of GNOME documents this is the GNOME 3.2 orderlies where Verite accesses the LibreOffice kit in the back end to opening the to open the open office document formats so for example this one is one of the open office document format and you can see that it opened LibreOffice inside the GNOME documents interface these black lines are actually some something related to LibreOffice 5.0 release but it's not there in LibreOffice 5.0 on the master and so yeah so like this was a text document so we can similarly open a document a presentation there we can go to a next slide and and and yeah the integration code that we require is very minimal you just need to call two three functions to have to pull all the widget inside your applications and it's done so it's nothing much work that you have to do for the integration work this is probably a slide this yeah this is probably a spreadsheet so yeah you can open all kind of documents you can let's try zooming it so yeah so yeah so this is it and yeah so this is it any questions