Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-03-05 23:53:57 -0500 (Thu, 05 Mar 2015)
New Revision: 9785
Modified:
trunk/gui/menu.c
Log:
in AG_MenuCollapse(), invalidate the surface handles only after the
window has been detached (using `window-detached')
Modified:
... [More]
trunk/gui/menu.c
===================================================================
--- trunk/gui/menu.c2015-03-06 04:43:03 UTC (rev 9784)
trunk/gui/menu.c2015-03-06 04:53:57 UTC (rev 9785)
< at >< at > -208,6 208,29 < at >< at >
return (win);
}
static void
MenuWindowDetached(AG_Event *event)
{
AG_Menu *m = AG_PTR(1);
AG_MenuItem *mi = AG_PTR(2);
AG_MenuItem *miSub;
Uint j;
AG_ObjectLock(m);
mi->view = NULL;
mi->sel_subitem = NULL;/* Loose selection */
/* The surface handles are no longer valid. */
TAILQ_FOREACH(miSub, &mi->subItems, items) {
for (j = 0; j < 2; j ) {
miSub->lblView[j] = -1;
}
miSub->icon = -1;
}
AG_ObjectUnlock(m);
}
/*
* Collapse the window displaying the specified item and its sub-menus
* (if any).
< at >< at > -217,7 240,7 < at >< at >
{
AG_Menu *m;
AG_MenuItem *miSub;
-Uint j;
AG_Window *miWin;
if (mi == NULL || mi->view == NULL || (m = mi->pmenu) == NULL)
return;
< at >< at > -231,19 254,9 < at >< at >
}
/* Destroy the MenuView's window. */
-AG_ObjectDetach(WIDGET(mi->view)->window);
-mi->view = NULL;
-
-/* Lose the current selection. */
-mi->sel_subitem = NULL;
-
-/* The surface handles are no longer valid. */
-TAILQ_FOREACH(miSub, &mi->subItems, items) {
-for (j = 0; j < 2; j ) {
-miSub->lblView[j] = -1;
-}
-miSub->icon = -1;
-}
miWin = WIDGET(mi->view)->window;
AG_ObjectDetach(miWin);
AG_SetEvent(miWin, "window-detached", MenuWindowDetached, "%p,%p", m, mi);
AG_ObjectUnlock(m);
}
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-03-05 23:42:42 -0500 (Thu, 05 Mar 2015)
New Revision: 9783
Modified:
trunk/gui/AG_Window.3
trunk/gui/window.c
Log:
post `window-detached' event after a window has been successfully detached.
Modified:
... [More]
trunk/gui/AG_Window.3
===================================================================
--- trunk/gui/AG_Window.32015-03-06 04:41:25 UTC (rev 9782)
+++ trunk/gui/AG_Window.32015-03-06 04:42:42 UTC (rev 9783)
< at >< at > -72,10 +72,14 < at >< at >
.Fn AG_WindowNew )
must be made visible using
.Fn AG_WindowShow .
-To close a window and free its allocated resources, one call to
-.Xr AG_ObjectDetach 3
-is sufficient (Agar will defer the actual destruction of the window
-until it becomes safe to do so).
+.Pp
+Windows are destroyed by a single call to
+.Xr AG_ObjectDetach 3 .
+The detach operation actually places the window on a queue, and actual
+freeing will occur after the end of the current event processing cycle.
+After a window has been successfully detached, the
+.Sq window-detached
+event is raised.
.Sh INHERITANCE HIERARCHY
.Xr AG_Object 3 ->
.Xr AG_Widget 3 ->
< at >< at > -854,16 +858,20 < at >< at >
objects the following events:
.Bl -tag -width 2n
.It Fn window-close "void"
-The user (or window system) is requesting that this window be closed.
-By default, named windows are hidden and unnamed windows are destroyed.
-Event handlers are free to ignore the request, or create new windows
-(e.g., confirmation dialogs) in response.
+Request to close the window (sent by the user / underlying window system).
+The default behavior is to hide named windows and detach unnamed windows..
+It is safe for an event handler to ignore the request, or to create new
+windows (e.g., a confirmation dialog) in response.
.It Fn window-modal-close "int x" "int y"
The window is modal (the
.Dv AG_WINDOW_MODAL
option is set), and a click or touch event was detected outside of its area
(at given coordinates).
By default, the request is ignored.
+.It Fn window-detached "void"
+The window has been successfully detached (as per a previous
+.Xr AG_ObjectDetach 3
+request).
.It Fn window-shown "void"
The window is now visible.
.It Fn window-hidden "void"
Modified: trunk/gui/window.c
===================================================================
--- trunk/gui/window.c2015-03-06 04:41:25 UTC (rev 9782)
+++ trunk/gui/window.c2015-03-06 04:42:42 UTC (rev 9783)
< at >< at > -1965,7 +1965,7 < at >< at >
if (win->flags & AG_WINDOW_MAIN) {
closedMain++;
}
-
+AG_PostEvent(drv, win, "window-detached", NULL);
AG_ObjectDestroy(win);
}
TAILQ_INIT(&agWindowDetachQ);
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-03-05 23:41:25 -0500 (Thu, 05 Mar 2015)
New Revision: 9782
Modified:
trunk/tests/agartest.c
trunk/tests/agartest.h
trunk/tests/charsets.c
trunk/tests/focusing.c
trunk/tests/threads.c
Log:
invoke destroy()
... [More]
operation post `window-detach'
Modified: trunk/tests/agartest.c
===================================================================
--- trunk/tests/agartest.c2015-03-04 07:12:55 UTC (rev 9781)
trunk/tests/agartest.c2015-03-06 04:41:25 UTC (rev 9782)
< at >< at > -213,7 213,7 < at >< at >
AG_ConsoleMsg(console, _("%s: Interactive test started"),
tc->name);
AG_SeparatorNewHoriz(win);
-AG_ButtonNewFn(win, AG_BUTTON_HFILL, _("Close this test"),
ti->closeBtn = AG_ButtonNewFn(win, AG_BUTTON_HFILL, _("Close this test"),
RequestTestClose, "%p", win);
AG_WindowSetPosition(win, AG_WINDOW_MC, 0);
AG_WindowAttach(winParent, win);
< at >< at > -264,14 264,11 < at >< at >
return;
}
-/* Close an interactive test. */
-void
-TestWindowClose(AG_Event *event)
static void
TestWindowDetached(AG_Event *event)
{
AG_TestInstance *ti = AG_PTR(1);
-AG_ConsoleMsg(console, _("Test %s: terminated"), ti->name);
-AG_ObjectDetach(ti->win);
TAILQ_REMOVE(&tests, ti, instances);
if (ti->tc->destroy != NULL) {
ti->tc->destroy(ti);
< at >< at > -279,6 276,17 < at >< at >
free(ti);
}
/* Close an interactive test. */
void
TestWindowClose(AG_Event *event)
{
AG_TestInstance *ti = AG_PTR(1);
AG_ConsoleMsg(console, _("Test %s: terminated"), ti->name);
AG_ObjectDetach(ti->win);
AG_SetEvent(ti->win, "window-detached", TestWindowDetached, "%p", ti);
}
/* Write a message to the test console (format string). */
void
TestMsg(void *obj, const char *fmt, ...)
Modified: trunk/tests/agartest.h
===================================================================
--- trunk/tests/agartest.h2015-03-04 07:12:55 UTC (rev 9781)
trunk/tests/agartest.h2015-03-06 04:41:25 UTC (rev 9782)
< at >< at > -39,6 39,7 < at >< at >
float score;/* Numerical result */
AG_Console *console;/* Output console */
AG_Window *win;/* Main (control) window */
AG_Button *closeBtn;/* "Close this test" */
AG_TAILQ_ENTRY(ag_test_instance) instances;
} AG_TestInstance;
Modified: trunk/tests/charsets.c
===================================================================
--- trunk/tests/charsets.c2015-03-04 07:12:55 UTC (rev 9781)
trunk/tests/charsets.c2015-03-06 04:41:25 UTC (rev 9782)
< at >< at > -12,27 12,49 < at >< at >
typedef struct {
AG_TestInstance _inherit;
-char myASCII[20*4];
-char myUTF[30*4];
-char myLat1[30*4];
-AG_Text *myTxt;
char myASCII[20*4];/* Example US-ASCII buffer */
char myUTF[30*4];/* Example UTF-8 buffer */
char myLat1[30*4];/* Example ISO-8859-1 buffer */
AG_Text *myTxt;/* Sample AG_TextElement(3) */
} MyTestInstance;
static int
Init(void *obj)
{
MyTestInstance *ti = obj;
if ((ti->myTxt = AG_TextNew(0)) == NULL) {
return (-1);
}
AG_TextSetEnt(ti->myTxt, AG_LANG_FR, "(UTF8) Fran\xc3\xa7\x61is!");
AG_TextSetEnt(ti->myTxt, AG_LANG_EN, "(UTF8) English!");
AG_TextSetEnt(ti->myTxt, AG_LANG_NO, "(UTF8) Norsk!");
return (0);
}
static void
Destroy(void *obj)
{
MyTestInstance *ti = obj;
AG_TextFree(ti->myTxt);
}
static int
TestGUI(void *obj, AG_Window *win)
{
MyTestInstance *ti = obj;
AG_Textbox *tb;
/* Bind to a C string in US-ASCII */
-AG_Strlcpy(ti->myASCII, "ASCII!", sizeof(ti->myASCII));
AG_Strlcpy(ti->myASCII, "(US-ASCII)", sizeof(ti->myASCII));
tb = AG_TextboxNew(win, AG_TEXTBOX_HFILL|AG_TEXTBOX_EXCL,
"ASCII Buffer: \n(%lu bytes)", (long unsigned)sizeof(ti->myASCII));
AG_TextboxBindASCII(tb, ti->myASCII, sizeof(ti->myASCII));
AG_TextboxSizeHintLines(tb, 2);
/* Bind to a C string in UTF-8 */
-AG_Strlcpy(ti->myUTF, "\xc3\x85ngstrom!", sizeof(ti->myUTF));
AG_Strlcpy(ti->myUTF, "(UTF8) \xc3\x85ngstrom!", sizeof(ti->myUTF));
tb = AG_TextboxNew(win, AG_TEXTBOX_HFILL|AG_TEXTBOX_EXCL,
"UTF-8 Buffer: \n(%lu bytes)", (long unsigned)sizeof(ti->myUTF));
AG_TextboxBindUTF8(tb, ti->myUTF, sizeof(ti->myUTF));
< at >< at > -40,7 62,7 < at >< at >
/* Bind to a C string in any iconv-supported encoding */
#ifdef HAVE_ICONV
-AG_Strlcpy(ti->myLat1, "Overv\xE5knign for feils\xF8king!", sizeof(ti->myLat1));
AG_Strlcpy(ti->myLat1, "(LATIN-1) overv\xE5knign for feils\xF8king!", sizeof(ti->myLat1));
tb = AG_TextboxNew(win, AG_TEXTBOX_HFILL|AG_TEXTBOX_EXCL,
"LATIN-1 Buffer: \n(%lu bytes)", (long unsigned)sizeof(ti->myLat1));
AG_TextboxBindEncoded(tb, "ISO-8859-1", ti->myLat1, sizeof(ti->myLat1));
< at >< at > -54,38 76,27 < at >< at >
AG_SeparatorNewHoriz(win);
/* Bind to a multilingual AG_Text(3) element. */
-if ((ti->myTxt = AG_TextNew(0)) != NULL) {
-AG_TextSetEnt(ti->myTxt, AG_LANG_FR, "Fran\xc3\xa7\x61is!");
-AG_TextSetEnt(ti->myTxt, AG_LANG_EN, "English!");
-AG_TextSetEnt(ti->myTxt, AG_LANG_NO, "Norsk!");
-AG_LabelNewS(win, 0, "Multilingual AG_Text(3) buffer:");
-tb = AG_TextboxNewS(win,
- AG_TEXTBOX_MULTILINGUAL|AG_TEXTBOX_EXPAND|AG_TEXTBOX_MULTILINE,
- NULL);
-AG_TextboxBindText(tb, ti->myTxt);
-AG_TextboxSetLang(tb, AG_LANG_FR);
-AG_TextboxSizeHint(tb, "XXXXXXXXXXXXXXXXXXXXXXXXX");
-AG_TextboxSizeHintLines(tb, 5);
-AG_TextboxSetCursorPos(tb, -1);/* End of string */
-}
AG_LabelNewS(win, 0, "Multilingual AG_Text(3) buffer:");
tb = AG_TextboxNewS(win,
AG_TEXTBOX_MULTILINGUAL|AG_TEXTBOX_EXPAND|
AG_TEXTBOX_MULTILINE|AG_TEXTBOX_EXCL,
NULL);
AG_TextboxBindText(tb, ti->myTxt);
AG_TextboxSetLang(tb, AG_LANG_FR);
AG_TextboxSizeHint(tb, "XXXXXXXXXXXXXXXXXXXXXXXXX");
AG_TextboxSizeHintLines(tb, 5);
AG_TextboxSetCursorPos(tb, -1);/* End of string */
return (0);
}
-static void
-Destroy(void *obj)
-{
-MyTestInstance *ti = obj;
-
-AG_TextFree(ti->myTxt);
-}
-
const AG_TestCase charsetsTest = {
"charsets",
N_("Test AG_Editable(3) bound to buffers in different character sets"),
"1.5.0",
0,
sizeof(MyTestInstance),
-NULL,/* init */
Init,
Destroy,
NULL,/* test */
TestGUI,
Modified: trunk/tests/focusing.c
===================================================================
--- trunk/tests/focusing.c2015-03-04 07:12:55 UTC (rev 9781)
trunk/tests/focusing.c2015-03-06 04:41:25 UTC (rev 9782)
< at >< at > -5,11 5,6 < at >< at >
#include "agartest.h"
-typedef struct {
-AG_TestInstance _inherit;
-AG_Widget *widget1, *widget2;
-} MyTestInstance;
-
static void
mousemotion(AG_Event *event)
{
< at >< at > -67,8 62,7 < at >< at >
static void
TestUnfocusedMotion(AG_Event *event)
{
-MyTestInstance *ti = AG_PTR(1);
-AG_Window *winParent = AG_PTR(2), *win;
AG_Window *winParent = AG_PTR(1), *win;
AG_Button *btn;
AG_Fixed *fx1, *fx2;
< at >< at > -91,8 85,6 < at >< at >
AG_FixedMove(fx1, btn, 0, 64);
AG_FixedSize(fx1, btn, 32, 32);
-ti->widget1 = AGWIDGET(btn);
-
fx2 = AG_FixedNew(fx1, AG_FIXED_BOX);
AGWIDGET(fx2)->flags |= AG_WIDGET_FOCUSABLE|AG_WIDGET_UNFOCUSED_MOTION;
AG_FixedMove(fx1, fx2, 64, 16);
< at >< at > -109,10 101,8 < at >< at >
static void
TestTabCycle(AG_Event *event)
{
-MyTestInstance *ti = AG_PTR(1);
-AG_Window *winParent = AG_PTR(2), *win;
AG_Window *winParent = AG_PTR(1), *win;
AG_Box *b, *b1, *b2;
-AG_Button *btn;
int i;
if ((win = AG_WindowNew(0)) == NULL) {
< at >< at > -124,8 114,7 < at >< at >
"<SHIFT TAB> = Cycle focus backward");
b = AG_BoxNewHoriz(win, AG_BOX_HOMOGENOUS|AG_BOX_EXPAND);
-btn = AG_ButtonNew(b, AG_BUTTON_HFILL, "Foo");
-ti->widget2 = AGWIDGET(btn);
AG_ButtonNew(b, AG_BUTTON_HFILL, "Foo");
b1 = AG_BoxNewVert(b, AG_BOX_VFILL);
for (i = 0; i < 5; i )
< at >< at > -139,54 128,14 < at >< at >
AG_WindowShow(win);
}
-static void
-FocusWidget1(AG_Event *event)
-{
-MyTestInstance *ti = AG_PTR(1);
-
-if (ti->widget1 != NULL)
-AG_WidgetFocus(ti->widget1);
-}
-
-static void
-FocusWidget2(AG_Event *event)
-{
-MyTestInstance *ti = AG_PTR(1);
-
-if (ti->widget2 != NULL)
-AG_WidgetFocus(ti->widget2);
-}
-
static int
-Init(void *obj)
-{
-MyTestInstance *ti = obj;
-
-ti->widget1 = NULL;
-ti->widget2 = NULL;
-return (0);
-}
-
-static int
TestGUI(void *obj, AG_Window *win)
{
-MyTestInstance *ti = obj;
-AG_Button *btn;
-AG_Box *box;
-
AG_LabelNewS(win, 0, "Tests for widget focus states");
-btn = AG_ButtonNewFn(win, 0, "Test unfocused mouse motion", TestUnfocusedMotion, "%p,%p", ti, win);
-AG_WidgetSetFocusable(btn, 0);
-btn = AG_ButtonNewFn(win, 0, "Test <tab> focus cycling", TestTabCycle, "%p,%p", ti, win);
-AG_WidgetSetFocusable(btn, 0);
-
-box = AG_BoxNewHoriz(win, AG_BOX_HFILL);
-{
-btn = AG_ButtonNewFn(box, 0, "Focus widget 1", FocusWidget1, "%p", ti);
-AG_WidgetSetFocusable(btn, 0);
-btn = AG_ButtonNewFn(box, 0, "Focus widget 2", FocusWidget2, "%p", ti);
-AG_WidgetSetFocusable(btn, 0);
-}
AG_ButtonNewFn(win, 0, "Test unfocused mouse motion",
TestUnfocusedMotion, "%p", win);
AG_ButtonNewFn(win, 0, "Test <tab> focus cycling",
TestTabCycle, "%p", win);
return (0);
}
< at >< at > -195,8 144,8 < at >< at >
N_("Test widget focus state control"),
"1.4.2",
0,
-sizeof(MyTestInstance),
-Init,
sizeof(AG_TestInstance),
NULL,/* init */
NULL,/* destroy */
NULL,/* test */
TestGUI,
Modified: trunk/tests/threads.c
===================================================================
--- trunk/tests/threads.c2015-03-04 07:12:55 UTC (rev 9781)
trunk/tests/threads.c2015-03-06 04:41:25 UTC (rev 9782)
< at >< at > -48,9 48,7 < at >< at >
AG_LabelNew(win, 0, "This window was created in a separate thread");
AG_WindowAttach(ti->winParent, win);
-Verbose("Showing window\n");
AG_WindowShow(win);
-Verbose("Window shown\n");
return (NULL);
}
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-03-04 02:12:55 -0500 (Wed, 04 Mar 2015)
New Revision: 9781
Modified:
trunk/core/string.c
Log:
correctly free the associated thread-specific keys used by the
AG_Printf() buffers.
Modified: trunk/core/string.c
... [More]
===================================================================
--- trunk/core/string.c2015-03-03 10:20:58 UTC (rev 9780)
+++ trunk/core/string.c2015-03-04 07:12:55 UTC (rev 9781)
< at >< at > -1358,10 +1358,16 < at >< at >
/* Free the AG_Printf() buffers. */
for (i = 0; i < AG_STRING_BUFFERS_MAX; i++) {
-Free(agPrintBuf[i]);
#ifdef AG_THREADS
+if ((agPrintBuf[i] = (char *)AG_ThreadKeyGet(agPrintBufKey[i]))
+ != NULL) {
+free(agPrintBuf[i]);
+}
AG_ThreadKeyDelete(agPrintBufKey[i]);
+#else
+Free(agPrintBuf[i]);
#endif
+agPrintBuf[i] = NULL;
}
/* Free the formatting engine extensions. */
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-03-03 05:20:58 -0500 (Tue, 03 Mar 2015)
New Revision: 9780
Modified:
trunk/tests/threads.c
Log:
prevent unsafe operation in the threads test
Modified: trunk/tests/threads.c
... [More]
===================================================================
--- trunk/tests/threads.c2015-03-03 08:09:29 UTC (rev 9779)
trunk/tests/threads.c2015-03-03 10:20:58 UTC (rev 9780)
< at >< at > -32,6 32,7 < at >< at >
int value;
} spinning;
int closeTest;
AG_Mutex lock;
} MyTestInstance;
static void *
< at >< at > -60,21 61,33 < at >< at >
TestMsg(ti, "Sleeping worker created");
for (;;) {
AG_MutexLock(&ti->lock);
if (ti->closeTest) {
-break;
TestMsg(ti, "Task aborted");
AG_MutexUnlock(&ti->lock);
goto out;
}
TestMsg(ti, "Sleeping worker: %d/%d", ti->sleeping.value, ti->sleeping..max);
if ( ti->sleeping.value == ti->sleeping.max) {
-TestMsg(ti, "Sleeping worker thread exiting");
-AG_ObjectDetach(ti->sleeping.win);
-ti->sleeping.win = NULL;
-AG_ThreadExit(NULL);
TestMsg(ti, "Task completed");
AG_MutexUnlock(&ti->lock);
goto out;
}
AG_LabelText(ti->sleeping.lbl,
"Sleeping worker progress: %d/%d", ti->sleeping.value, ti->sleeping.max);
-AG_Delay(1000);
AG_MutexUnlock(&ti->lock);
AG_Delay(100);
}
-ti->sleeping.running = 0;
out:
AG_MutexLock(&ti->lock);
ti->closeTest = 0;
if (ti->sleeping.win != NULL) {
AG_ObjectDetach(ti->sleeping.win);
ti->sleeping.win = NULL;
ti->sleeping.running = 0;
}
AG_MutexUnlock(&ti->lock);
return (NULL);
}
< at >< at > -87,16 100,18 < at >< at >
TestMsg(ti, "Spinning worker created");
for (;;) {
int i;
-
AG_MutexLock(&ti->lock);
if (ti->closeTest) {
-break;
TestMsg(ti, "Task aborted. x=%f, y=%f", x, y);
AG_MutexUnlock(&ti->lock);
goto out;
}
TestMsg(ti, "Spinning worker: %d/%d", ti->spinning.value, ti->spinning..max);
if ( ti->spinning.value == ti->spinning.max) {
-TestMsg(ti, "Spinning worker thread exiting. x=%f, y=%f", x, y);
-AG_ObjectDetach(ti->spinning.win);
-ti->spinning.win = NULL;
-AG_ThreadExit(NULL);
TestMsg(ti, "Task completed. x=%f, y=%f", x, y);
AG_MutexUnlock(&ti->lock);
goto out;
}
AG_LabelText(ti->spinning.lbl,
"Spinning worker progress: %d/%d", ti->spinning.value, ti->spinning.max);
< at >< at > -105,8 120,17 < at >< at >
x = sin(cos(y)) tan((double)i);
if (x != 12.345) { x = 1.0; }
}
AG_MutexUnlock(&ti->lock);
AG_Delay(1);
}
-ti->spinning.running = 0;
out:
AG_MutexLock(&ti->lock);
if (ti->spinning.win != NULL) {
AG_ObjectDetach(ti->spinning.win);
ti->spinning.win = NULL;
ti->spinning.running = 0;
}
AG_MutexUnlock(&ti->lock);
return (NULL);
}
< at >< at > -128,8 152,11 < at >< at >
AG_Window *win;
AG_ProgressBar *pb;
AG_MutexLock(&ti->lock);
if (ti->sleeping.win != NULL ||
(win = AG_WindowNew(AG_WINDOW_NOCLOSE)) == NULL) {
AG_MutexUnlock(&ti->lock);
return;
}
ti->sleeping.win = win;
< at >< at > -144,11 171,13 < at >< at >
AG_BindInt(pb, "min", &ti->sleeping.min);
AG_BindInt(pb, "max", &ti->sleeping.max);
ti->sleeping.lbl = AG_LabelNew(win, AG_LABEL_HFILL, "...");
-AG_WindowAttach(ti->winParent, win);
/*AG_WindowAttach(ti->winParent, win); */
AG_WindowShow(win);
AG_ThreadCreate(&ti->sleeping.th, SleepingWorker, ti);
ti->sleeping.running = 1;
AG_MutexUnlock(&ti->lock);
}
static void
< at >< at > -157,9 186,12 < at >< at >
MyTestInstance *ti = AG_PTR(1);
AG_Window *win;
AG_ProgressBar *pb;
AG_MutexLock(&ti->lock);
if (ti->spinning.win != NULL ||
(win = AG_WindowNew(AG_WINDOW_NOCLOSE)) == NULL) {
AG_MutexUnlock(&ti->lock);
return;
}
ti->spinning.win = win;
< at >< at > -174,11 206,13 < at >< at >
AG_BindInt(pb, "min", &ti->spinning.min);
AG_BindInt(pb, "max", &ti->spinning.max);
ti->spinning.lbl = AG_LabelNew(win, AG_LABEL_HFILL, "...");
-AG_WindowAttach(ti->winParent, win);
/*AG_WindowAttach(ti->winParent, win); */
AG_WindowShow(win);
AG_ThreadCreate(&ti->spinning.th, SpinningWorker, ti);
ti->spinning.running = 1;
AG_MutexUnlock(&ti->lock);
}
static int
< at >< at > -194,6 228,7 < at >< at >
ti->spinning.win = NULL;
ti->spinning.running = 0;
ti->closeTest = 0;
AG_MutexInit(&ti->lock);
return (0);
}
< at >< at > -202,6 237,7 < at >< at >
{
MyTestInstance *ti = obj;
AG_MutexDestroy(&ti->lock);
AG_ObjectDestroy(&ti->workerMgr);
}
< at >< at > -210,14 246,19 < at >< at >
{
MyTestInstance *ti = AG_PTR(1);
-ti->closeTest = 1;
-
-while (ti->sleeping.running) {
-AG_Delay(50);
AG_MutexLock(&ti->lock);
if (ti->sleeping.running) {
TestMsg(ti, "Sleeping worker is not finished");
AG_MutexUnlock(&ti->lock);
return;
}
-while (ti->spinning.running) {
-AG_Delay(50);
if (ti->spinning.running) {
TestMsg(ti, "Spinning worker is not finished");
AG_MutexUnlock(&ti->lock);
return;
}
AG_MutexUnlock(&ti->lock);
TestWindowClose(event);
}
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-03-03 03:09:29 -0500 (Tue, 03 Mar 2015)
New Revision: 9779
Modified:
trunk/core/event.c
Log:
prevent cleanup routine of agEventSourceKey from calling DestroyEventSource()
twice
Modified: trunk/core/event.c
... [More]
===================================================================
--- trunk/core/event.c2015-03-02 04:50:47 UTC (rev 9778)
+++ trunk/core/event.c2015-03-03 08:09:29 UTC (rev 9779)
< at >< at > -641,13 +641,19 < at >< at >
{
AG_EventSource *src = pEventSource;
AG_EventSink *es, *esNext;
+
+if (agEventSource == NULL)
+return;
+
#ifdef HAVE_KQUEUE
-AG_EventSourceKQUEUE *kq = pEventSource;
+{
+AG_EventSourceKQUEUE *kq = pEventSource;
-if (kq->fd != -1) {
-close(kq->fd);
+if (kq->fd != -1) {
+close(kq->fd);
+}
+Free(kq->changes);
}
-Free(kq->changes);
#endif
for (es = TAILQ_FIRST(&src->prologues); es != TAILQ_END(&src->prologues); es = esNext) {
esNext = TAILQ_NEXT(es, sinks);
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-20 00:01:47 -0500 (Fri, 20 Feb 2015)
New Revision: 9775
Modified:
trunk/gui/window.c
Log:
unused warnings
Modified: trunk/gui/window.c
===================================================================
---
... [More]
trunk/gui/window.c2015-02-19 15:36:39 UTC (rev 9774)
+++ trunk/gui/window.c2015-02-20 05:01:47 UTC (rev 9775)
< at >< at > -284,14 +284,10 < at >< at >
Detach(AG_Event *event)
{
AG_Window *win = AG_SELF();
-AG_Driver *drv = OBJECT(win)->parent, *odrv;
+AG_Driver *drv;
AG_Window *other, *subwin;
AG_Timer *to, *toNext;
-#ifdef AG_DEBUG
-if (drv == NULL || !AG_OfClass(drv, "AG_Driver:*"))
-AG_FatalError("Window is not attached to a Driver");
-#endif
AG_LockVFS(&agDrivers);
/* Mark window detach in progress */
< at >< at > -308,8 +304,8 < at >< at >
AG_UnlockTiming();
/* Implicitely detach window dependencies. */
-AGOBJECT_FOREACH_CHILD(odrv, &agDrivers, ag_driver) {
-AG_FOREACH_WINDOW(other, odrv) {
+AGOBJECT_FOREACH_CHILD(drv, &agDrivers, ag_driver) {
+AG_FOREACH_WINDOW(other, drv) {
if (other == win) {
continue;
}
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-19 10:36:39 -0500 (Thu, 19 Feb 2015)
New Revision: 9774
Modified:
trunk/gui/drv_glx.c
trunk/gui/drv_sdl_common.c
Log:
don't try to free shared cursors
Modified: trunk/gui/drv_glx.c
... [More]
===================================================================
--- trunk/gui/drv_glx.c2015-02-19 15:14:11 UTC (rev 9773)
+++ trunk/gui/drv_glx.c2015-02-19 15:36:39 UTC (rev 9774)
< at >< at > -99,6 +99,7 < at >< at >
XColor white;
Cursor xc;
int visible;
+int shared;
} AG_CursorGLX;
AG_DriverMwClass agDriverGLX;
< at >< at > -918,9 +919,11 < at >< at >
/*
* Initialize generic Agar cursor part.
*/
-if ((ac = acGLX = TryMalloc(sizeof(AG_CursorGLX))) == NULL) {
+if ((acGLX = TryMalloc(sizeof(AG_CursorGLX))) == NULL) {
return (NULL);
}
+ac = (AG_Cursor *)acGLX;
+
if ((ac->data = TryMalloc(size)) == NULL) {
free(ac);
return (NULL);
< at >< at > -1000,6 +1003,7 < at >< at >
acGLX->xc = XCreatePixmapCursor(agDisplay, dataPixmap, maskPixmap,
&acGLX->black, &acGLX->white, ac->xHot, ac->yHot);
acGLX->visible = 0;
+acGLX->shared = 0;
XFreePixmap(agDisplay, dataPixmap);
XFreePixmap(agDisplay, maskPixmap);
< at >< at > -1017,6 +1021,7 < at >< at >
static void
GLX_FreeCursor(void *obj, AG_Cursor *ac)
{
+AG_Driver *drv = obj;
AG_DriverGLX *glx = obj;
AG_CursorGLX *acGLX = (AG_CursorGLX *)ac;
< at >< at > -1025,8 +1030,8 < at >< at >
if (ac == drv->activeCursor)
drv->activeCursor = NULL;
-
-XFreeCursor(agDisplay, acGLX->xc);
+if (!acGLX->shared)
+XFreeCursor(agDisplay, acGLX->xc);
AG_MutexUnlock(&glx->lock);
AG_MutexUnlock(&agDisplayLock);
< at >< at > -1041,7 +1046,7 < at >< at >
{
AG_Driver *drv = obj;
AG_DriverGLX *glx = obj;
-AG_CursorGLX *cg = ac->p;
+AG_CursorGLX *acGLX = (AG_CursorGLX *)ac;
if (drv->activeCursor == ac)
return (0);
< at >< at > -1052,7 +1057,7 < at >< at >
if (ac == TAILQ_FIRST(&drv->cursors)) {
XUndefineCursor(agDisplay, glx->w);
} else {
-XDefineCursor(agDisplay, glx->w, cg->xc);
+XDefineCursor(agDisplay, glx->w, acGLX->xc);
}
AG_MutexUnlock(&glx->lock);
< at >< at > -1061,7 +1066,7 < at >< at >
XSync(agDisplay, False);
drv->activeCursor = ac;
-cg->visible = 1;
+acGLX->visible = 1;
return (0);
}
< at >< at > -1123,20 +1128,17 < at >< at >
{
AG_Driver *drv = AGDRIVER(glx);
AG_Cursor *ac;
-AG_CursorGLX *cursGLX;
+AG_CursorGLX *acGLX;
-if ((cursGLX = TryMalloc(sizeof(AG_CursorGLX))) == NULL) {
+if ((acGLX = TryMalloc(sizeof(AG_CursorGLX))) == NULL) {
return (-1);
}
-if ((ac = TryMalloc(sizeof(AG_Cursor))) == NULL) {
-free(cursGLX);
-return (-1);
-}
+ac = (AG_Cursor *)acGLX;
AG_CursorInit(ac);
-cursGLX->xc = XCreateFontCursor(agDisplay, XC_left_ptr);
-cursGLX->visible = 1;
-ac->p = cursGLX;
+acGLX->xc = XCreateFontCursor(agDisplay, XC_left_ptr);
+acGLX->visible = 1;
+acGLX->shared = 1;
TAILQ_INSERT_HEAD(&drv->cursors, ac, cursors);
drv->nCursors++;
Modified: trunk/gui/drv_sdl_common.c
===================================================================
--- trunk/gui/drv_sdl_common.c2015-02-19 15:14:11 UTC (rev 9773)
+++ trunk/gui/drv_sdl_common.c2015-02-19 15:36:39 UTC (rev 9774)
< at >< at > -496,11 +496,13 < at >< at >
return (NULL);
}
if ((ac->data = TryMalloc(size)) == NULL) {
-goto fail;
+free(ac);
+return (NULL);
}
if ((ac->mask = TryMalloc(size)) == NULL) {
free(ac->data);
-goto fail;
+free(ac);
+return (NULL);
}
memcpy(ac->data, data, size);
memcpy(ac->mask, mask, size);
< at >< at > -514,7 +516,7 < at >< at >
ac->xHot, ac->yHot);
if (sc == NULL) {
AG_SetError("SDL_CreateCursor failed");
-return (-1);
+goto fail;
}
ac->p = (void *)sc;
return (ac);
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-19 10:13:40 -0500 (Thu, 19 Feb 2015)
New Revision: 9772
Modified:
trunk/gui/AG_Driver.3
trunk/gui/cursors.c
trunk/gui/drv.h
trunk/gui/drv_glx.c
trunk/gui/drv_sdl_common.c
trunk/gui/drv_sdl_common.h
... [More]
trunk/gui/drv_wgl.c
Log:
- extend the AG_Cursor structure to include driver-specific data, instead
of referencing an external structure.
- have the drivers handle entire createCursor() operation.
Modified: trunk/gui/AG_Driver.3
===================================================================
--- trunk/gui/AG_Driver.32015-02-19 15:08:42 UTC (rev 9771)
+++ trunk/gui/AG_Driver.32015-02-19 15:13:40 UTC (rev 9772)
< at >< at > -195,7 +195,9 < at >< at >
void (*popBlendingMode)(void *drv);
/* Hardware cursor interface */
-int (*createCursor)(void *drv, AG_Cursor *curs);
+AG_Cursor *(*createCursor)(void *drv, Uint w, Uint h,
+ const Uint8 *data, const Uint8 *mask,
+ int xHot, int yHot);
void (*freeCursor)(void *drv, AG_Cursor *curs);
int (*setCursor)(void *drv, AG_Cursor *curs);
void (*unsetCursor)(void *drv);
< at >< at > -432,9 +434,14 < at >< at >
.Pp
The
.Fn createCursor
-operation registers a hardware cursor for the specified
-.Ft AG_Cursor
-structure, returning 0 on success or -1 on failure.
+operation creates a hardware cursor from the bitmap data
+.Fa data
+and transparency mask
+.Fa mask .
+The hotspot coordinates are given in
+.Fa xHot ,
+.Fa yHot .
+If a hardware cursor cannot be allocated, the call should return NULL.
.Fn freeCursor
destroys any hardware cursor corresponding to the given
.Ft AG_Cursor
Modified: trunk/gui/cursors.c
===================================================================
--- trunk/gui/cursors.c2015-02-19 15:08:42 UTC (rev 9771)
+++ trunk/gui/cursors.c2015-02-19 15:13:40 UTC (rev 9772)
< at >< at > -58,57 +58,27 < at >< at >
int xHot, int yHot)
{
AG_Driver *drv = obj;
-AG_Cursor *curs;
-Uint size = w*h;
+AG_Cursor *ac;
-if ((curs = TryMalloc(sizeof(AG_Cursor))) == NULL) {
+ac = AGDRIVER_CLASS(drv)->createCursor(drv, w, h, data, mask,
+ xHot, yHot);
+if (ac == NULL) {
return (NULL);
}
-if ((curs->data = TryMalloc(size)) == NULL) {
-free(curs);
-return (NULL);
-}
-if ((curs->mask = TryMalloc(size)) == NULL) {
-goto fail;
-}
-memcpy(curs->data, data, size);
-memcpy(curs->mask, mask, size);
-curs->w = w;
-curs->h = h;
-curs->xHot = xHot;
-curs->yHot = yHot;
-
-if (AGDRIVER_CLASS(drv)->createCursor(drv, curs) == -1) {
-goto fail;
-}
-TAILQ_INSERT_TAIL(&drv->cursors, curs, cursors);
+TAILQ_INSERT_TAIL(&drv->cursors, ac, cursors);
drv->nCursors++;
-return (curs);
-fail:
-free(curs->data);
-free(curs->mask);
-free(curs);
-return (NULL);
+return (ac);
}
-static __inline__ void
-FreeCursor(AG_Driver *drv, AG_Cursor *curs)
-{
-AGDRIVER_CLASS(drv)->freeCursor(drv, curs);
-free(curs->data);
-free(curs->mask);
-free(curs);
-}
-
/* Delete a registered cursor. */
void
-AG_CursorFree(void *obj, AG_Cursor *curs)
+AG_CursorFree(void *obj, AG_Cursor *ac)
{
AG_Driver *drv = obj;
-TAILQ_REMOVE(&drv->cursors, curs, cursors);
+TAILQ_REMOVE(&drv->cursors, ac, cursors);
drv->nCursors--;
-FreeCursor(drv, curs);
+AGDRIVER_CLASS(drv)->freeCursor(drv, ac);
}
/* Create a cursor from the contents of an XPM file. */
< at >< at > -177,7 +147,7 < at >< at >
ac != TAILQ_END(&drv->cursors);
ac = acNext) {
acNext = TAILQ_NEXT(ac, cursors);
-FreeCursor(drv, ac);
+AGDRIVER_CLASS(drv)->freeCursor(drv, ac);
}
TAILQ_INIT(&drv->cursors);
drv->nCursors = 0;
Modified: trunk/gui/drv.h
===================================================================
--- trunk/gui/drv.h2015-02-19 15:08:42 UTC (rev 9771)
+++ trunk/gui/drv.h2015-02-19 15:13:40 UTC (rev 9772)
< at >< at > -72,7 +72,7 < at >< at >
void (*pushBlendingMode)(void *drv, AG_BlendFn srcFn, AG_BlendFn dstFn);
void (*popBlendingMode)(void *drv);
/* Hardware cursor operations */
-int (*createCursor)(void *drv, struct ag_cursor *curs);
+struct ag_cursor *(*createCursor)(void *drv, Uint w, Uint h, const Uint8 *data, const Uint8 *mask, int xHot, int yHot);
void (*freeCursor)(void *drv, struct ag_cursor *curs);
int (*setCursor)(void *drv, struct ag_cursor *curs);
void (*unsetCursor)(void *drv);
Modified: trunk/gui/drv_glx.c
===================================================================
--- trunk/gui/drv_glx.c2015-02-19 15:08:42 UTC (rev 9771)
+++ trunk/gui/drv_glx.c2015-02-19 15:13:40 UTC (rev 9772)
< at >< at > -94,6 +94,7 < at >< at >
#include <agar/gui/drv_glx_keymaps.h>
typedef struct ag_cursor_glx {
+struct ag_cursor _inherit;
XColor black;
XColor white;
Cursor xc;
< at >< at > -899,38 +900,61 < at >< at >
* Cursor operations
*/
-static int
-GLX_CreateCursor(void *obj, AG_Cursor *ac)
+static AG_Cursor *
+GLX_CreateCursor(void *obj, Uint w, Uint h, const Uint8 *data, const Uint8 *mask,
+ int xHot, int yHot)
{
AG_DriverGLX *glx = obj;
-AG_CursorGLX *cg;
-int i, size;
+AG_Cursor *ac;
+AG_CursorGLX *acGLX;
+Uint size = w*h, dataSize;
+int i;
char *xData, *xMask;
XGCValues gcVals;
GC gc;
XImage *dataImg, *maskImg;
Pixmap dataPixmap, maskPixmap;
-if ((cg = TryMalloc(sizeof(AG_CursorGLX))) == NULL) {
-return (-1);
+/*
+ * Initialize generic Agar cursor part.
+ */
+if ((ac = acGLX = TryMalloc(sizeof(AG_CursorGLX))) == NULL) {
+return (NULL);
}
-memset(&cg->black, 0, sizeof(cg->black));
-cg->white.pixel = 0xffff;
-cg->white.red = 0xffff;
-cg->white.green = 0xffff;
-cg->white.blue = 0xffff;
+if ((ac->data = TryMalloc(size)) == NULL) {
+free(ac);
+return (NULL);
+}
+if ((ac->mask = TryMalloc(size)) == NULL) {
+free(ac->data);
+free(ac);
+return (NULL);
+}
+memcpy(ac->data, data, size);
+memcpy(ac->mask, mask, size);
+ac->w = w;
+ac->h = h;
+ac->xHot = xHot;
+ac->yHot = yHot;
-size = (ac->w/8)*ac->h;
-if ((xData = TryMalloc(size)) == NULL) {
-free(cg);
-return (-1);
+/*
+ * Initialize X11-specific part.
+ */
+memset(&acGLX->black, 0, sizeof(acGLX->black));
+acGLX->white.pixel = 0xffff;
+acGLX->white.red = 0xffff;
+acGLX->white.green = 0xffff;
+acGLX->white.blue = 0xffff;
+
+dataSize = (ac->w / 8) * ac->h;
+if ((xData = TryMalloc(dataSize)) == NULL) {
+goto fail;
}
-if ((xMask = TryMalloc(size)) == NULL) {
+if ((xMask = TryMalloc(dataSize)) == NULL) {
free(xData);
-free(cg);
-return (-1);
+goto fail;
}
-for (i = 0; i < size; i++) {
+for (i = 0; i < dataSize; i++) {
xMask[i] = ac->data[i] | ac->mask[i];
xData[i] = ac->data[i];
}
< at >< at > -973,40 +997,43 < at >< at >
XDestroyImage(maskImg);
/* Create the X cursor */
-cg->xc = XCreatePixmapCursor(agDisplay, dataPixmap, maskPixmap,
- &cg->black, &cg->white, ac->xHot, ac->yHot);
-cg->visible = 0;
+acGLX->xc = XCreatePixmapCursor(agDisplay, dataPixmap, maskPixmap,
+ &acGLX->black, &acGLX->white, ac->xHot, ac->yHot);
+acGLX->visible = 0;
XFreePixmap(agDisplay, dataPixmap);
XFreePixmap(agDisplay, maskPixmap);
AG_MutexUnlock(&glx->lock);
AG_MutexUnlock(&agDisplayLock);
-
-XSync(agDisplay, False);
-
-ac->p = cg;
-return (0);
+return (ac);
+fail:
+free(ac->data);
+free(ac->mask);
+free(ac);
+return (NULL);
}
static void
GLX_FreeCursor(void *obj, AG_Cursor *ac)
{
AG_DriverGLX *glx = obj;
-AG_CursorGLX *cg = ac->p;
+AG_CursorGLX *acGLX = (AG_CursorGLX *)ac;
AG_MutexLock(&agDisplayLock);
AG_MutexLock(&glx->lock);
-XFreeCursor(agDisplay, cg->xc);
+if (ac == drv->activeCursor)
+drv->activeCursor = NULL;
+
+XFreeCursor(agDisplay, acGLX->xc);
AG_MutexUnlock(&glx->lock);
AG_MutexUnlock(&agDisplayLock);
-XSync(agDisplay, False);
-
-free(cg);
-ac->p = NULL;
+free(ac->data);
+free(ac->mask);
+free(ac);
}
static int
< at >< at > -1016,9 +1043,8 < at >< at >
AG_DriverGLX *glx = obj;
AG_CursorGLX *cg = ac->p;
-if (drv->activeCursor == ac) {
+if (drv->activeCursor == ac)
return (0);
-}
AG_MutexLock(&agDisplayLock);
AG_MutexLock(&glx->lock);
Modified: trunk/gui/drv_sdl_common.c
===================================================================
--- trunk/gui/drv_sdl_common.c2015-02-19 15:08:42 UTC (rev 9771)
+++ trunk/gui/drv_sdl_common.c2015-02-19 15:13:40 UTC (rev 9772)
< at >< at > -484,10 +484,30 < at >< at >
}
/* Create a cursor. */
-int
-AG_SDL_CreateCursor(void *obj, AG_Cursor *ac)
+AG_Cursor *
+AG_SDL_CreateCursor(void *obj, Uint w, Uint h, const Uint8 *data,
+ const Uint8 *mask, int xHot, int yHot)
{
+AG_Cursor *ac;
SDL_Cursor *sc;
+Uint size = w*h;
+
+if ((ac = TryMalloc(sizeof(AG_Cursor))) == NULL) {
+return (NULL);
+}
+if ((ac->data = TryMalloc(size)) == NULL) {
+goto fail;
+}
+if ((ac->mask = TryMalloc(size)) == NULL) {
+free(ac->data);
+goto fail;
+}
+memcpy(ac->data, data, size);
+memcpy(ac->mask, mask, size);
+ac->w = w;
+ac->h = h;
+ac->xHot = xHot;
+ac->yHot = yHot;
sc = SDL_CreateCursor(ac->data, ac->mask,
ac->w, ac->h,
< at >< at > -497,7 +517,12 < at >< at >
return (-1);
}
ac->p = (void *)sc;
-return (0);
+return (ac);
+fail:
+free(ac->data);
+free(ac->mask);
+free(ac);
+return (NULL);
}
/* Release a cursor. */
< at >< at > -506,11 +531,13 < at >< at >
{
AG_Driver *drv = obj;
-if (ac == TAILQ_FIRST(&drv->cursors))
-return;
+if (ac == drv->activeCursor)
+drv->activeCursor = NULL;
SDL_FreeCursor((SDL_Cursor *)(ac->p));
-ac->p = NULL;
+free(ac->data);
+free(ac->mask);
+free(ac);
}
/* Retrieve cursor visibility status. */
Modified: trunk/gui/drv_sdl_common.h
===================================================================
--- trunk/gui/drv_sdl_common.h2015-02-19 15:08:42 UTC (rev 9771)
+++ trunk/gui/drv_sdl_common.h2015-02-19 15:13:40 UTC (rev 9772)
< at >< at > -44,7 +44,7 < at >< at >
int AG_SDL_InitDefaultCursor(void *);
int AG_SDL_SetCursor(void *, AG_Cursor *);
void AG_SDL_UnsetCursor(void *);
-int AG_SDL_CreateCursor(void *, AG_Cursor *);
+AG_Cursor *AG_SDL_CreateCursor(void *, Uint, Uint, const Uint8 *, const Uint8 *, int, int);
void AG_SDL_FreeCursor(void *, AG_Cursor *);
int AG_SDL_GetCursorVisibility(void *);
void AG_SDL_SetCursorVisibility(void *, int);
Modified: trunk/gui/drv_wgl.c
===================================================================
--- trunk/gui/drv_wgl.c2015-02-19 15:08:42 UTC (rev 9771)
+++ trunk/gui/drv_wgl.c2015-02-19 15:13:40 UTC (rev 9772)
< at >< at > -65,6 +65,8 < at >< at >
} AG_DriverWGL;
typedef struct ag_cursor_wgl {
+struct ag_cursor _inherit;
+int shared;/* Shared cursor */
COLORREF black;
COLORREF white;
HCURSOR cursor;
< at >< at > -1125,91 +1127,114 < at >< at >
for (i = 0; i < nStockCursors; i++) {
AG_Cursor *ac;
-struct ag_cursor_wgl *cg;
+AG_CursorWGL *acWGL;
-if ((ac = TryMalloc(sizeof(AG_Cursor))) == NULL) {
+if ((acWGL = TryMalloc(sizeof(AG_CursorWGL))) == NULL) {
return (-1);
}
-if ((cg = TryMalloc(sizeof(struct ag_cursor_wgl))) == NULL) {
-free(ac);
-return (-1);
-}
-ac->p = cg;
-cg->cursor = LoadCursor(NULL, IDC_ARROW);
+ac = (AG_Cursor *)acWGL;
+acWGL->shared = 1;
+acWGL->cursor = LoadCursor(NULL, IDC_ARROW);
AG_CursorInit(ac);
-
TAILQ_INSERT_HEAD(&drv->cursors, ac, cursors);
drv->nCursors++;
}
return (0);
}
-static int
-WGL_CreateCursor(void *obj, AG_Cursor *ac)
+static AG_Cursor *
+WGL_CreateCursor(void *obj, Uint w, Uint h, const Uint8 *data, const Uint8 *mask,
+ int xHot, int yHot)
{
-AG_CursorWGL *cg;
-int size, i;
-BYTE *xorMask, *andMask;
+AG_Cursor *ac;
+AG_CursorWGL *acWGL;
+int dataSize, i;
+BYTE *xorMask, *andMask;
+Uint size = w*h;
-if ((cg = TryMalloc(sizeof(AG_CursorWGL))) == NULL) {
-return (-1);
+/*
+ * Initialize generic Agar cursor part.
+ */
+if ((acWGL = TryMalloc(sizeof(AG_CursorWGL))) == NULL) {
+return (NULL);
}
-cg->black = RGB(0, 0, 0);
-cg->white = RGB(0xFF, 0xFF, 0xFF);
-
-/* Calc size for cursor data */
-size = (ac->w / 8) * ac->h;
+ac = (AG_Cursor *)acWGL;
-/* Allocate memory for xorMask (which represents the cursor data) */
-if ((xorMask = TryMalloc(size)) == NULL) {
-free(cg);
-return (-1);
+if ((ac->data = TryMalloc(size)) == NULL) {
+goto fail;
}
+if ((ac->mask = TryMalloc(size)) == NULL) {
+free(ac->data);
+goto fail;
+}
+memcpy(ac->data, data, size);
+memcpy(ac->mask, mask, size);
+ac->w = w;
+ac->h = h;
+ac->xHot = xHot;
+ac->yHot = yHot;
-/* Allocate memory for andMask (which represents the transparence) */
-if ((andMask = TryMalloc(size)) == NULL) {
+/*
+ * Initialize Windows-specific part.
+ */
+acWGL->shared = 0;
+acWGL->black = RGB(0, 0, 0);
+acWGL->white = RGB(0xFF, 0xFF, 0xFF);
+
+dataSize = (ac->w / 8) * ac->h;
+if ((xorMask = TryMalloc(dataSize)) == NULL) {
+free(ac->data);
+goto fail;
+}
+if ((andMask = TryMalloc(dataSize)) == NULL) {
free(xorMask);
-free(cg);
-return (-1);
+free(ac->data);
+goto fail;
}
-
-/* Copy cursor data into buffers for use with CreateCursor */
-for (i = 0; i < size; i++) {
+for (i = 0; i < dataSize; i++) {
andMask[i] = ~ac->mask[i];
xorMask[i] = ~ac->data[i] ^ ~ac->mask[i];
}
-/* Create cursor */
-if ((cg->cursor = CreateCursor(GetModuleHandle(NULL),
- ac->xHot, ac->yHot, ac->w, ac->h, andMask, xorMask))) {
-ac->p = cg;
-return (0);
+acWGL->cursor = CreateCursor(GetModuleHandle(NULL), ac->xHot, ac->yHot,
+ ac->w, ac->h, andMask, xorMask);
+if (!acWGL->cursor) {
+WGL_SetWindowsError("CreateCursor", GetLastError());
+goto fail;
}
-
-WGL_SetWindowsError("CreateCursor failed!", GetLastError());
-return (-1);
+return (ac);
+fail:
+free(ac);
+return (NULL);
}
static void
WGL_FreeCursor(void *obj, AG_Cursor *ac)
{
-AG_CursorWGL *cg = ac->p;
-
-DestroyCursor(cg->cursor);
-free(cg);
-ac->p = NULL;
+AG_Driver *drv = obj;
+AG_CursorWGL *acWGL = (AG_CursorWGL *)ac;
+
+if (ac == drv->activeCursor) {
+drv->activeCursor = NULL;
+}
+if (!acWGL->shared) {
+DestroyCursor(acWGL->cursor);
+}
+free(ac->data);
+free(ac->mask);
+free(ac);
}
static int
WGL_SetCursor(void *obj, AG_Cursor *ac)
{
AG_Driver *drv = obj;
-AG_CursorWGL *cg = ac->p;
+AG_CursorWGL *acWGL = (AG_CursorWGL *)ac;
if (drv->activeCursor == ac) {
return (0);
}
-SetCursor(cg->cursor);
+SetCursor(acWGL->cursor);
drv->activeCursor = ac;
return (0);
}
[Less]
|
Posted
over 10 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-19 10:07:13 -0500 (Thu, 19 Feb 2015)
New Revision: 9768
Modified:
trunk/core/variable.c
Log:
use explicit %llu to print long long unsigned ints
Modified: trunk/core/variable.c
... [More]
===================================================================
--- trunk/core/variable.c2015-02-19 15:06:48 UTC (rev 9767)
trunk/core/variable.c2015-02-19 15:07:13 UTC (rev 9768)
< at >< at > -241,6 241,8 < at >< at >
#ifdef HAVE_64BIT
case AG_VARIABLE_SINT64:Snprintf(s, len, "%lld", (long long)V->data.s64);break;
case AG_VARIABLE_P_SINT64:Snprintf(s, len, "%lld", (long long)*(Sint64 *)V->data.p);break;
case AG_VARIABLE_UINT64:Snprintf(s, len, "%llu", (unsigned long long)V->data.u64);break;
case AG_VARIABLE_P_UINT64:Snprintf(s, len, "%llu", (unsigned long long)*(Sint64 *)V->data.p);break;
#endif
case AG_VARIABLE_FLOAT:Snprintf(s, len, "%.2f", V->data.flt);break;
case AG_VARIABLE_P_FLOAT:Snprintf(s, len, "%.2f", *(float *)V->data.p);break;
[Less]
|