Gfxprim
Threads by month
- ----- 2026 -----
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- 929 discussions
[repo.or.cz] gfxprim.git branch master updated: cb2c440163c18fe8cdbe96969ea28fe38da3fb56
by metan 08 Mar '13
by metan 08 Mar '13
08 Mar '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via cb2c440163c18fe8cdbe96969ea28fe38da3fb56 (commit)
from abee71632bc9666b9b9c483868f17c9920be6343 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/cb2c440163c18fe8cdbe96969ea28fe38da3…
commit cb2c440163c18fe8cdbe96969ea28fe38da3fb56
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Mar 8 13:46:32 2013 +0100
tests: filters: Add dump API Coverage generator.
diff --git a/tests/filters/APICoverage.gen.c.t b/tests/filters/APICoverage.gen.c.t
new file mode 100644
index 0000000..3b46006
--- /dev/null
+++ b/tests/filters/APICoverage.gen.c.t
@@ -0,0 +1,140 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim 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 gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ The purpose of this test is to exercise as much codepaths as possible
+ without checking for result corectness.
+
+ */
+
+%% extends "base.test.c.t"
+
+%% block body
+
+#include <stdio.h>
+
+#include <core/GP_Context.h>
+#include <filters/GP_Filters.h>
+
+#include "tst_test.h"
+
+%% set API_List = [['MirrorH', 'GP_Context:in', 'GP_Context:out', 'GP_ProgressCallback'],
+ ['MirrorH_Alloc', 'GP_Context:in', 'GP_ProgressCallback'],
+
+ ['MirrorV', 'GP_Context:in', 'GP_Context:out', 'GP_ProgressCallback'],
+ ['MirrorV_Alloc', 'GP_Context:in', 'GP_ProgressCallback'],
+
+ ['Rotate90', 'GP_Context:in', 'GP_Context:out', 'GP_ProgressCallback'],
+ ['Rotate90_Alloc', 'GP_Context:in', 'GP_ProgressCallback'],
+
+ ['Rotate180', 'GP_Context:in', 'GP_Context:out', 'GP_ProgressCallback'],
+ ['Rotate180_Alloc', 'GP_Context:in', 'GP_ProgressCallback'],
+
+ ['Rotate270', 'GP_Context:in', 'GP_Context:out', 'GP_ProgressCallback'],
+ ['Rotate270_Alloc', 'GP_Context:in', 'GP_ProgressCallback'],
+
+ ['GaussianBlur', 'GP_Context:in', 'GP_Context:out',
+ 'float:sigma_x', 'float:sigma_y', 'GP_ProgressCallback'],
+ ['GaussianBlurAlloc', 'GP_Context:in', 'float:sigma_x',
+ 'float:sigma_y', 'GP_ProgressCallback'],
+
+ ['GaussianNoiseAdd', 'GP_Context:in', 'GP_Context:out',
+ 'float:sigma', 'float:mu', 'GP_ProgressCallback'],
+ ['GaussianNoiseAddAlloc', 'GP_Context:in',
+ 'float:sigma', 'float:mu', 'GP_ProgressCallback'],
+
+ ['Median', 'GP_Context:in', 'GP_Context:out',
+ 'int:xmed', 'int:ymed', 'GP_ProgressCallback'],
+ ['MedianAlloc', 'GP_Context:in',
+ 'int:xmed', 'int:ymed', 'GP_ProgressCallback'],
+
+ ['Sigma', 'GP_Context:in', 'GP_Context:out',
+ 'int:xrad', 'int:yrad', 'int:min', 'float:sigma', 'GP_ProgressCallback'],
+ ['SigmaAlloc', 'GP_Context:in',
+ 'int:xrad', 'int:yrad', 'int:min', 'float:sigma', 'GP_ProgressCallback'],
+
+ ['ResizeNN', 'GP_Context:in', 'GP_Context:out', 'GP_ProgressCallback'],
+ ['ResizeNNAlloc', 'GP_Context:in', 'int:w', 'int:h', 'GP_ProgressCallback'],
+]
+
+%% macro prep_context(id, pt)
+ GP_Context *{{ id }} = GP_ContextAlloc(113, 900, GP_PIXEL_{{ pt.name }});
+%% endmacro
+
+%% macro prep_float(id)
+ float {{ id }} = 1;
+%% endmacro
+
+%% macro prep_int(id)
+ int {{ id }} = 2;
+%% endmacro
+
+%% macro prep_param(param, pt)
+%% if (param.split(':', 1)[0] == 'GP_Context')
+{{ prep_context(param.split(':', 1)[1], pt) }}
+%% endif
+%% if (param.split(':', 1)[0] == 'float')
+{{ prep_float(param.split(':', 1)[1]) }}
+%% endif
+%% if (param.split(':', 1)[0] == 'int')
+{{ prep_int(param.split(':', 1)[1]) }}
+%% endif
+%% endmacro
+
+{% macro get_param(param) %}{% if len(param.split(':', 1)) == 1 %}NULL{% else %}{{ param.split(':', 1)[1] }}{% endif %}{% endmacro %}
+
+%% for pt in pixeltypes
+%% if not pt.is_unknown()
+%% for fn in API_List
+
+static int Filter_{{ fn[0]}}_{{ pt.name }}(void)
+{
+%% for param in fn[1:]
+{{ prep_param(param, pt) }}
+%% endfor
+
+ GP_Filter{{ fn[0] }}({{ get_param(fn[1]) }}{% for param in fn[2:] %}, {{ get_param(param) }}{% endfor %});
+
+ return TST_SUCCESS;
+}
+
+%% endfor
+%% endif
+%% endfor
+
+const struct tst_suite tst_suite = {
+ .suite_name = "Filters API Coverage",
+ .tests = {
+%% for fn in API_List
+%% for pt in pixeltypes
+%% if not pt.is_unknown()
+ {.name = "Filter {{ fn[0] }} {{ pt.name }}",
+ .tst_fn = Filter_{{ fn[0] }}_{{ pt.name }}},
+%% endif
+%% endfor
+%% endfor
+ {.name = NULL}
+ }
+};
+
+%% endblock body
diff --git a/tests/filters/Makefile b/tests/filters/Makefile
index b0a590d..bda08a5 100644
--- a/tests/filters/Makefile
+++ b/tests/filters/Makefile
@@ -1,13 +1,16 @@
TOPDIR=../..
include $(TOPDIR)/pre.mk
-CSOURCES=$(shell echo *.c)
+CSOURCES=FilterMirrorH.c
-APPS=FilterMirrorH
+GENSOURCES=APICoverage.gen.c
+
+APPS=FilterMirrorH APICoverage.gen
include ../tests.mk
FilterMirrorH: common.o
+include $(TOPDIR)/gen.mk
include $(TOPDIR)/app.mk
include $(TOPDIR)/post.mk
diff --git a/tests/filters/runtest.sh b/tests/filters/runtest.sh
index c820af1..6b11a77 100755
--- a/tests/filters/runtest.sh
+++ b/tests/filters/runtest.sh
@@ -10,3 +10,4 @@
export LIBC_FATAL_STDERR_=1
LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./FilterMirrorH "$@"
+LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./APICoverage.gen "$@"
diff --git a/tests/filters/test_list.txt b/tests/filters/test_list.txt
index 2f9a127..4b3dee1 100644
--- a/tests/filters/test_list.txt
+++ b/tests/filters/test_list.txt
@@ -1,3 +1,4 @@
# Filters test list
+APICoverage.gen
FilterMirrorH
-----------------------------------------------------------------------
Summary of changes:
tests/filters/APICoverage.gen.c.t | 140 +++++++++++++++++++++++++++++++++++++
tests/filters/Makefile | 7 ++-
tests/filters/runtest.sh | 1 +
tests/filters/test_list.txt | 1 +
4 files changed, 147 insertions(+), 2 deletions(-)
create mode 100644 tests/filters/APICoverage.gen.c.t
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: abee71632bc9666b9b9c483868f17c9920be6343
by metan 03 Mar '13
by metan 03 Mar '13
03 Mar '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via abee71632bc9666b9b9c483868f17c9920be6343 (commit)
from 51f403b8ec7418bee0bc1e80fd80136ad9d88586 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/abee71632bc9666b9b9c483868f17c9920be…
commit abee71632bc9666b9b9c483868f17c9920be6343
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Mar 3 23:48:49 2013 +0100
doc: filters: Add link to progress callback description.
diff --git a/doc/filters.txt b/doc/filters.txt
index dba963e..adc5ce7 100644
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -19,7 +19,7 @@ For convenience, the filters API is unified:
* First argument(s) are always source(s)
* Then, in case of second variant, destination
* Other parameters follow
-* And the last argument is progress callback
+* And the last argument is link:progress_callback.html[progress callback]
When using allocating version of the filter, pointer to the newly allocated
context is returned, or in case of failure 'NULL' is returned.
-----------------------------------------------------------------------
Summary of changes:
doc/filters.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 51f403b8ec7418bee0bc1e80fd80136ad9d88586
by metan 03 Mar '13
by metan 03 Mar '13
03 Mar '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 51f403b8ec7418bee0bc1e80fd80136ad9d88586 (commit)
from 443c7577a6a1961dde7b5a150e9a3ec25d317260 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/51f403b8ec7418bee0bc1e80fd80136ad9d8…
commit 51f403b8ec7418bee0bc1e80fd80136ad9d88586
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Mar 3 23:43:18 2013 +0100
filters: FilterMirrorH: Small fixes, more to come.
diff --git a/libs/filters/GP_Rotate.c b/libs/filters/GP_Rotate.c
index 7bfa309..a164886 100644
--- a/libs/filters/GP_Rotate.c
+++ b/libs/filters/GP_Rotate.c
@@ -16,14 +16,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2011 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
+#include <errno.h>
+
#include "core/GP_Core.h"
#include "core/GP_FnPerBpp.h"
-#include "GP_Rotate.h"
+#include "filters/GP_Rotate.h"
#include <string.h>
@@ -32,34 +34,39 @@ int GP_FilterMirrorH_Raw(const GP_Context *src, GP_Context *dst,
{
uint32_t bpr = src->bytes_per_row;
uint8_t buf[bpr];
- uint32_t y;
+ unsigned int y;
GP_DEBUG(1, "Mirroring image horizontally %ux%u", src->w, src->h);
#warning FIXME: non byte aligned pixels
-
+
/* Note that this should work both for src != dst and src == dst */
for (y = 0; y < src->h/2; y++) {
- uint8_t *sl1 = src->pixels + bpr * y;
- uint8_t *sl2 = src->pixels + bpr * (src->h - y - 1);
- uint8_t *dl1 = dst->pixels + bpr * y;
- uint8_t *dl2 = dst->pixels + bpr * (src->h - y - 1);
+ uint8_t *sl1 = GP_PIXEL_ADDR(src, 0, y);
+ uint8_t *sl2 = GP_PIXEL_ADDR(src, 0, src->h - y - 1);
+ uint8_t *dl1 = GP_PIXEL_ADDR(dst, 0, y);
+ uint8_t *dl2 = GP_PIXEL_ADDR(dst, 0, src->h - y - 1);
+
+ int i;
memcpy(buf, sl1, bpr);
memcpy(dl1, sl2, bpr);
memcpy(dl2, buf, bpr);
- if (GP_ProgressCallbackReport(callback, 2 * y, src->h, src->w))
+ if (GP_ProgressCallbackReport(callback, 2 * y, src->h, src->w)) {
+ GP_DEBUG(1, "Operation aborted");
+ errno = ECANCELED;
return 1;
+ }
}
/* Copy the middle odd line */
if (src != dst && src->h % 2) {
y = src->h / 2;
- uint8_t *sl = src->pixels + bpr * y;
- uint8_t *dl = dst->pixels + bpr * y;
-
+ uint8_t *sl = GP_PIXEL_ADDR(src, 0, y);
+ uint8_t *dl = GP_PIXEL_ADDR(dst, 0, y);
+
memcpy(dl, sl, bpr);
}
@@ -76,10 +83,8 @@ int GP_FilterMirrorH(const GP_Context *src, GP_Context *dst,
GP_ASSERT(src->w <= dst->w && src->h <= dst->h,
"Destination is not large enough");
- if (GP_FilterMirrorH_Raw(src, dst, callback)) {
- GP_DEBUG(1, "Operation aborted");
+ if (GP_FilterMirrorH_Raw(src, dst, callback))
return 1;
- }
return 0;
}
-----------------------------------------------------------------------
Summary of changes:
libs/filters/GP_Rotate.c | 35 ++++++++++++++++++++---------------
1 files changed, 20 insertions(+), 15 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 443c7577a6a1961dde7b5a150e9a3ec25d317260
by metan 03 Mar '13
by metan 03 Mar '13
03 Mar '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 443c7577a6a1961dde7b5a150e9a3ec25d317260 (commit)
from 8ac4aa41dac9e27830da30fc1b2804f4404edaa5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/443c7577a6a1961dde7b5a150e9a3ec25d31…
commit 443c7577a6a1961dde7b5a150e9a3ec25d317260
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Mar 3 22:57:55 2013 +0100
tests: filters: Add basic test for MirrorH filter.
diff --git a/tests/filters/FilterMirrorH.c b/tests/filters/FilterMirrorH.c
new file mode 100644
index 0000000..8aa50ac
--- /dev/null
+++ b/tests/filters/FilterMirrorH.c
@@ -0,0 +1,311 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim 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 gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <errno.h>
+
+#include <core/GP_Context.h>
+#include <filters/GP_Rotate.h>
+
+#include "tst_test.h"
+
+#include "common.h"
+
+struct testcase {
+ GP_Size w, h;
+
+ GP_PixelType pixel_type;
+
+ uint8_t offset;
+
+ /* result */
+ const char *res;
+
+ /* source */
+ char src[];
+};
+
+static int test_mirror_h(struct testcase *t)
+{
+ GP_Context src, *c;
+ int err;
+
+ /* Initialize source context */
+ GP_ContextInit(&src, t->w, t->h, t->pixel_type, t->src);
+
+ /* Set offset to emulate non-byte aligned subcontexts */
+ src.offset = t->offset;
+
+ /* Test with allocated destination */
+ c = GP_ContextAlloc(t->w, t->h, t->pixel_type);
+
+ if (c == NULL) {
+ tst_err("Failed to allocate context");
+ return TST_UNTESTED;
+ }
+
+ GP_FilterMirrorH(&src, c, NULL);
+
+ err = compare_buffers(t->res, c);
+
+ GP_ContextFree(c);
+
+ /* And with in-place variant */
+// GP_FilterMirrorH(&src, &src, NULL);
+
+// err |= compare_buffers(t->res, &src);
+
+ if (err)
+ return TST_FAILED;
+
+ return TST_SUCCESS;
+}
+
+struct testcase testcase_1x1 = {
+ .w = 1,
+ .h = 1,
+
+ .pixel_type = GP_PIXEL_G8,
+
+ .res = (const char[]) {
+ 0xf0,
+ },
+
+ .src = {
+ 0xf0,
+ }
+};
+
+struct testcase testcase_2x2 = {
+ .w = 2,
+ .h = 2,
+
+ .pixel_type = GP_PIXEL_G8,
+
+ .res = (const char[]) {
+ 2, 3,
+ 0, 1,
+ },
+
+ .src = {
+ 0, 1,
+ 2, 3,
+ }
+};
+
+struct testcase testcase_10x2 = {
+ .w = 10,
+ .h = 2,
+
+ .pixel_type = GP_PIXEL_G8,
+
+ .res = (const char[]) {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ },
+
+ .src = {
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ }
+};
+
+struct testcase testcase_2x3 = {
+ .w = 2,
+ .h = 3,
+
+ .pixel_type = GP_PIXEL_G8,
+
+ .res = (const char[]) {
+ 4, 5,
+ 2, 3,
+ 0, 1,
+ },
+
+ .src = {
+ 0, 1,
+ 2, 3,
+ 4, 5,
+ }
+};
+
+
+struct testcase testcase_3x3 = {
+ .w = 3,
+ .h = 3,
+
+ .pixel_type = GP_PIXEL_G8,
+
+ .res = (const char[]) {
+ 6, 7, 8,
+ 3, 4, 5,
+ 0, 1, 2,
+ },
+
+ .src = {
+ 0, 1, 2,
+ 3, 4, 5,
+ 6, 7, 8,
+ }
+};
+
+struct testcase testcase_4x4 = {
+ .w = 4,
+ .h = 4,
+
+ .pixel_type = GP_PIXEL_G8,
+
+ .res = (const char[]) {
+ 12, 13, 14, 15,
+ 8, 9, 10, 11,
+ 4, 5, 6, 7,
+ 0, 1, 2, 3,
+ },
+
+ .src = {
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 9, 10, 11,
+ 12, 13, 14, 15,
+ }
+};
+
+/* Now tests with pixel types that are not byte aligned */
+//TODO: Fix comparsion
+struct testcase testcase_G1_16x2 = {
+ .w = 3,
+ .h = 2,
+
+ .pixel_type = GP_PIXEL_G1,
+
+ .offset = 4,
+
+ .res = (const char[]) {
+ 0x0f, 0xaa, 0xf0,
+ 0xff, 0xff, 0xff,
+ },
+
+ .src = {
+ 0x0f, 0xff, 0xf0,
+ 0xff, 0xaa, 0xff,
+ }
+};
+
+static int abort_callback_fn(GP_ProgressCallback GP_UNUSED(*self))
+{
+ return 1;
+}
+
+static GP_ProgressCallback abort_callback = {
+ .callback = abort_callback_fn,
+};
+
+static int test_abort(void)
+{
+ int ret;
+ GP_Context *c;
+
+ c = GP_ContextAlloc(10, 10, GP_PIXEL_G8);
+
+ if (c == NULL) {
+ tst_err("Failed to allocate context");
+ return TST_UNTESTED;
+ }
+
+ ret = GP_FilterMirrorH(c, c, &abort_callback);
+
+ if (ret == 0) {
+ tst_msg("Aborted filter haven't returned non-zero");
+ return TST_FAILED;
+ }
+
+ if (errno != ECANCELED) {
+ tst_msg("Errno wasn't set to ECANCELED");
+ return TST_FAILED;
+ }
+
+ return TST_SUCCESS;
+}
+
+static int all_pixels(void)
+{
+ GP_Pixel pixel_type;
+
+ for (pixel_type = 1; pixel_type < GP_PIXEL_MAX; pixel_type++) {
+ GP_Context *c;
+
+ tst_msg("Trying pixel %s", GP_PixelTypeName(pixel_type));
+
+ c = GP_ContextAlloc(10, 10, pixel_type);
+
+ if (c == NULL) {
+ tst_err("Failed to allocate context");
+ return TST_UNTESTED;
+ }
+
+ GP_FilterMirrorH(c, c, NULL);
+
+ GP_ContextFree(c);
+ }
+
+ return TST_SUCCESS;
+}
+
+const struct tst_suite tst_suite = {
+ .suite_name = "MirrorH Filter Testsuite",
+ .tests = {
+ {.name = "MirrorH 1x1",
+ .tst_fn = test_mirror_h,
+ .data = &testcase_1x1},
+
+ {.name = "MirrorH 2x2",
+ .tst_fn = test_mirror_h,
+ .data = &testcase_2x2},
+
+ {.name = "MirrorH 10x2",
+ .tst_fn = test_mirror_h,
+ .data = &testcase_10x2},
+
+ {.name = "MirrorH 2x3",
+ .tst_fn = test_mirror_h,
+ .data = &testcase_2x3},
+
+ {.name = "MirrorH 3x3",
+ .tst_fn = test_mirror_h,
+ .data = &testcase_3x3},
+
+ {.name = "MirrorH 4x4",
+ .tst_fn = test_mirror_h,
+ .data = &testcase_3x3},
+
+ {.name = "MirrorH G1 16x2",
+ .tst_fn = test_mirror_h,
+ .data = &testcase_G1_16x2},
+
+ {.name = "MirrorH Callback Abort",
+ .tst_fn = test_abort},
+
+ {.name = "MirrorH x Pixels",
+ .tst_fn = all_pixels},
+
+ {.name = NULL}
+ }
+};
diff --git a/tests/filters/Makefile b/tests/filters/Makefile
index aaa6125..b0a590d 100644
--- a/tests/filters/Makefile
+++ b/tests/filters/Makefile
@@ -3,9 +3,11 @@ include $(TOPDIR)/pre.mk
CSOURCES=$(shell echo *.c)
-APPS=LinearConvolution
+APPS=FilterMirrorH
include ../tests.mk
+FilterMirrorH: common.o
+
include $(TOPDIR)/app.mk
include $(TOPDIR)/post.mk
diff --git a/tests/filters/common.c b/tests/filters/common.c
new file mode 100644
index 0000000..35a6d13
--- /dev/null
+++ b/tests/filters/common.c
@@ -0,0 +1,87 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim 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 gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#include <stdio.h>
+
+#include "common.h"
+
+static void dump_buffer(const char *pattern, int w, int h)
+{
+ int x, y;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++)
+ printf("%2x ", (uint8_t)pattern[x + y * w]);
+ printf("n");
+ }
+}
+
+void dump_buffers(const char *pattern, const GP_Context *c)
+{
+ printf("Expected pattern:n");
+ dump_buffer(pattern, c->w, c->h);
+ printf("Rendered pattern:n");
+ dump_buffer((char*)c->pixels, c->w, c->h);
+ printf("Difference:n");
+
+ unsigned int x, y;
+
+ for (y = 0; y < c->h; y++) {
+ for (x = 0; x < c->w; x++) {
+ unsigned int idx = x + y * c->w;
+ char p = ((char*)c->pixels)[idx];
+
+ if (pattern[idx] != p) {
+ /* TODO: we expect background to be 0 */
+ if (p == 0)
+ printf(" x ");
+ else
+ printf(" * ");
+ } else {
+ printf("%2x ", (uint8_t)pattern[idx]);
+ }
+
+ }
+
+ printf("n");
+ }
+}
+
+int compare_buffers(const char *pattern, const GP_Context *c)
+{
+ GP_Size x, y;
+ int err = 0;
+
+ for (x = 0; x < c->w; x++) {
+ for (y = 0; y < c->h; y++) {
+ unsigned int idx = x + y * c->w;
+
+ if (pattern[idx] != ((char*)c->pixels)[idx])
+ err++;
+ }
+ }
+
+ if (err)
+ dump_buffers(pattern, c);
+
+ return err;
+}
diff --git a/tests/filters/common.h b/tests/filters/common.h
new file mode 100644
index 0000000..65b9d19
--- /dev/null
+++ b/tests/filters/common.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim 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 gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <core/GP_Context.h>
+
+void dump_buffers(const char *pattern, const GP_Context *c);
+
+int compare_buffers(const char *pattern, const GP_Context *c);
+
+#endif /* __COMMON_H__ */
diff --git a/tests/filters/runtest.sh b/tests/filters/runtest.sh
index 9efe909..c820af1 100755
--- a/tests/filters/runtest.sh
+++ b/tests/filters/runtest.sh
@@ -9,4 +9,4 @@
#
export LIBC_FATAL_STDERR_=1
-LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./LinearConvolution "$@"
+LD_PRELOAD=`pwd`/../framework/libtst_preload.so LD_LIBRARY_PATH=../../build/ ./FilterMirrorH "$@"
diff --git a/tests/filters/test_list.txt b/tests/filters/test_list.txt
new file mode 100644
index 0000000..2f9a127
--- /dev/null
+++ b/tests/filters/test_list.txt
@@ -0,0 +1,3 @@
+# Filters test list
+
+FilterMirrorH
-----------------------------------------------------------------------
Summary of changes:
tests/filters/FilterMirrorH.c | 311 +++++++++++++++++++++++++++++++++++++++
tests/filters/Makefile | 4 +-
tests/{gfx => filters}/common.c | 0
tests/{gfx => filters}/common.h | 0
tests/filters/runtest.sh | 2 +-
tests/filters/test_list.txt | 3 +
6 files changed, 318 insertions(+), 2 deletions(-)
create mode 100644 tests/filters/FilterMirrorH.c
copy tests/{gfx => filters}/common.c (100%)
copy tests/{gfx => filters}/common.h (100%)
create mode 100644 tests/filters/test_list.txt
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 8ac4aa41dac9e27830da30fc1b2804f4404edaa5
by metan 03 Mar '13
by metan 03 Mar '13
03 Mar '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 8ac4aa41dac9e27830da30fc1b2804f4404edaa5 (commit)
via 8bfe15827e2fc8dcdee58cf3d435a78e8b9955b8 (commit)
via 5614a72ad692285e00909d83a971eab6e0aa6199 (commit)
via fad224dbbcdf6744e57cbf0ca235f226e37f794a (commit)
from 402373dac8551c34bf48ceeba4aace19cee0eea9 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/8ac4aa41dac9e27830da30fc1b2804f4404e…
commit 8ac4aa41dac9e27830da30fc1b2804f4404edaa5
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Mar 3 19:06:38 2013 +0100
core: context: Fix GP_PIXEL_ADDR() macro.
diff --git a/include/core/GP_Context.h b/include/core/GP_Context.h
index 0977a27..83d3c10 100644
--- a/include/core/GP_Context.h
+++ b/include/core/GP_Context.h
@@ -19,7 +19,7 @@
* Copyright (C) 2009-2011 Jiri "BlueBear" Dluhos *
* <jiri.bluebear.dluhos(a)gmail.com> *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -78,9 +78,9 @@ typedef struct GP_Context {
* Rows and columns are specified in the image's orientation
* (i.e. they might not be XY if the image is rotated).
*/
-#define GP_PIXEL_ADDR(context, x, y) (((context)->pixels - + y * (context)->bytes_per_row - + (x * (context)->bpp) / 8))
+#define GP_PIXEL_ADDR(context, x, y) ((context)->pixels + + (y) * (context)->bytes_per_row + + ((x) * (context)->bpp) / 8)
#define GP_CALC_ROW_SIZE(pixel_type, width) ((GP_PixelSize(pixel_type) * width) / 8 +
http://repo.or.cz/w/gfxprim.git/commit/8bfe15827e2fc8dcdee58cf3d435a78e8b99…
commit 8bfe15827e2fc8dcdee58cf3d435a78e8b9955b8
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Mar 3 17:45:03 2013 +0100
doc: Update debug layer docs.
diff --git a/doc/debug.txt b/doc/debug.txt
index 3f1cc69..cdc3d4b 100644
--- a/doc/debug.txt
+++ b/doc/debug.txt
@@ -1,8 +1,23 @@
Debug Messages
--------------
-The GFXprim library includes a debug messages infrastructure in order to ease
-debugging.
+The GFXprim library includes a debug message infrastructure in order to ease
+the debugging.
+
+Many places of the library uses debug messages to report warnings, bugs, or
+generally important events (i.e. context has been allocated, filter function
+has been called).
+
+Debug messages are printed into the stderr and could be redirected to custom
+handler.
+
+The verbosity of the messages could be changed by the debug level. The debug
+level is an unsigned integer (by default set to '0') and only messages that have
+debug level lower or equal to debug level are printed.
+
+There are few special debug message types with negative debug level (that
+means that they are always printed), and as so these are used on various error
+conditions, see bellow for more information.
[source,c]
-------------------------------------------------------------------------------
@@ -15,17 +30,17 @@ void GP_SetDebugLevel(unsigned int level);
unsigned int GP_GetDebugLevel(void);
-------------------------------------------------------------------------------
-Sets or gets library debug level. The default level is 0 at which only BUG,
-WARNING, TODO and messages with debug level 0 are shown.
+Sets or gets library debug level. The default level is '0' at which only
+'FATAL', 'BUG', 'WARNING', 'TODO' and messages with debug level '0' are shown.
Increasing this number would cause the library to be more verbose in debugging
messages.
-Setting debug level to 1 would expose debug messages when object was created
+Setting debug level to '1' would expose debug messages when object was created
or destroyed or when particular algorithm has been started.
-Setting debug level to value higher than 1 would expose even more verbose
-messages the current maximum used by debug messages is 4.
+Setting debug level to value higher than '1' would expose even more verbose
+messages the current maximum used by debug messages is '4'.
The debug level may also be set by setting the 'GP_DEBUG' environment
variable. In such case the debug level is set accordingly to its value when
@@ -45,10 +60,47 @@ GP_WARN(...)
GP_BUG(...)
+GP_FATAL(...)
+
void GP_DebugPrint(int level, const char *file, const char *function, int line,
const char *fmt, ...);
-------------------------------------------------------------------------------
-Printf-like macros used to create debug messages. All of them calls the
-'GP_DebugPrint()' function with correct parameters.
+Printf-like macros used to print debug messages. All of them calls the
+'GP_DebugPrint()' function with slightly parameters.
+
+[source,c]
+-------------------------------------------------------------------------------
+enum GP_DebugType {
+ GP_DEBUG_TODO = -1,
+ GP_DEBUG_WARN = -2,
+ GP_DEBUG_BUG = -3,
+ GP_DEBUG_FATAL = -4,
+};
+
+/*
+ * Custom debug message handler structure.
+ */
+struct GP_DebugMsg {
+ int level;
+ const char *file;
+ const char *fn;
+ unsigned int line;
+ const char *msg;
+};
+
+/*
+ * Sets custom debug message handler.
+ *
+ * If NULL is passed, custom handler is disabled and debug messages are printed
+ * into the stderr.
+ */
+void GP_SetDebugHandler(void (*handler)(const struct GP_DebugMsg *msg));
+
+-------------------------------------------------------------------------------
+
+By default debug messages are printed into the 'stderr' you can redirect them
+to your debug handler by this function.
+NOTE: For more information see debug message handler
+ link:example_debug_handler.html[example].
diff --git a/doc/example_debug_handler.txt b/doc/example_debug_handler.txt
new file mode 100644
index 0000000..a859f68
--- /dev/null
+++ b/doc/example_debug_handler.txt
@@ -0,0 +1,7 @@
+Debug Message Handler Example
+-----------------------------
+
+[source,c]
+------------------------------------------------------------------
+include::../demos/c_simple/debug_handler.c[]
+------------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/5614a72ad692285e00909d83a971eab6e0aa…
commit 5614a72ad692285e00909d83a971eab6e0aa6199
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Mar 3 17:26:59 2013 +0100
libs: backends: GP_X11: Small cleanup.
diff --git a/libs/backends/GP_X11.c b/libs/backends/GP_X11.c
index e3ee8eb..59b28ae 100644
--- a/libs/backends/GP_X11.c
+++ b/libs/backends/GP_X11.c
@@ -97,14 +97,7 @@ static void x11_flip(GP_Backend *self)
XLockDisplay(win->dpy);
-#ifdef HAVE_X_SHM
- if (win->shm_flag)
- XShmPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr),
- win->img, 0, 0, 0, 0, w, h, False);
- else
-#endif /* HAVE_X_SHM */
- XPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr),
- win->img, 0, 0, 0, 0, w, h);
+ putimage(win, 0, 0, w - 1, h - 1);
XFlush(win->dpy);
@@ -113,9 +106,9 @@ static void x11_flip(GP_Backend *self)
static void x11_ev(XEvent *ev)
{
- /* Lookup for window */
static struct x11_win *win = NULL;
+ /* Lookup for window */
if (win == NULL || win->win != ev->xany.window) {
win = win_list_lookup(ev->xany.window);
@@ -566,12 +559,12 @@ GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
goto err1;
}
- /* Init the event queue, once we know the window size */
- GP_EventQueueInit(&backend->event_queue, wreq.w, wreq.h, 0);
-
if (flags & GP_X11_FULLSCREEN)
x11_win_fullscreen(win, 1);
+ /* Init the event queue, once we know the window size */
+ GP_EventQueueInit(&backend->event_queue, wreq.w, wreq.h, 0);
+
backend->context = NULL;
if ((flags & GP_X11_DISABLE_SHM) || create_shm_ximage(backend, w, h))
http://repo.or.cz/w/gfxprim.git/commit/fad224dbbcdf6744e57cbf0ca235f226e37f…
commit fad224dbbcdf6744e57cbf0ca235f226e37f794a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sun Mar 3 17:16:59 2013 +0100
libs: core: debug: API for custom message handler.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index bca6fa2..3e741cc 100644
--- a/demos/c_simple/Makefile
+++ b/demos/c_simple/Makefile
@@ -18,7 +18,8 @@ APPS=backend_example loaders_example loaders filters_symmetry gfx_koch virtual_backend_example meta_data meta_data_dump tmp_file showimage v4l2_show v4l2_grab convolution weighted_median shapetest koch input_example fileview linetest randomshapetest fonttest- loaders_register blittest textaligntest abort sin_AA x11_windows
+ loaders_register blittest textaligntest abort sin_AA x11_windows+ debug_handler
ifeq ($(HAVE_LIBSDL),yes)
APPS+=SDL_glue
diff --git a/libs/core/GP_Debug.c b/demos/c_simple/debug_handler.c
similarity index 55%
copy from libs/core/GP_Debug.c
copy to demos/c_simple/debug_handler.c
index 75a54f3..9623645 100644
--- a/libs/core/GP_Debug.c
+++ b/demos/c_simple/debug_handler.c
@@ -16,76 +16,59 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
-#include <stdarg.h>
+/*
+
+ Example on custom debug message handler.
-#include "GP_Debug.h"
+ */
-static unsigned int debug_level = GP_DEFAULT_DEBUG_LEVEL;
-static int env_used = 0;
+#include <GP.h>
-void GP_SetDebugLevel(unsigned int level)
+static char level_to_c(int level)
{
- debug_level = level;
+ switch (level) {
+ case GP_DEBUG_TODO:
+ return 'T';
+ case GP_DEBUG_WARN:
+ return 'W';
+ case GP_DEBUG_BUG:
+ return 'B';
+ case GP_DEBUG_FATAL:
+ return 'F';
+ case 0 ... 9:
+ return '0' + level;
+ default:
+ return 'U';
+ }
}
-unsigned int GP_GetDebugLevel(void)
+void debug_handler(const struct GP_DebugMsg *msg)
{
- return debug_level;
+ printf("%c: %s->%s():%u: %sn", level_to_c(msg->level), msg->file,
+ msg->fn, msg->line, msg->msg);
}
-void GP_DebugPrint(int level, const char *file, const char *function, int line,
- const char *fmt, ...)
+int main(void)
{
- int i;
+ /* Set custom debug handler */
+ GP_SetDebugHandler(debug_handler);
- if (!env_used) {
- char *level = getenv("GP_DEBUG");
-
- env_used = 1;
-
- if (level != NULL) {
- int new_level = atoi(level);
-
- if (new_level >= 0) {
- debug_level = new_level;
+ /* Print some debug messages */
+ GP_WARN("This is a warning");
+ GP_FATAL("This is a fatal condition");
- GP_DEBUG(1, "Using debug level GP_DEBUG=%i "
- "from enviroment variable",
- debug_level);
- }
- }
- }
-
- if (level > (int)debug_level)
- return;
+ /* Turn on verbose debug and call some library functions */
+ GP_SetDebugLevel(10);
- for (i = 1; i < level; i++)
- fputc(' ', stderr);
+ GP_Context *ctx = GP_ContextAlloc(1000, 1000, 1);
- switch (level) {
- case -3:
- fprintf(stderr, "*** BUG: %s:%s():%u: ", file, function, line);
- break;
- case -2:
- fprintf(stderr, "*** WARNING: %s:%s():%u: ", file, function, line);
- break;
- case -1:
- fprintf(stderr, "*** TODO: %s:%s():%u: ", file, function, line);
- break;
- default:
- fprintf(stderr, "%u: %s:%s():%u: ",
- level, file, function, line);
- break;
- }
+ GP_FilterGaussianBlur(ctx, ctx, 10, 10, NULL);
+
+ GP_ContextFree(ctx);
- va_list va;
- va_start(va, fmt);
- vfprintf(stderr, fmt, va);
- va_end(va);
-
- fputc('n', stderr);
+ return 0;
}
diff --git a/include/core/GP_Debug.h b/include/core/GP_Debug.h
index a09ba69..4008bcd 100644
--- a/include/core/GP_Debug.h
+++ b/include/core/GP_Debug.h
@@ -16,37 +16,63 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
/*
-
- Debug messages and debug level. Debug level is an unsigned integer.
- Messages with debug level 0 are always printed (you should generally avoid
- using them unless you wan't user to see the message.)
+ Debug message layer.
- Debug level 1 should be used on object initalization and generally rare and
- important events.
+ Many places of the library uses debug messages to report warnings, bugs, or
+ generally important events (i.e. context has been allocated, filter function
+ has been called).
- Debug level > 1 is intended for more verbose reporting, like inner cycles
- or loop debugging.
+ Debug messages are printed into the stderr and could be redirected to custom
+ handler.
- Debug levels with negative level are special. Debug level -1 means TODO,
- level -2 says WARNING while -2 means BUG (i.e. library get into unconsistent
- state).
+ The verbosity of the messages could be changed by the debug level. The debug
+ level is an unsigned integer (by default set to '0') and only messages that have
+ debug level lower or equal to debug level are printed.
+
+ There are few special debug message types with negative debug level (that
+ means that they are always printed), and as so these are used on various error
+ conditions, see bellow for more information.
*/
-#ifndef GP_DEBUG_H
-#define GP_DEBUG_H
+#ifndef CORE_GP_DEBUG_H
+#define CORE_GP_DEBUG_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
+/*
+ * Messages with debug level 0 are always printed (you should generally avoid
+ * using them unless you wan't user to see the message.)
+ *
+ * Debug level 1 should be used on object initalization and generally rare and
+ * important events.
+ *
+ * Debug level > 1 is intended for more verbose reporting, like inner cycles
+ * or loop debugging.
+ *
+ * Debug levels with negative level are special.
+ *
+ * -1 TODO - not implemented feature
+ * -2 WARNING - generally error that can be recovered
+ * -3 BUG - library gets into unconsistent state
+ * -4 FATAL - fatal condition, not compiled with XYZ support etc.
+ */
+enum GP_DebugType {
+ GP_DEBUG_TODO = -1,
+ GP_DEBUG_WARN = -2,
+ GP_DEBUG_BUG = -3,
+ GP_DEBUG_FATAL = -4,
+};
+
#define GP_DEFAULT_DEBUG_LEVEL 0
#define GP_DEBUG(level, ...) @@ -61,11 +87,40 @@
#define GP_BUG(...) GP_DebugPrint(-3, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define GP_FATAL(...) + GP_DebugPrint(-4, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+
+void GP_DebugPrint(int level, const char *file, const char *function, int line,
+ const char *fmt, ...) __attribute__ ((format (printf, 5, 6)));
+
+/*
+ * Sets debug level.
+ */
void GP_SetDebugLevel(unsigned int level);
+/*
+ * Returns current debug level.
+ */
unsigned int GP_GetDebugLevel(void);
-void GP_DebugPrint(int level, const char *file, const char *function, int line,
- const char *fmt, ...) __attribute__ ((format (printf, 5, 6)));
-#endif /* GP_DEBUG_H */
+/*
+ * Custom debug message handler structure.
+ */
+struct GP_DebugMsg {
+ int level;
+ const char *file;
+ const char *fn;
+ unsigned int line;
+ const char *msg;
+};
+
+/*
+ * Sets custom debug message handler.
+ *
+ * If NULL is passed, custom handler is disabled and debug messages are printed
+ * into the stderr.
+ */
+void GP_SetDebugHandler(void (*handler)(const struct GP_DebugMsg *msg));
+
+#endif /* CORE_GP_DEBUG_H */
diff --git a/libs/core/GP_Context.c b/libs/core/GP_Context.c
index 6cb08a5..ff65884 100644
--- a/libs/core/GP_Context.c
+++ b/libs/core/GP_Context.c
@@ -47,6 +47,9 @@ GP_Context *GP_ContextAlloc(GP_Size w, GP_Size h, GP_PixelType type)
uint32_t bpr = get_bpr(bpp, w);
void *pixels;
+ GP_DEBUG(1, "Allocating context %u x %u - %s",
+ w, h, GP_PixelTypeName(type));
+
pixels = malloc(bpr * h);
context = malloc(sizeof(GP_Context));
@@ -58,10 +61,10 @@ GP_Context *GP_ContextAlloc(GP_Size w, GP_Size h, GP_PixelType type)
return NULL;
}
- context->pixels = pixels;
- context->bpp = bpp;
- context->bytes_per_row = bpr;
- context->offset = 0;
+ context->pixels = pixels;
+ context->bpp = bpp;
+ context->bytes_per_row = bpr;
+ context->offset = 0;
context->w = w;
context->h = h;
diff --git a/libs/core/GP_Debug.c b/libs/core/GP_Debug.c
index 75a54f3..db1ed26 100644
--- a/libs/core/GP_Debug.c
+++ b/libs/core/GP_Debug.c
@@ -16,17 +16,20 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
#include <stdarg.h>
-#include "GP_Debug.h"
+#include "core/GP_Debug.h"
static unsigned int debug_level = GP_DEFAULT_DEBUG_LEVEL;
+
static int env_used = 0;
+static void (*debug_handler)(const struct GP_DebugMsg *msg) = NULL;
+
void GP_SetDebugLevel(unsigned int level)
{
debug_level = level;
@@ -37,6 +40,11 @@ unsigned int GP_GetDebugLevel(void)
return debug_level;
}
+void GP_SetDebugHandler(void (*handler)(const struct GP_DebugMsg *msg))
+{
+ debug_handler = handler;
+}
+
void GP_DebugPrint(int level, const char *file, const char *function, int line,
const char *fmt, ...)
{
@@ -63,17 +71,42 @@ void GP_DebugPrint(int level, const char *file, const char *function, int line,
if (level > (int)debug_level)
return;
+ /* If handler is set, fill struct msg and call it */
+ if (debug_handler) {
+ char buf[256];
+
+ va_list va;
+ va_start(va, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, va);
+ va_end(va);
+
+ struct GP_DebugMsg msg = {
+ .level = level,
+ .file = file,
+ .fn = function,
+ .line = line,
+ .msg = buf,
+ };
+
+ debug_handler(&msg);
+
+ return;
+ }
+
for (i = 1; i < level; i++)
fputc(' ', stderr);
switch (level) {
- case -3:
+ case GP_DEBUG_FATAL:
+ fprintf(stderr, "*** FATAL: %s:%s():%u: ", file, function, line);
+ break;
+ case GP_DEBUG_BUG:
fprintf(stderr, "*** BUG: %s:%s():%u: ", file, function, line);
break;
- case -2:
+ case GP_DEBUG_WARN:
fprintf(stderr, "*** WARNING: %s:%s():%u: ", file, function, line);
break;
- case -1:
+ case GP_DEBUG_TODO:
fprintf(stderr, "*** TODO: %s:%s():%u: ", file, function, line);
break;
default:
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/Makefile | 3 +-
.../c_simple/debug_handler.c | 66 ++++++++------
doc/debug.txt | 70 +++++++++++++--
...ress_callback.txt => example_debug_handler.txt} | 6 +-
include/core/GP_Context.h | 8 +-
include/core/GP_Debug.h | 89 ++++++++++++++++----
libs/backends/GP_X11.c | 17 +---
libs/core/GP_Context.c | 11 ++-
libs/core/GP_Debug.c | 43 ++++++++-
9 files changed, 230 insertions(+), 83 deletions(-)
copy tests/drivers/linux_input.c => demos/c_simple/debug_handler.c (66%)
copy doc/{example_loaders_progress_callback.txt => example_debug_handler.txt} (58%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 402373dac8551c34bf48ceeba4aace19cee0eea9
by metan 01 Mar '13
by metan 01 Mar '13
01 Mar '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 402373dac8551c34bf48ceeba4aace19cee0eea9 (commit)
via 9c639e42fa7d4c0254d00294bd7100ef24ca42a8 (commit)
from 21e1fa797b0f25794c323793ebcff1c1762c755a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/402373dac8551c34bf48ceeba4aace19cee0…
commit 402373dac8551c34bf48ceeba4aace19cee0eea9
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Mar 1 23:36:26 2013 +0100
examples: add X11 multiple windows example.
diff --git a/demos/c_simple/Makefile b/demos/c_simple/Makefile
index 782eee2..bca6fa2 100644
--- a/demos/c_simple/Makefile
+++ b/demos/c_simple/Makefile
@@ -18,7 +18,7 @@ APPS=backend_example loaders_example loaders filters_symmetry gfx_koch virtual_backend_example meta_data meta_data_dump tmp_file showimage v4l2_show v4l2_grab convolution weighted_median shapetest koch input_example fileview linetest randomshapetest fonttest- loaders_register blittest textaligntest abort sin_AA
+ loaders_register blittest textaligntest abort sin_AA x11_windows
ifeq ($(HAVE_LIBSDL),yes)
APPS+=SDL_glue
diff --git a/demos/c_simple/x11_windows.c b/demos/c_simple/x11_windows.c
new file mode 100644
index 0000000..2c77075
--- /dev/null
+++ b/demos/c_simple/x11_windows.c
@@ -0,0 +1,123 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim 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 gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+ /*
+
+ Simple backend example.
+
+ */
+
+#include <GP.h>
+
+static void redraw(struct GP_Context *context)
+{
+ GP_Pixel white_pixel, black_pixel;
+
+ black_pixel = GP_ColorToContextPixel(GP_COL_BLACK, context);
+ white_pixel = GP_ColorToContextPixel(GP_COL_WHITE, context);
+
+ GP_Fill(context, black_pixel);
+ GP_Line(context, 0, 0, context->w - 1, context->h - 1, white_pixel);
+ GP_Line(context, 0, context->h - 1, context->w - 1, 0, white_pixel);
+}
+
+static int ev_loop(struct GP_Backend *backend, const char *name)
+{
+ GP_Event ev;
+
+ if (backend == NULL)
+ return 0;
+
+ while (GP_BackendGetEvent(backend, &ev)) {
+
+ printf("-------------------------- %sn", name);
+
+ GP_EventDump(&ev);
+
+ switch (ev.type) {
+ case GP_EV_KEY:
+ switch (ev.val.val) {
+ case GP_KEY_ESC:
+ case GP_KEY_Q:
+ GP_BackendExit(backend);
+ return 1;
+ break;
+ }
+ break;
+ case GP_EV_SYS:
+ switch (ev.code) {
+ case GP_EV_SYS_RESIZE:
+ GP_BackendResizeAck(backend);
+ break;
+ case GP_EV_SYS_QUIT:
+ GP_BackendExit(backend);
+ return 1;
+ break;
+ }
+ break;
+ }
+
+ printf("-----------------------------n");
+ }
+
+ return 0;
+}
+
+int main(void)
+{
+ GP_Backend *win_1, *win_2;
+
+ win_1 = GP_BackendX11Init(NULL, 0, 0, 300, 300, "win 1", 0);
+ win_2 = GP_BackendX11Init(NULL, 0, 0, 300, 300, "win 2", 0);
+
+ /* Update the backend screen */
+ redraw(win_1->context);
+ redraw(win_2->context);
+
+ GP_BackendFlip(win_1);
+ GP_BackendFlip(win_2);
+
+ for (;;) {
+ /*
+ * Wait for backend event.
+ *
+ * Either window is fine as they share connection.
+ */
+ GP_Backend *b = win_1 ? win_1 : win_2;
+
+ if (b == NULL)
+ return 0;
+
+ GP_BackendWait(b);
+
+ if (ev_loop(win_1, "win 1"))
+ win_1 = NULL;
+
+ if (ev_loop(win_2, "win 2"))
+ win_2 = NULL;
+ }
+
+ GP_BackendExit(win_1);
+ GP_BackendExit(win_2);
+
+ return 0;
+}
http://repo.or.cz/w/gfxprim.git/commit/9c639e42fa7d4c0254d00294bd7100ef24ca…
commit 9c639e42fa7d4c0254d00294bd7100ef24ca42a8
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Mar 1 23:35:26 2013 +0100
backends: X11: Fix double close on exit.
This fixes segfault for multiple window X11 backend.
diff --git a/libs/backends/GP_X11.c b/libs/backends/GP_X11.c
index 3a6e2ba..e3ee8eb 100644
--- a/libs/backends/GP_X11.c
+++ b/libs/backends/GP_X11.c
@@ -525,8 +525,6 @@ static void x11_exit(GP_Backend *self)
{
window_close(self);
- x11_close();
-
free(self);
}
diff --git a/libs/backends/GP_X11_Win.h b/libs/backends/GP_X11_Win.h
index 759ec73..11786a8 100644
--- a/libs/backends/GP_X11_Win.h
+++ b/libs/backends/GP_X11_Win.h
@@ -394,7 +394,8 @@ void x11_win_close(struct x11_win *win)
else
destroy_ximage(self);
*/
-
+ XUnmapWindow(win->dpy, win->win);
+
XDestroyWindow(win->dpy, win->win);
XUnlockDisplay(win->dpy);
-----------------------------------------------------------------------
Summary of changes:
demos/c_simple/Makefile | 2 +-
.../c_simple/{backend_example.c => x11_windows.c} | 129 +++++++++++---------
libs/backends/GP_X11.c | 2 -
libs/backends/GP_X11_Win.h | 3 +-
4 files changed, 74 insertions(+), 62 deletions(-)
copy demos/c_simple/{backend_example.c => x11_windows.c} (63%)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 21e1fa797b0f25794c323793ebcff1c1762c755a
by metan 01 Mar '13
by metan 01 Mar '13
01 Mar '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 21e1fa797b0f25794c323793ebcff1c1762c755a (commit)
via 1514e22782408ebbad3db2b9b4f37082f5e7e8f5 (commit)
via 19ad346473c404690363482eb05aba63474eeed5 (commit)
from 1436f47f05624f213e5065a9436ccc404e6b8bad (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/21e1fa797b0f25794c323793ebcff1c1762c…
commit 21e1fa797b0f25794c323793ebcff1c1762c755a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Mar 1 13:42:47 2013 +0100
libs: backends: X11 backend code refactoring.
First part of the cleanup + initial support
for multiple windows.
diff --git a/libs/backends/GP_X11.c b/libs/backends/GP_X11.c
index c5b17d8..3a6e2ba 100644
--- a/libs/backends/GP_X11.c
+++ b/libs/backends/GP_X11.c
@@ -42,103 +42,91 @@
#endif /* HAVE_X_SHM */
#include "input/GP_InputDriverX11.h"
-#include "GP_X11.h"
-
-struct x11_priv {
- /* Connection details */
- Display *dpy;
- int scr;
- Screen *scr_ptr;
- int scr_depth;
- Window win;
- Visual *vis;
-
- /* Image details */
- XImage *img;
-
-#ifdef HAVE_X_SHM
- XShmSegmentInfo shminfo;
-#endif /* HAVE_X_SHM */
-
- GP_Context context;
- int resized_flag:1;
- int shm_flag:1;
+#include "backends/GP_X11.h"
- /* used to store width and height from ConfigureNotify event */
- unsigned int new_w;
- unsigned int new_h;
-};
+#include "GP_X11_Conn.h"
+#include "GP_X11_Win.h"
static int resize_ximage(GP_Backend *self, int w, int h);
static int resize_shm_ximage(GP_Backend *self, int w, int h);
-static void putimage(struct GP_Backend *self, int x0, int y0, int x1, int y1)
+static void putimage(struct x11_win *win, int x0, int y0, int x1, int y1)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
-
#ifdef HAVE_X_SHM
- if (x11->shm_flag)
- XShmPutImage(x11->dpy, x11->win, DefaultGC(x11->dpy, x11->scr),
- x11->img, x0, y0, x0, y0, x1-x0+1, y1-y0+1, False);
+ if (win->shm_flag)
+ XShmPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr),
+ win->img, x0, y0, x0, y0, x1-x0+1, y1-y0+1, False);
else
#endif /* HAVE_X_SHM */
- XPutImage(x11->dpy, x11->win, DefaultGC(x11->dpy, x11->scr),
- x11->img, x0, y0, x0, y0, x1-x0+1, y1-y0+1);
+ XPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr),
+ win->img, x0, y0, x0, y0, x1-x0+1, y1-y0+1);
}
static void x11_update_rect(GP_Backend *self, GP_Coord x0, GP_Coord y0,
GP_Coord x1, GP_Coord y1)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
-
+ struct x11_win *win = GP_BACKEND_PRIV(self);
+
GP_DEBUG(4, "Updating rect %ix%i-%ix%i", x0, y0, x1, y1);
-
- if (x11->resized_flag) {
+
+ if (win->resized_flag) {
GP_DEBUG(4, "Ignoring update rect, waiting for resize ack");
return;
}
-
- XLockDisplay(x11->dpy);
- putimage(self, x0, y0, x1, y1);
+ XLockDisplay(win->dpy);
+
+ putimage(win, x0, y0, x1, y1);
- XUnlockDisplay(x11->dpy);
+ XUnlockDisplay(win->dpy);
}
static void x11_flip(GP_Backend *self)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
unsigned int w = self->context->w;
unsigned int h = self->context->h;
GP_DEBUG(4, "Flipping context");
-
- if (x11->resized_flag) {
+
+ if (win->resized_flag) {
GP_DEBUG(4, "Ignoring flip, waiting for resize ack");
return;
}
-
- XLockDisplay(x11->dpy);
+
+ XLockDisplay(win->dpy);
#ifdef HAVE_X_SHM
- if (x11->shm_flag)
- XShmPutImage(x11->dpy, x11->win, DefaultGC(x11->dpy, x11->scr),
- x11->img, 0, 0, 0, 0, w, h, False);
+ if (win->shm_flag)
+ XShmPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr),
+ win->img, 0, 0, 0, 0, w, h, False);
else
#endif /* HAVE_X_SHM */
- XPutImage(x11->dpy, x11->win, DefaultGC(x11->dpy, x11->scr),
- x11->img, 0, 0, 0, 0, w, h);
-
- XFlush(x11->dpy);
-
- XUnlockDisplay(x11->dpy);
+ XPutImage(win->dpy, win->win, DefaultGC(win->dpy, win->scr),
+ win->img, 0, 0, 0, 0, w, h);
+
+ XFlush(win->dpy);
+
+ XUnlockDisplay(win->dpy);
}
-static void x11_ev(GP_Backend *self, XEvent *ev)
+static void x11_ev(XEvent *ev)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
-
+ /* Lookup for window */
+ static struct x11_win *win = NULL;
+
+ if (win == NULL || win->win != ev->xany.window) {
+ win = win_list_lookup(ev->xany.window);
+
+ if (win == NULL) {
+ GP_WARN("Event for unknown window, ignoring.");
+ return;
+ }
+ }
+
+ struct GP_Backend *self = GP_CONTAINER_OF(win, struct GP_Backend, priv);
+
switch (ev->type) {
case Expose:
GP_DEBUG(4, "Expose %ix%i-%ix%i %i",
@@ -146,7 +134,7 @@ static void x11_ev(GP_Backend *self, XEvent *ev)
ev->xexpose.width, ev->xexpose.height,
ev->xexpose.count);
- if (x11->resized_flag)
+ if (win->resized_flag)
break;
/* Safety measure */
@@ -154,7 +142,7 @@ static void x11_ev(GP_Backend *self, XEvent *ev)
GP_WARN("Expose x + w > context->w");
break;
}
-
+
if (ev->xexpose.y + ev->xexpose.height > (int)self->context->h) {
GP_WARN("Expose y + h > context->h");
break;
@@ -170,58 +158,58 @@ static void x11_ev(GP_Backend *self, XEvent *ev)
ev->xconfigure.height == (int)self->context->h)
break;
- if (ev->xconfigure.width == (int)x11->new_w &&
- ev->xconfigure.height == (int)x11->new_h)
+ if (ev->xconfigure.width == (int)win->new_w &&
+ ev->xconfigure.height == (int)win->new_h)
break;
- x11->new_w = ev->xconfigure.width;
- x11->new_h = ev->xconfigure.height;
+ win->new_w = ev->xconfigure.width;
+ win->new_h = ev->xconfigure.height;
- GP_DEBUG(4, "Configure Notify %ux%u", x11->new_w, x11->new_h);
+ GP_DEBUG(4, "Configure Notify %ux%u", win->new_w, win->new_h);
/* Window has been resized, set flag. */
- x11->resized_flag = 1;
+ win->resized_flag = 1;
default:
//TODO: More accurate window w and h?
GP_InputDriverX11EventPut(&self->event_queue, ev,
- x11->context.w, x11->context.h);
+ win->context.w, win->context.h);
break;
}
}
static void x11_poll(GP_Backend *self)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
XEvent ev;
- XLockDisplay(x11->dpy);
-
- while (XPending(x11->dpy)) {
- XNextEvent(x11->dpy, &ev);
- x11_ev(self, &ev);
+ XLockDisplay(win->dpy);
+
+ while (XPending(win->dpy)) {
+ XNextEvent(win->dpy, &ev);
+ x11_ev(&ev);
}
-
- XUnlockDisplay(x11->dpy);
+
+ XUnlockDisplay(win->dpy);
}
static void x11_wait(GP_Backend *self)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
XEvent ev;
- XLockDisplay(x11->dpy);
-
- XNextEvent(x11->dpy, &ev);
- x11_ev(self, &ev);
-
- XUnlockDisplay(x11->dpy);
+ XLockDisplay(win->dpy);
+
+ XNextEvent(win->dpy, &ev);
+ x11_ev(&ev);
+
+ XUnlockDisplay(win->dpy);
}
static int resize_buffer(struct GP_Backend *self, uint32_t w, uint32_t h)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
- if (x11->shm_flag) {
+ if (win->shm_flag) {
if (resize_shm_ximage(self, w, h))
return 1;
} else {
@@ -236,54 +224,54 @@ static int x11_set_attributes(struct GP_Backend *self,
uint32_t w, uint32_t h,
const char *caption)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
- XLockDisplay(x11->dpy);
+ XLockDisplay(win->dpy);
if (caption != NULL) {
GP_DEBUG(3, "Setting window caption to '%s'", caption);
- XmbSetWMProperties(x11->dpy, x11->win, caption, caption,
+ XmbSetWMProperties(win->dpy, win->win, caption, caption,
NULL, 0, NULL, NULL, NULL);
}
if (w != 0 && h != 0) {
GP_DEBUG(3, "Setting window size to %ux%u", w, h);
- XResizeWindow(x11->dpy, x11->win, w, h);
+ XResizeWindow(win->dpy, win->win, w, h);
}
- XFlush(x11->dpy);
+ XFlush(win->dpy);
- XUnlockDisplay(x11->dpy);
+ XUnlockDisplay(win->dpy);
return 0;
}
static int x11_resize_ack(struct GP_Backend *self)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
int ret;
- XLockDisplay(x11->dpy);
+ XLockDisplay(win->dpy);
- GP_DEBUG(3, "Setting buffer size to %ux%u", x11->new_w, x11->new_h);
+ GP_DEBUG(3, "Setting buffer size to %ux%u", win->new_w, win->new_h);
- ret = resize_buffer(self, x11->new_w, x11->new_h);
+ ret = resize_buffer(self, win->new_w, win->new_h);
- x11->resized_flag = 0;
+ win->resized_flag = 0;
if (!ret) {
GP_EventQueueSetScreenSize(&self->event_queue,
- x11->new_w, x11->new_h);
+ win->new_w, win->new_h);
}
GP_DEBUG(3, "Done");
- XUnlockDisplay(x11->dpy);
+ XUnlockDisplay(win->dpy);
return ret;
}
-static void match_pixel_type(struct x11_priv *x11,
+static void match_pixel_type(struct x11_win *win,
enum GP_PixelType *pixel_type, int *depth)
{
/*
@@ -292,9 +280,9 @@ static void match_pixel_type(struct x11_priv *x11,
* Do best effor on selecting appropriate pixel type
*/
for (*depth = 8; *depth <= 32; *depth<<=1) {
- *pixel_type = GP_PixelRGBMatch(x11->vis->red_mask,
- x11->vis->green_mask,
- x11->vis->blue_mask,
+ *pixel_type = GP_PixelRGBMatch(win->vis->red_mask,
+ win->vis->green_mask,
+ win->vis->blue_mask,
0x0, *depth);
if (*pixel_type != GP_PIXEL_UNKNOWN)
@@ -306,9 +294,9 @@ static void match_pixel_type(struct x11_priv *x11,
static int create_shm_ximage(GP_Backend *self, GP_Size w, GP_Size h)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
- if (XShmQueryExtension(x11->dpy) == False) {
+ if (XShmQueryExtension(win->dpy) == False) {
GP_DEBUG(1, "MIT SHM Extension not supported, "
"falling back to XImage");
return 1;
@@ -321,7 +309,7 @@ static int create_shm_ximage(GP_Backend *self, GP_Size w, GP_Size h)
int depth;
if (self->context == NULL)
- match_pixel_type(x11, &pixel_type, &depth);
+ match_pixel_type(win, &pixel_type, &depth);
else
pixel_type = self->context->pixel_type;
@@ -330,93 +318,93 @@ static int create_shm_ximage(GP_Backend *self, GP_Size w, GP_Size h)
return 1;
}
- x11->img = XShmCreateImage(x11->dpy, x11->vis, x11->scr_depth,
- ZPixmap, NULL, &x11->shminfo, w, h);
+ win->img = XShmCreateImage(win->dpy, win->vis, win->scr_depth,
+ ZPixmap, NULL, &win->shminfo, w, h);
- if (x11->img == NULL) {
+ if (win->img == NULL) {
GP_WARN("Failed to create SHM XImage");
return 1;
}
- size_t size = x11->img->bytes_per_line * x11->img->height;
+ size_t size = win->img->bytes_per_line * win->img->height;
- x11->shminfo.shmid = shmget(IPC_PRIVATE, size, 0600);
+ win->shminfo.shmid = shmget(IPC_PRIVATE, size, 0600);
- if (x11->shminfo.shmid == -1) {
+ if (win->shminfo.shmid == -1) {
GP_WARN("Calling shmget() failed: %s", strerror(errno));
goto err0;
}
- x11->shminfo.shmaddr = x11->img->data = shmat(x11->shminfo.shmid, 0, 0);
+ win->shminfo.shmaddr = win->img->data = shmat(win->shminfo.shmid, 0, 0);
- if (x11->shminfo.shmaddr == (void *)-1) {
+ if (win->shminfo.shmaddr == (void *)-1) {
GP_WARN("Calling shmat() failed: %s", strerror(errno));
goto err1;
}
/* Mark SHM for deletion after detach */
- if (shmctl(x11->shminfo.shmid, IPC_RMID, 0)) {
+ if (shmctl(win->shminfo.shmid, IPC_RMID, 0)) {
GP_WARN("Calling shmctl(..., IPC_RMID), 0) failed: %s",
strerror(errno));
goto err2;
}
- x11->shminfo.readOnly = False;
+ win->shminfo.readOnly = False;
- if (XShmAttach(x11->dpy, &x11->shminfo) == False) {
+ if (XShmAttach(win->dpy, &win->shminfo) == False) {
GP_WARN("XShmAttach failed");
goto err2;
}
- GP_ContextInit(&x11->context, w, h, pixel_type, x11->shminfo.shmaddr);
- x11->context.bytes_per_row = x11->img->bytes_per_line;
+ GP_ContextInit(&win->context, w, h, pixel_type, win->shminfo.shmaddr);
+ win->context.bytes_per_row = win->img->bytes_per_line;
- self->context = &x11->context;
+ self->context = &win->context;
- x11->shm_flag = 1;
+ win->shm_flag = 1;
//FIXME: Proper synchronization
- XSync(x11->dpy, True);
+ XSync(win->dpy, True);
return 0;
err2:
- shmdt(x11->shminfo.shmaddr);
+ shmdt(win->shminfo.shmaddr);
err1:
- shmctl(x11->shminfo.shmid, IPC_RMID, 0);
+ shmctl(win->shminfo.shmid, IPC_RMID, 0);
err0:
- XDestroyImage(x11->img);
+ XDestroyImage(win->img);
return 1;
}
static void destroy_shm_ximage(GP_Backend *self)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
- XLockDisplay(x11->dpy);
+ XLockDisplay(win->dpy);
- XShmDetach(x11->dpy, &x11->shminfo);
- XFlush(x11->dpy);
- shmdt(x11->shminfo.shmaddr);
- XDestroyImage(x11->img);
- XFlush(x11->dpy);
+ XShmDetach(win->dpy, &win->shminfo);
+ XFlush(win->dpy);
+ shmdt(win->shminfo.shmaddr);
+ XDestroyImage(win->img);
+ XFlush(win->dpy);
- XUnlockDisplay(x11->dpy);
+ XUnlockDisplay(win->dpy);
}
static int resize_shm_ximage(GP_Backend *self, int w, int h)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
int ret;
GP_DEBUG(4, "Resizing XShmImage %ux%u -> %ux%u",
self->context->w, self->context->h, w, h);
- XLockDisplay(x11->dpy);
+ XLockDisplay(win->dpy);
destroy_shm_ximage(self);
ret = create_shm_ximage(self, w, h);
- XUnlockDisplay(x11->dpy);
+ XUnlockDisplay(win->dpy);
return ret;
}
@@ -445,11 +433,11 @@ static int resize_shm_ximage(GP_Backend GP_UNUSED(*self),
static int create_ximage(GP_Backend *self, GP_Size w, GP_Size h)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
enum GP_PixelType pixel_type;
int depth;
- match_pixel_type(x11, &pixel_type, &depth);
+ match_pixel_type(win, &pixel_type, &depth);
if (pixel_type == GP_PIXEL_UNKNOWN) {
GP_DEBUG(1, "Unknown pixel type");
@@ -461,39 +449,39 @@ static int create_ximage(GP_Backend *self, GP_Size w, GP_Size h)
if (self->context == NULL)
return 1;
- x11->img = XCreateImage(x11->dpy, x11->vis, x11->scr_depth, ZPixmap, 0,
+ win->img = XCreateImage(win->dpy, win->vis, win->scr_depth, ZPixmap, 0,
NULL, w, h, depth, 0);
- if (x11->img == NULL) {
+ if (win->img == NULL) {
GP_DEBUG(1, "Failed to create XImage");
GP_ContextFree(self->context);
return 1;
}
- x11->shm_flag = 0;
+ win->shm_flag = 0;
- x11->img->data = (char*)self->context->pixels;
+ win->img->data = (char*)self->context->pixels;
return 0;
}
static void destroy_ximage(GP_Backend *self)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
GP_ContextFree(self->context);
- x11->img->data = NULL;
- XDestroyImage(x11->img);
+ win->img->data = NULL;
+ XDestroyImage(win->img);
}
static int resize_ximage(GP_Backend *self, int w, int h)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
XImage *img;
/* Create new X image */
- img = XCreateImage(x11->dpy, x11->vis, x11->scr_depth, ZPixmap, 0, NULL,
- w, h, x11->img->bitmap_pad, 0);
+ img = XCreateImage(win->dpy, win->vis, win->scr_depth, ZPixmap, 0, NULL,
+ w, h, win->img->bitmap_pad, 0);
if (img == NULL) {
GP_DEBUG(2, "XCreateImage failed");
@@ -507,288 +495,39 @@ static int resize_ximage(GP_Backend *self, int w, int h)
}
/* Free old image */
- x11->img->data = NULL;
- XDestroyImage(x11->img);
+ win->img->data = NULL;
+ XDestroyImage(win->img);
/* Swap the pointers */
img->data = (char*)self->context->pixels;
- x11->img = img;
+ win->img = img;
return 0;
}
static void window_close(GP_Backend *self)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
- XLockDisplay(x11->dpy);
+ XLockDisplay(win->dpy);
- if (x11->shm_flag)
+ if (win->shm_flag)
destroy_shm_ximage(self);
else
destroy_ximage(self);
- XDestroyWindow(x11->dpy, x11->win);
-
- XUnlockDisplay(x11->dpy);
+ x11_win_close(win);
+
+ XUnlockDisplay(win->dpy);
}
static void x11_exit(GP_Backend *self)
{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
-
- XLockDisplay(x11->dpy);
-
window_close(self);
- /* I wonder if this is right sequence... */
- //XUnlockDisplay(x11->dpy);
- XCloseDisplay(x11->dpy);
-
- free(self);
-}
-
-static void create_window(struct x11_priv *x11, int x, int y,
- unsigned int *w, unsigned int *h,
- const char *caption, enum GP_BackendX11Flags flags)
-{
- XSetWindowAttributes attrs;
- unsigned long attr_mask = 0;
-
- /* Set event mask */
- attrs.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask |
- KeyReleaseMask | PointerMotionMask;
- attr_mask |= CWEventMask;
-
- /*
- * If root window was selected, resize w and h and set x11->win to root
- * window.
- */
- if (flags & GP_X11_USE_ROOT_WIN) {
- x11->win = DefaultRootWindow(x11->dpy);
- *w = DisplayWidth(x11->dpy, x11->scr);
- *h = DisplayHeight(x11->dpy, x11->scr);
-
- GP_DEBUG(2, "Using root window, owerriding size to %ux%u",
- *w, *h);
-
- XChangeWindowAttributes(x11->dpy, x11->win, attr_mask, &attrs);
-
- return;
- }
-
- /*
- * For some reason reading mouse button clicks on root win are not
- * allowed...
- */
- attrs.event_mask |= ButtonPressMask | ButtonReleaseMask;
-
- /*
- * Create undecoreated root window on background
- */
- if (flags & GP_X11_CREATE_ROOT_WIN) {
- Atom xa;
-
- *w = DisplayWidth(x11->dpy, x11->scr);
- *h = DisplayHeight(x11->dpy, x11->scr);
-
- GP_DEBUG(2, "Creating a window above root, owerriding size to %ux%u",
- *w, *h);
-
- x11->win = XCreateWindow(x11->dpy, DefaultRootWindow(x11->dpy),
- 0, 0, *w, *h, 0, CopyFromParent,
- InputOutput, CopyFromParent, attr_mask, &attrs);
-
- /* Set empty WM_PROTOCOLS */
- GP_DEBUG(2, "Setting empty MW_PROTOCOLS");
- XSetWMProtocols(x11->dpy, x11->win, NULL, 0);
-
- /* Set window type to desktop */
- xa = XInternAtom(x11->dpy, "_NET_WM_WINDOW_TYPE", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Setting Atom _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_DESKTOP");
-
- Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
-
- XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32,
- PropModeReplace, (unsigned char *) &xa_prop, 1);
- }
-
- /* Turn off window decoration */
- xa = XInternAtom(x11->dpy, "_MOTIF_WM_HINTS", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Setting Atom _MOTIF_WM_HINTS to 2, 0, 0, 0, 0");
-
- long prop[5] = {2, 0, 0, 0, 0};
-
- XChangeProperty(x11->dpy, x11->win, xa, xa, 32,
- PropModeReplace, (unsigned char *) prop, 5);
- }
-
- /* Set below other windows */
- xa = XInternAtom(x11->dpy, "_WIN_LAYER", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Setting Atom _WIN_LAYER to 6");
-
- long prop = 6;
-
- XChangeProperty(x11->dpy, x11->win, xa, XA_CARDINAL, 32,
- PropModeAppend, (unsigned char *) &prop, 1);
- }
-
- xa = XInternAtom(x11->dpy, "_NET_WM_STATE", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Setting Atom _NET_WM_STATE to _NET_WM_STATE_BELOW");
-
- Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_STATE_BELOW", False);
-
- XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32,
- PropModeAppend, (unsigned char *) &xa_prop, 1);
- }
-
- /* Set sticky */
- xa = XInternAtom(x11->dpy, "_NET_WM_DESKTOP", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Setting Atom _NET_WM_DESKTOP to 0xffffffff");
-
- CARD32 xa_prop = 0xffffffff;
-
- XChangeProperty(x11->dpy, x11->win, xa, XA_CARDINAL, 32,
- PropModeAppend, (unsigned char *) &xa_prop, 1);
- }
-
- xa = XInternAtom(x11->dpy, "_NET_WM_STATE", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_WM_STATE_STICKY");
-
- Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_STATE_STICKY", False);
-
- XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32,
- PropModeAppend, (unsigned char *) &xa_prop, 1);
- }
-
- /* Skip taskbar */
- xa = XInternAtom(x11->dpy, "_NET_WM_STATE", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_STATE_SKIP_TASKBAR");
-
- Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
-
- XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32,
- PropModeAppend, (unsigned char *) &xa_prop, 1);
- }
-
- /* Skip pager */
- xa = XInternAtom(x11->dpy, "_NET_WM_STATE", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_STATE_SKIP_PAGER");
-
- Atom xa_prop = XInternAtom(x11->dpy, "_NET_WM_STATE_SKIP_PAGER", False);
-
- XChangeProperty(x11->dpy, x11->win, xa, XA_ATOM, 32,
- PropModeAppend, (unsigned char *) &xa_prop, 1);
- }
+ x11_close();
- /* Set 100% opacity */
- xa = XInternAtom(x11->dpy, "_NET_WM_WINDOW_OPACITY", False);
-
- if (xa != None) {
- GP_DEBUG(2, "Setting Atom _NET_WM_WINDOW_OPACITY to 0xffffffff");
-
- long prop = 0xffffffff;
-
- XChangeProperty(x11->dpy, x11->win, xa, XA_CARDINAL, 32,
- PropModeAppend, (unsigned char *) &prop, 1);
- }
-
- /* Show window */
- XMapWindow(x11->dpy, x11->win);
- return;
- }
-
- GP_DEBUG(2, "Opening window '%s' %ix%i-%ux%u",
- caption, x, y, *w, *h);
-
- x11->win = XCreateWindow(x11->dpy, DefaultRootWindow(x11->dpy),
- x, y, *w, *h, 0, CopyFromParent,
- InputOutput, CopyFromParent, attr_mask, &attrs);
-
- /* Set window caption */
- XmbSetWMProperties(x11->dpy, x11->win, caption, caption,
- NULL, 0, NULL, NULL, NULL);
-
- /* Make the window close button send event */
- Atom xa = XInternAtom(x11->dpy, "WM_DELETE_WINDOW", True);
-
- if (xa != None) {
- GP_DEBUG(2, "Setting WM_DELETE_WINDOW Atom to True");
-
- XSetWMProtocols(x11->dpy, x11->win, &xa, 1);
- } else {
- GP_DEBUG(2, "Failed to set WM_DELETE_WINDOW Atom to True");
- }
-
- /* Show window */
- XMapWindow(x11->dpy, x11->win);
-}
-
-#ifndef _NET_WM_STATE_ADD
-# define _NET_WM_STATE_ADD 1
-#endif /* _NET_WM_STATE_ADD */
-
-#ifndef _NET_WM_STATE_REMOVE
-# define _NET_WM_STATE_REMOVE 0
-#endif /* _NET_WM_STATE_REMOVE */
-
-/* Send NETWM message, most modern Window Managers should understand */
-static void request_fullscreen(struct GP_Backend *self, int mode)
-{
- struct x11_priv *x11 = GP_BACKEND_PRIV(self);
-
- if (mode < 0 || mode > 2) {
- GP_WARN("Invalid fullscreen mode = %u", mode);
- return;
- }
-
- GP_DEBUG(2, "Requesting fullscreen mode = %u", mode);
-
- Atom wm_state, fullscreen;
-
- wm_state = XInternAtom(x11->dpy, "_NET_WM_STATE", True);
- fullscreen = XInternAtom(x11->dpy, "_NET_WM_STATE_FULLSCREEN", True);
-
- if (wm_state == None || fullscreen == None) {
- GP_WARN("Failed to create _NET_WM_* atoms");
- return;
- }
-
- XEvent ev;
-
- memset(&ev, 0, sizeof(ev));
-
- ev.type = ClientMessage;
- ev.xclient.window = x11->win;
- ev.xclient.message_type = wm_state;
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = mode;
- ev.xclient.data.l[1] = fullscreen;
- ev.xclient.data.l[2] = 0;
- ev.xclient.data.l[3] = 1;
-
- if (!XSendEvent(x11->dpy, XDefaultRootWindow(x11->dpy), False, SubstructureNotifyMask, &ev)) {
- GP_WARN("Failed to send _NET_WM_STATE_FULLSCREEN event");
- return;
- }
-
- XFlush(x11->dpy);
+ free(self);
}
GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
@@ -797,53 +536,43 @@ GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
enum GP_BackendX11Flags flags)
{
GP_Backend *backend;
- struct x11_priv *x11;
-
- GP_DEBUG(1, "Initalizing X11 display '%s'", display);
-
- if (!XInitThreads()) {
- GP_DEBUG(2, "XInitThreads failed");
- return NULL;
- }
+ struct x11_win *win;
backend = malloc(sizeof(GP_Backend) +
- sizeof(struct x11_priv));
+ sizeof(struct x11_win));
if (backend == NULL)
return NULL;
- x11 = GP_BACKEND_PRIV(backend);
-
- x11->dpy = XOpenDisplay(display);
-
- if (x11->dpy == NULL)
- goto err0;
+ win = GP_BACKEND_PRIV(backend);
- /* Initialized key translation table */
- GP_InputDriverX11Init(x11->dpy);
+ //XSynchronize(win->dpy, True);
- //XSynchronize(x11->dpy, True);
+ /* Pack parameters and open window */
+ struct x11_wreq wreq = {
+ .win = win,
+ .display = display,
+ .x = x,
+ .y = y,
+ .w = w,
+ .h = h,
+ .caption = caption,
+ .flags = flags,
+ };
- x11->scr = DefaultScreen(x11->dpy);
- x11->vis = DefaultVisual(x11->dpy, x11->scr);
- x11->scr_ptr = DefaultScreenOfDisplay(x11->dpy);
- x11->scr_depth = DefaultDepthOfScreen(x11->scr_ptr);
+ x11_win_open(&wreq);
- GP_DEBUG(2, "Have Visual id %i, depth %u", (int)x11->vis->visualid, x11->scr_depth);
-
- create_window(x11, x, y, &w, &h, caption, flags);
-
- if (x11->win == None) {
+ if (win->win == None) {
//TODO: Error message?
GP_DEBUG(1, "Failed to create window");
goto err1;
}
/* Init the event queue, once we know the window size */
- GP_EventQueueInit(&backend->event_queue, w, h, 0);
+ GP_EventQueueInit(&backend->event_queue, wreq.w, wreq.h, 0);
if (flags & GP_X11_FULLSCREEN)
- request_fullscreen(backend, 1);
+ x11_win_fullscreen(win, 1);
backend->context = NULL;
@@ -851,9 +580,9 @@ GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
if (create_ximage(backend, w, h))
goto err1;
- XFlush(x11->dpy);
+ XFlush(win->dpy);
- x11->resized_flag = 0;
+ win->resized_flag = 0;
backend->name = "X11";
backend->Flip = x11_flip;
@@ -863,19 +592,20 @@ GP_Backend *GP_BackendX11Init(const char *display, int x, int y,
backend->Wait = x11_wait;
backend->SetAttributes = x11_set_attributes;
backend->ResizeAck = x11_resize_ack;
- backend->fd = XConnectionNumber(x11->dpy);
+ backend->fd = XConnectionNumber(win->dpy);
return backend;
err1:
- XCloseDisplay(x11->dpy);
-err0:
+ x11_close();
free(backend);
return NULL;
}
void GP_BackendX11RequestFullscreen(GP_Backend *self, int mode)
{
- request_fullscreen(self, mode);
+ struct x11_win *win = GP_BACKEND_PRIV(self);
+
+ x11_win_fullscreen(win, mode);
}
#else
diff --git a/libs/backends/GP_X11_Conn.h b/libs/backends/GP_X11_Conn.h
new file mode 100644
index 0000000..f8bf3bf
--- /dev/null
+++ b/libs/backends/GP_X11_Conn.h
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim 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 gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+/*
+ * X11 connection, singleton.
+ */
+struct x11_conn {
+ Display *dpy;
+
+ /* window reference counter */
+ unsigned int ref_cnt;
+};
+
+static struct x11_conn x11_conn = {
+ .dpy = NULL,
+ .ref_cnt = 0,
+};
+
+static unsigned int x11_open(const char *display)
+{
+ if (x11_conn.ref_cnt != 0)
+ return ++x11_conn.ref_cnt;
+
+ GP_DEBUG(1, "Opening X11 display '%s'", display);
+
+ if (!XInitThreads()) {
+ GP_DEBUG(2, "XInitThreads failed");
+ return 0;
+ }
+
+ x11_conn.dpy = XOpenDisplay(display);
+
+ if (x11_conn.dpy == NULL) {
+ GP_WARN("Failed to initialize X11 display");
+ return 0;
+ }
+
+ /* Initialized key translation table */
+ GP_InputDriverX11Init(x11_conn.dpy);
+
+ return ++x11_conn.ref_cnt;
+}
+
+static void x11_close(void)
+{
+ /* Ignore close requests if connection is closed */
+ if (x11_conn.ref_cnt == 0)
+ return;
+
+ if (--x11_conn.ref_cnt != 0)
+ return;
+
+ GP_DEBUG(1, "Closing X11 display");
+
+ XLockDisplay(x11_conn.dpy);
+
+ /* I wonder if this is right sequence... */
+ //XUnlockDisplay(x11_conn.dpy);
+ XCloseDisplay(x11_conn.dpy);
+}
diff --git a/libs/backends/GP_X11_Win.h b/libs/backends/GP_X11_Win.h
new file mode 100644
index 0000000..759ec73
--- /dev/null
+++ b/libs/backends/GP_X11_Win.h
@@ -0,0 +1,404 @@
+/*****************************************************************************
+ * This file is part of gfxprim library. *
+ * *
+ * Gfxprim 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 2.1 of the License, or (at your option) any later version. *
+ * *
+ * Gfxprim 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 gfxprim; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
+ * *
+ *****************************************************************************/
+
+/*
+ * X11 window.
+ */
+struct x11_win {
+ /* X11 Display */
+ Display *dpy;
+ /* X11 Screen */
+ int scr;
+ /* X11 Screen depth */
+ int scr_depth;
+ /* X11 Visual */
+ Visual *vis;
+ /* X11 Window */
+ Window win;
+
+ /* Image info SHM or XImage */
+ XImage *img;
+
+#ifdef HAVE_X_SHM
+ XShmSegmentInfo shminfo;
+#endif /* HAVE_X_SHM */
+
+ GP_Context context;
+
+ /* Window list pointers */
+ struct x11_win *prev;
+ struct x11_win *next;
+
+ /* Flags */
+ int resized_flag:1;
+ int shm_flag:1;
+
+ /* used to store width and height from ConfigureNotify event */
+ unsigned int new_w;
+ unsigned int new_h;
+};
+
+static struct x11_win *win_list = NULL;
+
+static void win_list_add(struct x11_win *win)
+{
+ win->next = win_list;
+ win->prev = NULL;
+ win_list = win;
+}
+
+static void win_list_rem(struct x11_win *win)
+{
+ if (win->prev)
+ win->prev->next = win->next;
+
+ if (win->next)
+ win->next->prev = win->prev;
+
+ if (win == win_list)
+ win_list = win->next;
+}
+
+struct x11_win *win_list_lookup(Window win)
+{
+ struct x11_win *i;
+
+ for (i = win_list; i != NULL; i = i->next) {
+ if (i->win == win)
+ return i;
+ }
+
+ return NULL;
+}
+
+#ifndef _NET_WM_STATE_ADD
+# define _NET_WM_STATE_ADD 1
+#endif /* _NET_WM_STATE_ADD */
+
+#ifndef _NET_WM_STATE_REMOVE
+# define _NET_WM_STATE_REMOVE 0
+#endif /* _NET_WM_STATE_REMOVE */
+
+/* Send NETWM message, most modern Window Managers should understand */
+static void x11_win_fullscreen(struct x11_win *win, int mode)
+{
+ if (mode < 0 || mode > 2) {
+ GP_WARN("Invalid fullscreen mode = %u", mode);
+ return;
+ }
+
+ GP_DEBUG(2, "Requesting fullscreen mode = %u", mode);
+
+ Atom wm_state, fullscreen;
+
+ wm_state = XInternAtom(win->dpy, "_NET_WM_STATE", True);
+ fullscreen = XInternAtom(win->dpy, "_NET_WM_STATE_FULLSCREEN", True);
+
+ if (wm_state == None || fullscreen == None) {
+ GP_WARN("Failed to create _NET_WM_* atoms");
+ return;
+ }
+
+ XEvent ev;
+
+ memset(&ev, 0, sizeof(ev));
+
+ ev.type = ClientMessage;
+ ev.xclient.window = win->win;
+ ev.xclient.message_type = wm_state;
+ ev.xclient.format = 32;
+ ev.xclient.data.l[0] = mode;
+ ev.xclient.data.l[1] = fullscreen;
+ ev.xclient.data.l[2] = 0;
+ ev.xclient.data.l[3] = 1;
+
+ if (!XSendEvent(win->dpy, XDefaultRootWindow(win->dpy),
+ False, SubstructureNotifyMask, &ev)) {
+ GP_WARN("Failed to send _NET_WM_STATE_FULLSCREEN event");
+ return;
+ }
+
+ XFlush(win->dpy);
+}
+
+/* Window request structure */
+struct x11_wreq {
+ struct x11_win *win;
+
+ /* X11 display */
+ const char *display;
+
+ /* geometry */
+ int x;
+ int y;
+ unsigned int w;
+ unsigned int h;
+
+ const char *caption;
+
+ unsigned int flags;
+};
+
+static void x11_get_screen_size(struct x11_wreq *wreq)
+{
+ wreq->w = DisplayWidth(wreq->win->dpy, wreq->win->scr);
+ wreq->h = DisplayHeight(wreq->win->dpy, wreq->win->scr);
+}
+
+static int x11_win_open(struct x11_wreq *wreq)
+{
+ XSetWindowAttributes attrs;
+ unsigned long attr_mask = 0;
+ struct x11_win *win;
+ Screen *scr_ptr;
+
+ /* Initialize connection/increase ref count */
+ if (!x11_open(wreq->display))
+ return 1;
+
+ win = wreq->win;
+
+ /* Copy display */
+ win->dpy = x11_conn.dpy;
+
+ /* Get visual and screen depth */
+ win->scr = DefaultScreen(win->dpy);
+ win->vis = DefaultVisual(win->dpy, win->scr);
+ scr_ptr = DefaultScreenOfDisplay(win->dpy);
+ win->scr_depth = DefaultDepthOfScreen(scr_ptr);
+
+ GP_DEBUG(2, "Have Visual id %i, depth %u", (int)win->vis->visualid, win->scr_depth);
+
+ /* Set event mask */
+ attrs.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask |
+ KeyReleaseMask | PointerMotionMask;
+ attr_mask |= CWEventMask;
+
+ /*
+ * If root window was selected, resize w and h and set win->win to root
+ * window.
+ */
+ if (wreq->flags & GP_X11_USE_ROOT_WIN) {
+
+ win->win = DefaultRootWindow(win->dpy);
+
+ x11_get_screen_size(wreq);
+
+ GP_DEBUG(2, "Using root window, owerriding size to %ux%u",
+ wreq->w, wreq->h);
+
+ win_list_add(win);
+
+ XChangeWindowAttributes(win->dpy, win->win, attr_mask, &attrs);
+
+ return 0;
+ }
+
+ /*
+ * For some reason reading mouse button clicks on root win are not
+ * allowed...
+ */
+ attrs.event_mask |= ButtonPressMask | ButtonReleaseMask;
+
+ /*
+ * Create undecoreated root window on background
+ */
+ if (wreq->flags & GP_X11_CREATE_ROOT_WIN) {
+ Atom xa;
+
+ x11_get_screen_size(wreq);
+
+ GP_DEBUG(2, "Creating a window above root, owerriding size to %ux%u",
+ wreq->w, wreq->h);
+
+ win->win = XCreateWindow(win->dpy, DefaultRootWindow(win->dpy),
+ 0, 0, wreq->w, wreq->h, 0, CopyFromParent,
+ InputOutput, CopyFromParent, attr_mask, &attrs);
+
+ /* Set empty WM_PROTOCOLS */
+ GP_DEBUG(2, "Setting empty MW_PROTOCOLS");
+ XSetWMProtocols(win->dpy, win->win, NULL, 0);
+
+ /* Set window type to desktop */
+ xa = XInternAtom(win->dpy, "_NET_WM_WINDOW_TYPE", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Setting Atom _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_DESKTOP");
+
+ Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
+
+ XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *) &xa_prop, 1);
+ }
+
+ /* Turn off window decoration */
+ xa = XInternAtom(win->dpy, "_MOTIF_WM_HINTS", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Setting Atom _MOTIF_WM_HINTS to 2, 0, 0, 0, 0");
+
+ long prop[5] = {2, 0, 0, 0, 0};
+
+ XChangeProperty(win->dpy, win->win, xa, xa, 32,
+ PropModeReplace, (unsigned char *) prop, 5);
+ }
+
+ /* Set below other windows */
+ xa = XInternAtom(win->dpy, "_WIN_LAYER", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Setting Atom _WIN_LAYER to 6");
+
+ long prop = 6;
+
+ XChangeProperty(win->dpy, win->win, xa, XA_CARDINAL, 32,
+ PropModeAppend, (unsigned char *) &prop, 1);
+ }
+
+ xa = XInternAtom(win->dpy, "_NET_WM_STATE", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Setting Atom _NET_WM_STATE to _NET_WM_STATE_BELOW");
+
+ Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_STATE_BELOW", False);
+
+ XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32,
+ PropModeAppend, (unsigned char *) &xa_prop, 1);
+ }
+
+ /* Set sticky */
+ xa = XInternAtom(win->dpy, "_NET_WM_DESKTOP", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Setting Atom _NET_WM_DESKTOP to 0xffffffff");
+
+ CARD32 xa_prop = 0xffffffff;
+
+ XChangeProperty(win->dpy, win->win, xa, XA_CARDINAL, 32,
+ PropModeAppend, (unsigned char *) &xa_prop, 1);
+ }
+
+ xa = XInternAtom(win->dpy, "_NET_WM_STATE", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_WM_STATE_STICKY");
+
+ Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_STATE_STICKY", False);
+
+ XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32,
+ PropModeAppend, (unsigned char *) &xa_prop, 1);
+ }
+
+ /* Skip taskbar */
+ xa = XInternAtom(win->dpy, "_NET_WM_STATE", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_STATE_SKIP_TASKBAR");
+
+ Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
+
+ XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32,
+ PropModeAppend, (unsigned char *) &xa_prop, 1);
+ }
+
+ /* Skip pager */
+ xa = XInternAtom(win->dpy, "_NET_WM_STATE", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Appending to Atom _NET_WM_STATE atom _NET_STATE_SKIP_PAGER");
+
+ Atom xa_prop = XInternAtom(win->dpy, "_NET_WM_STATE_SKIP_PAGER", False);
+
+ XChangeProperty(win->dpy, win->win, xa, XA_ATOM, 32,
+ PropModeAppend, (unsigned char *) &xa_prop, 1);
+ }
+
+ /* Set 100% opacity */
+ xa = XInternAtom(win->dpy, "_NET_WM_WINDOW_OPACITY", False);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Setting Atom _NET_WM_WINDOW_OPACITY to 0xffffffff");
+
+ long prop = 0xffffffff;
+
+ XChangeProperty(win->dpy, win->win, xa, XA_CARDINAL, 32,
+ PropModeAppend, (unsigned char *) &prop, 1);
+ }
+
+ win_list_add(win);
+
+ /* Show window */
+ XMapWindow(win->dpy, win->win);
+ return 0;
+ }
+
+ GP_DEBUG(2, "Opening window '%s' %ix%i-%ux%u",
+ wreq->caption, wreq->x, wreq->y, wreq->w, wreq->h);
+
+ win->win = XCreateWindow(win->dpy, DefaultRootWindow(win->dpy),
+ wreq->x, wreq->y, wreq->w, wreq->h, 0,
+ CopyFromParent, InputOutput, CopyFromParent,
+ attr_mask, &attrs);
+
+ /* Set window caption */
+ XmbSetWMProperties(win->dpy, win->win, wreq->caption, wreq->caption,
+ NULL, 0, NULL, NULL, NULL);
+
+ /* Make the window close button send event */
+ Atom xa = XInternAtom(win->dpy, "WM_DELETE_WINDOW", True);
+
+ if (xa != None) {
+ GP_DEBUG(2, "Setting WM_DELETE_WINDOW Atom to True");
+
+ XSetWMProtocols(win->dpy, win->win, &xa, 1);
+ } else {
+ GP_DEBUG(2, "Failed to set WM_DELETE_WINDOW Atom to True");
+ }
+
+ win_list_add(win);
+
+ /* Show window */
+ XMapWindow(win->dpy, win->win);
+
+ return 0;
+}
+
+void x11_win_close(struct x11_win *win)
+{
+ XLockDisplay(win->dpy);
+
+ win_list_rem(win);
+
+/*
+ if (x11->shm_flag)
+ destroy_shm_ximage(self);
+ else
+ destroy_ximage(self);
+*/
+
+ XDestroyWindow(win->dpy, win->win);
+
+ XUnlockDisplay(win->dpy);
+
+ /* Close connection/Decrease ref count */
+ x11_close();
+}
http://repo.or.cz/w/gfxprim.git/commit/1514e22782408ebbad3db2b9b4f37082f5e7…
commit 1514e22782408ebbad3db2b9b4f37082f5e7e8f5
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Mar 1 13:42:21 2013 +0100
core: GP_Common.h: Add GP_CONTAINER_OF()
diff --git a/include/core/GP_Common.h b/include/core/GP_Common.h
index 8718054..5a779c0 100644
--- a/include/core/GP_Common.h
+++ b/include/core/GP_Common.h
@@ -78,6 +78,9 @@
#define GP_ARRAY_SIZE(array) (sizeof(array) / sizeof(*array))
+#define GP_CONTAINER_OF(ptr, structure, member) + ((structure *)((char *)(ptr) - offsetof(structure, member)))
+
#endif /* __cplusplus */
/*
http://repo.or.cz/w/gfxprim.git/commit/19ad346473c404690363482eb05aba63474e…
commit 19ad346473c404690363482eb05aba63474eeed5
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Mar 1 11:25:32 2013 +0100
libs: backends: Fixes.
* Fix off-by-one in GP_BackendUpdateRectXYWH()
* Allow for NULL UpdateRect and Flip
- fix backends accordingly
diff --git a/include/backends/GP_Backend.h b/include/backends/GP_Backend.h
index f4db9e4..c1b89d6 100644
--- a/include/backends/GP_Backend.h
+++ b/include/backends/GP_Backend.h
@@ -145,10 +145,7 @@ typedef struct GP_Backend {
/*
* Calls backend->Flip().
*/
-static inline void GP_BackendFlip(GP_Backend *backend)
-{
- backend->Flip(backend);
-}
+void GP_BackendFlip(GP_Backend *backend);
/*
* Calls backend->UpdateRect().
@@ -168,7 +165,7 @@ static inline void GP_BackendUpdateRectXYWH(GP_Backend *backend,
GP_Coord x, GP_Coord y,
GP_Size w, GP_Size h)
{
- GP_BackendUpdateRectXYXY(backend, x, y, x + w, y + h);
+ GP_BackendUpdateRectXYXY(backend, x, y, x + w - 1, y + h - 1);
}
/*
diff --git a/libs/backends/GP_Backend.c b/libs/backends/GP_Backend.c
index 6839187..87959e3 100644
--- a/libs/backends/GP_Backend.c
+++ b/libs/backends/GP_Backend.c
@@ -16,7 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
- * Copyright (C) 2009-2012 Cyril Hrubis <metan(a)ucw.cz> *
+ * Copyright (C) 2009-2013 Cyril Hrubis <metan(a)ucw.cz> *
* *
*****************************************************************************/
@@ -26,10 +26,19 @@
#include "backends/GP_Backend.h"
+void GP_BackendFlip(GP_Backend *backend)
+{
+ if (backend->Flip != NULL)
+ backend->Flip(backend);
+}
+
void GP_BackendUpdateRectXYXY(GP_Backend *backend,
GP_Coord x0, GP_Coord y0,
GP_Coord x1, GP_Coord y1)
{
+ if (backend->UpdateRect == NULL)
+ return;
+
GP_TRANSFORM_POINT(backend->context, x0, y0);
GP_TRANSFORM_POINT(backend->context, x1, y1);
diff --git a/libs/backends/GP_LinuxFB.c b/libs/backends/GP_LinuxFB.c
index 43197d6..38d9ae4 100644
--- a/libs/backends/GP_LinuxFB.c
+++ b/libs/backends/GP_LinuxFB.c
@@ -163,20 +163,6 @@ static int allocate_console(struct fb_priv *fb, int flag)
/* Backend API callbacks */
-static void fb_flip_noop(GP_Backend *self __attribute__((unused)))
-{
-
-}
-
-static void fb_update_rect_noop(GP_Backend *self __attribute__((unused)),
- GP_Coord x1 __attribute__((unused)),
- GP_Coord y1 __attribute__((unused)),
- GP_Coord x2 __attribute__((unused)),
- GP_Coord y2 __attribute__((unused)))
-{
-
-}
-
static void fb_poll(GP_Backend *self)
{
struct fb_priv *fb = GP_BACKEND_PRIV(self);
@@ -320,8 +306,8 @@ GP_Backend *GP_BackendLinuxFBInit(const char *path, int flag)
/* update API */
backend->name = "Linux FB";
backend->context = &fb->context;
- backend->Flip = fb_flip_noop;
- backend->UpdateRect = fb_update_rect_noop;
+ backend->Flip = NULL;
+ backend->UpdateRect = NULL;
backend->Exit = fb_exit;
backend->SetAttributes = NULL;
backend->ResizeAck = NULL;
-----------------------------------------------------------------------
Summary of changes:
include/backends/GP_Backend.h | 7 +-
include/core/GP_Common.h | 3 +
libs/backends/GP_Backend.c | 11 +-
libs/backends/GP_LinuxFB.c | 18 +-
libs/backends/GP_X11.c | 612 ++++++--------------
.../bogoman_debug.c => libs/backends/GP_X11_Conn.h | 66 ++-
libs/backends/GP_X11_Win.h | 404 +++++++++++++
7 files changed, 639 insertions(+), 482 deletions(-)
copy demos/bogoman/bogoman_debug.c => libs/backends/GP_X11_Conn.h (62%)
create mode 100644 libs/backends/GP_X11_Win.h
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 1436f47f05624f213e5065a9436ccc404e6b8bad
by metan 25 Feb '13
by metan 25 Feb '13
25 Feb '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 1436f47f05624f213e5065a9436ccc404e6b8bad (commit)
from cc29e24343c95c5edd528e3567af652fc9b70b7f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/1436f47f05624f213e5065a9436ccc404e6b…
commit 1436f47f05624f213e5065a9436ccc404e6b8bad
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Mon Feb 25 11:04:40 2013 +0100
doc: text: Add note about width and height.
diff --git a/doc/text_api.txt b/doc/text_api.txt
index 08cd715..1a77a7d 100644
--- a/doc/text_api.txt
+++ b/doc/text_api.txt
@@ -219,4 +219,11 @@ void GP_FontFaceFree(GP_FontFace *self);
Renders TrueType font using link:http://www.freetype.org[FreeType] (currently
printable ASCII only) into GFXprim font structures.
+One of the 'width' or 'height' may be zero, which means that the second value
+should be computed accordingly.
+
+NOTE: If you pass both 'width' and 'height' non-zero the resulting font may
+ look strange as this action forced unnatural aspect ratio.
+
+
TIP: For Font and TextStyle handling see link:example_fonts.html[examples].
-----------------------------------------------------------------------
Summary of changes:
doc/text_api.txt | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: cc29e24343c95c5edd528e3567af652fc9b70b7f
by metan 23 Feb '13
by metan 23 Feb '13
23 Feb '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via cc29e24343c95c5edd528e3567af652fc9b70b7f (commit)
via ccfd33d3383ba4de615825d986dbf46805ef8d6a (commit)
from 188ea2197a3fdfddccedad25a563c9ee92059abf (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/cc29e24343c95c5edd528e3567af652fc9b7…
commit cc29e24343c95c5edd528e3567af652fc9b70b7f
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Feb 23 16:08:06 2013 +0100
doc: Edhance text API docs.
diff --git a/doc/example_fonts.txt b/doc/example_fonts.txt
new file mode 100644
index 0000000..85a6618
--- /dev/null
+++ b/doc/example_fonts.txt
@@ -0,0 +1,17 @@
+Font Test Example
+-----------------
+.A simple program to show all font characters with different styles.
+
+[source,c]
+------------------------------------------------------------------
+include::../demos/c_simple/fonttest.c[]
+------------------------------------------------------------------
+
+Fileview
+--------
+.A simple program to show contents of a file.
+
+[source,c]
+------------------------------------------------------------------
+include::../demos/c_simple/fileview.c[]
+------------------------------------------------------------------
diff --git a/doc/images/fonts/default_console_font.png b/doc/images/fonts/default_console_font.png
new file mode 100644
index 0000000..badc72a
Binary files /dev/null and b/doc/images/fonts/default_console_font.png differ
diff --git a/doc/images/fonts/default_console_font_big.png b/doc/images/fonts/default_console_font_big.png
new file mode 100644
index 0000000..19d6c03
Binary files /dev/null and b/doc/images/fonts/default_console_font_big.png differ
diff --git a/doc/images/fonts/default_console_font_embolding.png b/doc/images/fonts/default_console_font_embolding.png
new file mode 100644
index 0000000..795773f
Binary files /dev/null and b/doc/images/fonts/default_console_font_embolding.png differ
diff --git a/doc/images/fonts/default_proportional_font.png b/doc/images/fonts/default_proportional_font.png
new file mode 100644
index 0000000..b436194
Binary files /dev/null and b/doc/images/fonts/default_proportional_font.png differ
diff --git a/doc/images/fonts/font_tiny.png b/doc/images/fonts/font_tiny.png
new file mode 100644
index 0000000..4865ff2
Binary files /dev/null and b/doc/images/fonts/font_tiny.png differ
diff --git a/doc/images/fonts/font_tiny_mono.png b/doc/images/fonts/font_tiny_mono.png
new file mode 100644
index 0000000..6cfd5c8
Binary files /dev/null and b/doc/images/fonts/font_tiny_mono.png differ
diff --git a/doc/images/fonts/glyph_metrics.png b/doc/images/fonts/glyph_metrics.png
new file mode 100644
index 0000000..d2efad3
Binary files /dev/null and b/doc/images/fonts/glyph_metrics.png differ
diff --git a/doc/text_api.txt b/doc/text_api.txt
index 0f3484c..08cd715 100644
--- a/doc/text_api.txt
+++ b/doc/text_api.txt
@@ -6,13 +6,17 @@ NOTE: You may want to see the link:coordinate_system.html[coordinate system] fir
Text
~~~~
-Text drawing is controlled by the 'GP_TextStyle' structure defined in
-'core/GP_TextStyle.h'. This structure carries the information about font,
-letter spacing and pixel multiplication and spacing. (If no font is specified,
-the default monospace font is used.)
+Text drawing is controlled by the <<TextStyle,GP_TextStyle>> structure. This
+structure carries the information about font, letter spacing and pixel
+multiplication and spacing. (If no font is specified, the default mono-space
+font is used.)
[source,c]
--------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <text/GP_Text.h>
+
/* Where the text should be drawn relatively to the specified point */
typedef enum GP_TextAlign {
GP_ALIGN_LEFT = 0x01, /* to the left from the point */
@@ -26,49 +30,193 @@ typedef enum GP_TextAlign {
void GP_Text(GP_Context *context, const GP_TextStyle *style,
int x, int y, int align, const char *str, GP_Pixel pixel);
+
+
+GP_Size GP_Print(GP_Context *context, const GP_TextStyle *style,
+ GP_Coord x, GP_Coord y, int align,
+ GP_Pixel fg_color, GP_Pixel bg_color, const char *fmt, ...);
--------------------------------------------------------------------------------
Draws text at the position x and y; the alignment of the text in relation
to the point is specified by alignment flags.
+
If the 'style' argument is 'NULL', a default style is used.
The text size can be computed by following functions:
[source,c]
--------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <text/GP_TextMetric.h>
+
unsigned int GP_TextWidth(const GP_TextStyle *style, const char *str);
--------------------------------------------------------------------------------
Returns the width (in pixels) that would be occupied by the string if rendered
using the specified style.
+Computing a length of a given string is more complicated than it appears to
+be. The first letter needs 'advance - bearing' pixels, the middle letters
+needs 'advance' pixels and the last letter needs 'bearing + width' pixel. See
+link:images/fonts/glyph_metrics.png[Glyph Metrics] for a description of the
+terms used in this paragraph.
+
[source,c]
--------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <text/GP_TextMetric.h>
+
unsigned int GP_TextMaxWidth(const GP_TextStyle *style, unsigned int len);
--------------------------------------------------------------------------------
-Returns maximum text width, in pixels, for string with 'len' letters. This call
-is useful for variable letter size fonts.
+Returns maximum text width, in pixels, for string with 'len' letters.
+
+This call simply computes width of a string rendered with 'len' largest glyphs
+(letters) in the font. Because of this the resulting size is often much larger
+than needed.
+
+[source,c]
+--------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <text/GP_TextMetric.h>
+
+GP_Size GP_TextMaxStrWidth(const GP_TextStyle *style, const char *str,
+ unsigned int len);
+--------------------------------------------------------------------------------
+
+Returns maximum text width, in pixels, for a string with 'len' letters that
+are composed only of letters from 'str'.
+
+This call simply computes width of a string rendered with largest letter from
+'str' and with 'len' characters.
[source,c]
--------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <text/GP_TextMetric.h>
+
unsigned int GP_TextAscent(const GP_TextStyle *style);
--------------------------------------------------------------------------------
The Ascent is the height in pixels from the top to the baseline.
+The baseline is imaginary line that letters are positioned upon and the ascent
+is usually height of capital letter, but it may be larger for certain fonts.
+
[source,c]
--------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <text/GP_TextMetric.h>
+
unsigned int GP_TextDescent(const GP_TextStyle *style);
--------------------------------------------------------------------------------
The Descent is the height in pixels from baseline to the bottom.
+The baseline is imaginary line that letters are positioned upon and the
+descent is usually height of upper part of the letter y that goes under the
+baseline, but it may be larger for certain fonts.
+
[source,c]
--------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <text/GP_TextMetric.h>
+
unsigned int GP_TextHeight(const GP_TextStyle *style);
--------------------------------------------------------------------------------
The Height is size of the font from top to the bottom, i.e. equals exactly to
the sum of ascent and descent.
+This simply returns height that is needed to draw a line of a text using a
+certain font style (without the spacing between the lines).
+
+[[TextStyle]]
+TextStyle
+~~~~~~~~~
+
+[source,c]
+--------------------------------------------------------------------------------
+#include <GP.h>
+/* or */
+#include <text/GP_TextStyle.h>
+
+typedef struct GP_TextStyle {
+ const struct GP_FontFace *font;
+
+ /* Spacing between pixels (0 is the default, no spacing). */
+ int pixel_xspace, pixel_yspace;
+
+ /* Multiplier of pixel width/height (1 is default). */
+ int pixel_xmul, pixel_ymul;
+
+ /* Extra spacing (in pixels) between characters. */
+ int char_xspace;
+
+} GP_TextStyle;
+--------------------------------------------------------------------------------
+
+The TextStyle structure describes the parameters for text rendering.
+
+The first parameter is font being used.
+TODO: link to font format and description.
+
+The 'xspace' and 'yspace' parameters controls spacing between the pixels and
+the 'xmul' and 'ymul' describes pixel multiplication in respective directions.
+
+The 'char_xspace' is used to add additional space between letters.
+
+.Default Console Font xmul=ymul=1 xspace=yspace=0
+image::images/fonts/default_console_font.png["Default Console Font"]
+
+.Default Console Font xmul=ymul=2 xspace=yspace=-1
+image::images/fonts/default_console_font_embolding.png["Default Console Font"]
+
+.Default Console Font xmul=ymul=2 xspace=yspace=1
+image::images/fonts/default_console_font_big.png["Default Console Font"]
+
+
+Compiled-in Fonts
+~~~~~~~~~~~~~~~~~
+
+There is a global constant pointer to each compiled-in font structure, see
+'include/text/GP_Fonts.h'.
+
+.Default Console Font
+image::images/fonts/default_console_font.png["Default Console Font"]
+
+.Default Proportional Font
+image::images/fonts/default_proportional_font.png["Default Proportional Font"]
+
+.Font Tiny Mono (GP_FontTinyMono)
+image::images/fonts/font_tiny_mono.png["Font Tiny Mono"]
+
+.Font Tiny (GP_FontTiny)
+image::images/fonts/font_tiny.png["Font Tiny"]
+
+TrueType Fonts
+~~~~~~~~~~~~~~
+
+[source,c]
+--------------------------------------------------------------------------------
+/*
+ * Load font face from file.
+ */
+GP_FontFace *GP_FontFaceLoad(const char *path, uint32_t width, uint32_t height);
+
+/*
+ * Free the font face.
+ */
+void GP_FontFaceFree(GP_FontFace *self);
+--------------------------------------------------------------------------------
+
+Renders TrueType font using link:http://www.freetype.org[FreeType] (currently
+printable ASCII only) into GFXprim font structures.
+
+TIP: For Font and TextStyle handling see link:example_fonts.html[examples].
http://repo.or.cz/w/gfxprim.git/commit/ccfd33d3383ba4de615825d986dbf46805ef…
commit ccfd33d3383ba4de615825d986dbf46805ef8d6a
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Sat Feb 23 15:44:06 2013 +0100
doc: Fix asciidoc.css
Set the left menu width, otherwise it spans
across the whole page and links under are
not clickable.
diff --git a/doc/asciidoc.css b/doc/asciidoc.css
index 20b466f..c663f2d 100644
--- a/doc/asciidoc.css
+++ b/doc/asciidoc.css
@@ -120,6 +120,7 @@ div.left-menu {
top: 90pt;
left: -100pt;
height: 0;
+ width: 100pt;
}
div.logo h1 {
-----------------------------------------------------------------------
Summary of changes:
doc/asciidoc.css | 1 +
doc/{example_v4l2.txt => example_fonts.txt} | 16 +-
doc/images/fonts/default_console_font.png | Bin 0 -> 3480 bytes
doc/images/fonts/default_console_font_big.png | Bin 0 -> 1509 bytes
.../fonts/default_console_font_embolding.png | Bin 0 -> 4125 bytes
doc/images/fonts/default_proportional_font.png | Bin 0 -> 3412 bytes
doc/images/fonts/font_tiny.png | Bin 0 -> 2763 bytes
doc/images/fonts/font_tiny_mono.png | Bin 0 -> 2834 bytes
doc/images/fonts/glyph_metrics.png | Bin 0 -> 3418 bytes
doc/text_api.txt | 160 +++++++++++++++++++-
10 files changed, 163 insertions(+), 14 deletions(-)
copy doc/{example_v4l2.txt => example_fonts.txt} (51%)
create mode 100644 doc/images/fonts/default_console_font.png
create mode 100644 doc/images/fonts/default_console_font_big.png
create mode 100644 doc/images/fonts/default_console_font_embolding.png
create mode 100644 doc/images/fonts/default_proportional_font.png
create mode 100644 doc/images/fonts/font_tiny.png
create mode 100644 doc/images/fonts/font_tiny_mono.png
create mode 100644 doc/images/fonts/glyph_metrics.png
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0
[repo.or.cz] gfxprim.git branch master updated: 188ea2197a3fdfddccedad25a563c9ee92059abf
by metan 22 Feb '13
by metan 22 Feb '13
22 Feb '13
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project gfxprim.git.
The branch, master has been updated
via 188ea2197a3fdfddccedad25a563c9ee92059abf (commit)
from 86bcd463620e8f23223be4ba6aa7c119431a17ff (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://repo.or.cz/w/gfxprim.git/commit/188ea2197a3fdfddccedad25a563c9ee9205…
commit 188ea2197a3fdfddccedad25a563c9ee92059abf
Author: Cyril Hrubis <metan(a)ucw.cz>
Date: Fri Feb 22 13:05:11 2013 +0100
build: Add check for python-config.
To compile python bindings both swig
and python-devel packages are needed.
Add check for python-config.
Now the bindings could be compiled
for different python versions by:
./configure --PYTHON_CONFIG=python-config-2.7
However the path for python binary is
not yet adjusted for the tests and demos.
diff --git a/config.mk b/config.mk
index 5a05ef1..c149a0c 100644
--- a/config.mk
+++ b/config.mk
@@ -1,10 +1,13 @@
include $(TOPDIR)/config.gen.mk
+
CFLAGS+=-I$(TOPDIR)/include/
# path to local module directory
PYLIBSDIR=$(TOPDIR)/pylib
-PYTHON_INCLUDE=`python-config --include`
+ifdef PYTHON_CONFIG
+PYTHON_INCLUDE=$(shell $(PYTHON_CONFIG) --include)
+endif
# To test with other python versions (example):
#PYTHON_BIN=${TOPDIR}/virtualpy2.4/bin/python
diff --git a/configure b/configure
index 4e23935..8704716 100755
--- a/configure
+++ b/configure
@@ -59,7 +59,18 @@ def check_for_swig(cfg):
sys.stderr.write('Non')
cfg['SWIG'][0] = ''
else:
- sys.stderr.write("Yesn")
+ sys.stderr.write('Yesn')
+
+def check_for_python_config(cfg):
+ sys.stderr.write("Checking for python-config ... ")
+
+ ret = os.system("%s --libs > /dev/null 2>&1" % cfg['PYTHON_CONFIG'][0])
+
+ if ret:
+ sys.stderr.write('Non')
+ cfg['PYTHON_CONFIG'][0] = ''
+ else:
+ sys.stderr.write('Yesn')
#
# Library checking api
@@ -164,14 +175,15 @@ def die_screaming(msg):
def basic_checks(cfg):
sys.stderr.write("Basic checksn")
sys.stderr.write("------------n")
-
+
if not c_compiler_exists(cfg):
die_screaming("No C compiler found")
-
+
if not python_module_installed(cfg, 'jinja2'):
die_screaming("No jinja2 python module found")
-
+
check_for_swig(cfg)
+ check_for_python_config(cfg)
sys.stderr.write("n")
#
@@ -179,6 +191,7 @@ def basic_checks(cfg):
#
def write_config_h(cfg, libs):
f = open("config.h", "w")
+ f.write("/*n * This file is genereated by configure scriptn */n");
f.write("#ifndef CONFIG_Hn#define CONFIG_Hnn")
libs.write_config_h(f);
f.write("#endif /* CONFIG_H */n");
@@ -237,11 +250,12 @@ if __name__ == '__main__':
#
# Dictionary for default configuration parameters
#
- cfg = {'CC' : ['gcc', 'Path/name of the C compiler'],
- 'CFLAGS' : ['-pthread -W -Wall -Wextra -fPIC -O2 -ggdb -D_FORTIFY_SOURCE=2', 'C compiler flags'],
- 'PYTHON_BIN' : ['python', 'Path/name of python interpreter'],
- 'SWIG' : ['swig', 'Simplified Wrapper and Interface Generator'],
- 'include_path': ['/usr/include', 'Path to the system headers']}
+ cfg = {'CC' : ['gcc', 'Path/name of the C compiler'],
+ 'CFLAGS' : ['-pthread -W -Wall -Wextra -fPIC -O2 -ggdb -D_FORTIFY_SOURCE=2', 'C compiler flags'],
+ 'PYTHON_BIN' : ['python', 'Path/name of python interpreter'],
+ 'SWIG' : ['swig', 'Simplified Wrapper and Interface Generator'],
+ 'PYTHON_CONFIG' : ['python-config', 'Python config helper'],
+ 'include_path' : ['/usr/include', 'Path to the system headers']}
#
# Library detection/enable disable
diff --git a/pywrap.mk b/pywrap.mk
index f41ce63..4518b71 100644
--- a/pywrap.mk
+++ b/pywrap.mk
@@ -7,7 +7,8 @@ SWIG_C=$(LIBNAME)_wrap.c
SWIG_PY=c_$(LIBNAME).py
SWIG_LIB=_c_$(LIBNAME).so
-ifneq ($(SWIG),)
+ifdef SWIG
+ifdef PYTHON_CONFIG
INCLUDES+=$(addprefix -I$(TOPDIR)/include/, $(INCLUDE))
@@ -33,6 +34,7 @@ else # VERBOSE
@$(CC) $< $(CFLAGS) -D_GNU_SOURCE=1 $(LDFLAGS) -I$(PYTHON_INCLUDE) --shared -lGP $(LDLIBS) -L$(TOPDIR)/build/ -o $@
endif # VERBOSE
-endif # ifneq ($(SWIG),)
+endif # PYTHON_CONFIG
+endif # SWIG
CLEAN+=$(SWIG_C) $(SWIG_PY) $(SWIG_LIB) *.pyc
-----------------------------------------------------------------------
Summary of changes:
config.mk | 5 ++++-
configure | 32 +++++++++++++++++++++++---------
pywrap.mk | 6 ++++--
3 files changed, 31 insertions(+), 12 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos(a)gmail.com
if you want to unsubscribe, or site admin admin(a)repo.or.cz if you receive
no reply.
--
gfxprim.git ("A simple 2D graphics library with emphasis on correctness and well-defined operation.")
1
0