# # Licensed under the GNU Lesser General Public License Version 3 # # This library is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the license, or # (at your option) any later version. # # This software is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this library. If not, see . ############################################# ### Definitions for wrapping Gtk+ ########### ############################################# # must start with wrap wrap: glib file: GLib-2.0.gir file: GModule-2.0.gir addAliases: start public alias uint uid_t; public alias int pid_t; version( Windows ) { alias int glong; alias uint gulong; } else version( X86_64 ) { alias long glong; alias ulong gulong; } else { alias int glong; alias uint gulong; } version( Windows ) enum _utfPostfix = "_utf8"; else enum _utfPostfix = ""; version (Windows) { private import core.stdc.stdio; static if( !is(typeof(fdopen(0, null))) ) { extern (C) FILE* fdopen(int, char*); } } static if ( __VERSION__ >= 2063 ) { public import std.typecons : scoped; template Scoped(T) { alias typeof(scoped!T(cast(typeof(T.tupleof[0]))null)) Scoped; } } else { // I'm getting the following error on the older dmd versions: // this for Scoped_store needs to be type Scoped not type inout(Scoped!(T)). // Unlike the phobos version this does use GC alocated memory for the object. // Within GtkD this is used to make sure destroy is called on the object // so it releases the resources it holds. struct Scoped(T) { T payload; alias payload this; @disable this(); @disable this(this); ~this() { .destroy(payload); } } auto scoped(T, Args...)(auto ref Args args) if (is(T == class)) { Scoped!(T) result = void; result.payload = new T(args); return result; } } /** * Get the length of a zero terminated array. */ size_t getArrayLength(T)(T* arr) { size_t len; for ( ; arr[len]; len++ ){} return len; } unittest { assert(getArrayLength("aaaaaaaaa\0".ptr) == 9); } Type* gMalloc(Type)() { import glib.c.functions; return cast(Type*)g_malloc0(Type.sizeof); } alias void* GIConv; addAliases: end addEnums: start enum GPriority { HIGH = -100, DEFAULT = 0, HIGH_IDLE = 100, DEFAULT_IDLE = 200, LOW = 300 } addEnums: end struct: Array class: ArrayG struct: Base64 move: base64_decode_step Base64 decode_step move: base64_decode_inplace Base64 decode_inplace noCode: decode_step array: decode_inplace Return out_len code: start /** * Incrementally decode a sequence of binary data from its Base-64 stringified * representation. By calling this function multiple times you can convert * data in chunks to avoid having to have the full encoded data in memory. * * The output buffer must be large enough to fit all the data that will * be written to it. Since base64 encodes 3 bytes in 4 chars you need * at least: (@len / 4) * 3 + 3 bytes (+ 3 may be needed in case of non-zero * state). * * Params: * inn = binary input data * len = max length of @in data to decode * output = output buffer * state = Saved state between steps, initialize to 0 * save = Saved state between steps, initialize to 0 * * Return: The number of bytes of output that was written * * Since: 2.12 */ public static size_t decodeStep(string inn, ref ubyte[] output, ref int state, ref uint save) { auto p = g_base64_decode_step(Str.toStringz(inn), cast(int)inn.length, cast(char*)output.ptr, &state, &save); return p; } code: end struct: BookmarkFile out: load_from_data_dirs full_path array: set_groups groups length struct: ByteArray class: ByteArray struct: Bytes noCode: new_take noCode: new_static struct: Checksum noCode: get_digest code: start /** * Gets the digest from checksum as a raw binary vector and places it * into buffer. The size of the digest depends on the type of checksum. * * Once this function has been called, the Checksum is closed and can * no longer be updated with update(). * * Params: * buffer = output buffer * digestLen = an inout parameter. The caller initializes it to the size of buffer. * After the call it contains the length of the digest. * * Since: 2.16 */ public void getDigest(ref ubyte[] buffer) { size_t digestLen = buffer.length; g_checksum_get_digest(gChecksum, buffer.ptr, &digestLen); buffer = buffer[0 .. digestLen]; } code: end struct: ConstructionException namespace: code: start class ConstructionException : Exception { this(string message) { super(message); } override string toString() { return "Construction failure, " ~ msg; } } code: end struct: DateTime structWrap: gpointer DateTime noCode: new_now_utc noCode: new_now_local noCode: new_from_unix_local noCode: new_from_unix_utc noCode: new_from_timeval_local noCode: new_from_timeval_utc noCode: new_local noCode: new_utc noCode: hash code: start /** * Creates a DateTime corresponding to the given Unix time t * Unix time is the number of seconds that have elapsed since 1970-01-01 * 00:00:00 UTC, regardless of the local time offset. * * This call can fail (ConstructionException) if t represents a time outside * of the supported range of GDateTime. * You should release the return value by calling unref() * when you are done with it * * Params: * t = the Unix time * utc = If true use utc else use the local timezone. * * Throws: ConstructionException GTK+ fails to create the object. * * Since: 2.26 */ public this (long t, bool utc = true) { GDateTime* p; if ( utc ) { p = g_date_time_new_from_unix_utc(t); } else { p = g_date_time_new_from_unix_local(t); } if(p is null) { throw new ConstructionException("null returned by g_date_time_new_from_unix_local(t)"); } this(cast(GDateTime*) p); } /** * Creates a DateTime corresponding to the given TimeVal tv. * The time contained in a TimeVal is always stored in the form of * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the * local time offset. * * This call can fail (ConstructionException) if tv represents a time outside * of the supported range of DateTime. * You should release the return value by calling unref() * when you are done with it. * * Params: * tv = a GTimeVal * utc = If true use utc else use the local timezone. * * Throws: ConstructionException GTK+ fails to create the object. * * Since: 2.26 */ public this (ref GTimeVal tv, bool utc = true) { GDateTime* p; if ( utc ) { p = g_date_time_new_from_timeval_utc(&tv); } else { p = g_date_time_new_from_timeval_local(&tv); } if(p is null) { throw new ConstructionException("null returned by g_date_time_new_from_timeval_local((tv is null) ? null : tv.getTimeValStruct())"); } this(cast(GDateTime*) p); } /** */ override bool opEquals(Object rhs) { DateTime date = cast(DateTime)rhs; if ( date is null ) return false; return equal(this, date) != 0; } /** */ override int opCmp(Object rhs) { DateTime date = cast(DateTime)rhs; if ( date is null ) return int.min; return compare(this, date); } /** */ override nothrow @trusted hash_t toHash() { return hash(); } /** * Hashes datetime into a guint, suitable for use within GHashTable. * Since 2.26 * Params: * datetime = a GDateTime * Returns: a guint containing the hash */ public nothrow @trusted uint hash() { try { return g_date_time_hash(gDateTime); } catch(Exception e) { return 0; } } code: end struct: Dir class: Directory struct: Error class: ErrorG move: propagate_error Error move: set_error_literal Error out: set_error_literal err out: propagate_error dest struct: GException namespace: import: glib.ErrorG import: glib.Str code: start class GException : Exception { ErrorG error; this(ErrorG error) { super( Str.toString(error.getErrorGStruct().message) ); this.error = error; } } code: end struct: GLib namespace: code: start static import glib.Version; deprecated("moves to the glib.Version module") alias glib.Version.Version Version; code: end struct: HashTable class: HashTable struct: Hmac noCode: get_digest move: compute_hmac_for_data Hmac move: compute_hmac_for_string Hmac array: compute_hmac_for_data data length array: compute_hmac_for_string str length code: start /** * Gets the digest from checksum as a raw binary array and places it * into buffer. The size of the digest depends on the type of checksum. * * Once this function has been called, the Hmac is closed and can * no longer be updated with update(). * * Params: * buffer = output buffer * * Since: 2.30 */ public void getDigest(ref ubyte[] buffer) { size_t digestLen = buffer.length; g_hmac_get_digest(gHmac, buffer.ptr, &digestLen); buffer = buffer[0 .. digestLen]; } code: end struct: IConv namespace: noStruct: true ref: iconv inbuf out: iconv inbytes_left array: iconv inbuf inbytes_left ref: iconv outbuf out: iconv outbytes_left array: iconv outbuf outbytes_left struct: Idle class: Idle cType: code: start /** Holds all idle delegates */ bool delegate()[] idleListeners; /** our idle ID */ uint idleID; /** * Creates a new idle cycle. * Params: * interval = the idle in milieconds * dlg = the delegate to be executed * fireNow = When true the delegate will be executed emmidiatly */ this(bool delegate() dlg, bool fireNow=false) { idleListeners ~= dlg; idleID = g_idle_add(cast(GSourceFunc)&idleCallback, cast(void*)this); if ( fireNow ) { if ( !dlg() ) { idleListeners.length = 0; } } } /** * Creates a new idle cycle. * Params: * dlg = the delegate to be executed * priority = Priority for the idle function * fireNow = When true the delegate will be executed emmidiatly */ this(bool delegate() dlg, GPriority priority, bool fireNow=false) { idleListeners ~= dlg; idleID = g_idle_add_full(priority, cast(GSourceFunc)&idleCallback, cast(void*)this, null); if ( fireNow ) { if ( !dlg() ) { idleListeners.length = 0; } } } /** */ public void stop() { if ( idleID > 0 ) { g_source_remove(idleID); } idleListeners.length = 0; } /** * Removes the idle from gtk */ ~this() { stop(); } /** * Adds a new delegate to this idle cycle * Params: * dlg = * fireNow = */ public void addListener(bool delegate() dlg, bool fireNow=false) { idleListeners ~= dlg; if ( fireNow ) { if ( !dlg() ) { idleListeners.length = idleListeners.length - 1; } } } /** * The callback execution from glib * Params: * idle = * Returns: */ extern(C) static bool idleCallback(Idle idle) { return idle.callAllListeners(); } /** * Executes all delegates on the execution list * Returns: */ private bool callAllListeners() { bool runAgain = false; int i = 0; while ( i 0 ) --l; return line[0..l]; } extern(C) static void childWatchCallback(int pid, int status, Spawn spawn) { //writefln("Spawn.childWatchCallback %s %s", pid, status); spawn.exitStatus = status; if ( spawn.externalWatch !is null ) { spawn.externalWatch(spawn); } spawn.close(); } public bool endOfOutput() { if ( standardOutput is null ) return true; return feof(standardOutput) != 0; } public bool endOfError() { if ( standardError is null ) return true; return feof(standardError) != 0; } string getOutputString() { return Str.toString(strOutput); } string getErrorString() { return Str.toString(strError); } int getExitStatus() { return exitStatus; } /** * Executes a command synchronasly and * optionally calls delegates for sysout, syserr and end of job * */ public int commandLineSync( ChildWatch externalWatch = null, bool delegate(string) readOutput = null, bool delegate(string) readError = null ) { string commandLine; foreach ( int count, string arg; argv) { if ( count > 0 ) { commandLine ~= ' '; } commandLine ~= arg; } int status = g_spawn_command_line_sync( Str.toStringz(commandLine), &strOutput, &strError, &exitStatus, &error); if ( readOutput != null ) { foreach ( string line ; splitLines(Str.toString(strOutput)) ) { readOutput(line); } } if ( readError != null ) { foreach ( string line ; splitLines(Str.toString(strError)) ) { readError(line); } } if ( externalWatch != null ) { externalWatch(this); } return status; } code: end struct: Str import: core.stdc.stdio import: core.stdc.string import: gobject.c.types code: start /* * Convert C-style 0 terminated string s to char[] string. * copied from phobos */ public static string toString(const(char)* s, size_t len = 0) { if ( s is null ) return cast(string)null; if ( len == 0 ) len = strlen(s); return s[0 .. len].idup; } /* * Convert array of chars s[] to a C-style 0 terminated string. * copied from phobos */ public static char* toStringz(string s) { if ( s is null ) return null; char[] copy; if (s.length == 0) { copy = "\0".dup; } else { // Need to make a copy copy = new char[s.length + 1]; copy[0..s.length] = s[]; copy[s.length] = 0; } return copy.ptr; } /** */ public static char** toStringzArray(string[] args) { if ( args is null ) { return null; } char** argv = (new char*[args.length]).ptr; int argc = 0; foreach (string p; args) { argv[argc++] = cast(char*)(p.dup~'\0'); } argv[argc] = null; return argv; } /** */ public static char*** toStringzArray(string[][] args) { if ( args is null ) { return null; } char**[] argv = new char**[args.length]; int argc = 0; foreach( string[] p; args ) { argv[argc++] = toStringzArray(p); } argv[argc] = null; return argv.ptr; } /** */ public static string[] toStringArray(const(char*)* args) { if ( args is null ) { return null; } string[] argv; while ( *args !is null ) { argv ~= toString(*args); args++; } return argv; } /** */ public static string[] toStringArray(const(char*)* args, size_t len) { string[] argv = new string[len]; for ( int i; i < len; i++ ) { argv[i] = toString(args[i]); } return argv; } /** */ public static string[][] toStringArray(char*** args) { string[][] argv; if ( args is null ) { return null; } while ( *args !is null ) { argv ~= toStringArray(*args); args++; } return argv; } /** */ public static void freeString(char* str) { g_free(str); } /** */ public static void freeStringArray(char** str) { g_strfreev(str); } /** */ public static void freeStringArray(char*** str) { while ( *str !is null ) { g_strfreev(*str); str++; } g_free(str); } code: end struct: String class: StringG struct: Thread noCode: new struct: Timeout class: Timeout cType: code: start /** Holds all timeout delegates */ bool delegate()[] timeoutListeners; /** our gtk timeout ID */ uint timeoutID; /** * Creates a new timeout cycle with the default priority, GPriority.DEFAULT. * * Note that timeout functions may be delayed, due to the processing of other * event sources. Thus they should not be relied on for precise timing. * After each call to the timeout function, the time of the next timeout is * recalculated based on the current time and the given interval * (it does not try to 'catch up' time lost in delays). * Params: * interval = the timeout in milieconds * delegate() = the delegate to be executed * fireNow = When true the delegate will be executed emmidiatly */ this(uint interval, bool delegate() dlg, bool fireNow=false) { timeoutListeners ~= dlg; timeoutID = g_timeout_add(interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this); if ( fireNow ) { if ( !dlg() ) { timeoutListeners.length = 0; } } } /** * Creates a new timeout cycle. * Params: * interval = the timeout in milieconds * delegate() = the delegate to be executed * priority = Priority for the timeout function * fireNow = When true the delegate will be executed emmidiatly */ this(uint interval, bool delegate() dlg, GPriority priority, bool fireNow=false) { timeoutListeners ~= dlg; timeoutID = g_timeout_add_full(priority, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, null); if ( fireNow ) { if ( !dlg() ) { timeoutListeners.length = 0; } } } /** * Creates a new timeout cycle with the default priority, GPriority.DEFAULT. * Params: * delegate() = the delegate to be executed * seconds = interval in seconds. * fireNow = When true the delegate will be executed emmidiatly */ this(bool delegate() dlg, uint seconds, bool fireNow=false) { timeoutListeners ~= dlg; timeoutID = g_timeout_add_seconds(seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this); if ( fireNow ) { if ( !dlg() ) { timeoutListeners.length = 0; } } } /** * Creates a new timeout cycle. * Params: * delegate() = the delegate to be executed * seconds = interval in seconds. * priority = Priority for the timeout function * fireNow = When true the delegate will be executed emmidiatly */ this(bool delegate() dlg, uint seconds, GPriority priority, bool fireNow=false) { timeoutListeners ~= dlg; timeoutID = g_timeout_add_seconds_full(priority, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, null); if ( fireNow ) { if ( !dlg() ) { timeoutListeners.length = 0; } } } /** */ public void stop() { if ( timeoutID > 0 ) { g_source_remove(timeoutID); } timeoutID = 0; timeoutListeners.length = 0; } /** * Removes the timeout from gtk */ ~this() { stop(); } /** * Adds a new delegate to this timeout cycle * Params: * dlg = * fireNow = */ public void addListener(bool delegate() dlg, bool fireNow=false) { timeoutListeners ~= dlg; if ( fireNow ) { if ( !dlg() ) { timeoutListeners.length = timeoutListeners.length - 1; } } } /** * The callback execution from glib * Params: * timeout = * Returns: */ extern(C) static bool timeoutCallback(Timeout timeout) { return timeout.callAllListeners(); } /** * Executes all delegates on the execution list * Returns: */ private bool callAllListeners() { bool runAgain = false; int i = 0; while ( i