This is my research notebook. I'm an OSX / iOS indie developer. After 8 years of Objective-C I really enjoy Swift nowadays. Trying to publish all my research on Development, Swift & other technologies here.
Tue, 8 Dec 2015 #
Now that Swift is open source, many interested users might be installing and testing it on their Linux systems. However, currently the Foundation framework is still very much a work-in-progress so if you're interested in developing more than a simple shell app, you'll need to link against existing Linux libraries like GTK, Cairo, or libpng in order to gain access to useful functionality.
I just finished implementing a simple Swift app which links against X11
, the most basic Unix UI library . In this short tutorial, I'll show how to write a simple X11 app, and how you can utilize this to link against other libraries.
In the process, we'll also use the new Swift package manager to create a simple re-usable package for the X11 library.
Here's a screenshot of the finished app in action:
1 Swift Packages
Before we write our actual X11 app, we need to define a Swift package which defines the links against the X11 library. Once this is done, we can easily share this package with other users, or re-use it in other projects. We have to differentiate between defining a package and using a package. Let's start with the first and then see how we can use that package.
1.1 Defining a package
Create a new folder which will host our package. Since we're linking against a C library, we follow the guidance of the Swift Package Manager documentation and prefix our library with the letter C. We'll name our library CX11.swift
In our case, we want to link against an existing C API and we do not intend to write any Swift wrapper code. Linking against C libraries and headers is achieved via the module.modulemap
file which contains the necessary directives for the Swift compiler to perform the correct linking. The documentation for the modulemap syntax can be found here. We create the module map file, and edit the contents (via an editor of your choice, in this case we're using nano
):
touch CX11.swift/module.modulemap
nano CX11.swift/module.modulemap
X11 is a huge library with a lot of functionality. You can see the contents if you head over to /usr/include/X11
. For our example, we don't need to include all the header files in there, instead we really only need two of them: Xlib.h
and X.h
. For different other libraries, you may need to include more headers. There is a convenient way to include all the headers in a directory which I'll point out below. Apart from including the headers, we also need to tell Swift which library to link against. We're using the link
keyword for that. Our modulemap
looks like this:
module CX11 [system] {
module Xlib {
header "/usr/include/X11/Xlib.h"
}
module X {
header "/usr/include/X11/X.h"
}
link "X11"
}
We're naming our module CX11
and we're creating two submodules. One for the Xlib and one for X. Each submodule defines the header it needs to import. Finally, we're linking against libx11 via the link
statement.
But what if we have not just one header file, but many of them. Module maps allow you to define an umbrella header or an umbrella directory.
Umbrella Header
This is a header that contains just references to other headers (via #include
) commands. A good example is <Cocoa/Cocoa.h>
or <Foundation/Foundation.h>
or <gtk/gtk.h>
.
Umbrella headers are defined via the umbrella keyword:
umbrella header "/usr/include/gtk/gtk.h"
Umbrella Directory
Sometimes you have a directory of headers but no umbrella header. In this case you just point Swift to the directory of headers:
umbrella "/usr/include/X11/"
In addition to the modulemap, we'll also need a Package.swift file, otherwise building will fail. This file can be empty though:
touch CX11.swift/Package.swift
The Swift package manager uses Git and Git Tags in order to manage packages. So before we're done, we need to create a Git repository for our Package, add all the files, and create a version tag. This is fairly easy though:
cd CX11.swift
git init
git add .
git commit -m "Initial Import"
git tag 1.0.0
cd ..
The commands above go into the folder, create a new Git repository, add all the files to it, create a first commit, and finally add a version tag (1.0.0
) for this commit.
That's it, our package is defined, but how do we use it?
1.2 Using Packages
In order to use a package, we need to define a Package.swift
file which will tell Swift which packages we intend to import for our project. But first, we need to create a directory for our project.
mkdir swift-x11
touch swift-x11/Package.swift
touch swift-x11/main.swift
Keep in mind that (for this example to work) the swift-x11
folder has to be next to the CX11.swift
folder. I.e.:
ls -l
CX11.swift
swift-x11
Before we start writing the actual Swift code to interact with X11, we need to tell our swift-x11
project how to import the CX11
package. This is done, as explained below, via the swift-x11/Package.swift
:
import PackageDescription
let package = Package(
dependencies: [
.Package(url: "../CX11.swift", majorVersion: 1)
]
)
This tells Swift that the package we intend to use is located in the ../CX11.swift
folder.
The url
(as the name suggests) does not need to be a local one. I've uploaded my own CX11.swift to GitHub, and you could alternatively link directly to the GitHub version as follows:
import PackageDescription
let package = Package(
dependencies: [
.Package(url: "https://github.com/terhechte/CX11.swift.git", majorVersion: 1)
]
)
2 Using X11
Now that we defined an X11 package, and set up the package manager definitions, we want to write our first X11 application.
One issue which I could not solve is that macro definitions in the X11 header file are not imported into Swift. The Xlib.h
defines many shortcut macros like:
#define RootWindow(dpy, src) (ScreenOfDisplay(dpy, src)->root)
#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)dpy)->screens[scr])
As these were not imported, I decided instead to always write out the contents of the macro. All the code below has to be put into the main.swift
file. You can also see the finished version here on GitHub. Please note that this is a simple and non-memory-safe example. This mostly serves to explain how to use C libraries under Linux. Also, my X11 knowledge is rather limited. I did Linux X11 programming more than 10 years ago and forgot most of it, so there may be factual errors in the explanation below. If you find them, feel free to open a PR on this repo :)
We begin by importing the CX11
library which we defined above:
import CX11.Xlib
import CX11.X
2.1 Setting up state
After this, we have to define a couple of variables.
- We need the X11 display (i.e. roughly speaking the X11 server connection). This will be the
d
variable
- We need a placeholder for the X11 window which we create. This will be the
w
variable.
- We also need to set aside a bit of memory for the X11 Server to store X11 input events. This is the
e
variable.
- We should also already store the text which we want to display in our window. This is the
msg
variable
- We need a place to store the current X11 screen (a X11 Display can have multiple screens). This will be the
s
variable.
- Finally, we need a pointer to the X11 root window, which houses the other windows. This is the
rootWindow
variable.
// The X11 Display
var d: _XPrivDisplay
// The window which we will create
var w: Window
// The events which X11 generates for us will be stored here
var e = UnsafeMutablePointer<_XEvent>.alloc(1)
// The text to display
var msg = "Hello Swift World"
// A pointer to the current X11 Screen
var s: UnsafeMutablePointer<Screen>
Now that we defined our variables, we need to open our connection to the X11 Server. However, as users can also run this app when no X server is running (i.e. in console mode) we need to make sure that the connection succeeded:
d = XOpenDisplay(nil)
if d == nil {
fatalError("cannot open display")
}
After we opened the display, we'd like to get the current default screen as well as the current root window. The RootWindow
macro is not available, so we will access the memory section of the C struct
directly. However, as the current screen s
is a UnsafeMutablePointer
, we need to add the memory
property in order to access the root
instance.
// Get the default screen
s = XDefaultScreenOfDisplay(d)
// And the current root window on that screen
let rootWindow = s.memory.root
2.2 Creating a Window
Finally we have everything in place to create our own window and place it on the screen. We're using the XCreateSimpleWindow
function for that. The function has the following parameters:
XCreateSimpleWindow(Display *display, Window parent, int x, int y,
unsigned int width, unsigned int height, unsigned int border_width,
unsigned long border, unsigned long background);
border
and background
are color values. In order to not think about color creation, we will simply pass in a reference to the default black and white colors which are defined on the current screen. We have to use the .memory
property again.
// Create our window
w = XCreateSimpleWindow(d, rootWindow, 10, 10, 200, 100, 1,
s.memory.black_pixel, s.memory.white_pixel)
This will create a new window on the rootWindow
position 10/10 of width 200 and height 100. The borders will be black, the background will be white.
2.4 Event Loop
Finally we do have everything in place to run our event loop while the window is being displayed. For this, we're using a while
loop which continously pulls the XNextEvent
function to get new X11 events. Then, we'll test the event to see whether it is a Expose
or a KeyPress
event. We're testing the events using the swift switch
statement:
loop: while true {
// Wait for the next event
XNextEvent(d, e)
switch e.memory.type {
// The window has to be drawn
case Expose:
// draw a small black rectangle
XFillRectangle(d, w, s.memory.default_gc, 20, 20, 10, 10)
// draw the text
XDrawString(d, w, s.memory.default_gc, 10, 70, msg, Int32(msg.characters.count))
// The user did press a key
case KeyPress:
break loop
// We never signed up for this event
default: fatalError("Unknown Event")
}
}
Our e
event structure is - again - a UnsafeMutablePointer
, so we have to access the actual structure via the memory
property. The Expose
event means that the window is visible, so we have to re-draw it. Our drawing is very simple: We're using the XFillRectangle
call to draw a small black box, and the XDrawString
call to draw our initial msg
text in the window at position 10, 70. Please note that I don't know whether X11 expects unicode or ascii, so the Int32(msg.characters.count)
is probably wrong, but it works in this example.
The other event, KeyPress
allows us to break the outer while
loop and quit the app once the user enters a key.
3 Running It
To use this, simply check out the repo (preferrably on Linux) and do the following in the folder:
This will clone the CX11.swift
package and build the binary in the .build/debug
folder.
Run it via:
.build/debug/swift-x11-example
This will execute the binary, and a small X11 Window should appear on your desktop:
Related Articles
- Thu, 24 Jan 2019:
An interactive Git Status client, written in C - Thu, 3 April 2018:
Expanding Swift's Reach - Wed, 10 Jan 2018:
Useful Optional Extensions - Sun, 10 Dec 2017:
Patterns for Working With Associated Types - Sun, 8 Oct 2017:
Taming SourceKitService for Less Xcode Memory Consumption - Sat, 30 Sep 2017:
Value Types for Simple Difference Detection - Fri, 15 Jul 2016:
Data in Swift 3 parsing a Doom WAD File - Thu, 28 Apr 2016:
SwiftWatch - Sat, 23 Apr 2016:
Raw value initializers for enums with associated types - Thu, 14 Apr 2016:
Force optionals in multi-unwrapped "guard let" or "if let" - Tue, 29 Mar 2016:
Three tips for concise Swift using the Guard statement - Tue, 2 Feb 2016:
Hirundo: Comfortably follow Swift Mailing Lists on OSX - Tue, 8 Dec 2015:
Swift Package Manager: Create and Use a X11 package on Linux - Mon, 30 Nov 2015:
Reduce all the things - Sat, 24 Oct 2015:
The Swift Reflection API and what you can do with it - Sat, 17 Oct 2015:
Advanced and Practical Enum usage in Swift - Wed, 30 Sep 2015:
Getting your iPhone 6s Chip Foundry from Swift - Tue, 25 Aug 2015:
Optional throw via try? in Swift 2 beta 6 - Thu, 20 Aug 2015:
Match Me if you can: Swift Pattern Matching in Detail. - Sun, 19 Jul 2015:
Tuples in Swift, Advanced Usage and Best Practices - Fri, 19 Jun 2015:
Using try / catch in Swift with asynchronous closures - Wed, 17 Jun 2015:
Generic method overloading by protocol in Swift - Fri, 13 Jun 2014:
Swift optionals made simple - Sun, 8 Jun 2014:
Creating a Swift syntax extension: the Lisp 'cond' function
{:description
"A tutorial on how to create a Swift Package for X11 on Linux and use it to write a simple X11 app",
:keyword-tags (:swift :linux),
:projects ({:project "Sarbatka", :link "/electronic-music.html"}),
:postlist
({:title "Blogstrapped.",
:url "/2011/12/01/blogstrapped/",
:tags "entrepeneurship blog",
:keyword-tags (:entrepeneurship :blog),
:date "Thu, 1 Dec 2011",
:keywords "entrepeneurship videro fear unknown stylemac",
:keyword-keywords
(:entrepeneurship :videro :fear :unknown :stylemac)}
{:title "Fast NSDictionary traversal in Objective-C",
:url "/2011/12/07/fast-nsdictionary-traversal-in-objective-c/",
:tags "objective-c ios cocoa",
:keyword-tags (:objective-c :ios :cocoa),
:date "Wed, 7 Dec 2011"}
{:title "How the iPad can improve focus",
:url "/2011/12/09/how-the-ipad-can-improve-focus/",
:tags "opinion",
:keyword-tags (:opinion),
:date "Fri, 9 Dec 2011"}
{:title "Use VIM as an Xcode alternative",
:url "/2013/01/29/use-vim-as-xcode-alternative-ios-mac-cocoa/",
:tags "cocoa objective-c ios",
:keyword-tags (:cocoa :objective-c :ios),
:date "Tue, 29 Jan 2013"}
{:title "Now Running Clojure",
:url "/2014/01/20/now-running-clojure/",
:tags "clojure blog",
:keyword-tags (:clojure :blog),
:date "Mon, 20 Jan 2014"}
{:title
"Debugging entitlement issues in Maps, iCloud, In-App, Keychain, or GameCenter",
:url
"/2014/01/21/debugging-entitlement-maps-icloud-gamecenter-issues/",
:tags "ios cocoa",
:keyword-tags (:ios :cocoa),
:date "Tue, 21 Jan 2014",
:keywords "ios cocoa entitlements",
:keyword-keywords (:ios :cocoa :entitlements)}
{:title
"Clojure/Enlive Static Site Generator that keeps your HTML intact",
:url
"/2014/01/22/clojure-enlive-static-site-generator-that-keeps-html-intact/",
:tags "blog clojure",
:keyword-tags (:blog :clojure),
:date "Wed, 22 Jan 2014",
:keywords "clojure static site generator jekyll html enlive",
:keyword-keywords
(:clojure :static :site :generator :jekyll :html :enlive)}
{:title "Finding a good URL Partitioning Scheme for PostgreSQL",
:url "/2014/01/24/finding-url-partitioning-scheme-postgres/",
:tags "postgresql clojure",
:keyword-tags (:postgresql :clojure),
:date "Fri, 24 Jan 2014",
:keywords "clojure postgresql partitioning scheme",
:keyword-keywords (:clojure :postgresql :partitioning :scheme)}
{:title "An Emacs Lisp tooling tutorial, writing a bulk mailer",
:url "/2014/01/29/emacs-lisp-tooling-tutorial-writing-bulk-mailer/",
:tags "emacs",
:keyword-tags (:emacs),
:date "Wed, 29 Jan 2014",
:keywords
"emacs lisp bulk mailer tutorial email vim vimscript evil",
:keyword-keywords
(:emacs :lisp :bulk :mailer :tutorial :email :vim :vimscript :evil)}
{:title
"Creating a Swift syntax extension: the Lisp 'cond' function",
:url "/2014/06/08/writing-simple-syntax-extensions-in-swift/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Sun, 8 Jun 2014",
:keywords
"clojure lisp swift cond syntax macro extension cocoa ios feature",
:keyword-keywords
(:clojure
:lisp
:swift
:cond
:syntax
:macro
:extension
:cocoa
:ios
:feature)}
{:title "Swift optionals made simple",
:url "/2014/06/13/swift-optionals-made-simple/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Fri, 13 Jun 2014",
:keywords
"lisp swift optional scala simple optionals switch chaining feature",
:keyword-keywords
(:lisp
:swift
:optional
:scala
:simple
:optionals
:switch
:chaining
:feature)}
{:title "Generic method overloading by protocol in Swift",
:url "/2015/06/17/swift-method-overloading-by-protocol/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Wed, 17 Jun 2015",
:keywords
"swift optional simple overloading method protocol extensions generics feature",
:keyword-keywords
(:swift
:optional
:simple
:overloading
:method
:protocol
:extensions
:generics
:feature)}
{:title "Using try / catch in Swift with asynchronous closures",
:url "/2015/06/19/swift-try-catch-asynchronous-closures/",
:tags "swift ios",
:keyword-tags (:swift :ios),
:date "Fri, 19 Jun 2015",
:keywords "swift try catch errortype closure async result feature",
:keyword-keywords
(:swift :try :catch :errortype :closure :async :result :feature)}
{:title "Debugging advanced compilation errors in ClojureScript",
:url "/2015/07/02/debugging-clojurescript-advanced-compilation/",
:tags "clojure",
:keyword-tags (:clojure),
:date "Thu, 2 Jul 2015",
:keywords "debugging clojure clojurescript externs",
:keyword-keywords (:debugging :clojure :clojurescript :externs)}
{:title "Tuples in Swift, Advanced Usage and Best Practices",
:url "/2015/07/19/tuples-swift-advanced-usage-best-practices/",
:tags "swift",
:keyword-tags (:swift),
:date "Sun, 19 Jul 2015",
:keywords "swift tuples generics feature",
:keyword-keywords (:swift :tuples :generics :feature)}
{:title "Match Me if you can: Swift Pattern Matching in Detail.",
:url "/2015/08/20/swift-pattern-matching-in-detail/",
:tags "swift ios cocoa",
:keyword-tags (:swift :ios :cocoa),
:date "Thu, 20 Aug 2015",
:keywords
"feature lisp swift optional scala simple optionals switch chaining for pattern matching clojure haskell",
:keyword-keywords
(:feature
:lisp
:swift
:optional
:scala
:simple
:optionals
:switch
:chaining
:for
:pattern
:matching
:clojure
:haskell)}
{:title "Optional throw via try? in Swift 2 beta 6",
:url "/2015/08/25/optional-throw-swift/",
:tags "swift",
:keyword-tags (:swift),
:date "Tue, 25 Aug 2015",
:keywords
"swift error throw result either rethrow try syntax swift2",
:keyword-keywords
(:swift
:error
:throw
:result
:either
:rethrow
:try
:syntax
:swift2)}
{:title "Getting your iPhone 6s Chip Foundry from Swift",
:url "/2015/09/30/getting-iphone6s-foundry-from-swift/",
:tags "swift",
:keyword-tags (:swift),
:date "Wed, 30 Sep 2015",
:keywords
"swift iphone6s iphone tsmc samsung gestalt private api foundation",
:keyword-keywords
(:swift
:iphone6s
:iphone
:tsmc
:samsung
:gestalt
:private
:api
:foundation)}
{:title "Advanced and Practical Enum usage in Swift",
:url "/2015/10/17/advanced-practical-enum-examples/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 17 Oct 2015",
:keywords
"feature swift enum algebraic caseclass union case switch pattern simple practical advanced example",
:keyword-keywords
(:feature
:swift
:enum
:algebraic
:caseclass
:union
:case
:switch
:pattern
:simple
:practical
:advanced
:example)}
{:title "The Swift Reflection API and what you can do with it",
:url "/2015/10/24/swift-reflection-api-what-you-can-do/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 24 Oct 2015",
:keywords
"feature swift reflection struct class displayType mirror api reflecting any anyobject",
:keyword-keywords
(:feature
:swift
:reflection
:struct
:class
:displayType
:mirror
:api
:reflecting
:any
:anyobject)}
{:title "Reduce all the things",
:url "/2015/11/30/reduce-all-the-things/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Mon, 30 Nov 2015",
:keywords
"feature swift reduce map filter group partition split interpose chunk functional programming flatMap",
:keyword-keywords
(:feature
:swift
:reduce
:map
:filter
:group
:partition
:split
:interpose
:chunk
:functional
:programming
:flatMap)}
{:title
"Swift Package Manager: Create and Use a X11 package on Linux",
:url "/2015/12/08/swift-ubuntu-x11-window-app/",
:tags "swift linux",
:keyword-tags (:swift :linux),
:date "Tue, 8 Dec 2015",
:keywords "linux x11 swift libx11 xserver xorg",
:keyword-keywords (:linux :x11 :swift :libx11 :xserver :xorg)}
{:title "Hirundo: Comfortably follow Swift Mailing Lists on OSX",
:url "/2016/02/02/hirundo-mac-app-swift-mailing-lists/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Tue, 2 Feb 2016",
:keywords
"swift mac cocoa mailing list swift-dev swift-eveolution swift-users reading macosx",
:keyword-keywords
(:swift
:mac
:cocoa
:mailing
:list
:swift-dev
:swift-eveolution
:swift-users
:reading
:macosx)}
{:title "Three tips for concise Swift using the Guard statement",
:url "/2016/03/29/three-tips-for-clean-swift-code/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Tue, 29 Mar 2016",
:keywords
"swift mac cocoa guard let enum pattern matching patterns",
:keyword-keywords
(:swift :mac :cocoa :guard :let :enum :pattern :matching :patterns)}
{:title "Using Git Hooks to prevent commiting test code",
:url "/2016/04/04/prevent-accidental-test-code-commits/",
:tags "git",
:keyword-tags (:git),
:date "Mon, 4 Apr 2016",
:keywords "git hook commit debug test code",
:keyword-keywords (:git :hook :commit :debug :test :code)}
{:title
"Force optionals in multi-unwrapped \"guard let\" or \"if let\"",
:url
"/2016/04/14/force-optionals-in-guard-or-let-optional-binding/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Thu, 14 Apr 2016",
:keywords
"swift guard let unwrap bind binding unwrapped optional some none optionals",
:keyword-keywords
(:swift
:guard
:let
:unwrap
:bind
:binding
:unwrapped
:optional
:some
:none
:optionals)}
{:title "Raw value initializers for enums with associated types",
:url "/2016/04/23/associated-types-enum-raw-value-initializers/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 23 Apr 2016",
:keywords
"swift optional enum raw value initializers associated type",
:keyword-keywords
(:swift
:optional
:enum
:raw
:value
:initializers
:associated
:type)}
{:title "SwiftWatch",
:url "/2016/04/28/swiftwatch/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Thu, 28 Apr 2016",
:keywords
"swift hackernews reddit designernews lamernews socialnews swiftlang programming community post vote comment",
:keyword-keywords
(:swift
:hackernews
:reddit
:designernews
:lamernews
:socialnews
:swiftlang
:programming
:community
:post
:vote
:comment)}
{:title "Data in Swift 3 parsing a Doom WAD File",
:url "/2016/07/15/swift3-nsdata-data/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Fri, 15 Jul 2016",
:keywords "swift doom wad lumps data nsdata swift3 binary bytes",
:keyword-keywords
(:swift :doom :wad :lumps :data :nsdata :swift3 :binary :bytes)}
{:title "Value Types for Simple Difference Detection",
:url "/2017/09/30/value-types-for-simple-difference-detection/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sat, 30 Sep 2017",
:keywords
"swift value types uitableview uicollectionview valuetypes struct class equatable tuple",
:keyword-keywords
(:swift
:value
:types
:uitableview
:uicollectionview
:valuetypes
:struct
:class
:equatable
:tuple)}
{:title "Taming SourceKitService for Less Xcode Memory Consumption",
:url "/2017/10/08/taming-sourcekitd/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sun, 8 Oct 2017",
:keywords "xcode sourcekit swift SourceKitService",
:keyword-keywords (:xcode :sourcekit :swift :SourceKitService)}
{:title "Patterns for Working With Associated Types",
:url "/2017/12/10/patterns-for-working-with-associated-types/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Sun, 10 Dec 2017",
:keywords
"swift protocol protocols associated associatedtype typealias pattern pat",
:keyword-keywords
(:swift
:protocol
:protocols
:associated
:associatedtype
:typealias
:pattern
:pat)}
{:title "Useful Optional Extensions",
:url "/2018/01/10/optional-extensions/",
:tags "swift cocoa ios",
:keyword-tags (:swift :cocoa :ios),
:date "Wed, 10 Jan 2018",
:keywords "swift protocol optional optionals extensions",
:keyword-keywords
(:swift :protocol :optional :optionals :extensions)}
{:title "Expanding Swift's Reach",
:url "/2018/05/03/expanding-swifts-reach/",
:tags "swift linux",
:keyword-tags (:swift :linux),
:date "Thu, 3 April 2018",
:keywords "swift linux server opensource",
:keyword-keywords (:swift :linux :server :opensource)}
{:title "An interactive Git Status client, written in C",
:url "/2019/01/24/interactive-git-status-written-in-c/",
:tags "c linux",
:keyword-tags (:c :linux),
:date "Thu, 24 Jan 2019",
:keywords "c linux macos ncurses git libgit",
:keyword-keywords (:c :linux :macos :ncurses :git :libgit)}),
:tags
"benedikt, c, clojure, clojurescript, cocoa, html, ios, javascript, libx11, linux, mac, objective-c, photodesk, research, stylemac, swift, terhechte, x11, xorg, xserver",
:type :post,
:keywords "linux x11 swift libx11 xserver xorg",
:title "Swift Package Manager: Create and Use a X11 package on Linux",
:author "Benedikt Terhechte",
:summary
"A tutorial on how to create a Swift Package for X11 on Linux and use it to write a simple X11 app",
:feature-image
"/img-content/2015-12-08-swift-ubuntu-x11-window-app-feature-image.jpg",
:categories
({:tag "blog", :url "/tags/blog/index.html", :count 3}
{:tag "c", :url "/tags/c/index.html", :count 1}
{:tag "clojure", :url "/tags/clojure/index.html", :count 4}
{:tag "cocoa", :url "/tags/cocoa/index.html", :count 20}
{:tag "emacs", :url "/tags/emacs/index.html", :count 1}
{:tag "entrepeneurship",
:url "/tags/entrepeneurship/index.html",
:count 1}
{:tag "git", :url "/tags/git/index.html", :count 1}
{:tag "ios", :url "/tags/ios/index.html", :count 21}
{:tag "linux", :url "/tags/linux/index.html", :count 3}
{:tag "objective-c", :url "/tags/objective-c/index.html", :count 2}
{:tag "opinion", :url "/tags/opinion/index.html", :count 1}
{:tag "postgresql", :url "/tags/postgresql/index.html", :count 1}
{:tag "swift", :url "/tags/swift/index.html", :count 23}),
:url "/2015/12/08/swift-ubuntu-x11-window-app/",
:options "toc:nil",
:blog-index nil,
:watching nil,
:site-title "Appventure",
:keyword-keywords (:linux :x11 :swift :libx11 :xserver :xorg)}
[{:keyword-tags (:swift :linux),
:tags "swift linux",
:date "Tue, 8 Dec 2015",
:footnotes nil,
:meta
{:feature-image
"/img-content/2015-12-08-swift-ubuntu-x11-window-app-feature-image.jpg",
:title
"Swift Package Manager: Create and Use a X11 package on Linux",
:keyword-tags (:swift :linux),
:tags "swift linux",
:keyword-keywords (:linux :x11 :swift :libx11 :xserver :xorg),
:keywords "linux x11 swift libx11 xserver xorg",
:summary
"A tutorial on how to create a Swift Package for X11 on Linux and use it to write a simple X11 app",
:description
"A tutorial on how to create a Swift Package for X11 on Linux and use it to write a simple X11 app",
:options "toc:nil"},
:content
"<!-- #+feature-image: /img-content/2015-12-08-swift-ubuntu-x11-window-app-feature-image.jpg -->\n\n<h6><a href=\"http://swift.gg/2016/01/13/swift-ubuntu-x11-window-app/\">This post is also available in <b>🇨🇳Chinese</b></a><span> Thanks to </span><a href=\"http://swift.gg/tags/APPVENTURE/\">SwiftGG</a></h6>\n\n<p>\nNow that Swift is open source, many interested users might be installing and testing it on their Linux systems. However, currently the Foundation framework is still very much a work-in-progress so if you're interested in developing more than a simple shell app, you'll need to link against existing Linux libraries like GTK, Cairo, or libpng in order to gain access to useful functionality.\n</p>\n\n<p>\nI just finished implementing a simple Swift app which links against <code>X11</code>, the most basic Unix UI library <sup><a id=\"fnr.1\" class=\"footref\" href=\"#fn.1\">1</a></sup>. In this short tutorial, I'll show how to write a simple X11 app, and how you can utilize this to link against other libraries.\n</p>\n\n<p>\nIn the process, we'll also use the new Swift package manager to create a simple re-usable package for the X11 library.\n</p>\n\n<p>\nHere's a screenshot of the finished app in action<sup><a id=\"fnr.2\" class=\"footref\" href=\"#fn.2\">2</a></sup>:\n</p>\n\n\n<div class=\"figure\">\n<p><img src=\"https://raw.githubusercontent.com/terhechte/swift-x11-example/master/screenshot.png\" alt=\"screenshot.png\" />\n</p>\n</div>\n\n<div id=\"outline-container-orgb06c639\" class=\"outline-2\">\n<h2 id=\"orgb06c639\"><span class=\"section-number-2\">1</span> Swift Packages</h2>\n<div class=\"outline-text-2\" id=\"text-1\">\n<p>\nBefore we write our actual X11 app, we need to <a href=\"https://github.com/apple/swift-package-manager\">define a Swift package</a> which defines the links against the X11 library. Once this is done, we can easily share this package with other users, or re-use it in other projects. We have to differentiate between defining a package and using a package. Let's start with the first and then see how we can use that package.\n</p>\n</div>\n\n<div id=\"outline-container-orgb82bdca\" class=\"outline-3\">\n<h3 id=\"orgb82bdca\"><span class=\"section-number-3\">1.1</span> Defining a package</h3>\n<div class=\"outline-text-3\" id=\"text-1-1\">\n<p>\nCreate a new folder which will host our package. Since we're linking against a C library, <a href=\"https://github.com/apple/swift-package-manager/blob/master/Documentation/SystemModules.md\">we follow the guidance of the Swift Package Manager documentation and prefix our library with the letter <b>C</b></a><sup><a id=\"fnr.3\" class=\"footref\" href=\"#fn.3\">3</a></sup>. We'll name our library <code>CX11.swift</code>\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-bash\">mkdir CX11.swift\n</pre>\n</div>\n\n<p>\nIn our case, we want to link against an existing C API and we do not intend to write any Swift wrapper code. Linking against C libraries and headers is achieved via the <code>module.modulemap</code> file which contains the necessary directives for the Swift compiler to perform the correct linking. <a href=\"http://clang.llvm.org/docs/Modules.html\">The documentation for the modulemap syntax can be found here</a>. We create the module map file, and edit the contents (via an editor of your choice, in this case we're using <code>nano</code>):\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-bash\">touch CX11.swift/module.modulemap\nnano CX11.swift/module.modulemap\n</pre>\n</div>\n\n<p>\nX11 is a huge library with a lot of functionality. You can see the contents if you head over to <code>/usr/include/X11</code>. For our example, we don't need to include all the header files in there, instead we really only need two of them: <code>Xlib.h</code> and <code>X.h</code>. For different other libraries, you may need to include more headers. There is a convenient way to include all the headers in a directory which I'll point out below. Apart from including the headers, we also need to tell Swift which library to link against. We're using the <code>link</code> keyword for that. Our <code>modulemap</code> looks like this:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-scala\">module CX11 [system] {\n module Xlib {\n\t header \"/usr/include/X11/Xlib.h\"\n }\n module X {\n\t header \"/usr/include/X11/X.h\"\n }\n link \"X11\"\n}\n</pre>\n</div>\n\n<p>\nWe're naming our module <code>CX11</code> and we're creating two submodules. One for the Xlib and one for X. Each submodule defines the header it needs to import. Finally, we're linking against libx11 via the <code>link</code> statement.\n</p>\n\n<p>\nBut what if we have not just one header file, but many of them. Module maps allow you to define an umbrella header or an umbrella directory.\n</p>\n\n<p>\n<b>Umbrella Header</b>\nThis is a header that contains just references to other headers (via <code>#include</code>) commands. A good example is <code><Cocoa/Cocoa.h></code> or <code><Foundation/Foundation.h></code> or <code><gtk/gtk.h></code>.\nUmbrella headers are defined via the umbrella keyword: \n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-scala\">umbrella header \"/usr/include/gtk/gtk.h\"\n</pre>\n</div>\n\n<p>\n<b>Umbrella Directory</b>\nSometimes you have a directory of headers but no umbrella header. In this case you just point Swift to the directory of headers:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-scala\">umbrella \"/usr/include/X11/\"\n</pre>\n</div>\n\n<p>\nIn addition to the modulemap, we'll also need a <b>Package.swift</b> file, otherwise building will fail. This file can be empty though:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-bash\">touch CX11.swift/Package.swift\n</pre>\n</div>\n\n<p>\nThe Swift package manager uses Git and Git Tags in order to manage packages. So before we're done, we need to create a Git repository for our Package, add all the files, and create a version tag. This is fairly easy though:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-bash\"><span style=\"font-weight: bold;\">cd</span> CX11.swift\ngit init\ngit add .\ngit commit -m <span style=\"font-style: italic;\">\"Initial Import\"</span>\ngit tag 1.0.0\n<span style=\"font-weight: bold;\">cd</span> ..\n</pre>\n</div>\n\n<p>\nThe commands above go into the folder, create a new Git repository, add all the files to it, create a first commit, and finally add a version tag (<code>1.0.0</code>) for this commit.\n</p>\n\n<p>\nThat's it, our package is defined, but how do we use it?\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-org88e6e92\" class=\"outline-3\">\n<h3 id=\"org88e6e92\"><span class=\"section-number-3\">1.2</span> Using Packages</h3>\n<div class=\"outline-text-3\" id=\"text-1-2\">\n<p>\nIn order to use a package, we need to define a <code>Package.swift</code> file which will tell Swift which packages we intend to import for our project. But first, we need to create a directory for our project.\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-bash\">mkdir swift-x11\ntouch swift-x11/Package.swift\ntouch swift-x11/main.swift\n</pre>\n</div>\n\n<p>\nKeep in mind that (for this example to work) the <code>swift-x11</code> folder has to be next to the <code>CX11.swift</code> folder. I.e.:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-bash\">ls -l\nCX11.swift\nswift-x11\n</pre>\n</div>\n\n<p>\nBefore we start writing the actual Swift code to interact with X11, we need to tell our <code>swift-x11</code> project how to import the <code>CX11</code> package. This is done, as explained below, via the <code>swift-x11/Package.swift</code>:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">import PackageDescription\n\nlet package = Package(\n dependencies: [\n .Package(url: \"../CX11.swift\", majorVersion: 1)\n ]\n)\n</pre>\n</div>\n\n<p>\nThis tells Swift that the package we intend to use is located in the <code>../CX11.swift</code> folder.\n</p>\n\n<p>\nThe <code>url</code> (as the name suggests) does not need to be a local one. <a href=\"https://github.com/terhechte/CX11.swift\">I've uploaded my own CX11.swift to GitHub</a>, and you could alternatively link directly to the GitHub version as follows:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">import PackageDescription\n\nlet package = Package(\n dependencies: [\n .Package(url: \"https://github.com/terhechte/CX11.swift.git\", majorVersion: 1)\n ]\n)\n</pre>\n</div>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-org3b4c874\" class=\"outline-2\">\n<h2 id=\"org3b4c874\"><span class=\"section-number-2\">2</span> Using X11</h2>\n<div class=\"outline-text-2\" id=\"text-2\">\n<p>\nNow that we defined an X11 package, and set up the package manager definitions, we want to write our first X11 application. \n</p>\n\n<p>\nOne issue which I could not solve is that macro definitions in the X11 header file are not imported into Swift. The <code>Xlib.h</code> defines many shortcut macros like:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-C\"><span style=\"font-weight: bold;\">#define</span> <span style=\"font-weight: bold;\">RootWindow</span>(<span style=\"font-weight: bold; font-style: italic;\">dpy</span>, <span style=\"font-weight: bold; font-style: italic;\">src</span>) (ScreenOfDisplay(dpy, src)->root)\n<span style=\"font-weight: bold;\">#define</span> <span style=\"font-weight: bold;\">ScreenOfDisplay</span>(<span style=\"font-weight: bold; font-style: italic;\">dpy</span>, <span style=\"font-weight: bold; font-style: italic;\">scr</span>)(&((<span style=\"font-weight: bold; text-decoration: underline;\">_XPrivDisplay</span>)dpy)->screens[scr])\n</pre>\n</div>\n\n<p>\nAs these were not imported, I decided instead to always write out the contents of the macro. All the code below has to be put into the <code>main.swift</code> file. <a href=\"https://github.com/terhechte/swift-x11-example\">You can also see the finished version here on GitHub</a>. Please note that this is a simple and non-memory-safe example. This mostly serves to explain how to use C libraries under Linux. Also, my X11 knowledge is rather limited. I did Linux X11 programming more than 10 years ago and forgot most of it, so there may be factual errors in the explanation below. If you find them, <a href=\"https://github.com/terhechte/appventure-blog/tree/master/resources/posts/2015-12-08-swift-ubuntu-x11-window-app.org\">feel free to open a PR on this repo :)</a>\n</p>\n\n<p>\nWe begin by importing the <code>CX11</code> library which we defined above:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">import CX11.Xlib\nimport CX11.X\n</pre>\n</div>\n</div>\n\n<div id=\"outline-container-org9bffe04\" class=\"outline-3\">\n<h3 id=\"org9bffe04\"><span class=\"section-number-3\">2.1</span> Setting up state</h3>\n<div class=\"outline-text-3\" id=\"text-2-1\">\n<p>\nAfter this, we have to define a couple of variables. \n</p>\n\n<ul class=\"org-ul\">\n<li>We need the X11 display (i.e. roughly speaking the X11 server connection). This will be the <code>d</code> variable</li>\n\n<li>We need a placeholder for the X11 window which we create. This will be the <code>w</code> variable.</li>\n\n<li>We also need to set aside a bit of memory for the X11 Server to store X11 input events. This is the <code>e</code> variable.</li>\n\n<li>We should also already store the text which we want to display in our window. This is the <code>msg</code> variable</li>\n\n<li>We need a place to store the current X11 screen (a X11 Display can have multiple screens). This will be the <code>s</code> variable.</li>\n\n<li>Finally, we need a pointer to the X11 root window, which houses the other windows. This is the <code>rootWindow</code> variable.</li>\n</ul>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">// The X11 Display\nvar d: _XPrivDisplay\n\n// The window which we will create\nvar w: Window\n\n// The events which X11 generates for us will be stored here\nvar e = UnsafeMutablePointer<_XEvent>.alloc(1)\n\n// The text to display\nvar msg = \"Hello Swift World\"\n\n// A pointer to the current X11 Screen\nvar s: UnsafeMutablePointer<Screen>\n</pre>\n</div>\n\n<p>\nNow that we defined our variables, we need to open our connection to the X11 Server. However, as users can also run this app when no X server is running (i.e. in console mode) we need to make sure that the connection succeeded:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">d = XOpenDisplay(nil)\nif d == nil {\n\tfatalError(\"cannot open display\")\n}\n</pre>\n</div>\n\n<p>\nAfter we opened the display, we'd like to get the current default screen as well as the current root window. The <code>RootWindow</code> macro is not available<sup><a id=\"fnr.4\" class=\"footref\" href=\"#fn.4\">4</a></sup>, so we will access the memory section of the <code>C struct</code> directly. However, as the current screen <code>s</code> is a <code>UnsafeMutablePointer</code>, we need to add the <code>memory</code> property in order to access the <code>root</code> instance.\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">// Get the default screen\ns = XDefaultScreenOfDisplay(d)\n\n// And the current root window on that screen\nlet rootWindow = s.memory.root\n</pre>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-org53299ea\" class=\"outline-3\">\n<h3 id=\"org53299ea\"><span class=\"section-number-3\">2.2</span> Creating a Window</h3>\n<div class=\"outline-text-3\" id=\"text-2-2\">\n<p>\nFinally we have everything in place to create our own window and place it on the screen. We're <a href=\"http://linux.die.net/man/3/xcreatesimplewindow\">using the <code>XCreateSimpleWindow</code> function for that</a>. The function has the following parameters:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-C\"><span style=\"font-weight: bold;\">XCreateSimpleWindow</span>(<span style=\"font-weight: bold; text-decoration: underline;\">Display</span> *<span style=\"font-weight: bold; font-style: italic;\">display</span>, <span style=\"font-weight: bold; text-decoration: underline;\">Window</span> <span style=\"font-weight: bold; font-style: italic;\">parent</span>, <span style=\"font-weight: bold; text-decoration: underline;\">int</span> <span style=\"font-weight: bold; font-style: italic;\">x</span>, <span style=\"font-weight: bold; text-decoration: underline;\">int</span> <span style=\"font-weight: bold; font-style: italic;\">y</span>, \n <span style=\"font-weight: bold; text-decoration: underline;\">unsigned</span> <span style=\"font-weight: bold; text-decoration: underline;\">int</span> <span style=\"font-weight: bold; font-style: italic;\">width</span>, <span style=\"font-weight: bold; text-decoration: underline;\">unsigned</span> <span style=\"font-weight: bold; text-decoration: underline;\">int</span> <span style=\"font-weight: bold; font-style: italic;\">height</span>, <span style=\"font-weight: bold; text-decoration: underline;\">unsigned</span> <span style=\"font-weight: bold; text-decoration: underline;\">int</span> <span style=\"font-weight: bold; font-style: italic;\">border_width</span>, \n <span style=\"font-weight: bold; text-decoration: underline;\">unsigned</span> <span style=\"font-weight: bold; text-decoration: underline;\">long</span> <span style=\"font-weight: bold; font-style: italic;\">border</span>, <span style=\"font-weight: bold; text-decoration: underline;\">unsigned</span> <span style=\"font-weight: bold; text-decoration: underline;\">long</span> <span style=\"font-weight: bold; font-style: italic;\">background</span>);\n</pre>\n</div>\n\n<p>\n<code>border</code> and <code>background</code> are color values. In order to not think about color creation, we will simply pass in a reference to the default black and white colors which are defined on the current screen. We have to use the <code>.memory</code> property again.\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">// Create our window\nw = XCreateSimpleWindow(d, rootWindow, 10, 10, 200, 100, 1, \n s.memory.black_pixel, s.memory.white_pixel)\n</pre>\n</div>\n\n<p>\nThis will create a new window on the <code>rootWindow</code> position 10/10 of width 200 and height 100. The borders will be black, the background will be white.\n</p>\n</div>\n</div>\n\n<div id=\"outline-container-orgdfdcf79\" class=\"outline-3\">\n<h3 id=\"orgdfdcf79\"><span class=\"section-number-3\">2.3</span> Input Events</h3>\n<div class=\"outline-text-3\" id=\"text-2-3\">\n<p>\nOf course, we also want to receive input events from the Xserver. In our case we'd like to know when the window is being displayed so that we can draw it, and we'd like to know when the user pressed a key so that we can quit the app. The first event is the <code>Expose</code> event, the second one is the <code>KeyPress</code> event. <a href=\"http://tronche.com/gui/x/xlib/event-handling/XSelectInput.html\">Receiving events works by registering event masks via the <code>XSelectInput</code> function</a>:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">XSelectInput(d, w, ExposureMask | KeyPressMask)\n</pre>\n</div>\n\n<p>\nNow that we created our window, we want to display it. <a href=\"http://tronche.com/gui/x/xlib/window/XMapWindow.html\">This is done via the <code>XMapWindow</code> function</a>:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\">XMapWindow(d, w)\n</pre>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-orgcad6c1b\" class=\"outline-3\">\n<h3 id=\"orgcad6c1b\"><span class=\"section-number-3\">2.4</span> Event Loop</h3>\n<div class=\"outline-text-3\" id=\"text-2-4\">\n<p>\nFinally we do have everything in place to run our event loop while the window is being displayed. For this, we're using a <code>while</code> loop which continously pulls the <code>XNextEvent</code> function to get new X11 events. Then, we'll test the event to see whether it is a <code>Expose</code> or a <code>KeyPress</code> event<sup><a id=\"fnr.5\" class=\"footref\" href=\"#fn.5\">5</a></sup>. We're testing the events using the swift <code>switch</code> statement:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-swift\" id=\"org99205bd\">loop: while true {\n\n // Wait for the next event\n XNextEvent(d, e)\n\n switch e.memory.type {\n // The window has to be drawn\n case Expose:\n // draw a small black rectangle\n XFillRectangle(d, w, s.memory.default_gc, 20, 20, 10, 10) \n // draw the text\n XDrawString(d, w, s.memory.default_gc, 10, 70, msg, Int32(msg.characters.count)) \n\n // The user did press a key\n case KeyPress:\n break loop\n\n // We never signed up for this event\n default: fatalError(\"Unknown Event\")\n\n }\n}\n</pre>\n</div>\n\n<p>\nOur <code>e</code> event structure is - again - a <code>UnsafeMutablePointer</code>, so we have to access the actual structure via the <code>memory</code> property. The <code>Expose</code> event means that the window is visible, so we have to re-draw it. Our drawing is very simple: We're using the <code>XFillRectangle</code> call to draw a small black box, and the <code>XDrawString</code> call to draw our initial <code>msg</code> text in the window at position 10, 70. Please note that I don't know whether X11 expects unicode or ascii, so the <code>Int32(msg.characters.count)</code> is probably wrong, but it works in this example.\n</p>\n\n<p>\nThe other event, <code>KeyPress</code> allows us to break the outer <code>while</code> loop and quit the app once the user enters a key.\n</p>\n</div>\n</div>\n</div>\n\n<div id=\"outline-container-orgfbf3e99\" class=\"outline-2\">\n<h2 id=\"orgfbf3e99\"><span class=\"section-number-2\">3</span> Running It</h2>\n<div class=\"outline-text-2\" id=\"text-3\">\n<p>\nTo use this, simply check out the repo (preferrably on Linux) and do the following in the folder:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-bash\">swift build\n</pre>\n</div>\n\n<p>\nThis will clone the <code>CX11.swift</code> package and build the binary in the <code>.build/debug</code> folder.\n</p>\n\n<p>\nRun it via:\n</p>\n\n<div class=\"org-src-container\">\n<pre class=\"src src-bash\">.build/debug/swift-x11-example\n</pre>\n</div>\n\n<p>\nThis will execute the binary, and a small X11 Window should appear on your desktop:\n</p>\n\n\n<div class=\"figure\">\n<p><img src=\"https://raw.githubusercontent.com/terhechte/swift-x11-example/master/screenshot.png\" alt=\"screenshot.png\" />\n</p>\n</div>\n</div>\n</div>\n\n\n<div id=\"outline-container-orgcfade62\" class=\"outline-2\">\n<h2 id=\"orgcfade62\"><span class=\"section-number-2\">4</span> Conclusion</h2>\n<div class=\"outline-text-2\" id=\"text-4\">\n<p>\nThis was a very simple example of how to use Swift under Linux to write an X11 app. This will also work for all kind of other apps using other libraries, of course. This tutorial also explained how the new Swift Package manager works by creating and using a simple <code>X11</code> package.\n</p>\n\n<p>\n<a href=\"https://github.com/terhechte/swift-x11-example\">The full example of the X11 app can be found here.</a>\n</p>\n\n<p>\n<a href=\"https://github.com/terhechte/CX11.swift\">The full example of the X11 package can be found here.</a>\n</p>\n</div>\n</div>\n<div id=\"footnotes\">\n<h2 class=\"footnotes\">Footnotes: </h2>\n<div id=\"text-footnotes\">\n\n<div class=\"footdef\"><sup><a id=\"fn.1\" class=\"footnum\" href=\"#fnr.1\">1</a></sup> <div class=\"footpara\">I started with GTK3, but could not get that to work</div></div>\n\n<div class=\"footdef\"><sup><a id=\"fn.2\" class=\"footnum\" href=\"#fnr.2\">2</a></sup> <div class=\"footpara\">Spectacular, isn't it ;)</div></div>\n\n<div class=\"footdef\"><sup><a id=\"fn.3\" class=\"footnum\" href=\"#fnr.3\">3</a></sup> <div class=\"footpara\">\"The convention we hope the community will adopt is to prefix such modules with C and to camelcase the modules as per Swift module name conventions. Then the community is free to name another module simply JPEG which contains more “Swifty” function wrappers around the raw C interface.\"</div></div>\n\n<div class=\"footdef\"><sup><a id=\"fn.4\" class=\"footnum\" href=\"#fnr.4\">4</a></sup> <div class=\"footpara\">See above, I couldn't figure out why</div></div>\n\n<div class=\"footdef\"><sup><a id=\"fn.5\" class=\"footnum\" href=\"#fnr.5\">5</a></sup> <div class=\"footpara\">Remember those are the only events we signed up for</div></div>\n\n\n</div>\n</div>",
:keywords "linux x11 swift libx11 xserver xorg",
:title
"Swift Package Manager: Create and Use a X11 package on Linux",
:filename "2015-12-08-swift-ubuntu-x11-window-app.org",
:id -69223385,
:url "/2015/12/08/swift-ubuntu-x11-window-app/",
:javadate #inst "2015-12-07T23:00:00.000-00:00",
:keyword-keywords (:linux :x11 :swift :libx11 :xserver :xorg)}]