ui/ui/toolkit.h

Sun, 21 Jan 2018 12:13:09 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 21 Jan 2018 12:13:09 +0100
changeset 152
62921b370c60
parent 149
479209198de3
child 163
b70e2a77dea0
permissions
-rw-r--r--

fixes use after free when a GtkTreeView was destroyed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2017 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef UI_TOOLKIT_H
#define	UI_TOOLKIT_H

#include <inttypes.h>

#ifdef UI_COCOA

#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#define UIWIDGET NSView*
#define UIMENU   NSMenu*
#else
typedef void* UIWIDGET;
typedef void* UIMENU;
#endif

#elif UI_GTK2 || UI_GTK3

#include <gtk/gtk.h>
#define UIWIDGET GtkWidget*
#define UIMENU   GtkMenu*
#define UI_GTK

#elif UI_MOTIF

#include <Xm/XmAll.h> 
#define UIWIDGET Widget
#define UIMENU   Widget

#elif defined(UI_QT4) || defined(UI_QT5)
#ifdef	__cplusplus
#include <QApplication>
#include <QWidget>
#include <QMenu>
#define UIWIDGET QWidget*
#define UIMENU   QMenu*
#else /* __cplusplus */
#define UIWIDGET void*
#define UIMENU   void*
#endif

#elif UI_WPF
#define UIWIDGET void*
#define UIMENU   void*
#endif

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#ifdef	__cplusplus
extern "C" {
#endif

#define UI_GROUP_SELECTION  20000
    
/* public types */
typedef int UiBool;

typedef struct UiObject     UiObject;
typedef struct UiEvent      UiEvent;
typedef struct UiMouseEvent UiMouseEvent;
typedef struct UiObserver   UiObserver;

typedef struct UiInteger    UiInteger;
typedef struct UiDouble     UiDouble;
typedef struct UiString     UiString;
typedef struct UiText       UiText;
typedef struct UiList       UiList;
typedef struct UiRange      UiRange;

typedef struct UiStr        UiStr;

/* begin opaque types */
typedef struct UiContext    UiContext;
typedef struct UiContainer  UiContainer;

typedef struct UiIcon       UiIcon;
typedef struct UiImage      UiImage;

typedef struct UiSelection  UiSelection;
/* end opaque types */

typedef struct UiTabbedPane UiTabbedPane;

enum UiMouseEventType { UI_PRESS = 0, UI_PRESS2 };


  
typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */

typedef void*(*ui_getvaluefunc)(void*, int);

typedef int(*ui_threadfunc)(void*);

typedef void(*ui_freefunc)(void*);

struct UiObject {
    /*
     * native widget
     */
    UIWIDGET    widget;
    
    /*
     * user window data
     */
    void        *window;
    
    /*
     * window context
     */
    UiContext   *ctx;
    
    /*
     * container interface
     */
    UiContainer *container;
    
    /*
     * next container object
     */
    UiObject    *next;
};

struct UiTabbedPane {
    /*
     * native widget
     */
    UIWIDGET  widget;
    
    /*
     * current document
     */
    void      *document;
    
    /*
     * parent context
     */
    UiContext *ctx;
};

struct UiEvent {
    UiObject *obj;
    void     *document;
    void     *window;
    void     *eventdata;
    int      intval;
};

struct UiMouseEvent {
    int x;
    int y;
    enum UiMouseEventType type;
    int button;
};

struct UiObserver {
    ui_callback callback;
    void *data;
    UiObserver *next;
};

struct UiStr {
    char *ptr;
    void (*free)(void *v);
};

struct UiInteger {
    int64_t  (*get)(UiInteger*);
    void (*set)(UiInteger*, int64_t);
    void *obj;
    
    int64_t value;
    UiObserver *observers;
};

struct UiDouble {
    double  (*get)(UiDouble*);
    void (*set)(UiDouble*, double);
    void *obj;
    
    double value;
    UiObserver *observers;
};

struct UiString {
    char* (*get)(UiString*);
    void  (*set)(UiString*, char*);
    void  *obj;
    
    UiStr value;
    UiObserver *observers;
};

struct UiText {
    void  (*set)(UiText*, char*);
    char* (*get)(UiText*);
    char* (*getsubstr)(UiText*, int, int); /* text, begin, end */
    void  (*insert)(UiText*, int, char*);
    void  (*setposition)(UiText*,int);
    int   (*position)(UiText*);
    void  (*selection)(UiText*, int*, int*); /* text, begin, end */
    int   (*length)(UiText*);
    void  (*remove)(UiText*, int, int); /* text, begin, end */
    UiStr value;
    int   pos;
    void  *obj;
    void  *undomgr;
    // TODO: replacefunc, ...
    UiObserver *observers;
};
    
/*
 * abstract list
 */
struct UiList {
    /* get the first element */
    void*(*first)(UiList *list);
    /* get the next element */
    void*(*next)(UiList *list);
    /* get the nth element */
    void*(*get)(UiList *list, int i);
    /* get the number of elements */
    int(*count)(UiList *list);
    /* iterator changes after first() next() and get() */
    void *iter;
    /* private - implementation dependent */
    void *data;
    
    /* binding function */
    void (*update)(UiList *list, int i);
    /* binding object */
    void *obj;
    
    /* list of observers */
    UiObserver *observers;
};

struct UiRange {
    double (*get)(UiRange *range);
    void   (*set)(UiRange *range, double value);
    void   (*setrange)(UiRange *range, double min, double max);
    void   (*setextent)(UiRange *range, double extent);
    double value;
    double min;
    double max;
    double extent;
    void   *obj;
    /* list of observers */
    UiObserver *observers;
};


void ui_init(char *appname, int argc, char **argv);
char* ui_appname();

void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata);

void ui_onstartup(ui_callback f, void *userdata);
void ui_onopen(ui_callback f, void *userdata);
void ui_onexit(ui_callback f, void *userdata);

void ui_main();
void ui_show(UiObject *obj);
void ui_close(UiObject *obj);

void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd);

void* ui_document_new(size_t size);
void  ui_document_destroy(void *doc);

void ui_set_document(UiObject *obj, void *document);
void ui_detach_document(UiObject *obj);
void* ui_get_document(UiObject *obj);
void ui_set_subdocument(void *document, void *sub);
void ui_detach_subdocument(void *document, void *sub);
void* ui_get_subdocument(void *document);

UiContext* ui_document_context(void *doc);



void ui_set_group(UiContext *ctx, int group);
void ui_unset_group(UiContext *ctx, int group);
int* ui_active_groups(UiContext *ctx, int *ngroups);
    
void* ui_malloc(UiContext *ctx, size_t size);
void* ui_calloc(UiContext *ctx, size_t nelem, size_t elsize);
void  ui_free(UiContext *ctx, void *ptr);
void* ui_realloc(UiContext *ctx, void *ptr, size_t size);

// types

UiInteger* ui_int_new(UiContext *ctx, char *name);
UiDouble* ui_double_new(UiContext *ctx, char *name);
UiString* ui_string_new(UiContext *ctx, char *name);
UiText* ui_text_new(UiContext *ctx, char *name);
UiRange* ui_range_new(UiContext *ctx, char *name);

UiObserver* ui_observer_new(ui_callback f, void *data);
UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer);
UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data);
void ui_notify(UiObserver *observer, void *data);
void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data);
void ui_notify_evt(UiObserver *observer, UiEvent *event);


UiList* ui_list_new(UiContext *ctx, char *name);
void* ui_list_first(UiList *list);
void* ui_list_next(UiList *list);
void* ui_list_get(UiList *list, int i);
int   ui_list_count(UiList *list);
void  ui_list_append(UiList *list, void *data);
void  ui_list_prepend(UiList *list, void *data);
void ui_list_clear(UiList *list);
void  ui_list_addobsv(UiList *list, ui_callback f, void *data);
void  ui_list_notify(UiList *list);

void ui_clipboard_set(char *str);
char* ui_clipboard_get();

void ui_add_image(char *imgname, char *filename); // TODO: remove?

// general widget functions
void ui_set_enabled(UIWIDGET widget, int enabled);
void ui_set_show_all(UIWIDGET widget, int value);
void ui_set_visible(UIWIDGET widget, int visible);


#ifdef	__cplusplus
}
#endif

#endif	/* UI_TOOLKIT_H */

mercurial