Skip to content

Instantly share code, notes, and snippets.

@kavanmevada
Last active March 8, 2022 17:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kavanmevada/601527461e7a36bf8eb1c92b4656473b to your computer and use it in GitHub Desktop.
Save kavanmevada/601527461e7a36bf8eb1c92b4656473b to your computer and use it in GitHub Desktop.
kotlin-native-gtk
package sample.GtkHelpers
import kotlinx.cinterop.*
import libgtk3.*
import platform.posix.exit
abstract class Application(application_id: String, gApplicationFlagsNone: GApplicationFlags) {
var builder: CPointer<GtkBuilder>? = null
var application: CPointer<GtkApplication>? = null
abstract fun onActivate(app: CPointer<GtkApplication>)
init {
gtk_application_new(application_id, gApplicationFlagsNone)?.let { application = it }
g_signal_connect_data(application?.reinterpret(), "activate", staticCFunction { app: CPointer<GtkApplication>, data: COpaquePointer? ->
data?.asStableRef<(CPointer<GtkApplication>) -> Unit>()?.get()?.let { it(app) }
null as COpaquePointer?
}.reinterpret(), StableRef.create(::onActivate).asCPointer(), null, 0u)
}
fun run(args: Array<String>) {
memScoped {
val status = g_application_run(application?.reinterpret(), args.size, args.map { it.cstr.ptr }.toCValues())
g_object_unref(application)
exit(status)
}
}
fun setContentView(templatePath: String) {
builder = gtk_builder_new_from_file(templatePath)
val builderObjs = gtk_builder_get_objects(builder)
val firstObj = g_slist_nth_data(builderObjs, 0)?.reinterpret<CPointerVar<GtkWidget>>()
gtk_application_add_window(application, firstObj?.reinterpret())
gtk_widget_show(firstObj?.reinterpret())
}
}
package sample
import kotlinx.cinterop.*
import libgtk3.*
import platform.posix.*
class AsyncTask<T, K>(input: T?, function: (T) -> K, function2: (T, K) -> Unit) {
val functionAsInput = StableRef.create((input to function) to function2).asCPointer()
val memoryAlloc = memScoped {
alloc<pthread_tVar>() to alloc<COpaquePointerVar>()
}
val result get() = memoryAlloc.second
init {
pthread_create(memoryAlloc.first.ptr, null, staticCFunction { pointer: COpaquePointer ->
initRuntimeIfNeeded()
val inputPair
= pointer.asStableRef<Pair<Pair<T, (T) -> K>, (Pair<T, K>) -> Unit>>().get()
val result = inputPair.first.second(inputPair.first.first)
val passDataToUi = StableRef.create((inputPair.first.first to result) to inputPair.second).asCPointer()
gdk_threads_add_idle(staticCFunction { pointer: COpaquePointer ->
val inputPair2
= pointer.asStableRef<Pair<Pair<T, K>, (T, K) -> Unit>>().get()
inputPair2.second(inputPair2.first.first, inputPair2.first.second)
null as COpaquePointer?
}.reinterpret(), passDataToUi)
return@staticCFunction StableRef.create(result as Any).asCPointer()
}.reinterpret(), functionAsInput)
}
}
build {
//Generate Resource File
mkdir("$buildDir/g_resources/")
ext.outputFile = file("$buildDir/g_resources/glibresources.gresource.xml")
outputFile.text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
outputFile.text += "\n<gresources>"
kotlin.linuxX64("linux").compilations.main.cinterops {
libgtk3 {
includeDirs "/usr/include/glib-2.0",
"/usr/lib64/glib-2.0/include",
"/usr/include/json-glib-1.0",
"/usr/include/gtk-3.0",
"/usr/include/pango-1.0",
"/usr/include/harfbuzz",
"/usr/include/cairo",
"/usr/include/gdk-pixbuf-2.0",
"/usr/include/atk-1.0",
"/usr/include/curl"
includeDirs "$buildDir/g_resources"
}
}
kotlin.sourceSets.linuxMain.resources.srcDirs.each { src ->
outputFile.text += "\n <gresource prefix=\"/org/gtk/example\">"
fileTree("${src.path}/layout").filter { it.name.endsWith('.ui') }.files.each { file ->
outputFile.text += "\n <file>layout/${file.name}</file>"
copy {
from file.path
into "$buildDir/g_resources/layout"
}
}
outputFile.text += "\n </gresource>"
outputFile.text += "\n <gresource prefix=\"/org/gtk/example/\">"
fileTree("${src.path}/raw").filter { it.isFile() }.files.each { file ->
outputFile.text += "\n <file>raw/${file.name}</file>"
copy {
from file.path
into "$buildDir/g_resources/raw"
}
}
outputFile.text += "\n </gresource>"
}
outputFile.text += "\n</gresources>"
exec {
workingDir "$buildDir/g_resources"
executable 'glib-compile-resources' args "glibresources.gresource.xml", "--generate-source", "--target=glibresources.c"
}
exec {
workingDir "$buildDir/g_resources"
executable 'glib-compile-resources' args "glibresources.gresource.xml", "--generate-header", "--target=glibresources.h"
}
exec {
workingDir "$buildDir/g_resources"
executable 'bash' args '-c', 'sed -i -e "s:gio.h>:gio.h>\\n#include \\"glibresources.h\\":" glibresources.c'
}
exec {
workingDir "$buildDir/g_resources"
executable 'gcc' args '-c', "-I$buildDir/g_resources", '-c', "-I/usr/include/glib-2.0", '-c', "-I/usr/lib64/glib-2.0/include", 'glibresources.c', '-o', 'glibresources.o'
}
exec {
workingDir "$buildDir/g_resources"
executable 'ar' args 'rcs', 'glibresources.a', 'glibresources.o'
}
}
package sample
import kotlinx.cinterop.*
import libgtk3.*
import platform.posix.*
fun curl_read_all_content(url: String) : String? {
initRuntimeIfNeeded()
val memory = StringBuilder()
curl_global_init(CURL_GLOBAL_ALL)
val curl = curl_easy_init()
curl_easy_setopt(curl, CURLOPT_URL, url)
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, staticCFunction {
contents: CPointer<ByteVar>?, size: size_t, nmemb: size_t, userp : COpaquePointer? ->
initRuntimeIfNeeded()
val mem = userp?.asStableRef<StringBuilder>()?.get()
mem?.append(contents?.toKString())
return@staticCFunction size * nmemb
})
curl_easy_setopt(curl, CURLOPT_WRITEDATA, StableRef.create(memory).asCPointer())
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0")
curl_easy_perform(curl)
curl_easy_cleanup(curl)
curl_global_cleanup()
return memory.toString()
}
headers = glibresources.h json-glib/json-glib.h gtk/gtk.h curl.h
staticLibraries = glibresources.a
libraryPaths = /run/media/kavan/67A4-0823/kotlin-native/work-projects/curl/build/g_resources
linkerOpts.linux = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu -lglib-2.0 -lgdk-3 -lgtk-3 -lgio-2.0 -lgobject-2.0 -ljson-glib-1.0 -lcurl
package sample
import kotlinx.cinterop.*
import libgtk3.*
import platform.posix.*
fun CPointer<GtkWidget>?.connect(name: String,function: () -> Unit) {
g_signal_connect_data(this, name, staticCFunction { pointer: COpaquePointer?, data: gpointer? ->
data?.asStableRef<() -> Unit>()?.get()?.let { it() }
null as COpaquePointer?
}.reinterpret(), StableRef.create(function).asCPointer(), null, 0U)
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkApplicationWindow">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
</child>
</object>
</interface>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment