184 changed files with 25628 additions and 0 deletions
@ -0,0 +1 @@ |
|||
docs/html |
File diff suppressed because it is too large
@ -0,0 +1,289 @@ |
|||
ChibiOS/GFX coding style |
|||
|
|||
To provide an easy-to-read code, we want to have a uniform |
|||
coding style within ChibiOS/GFX. |
|||
Because I personally like the widley used linux kernel coding style, |
|||
I decided to use it for ChibiOS/GFX as well. |
|||
Therefore, the coding style documentation is a 1:1 copy from the |
|||
codingstyle.txt of the linux kernel source code. |
|||
|
|||
Please make sure you match these coding styles before you contribute |
|||
any code. If you find any existing code which dosen't match these rules, |
|||
please feel free to submit a patch. |
|||
|
|||
There are only two rules which are not similar to the following |
|||
documentation: |
|||
|
|||
- Prefered tabsize is 4, not 8 |
|||
- We don't use 80 character columns |
|||
|
|||
|
|||
Please read through the following carefully: |
|||
|
|||
|
|||
|
|||
Linux kernel coding style |
|||
|
|||
This is a short document describing the preferred coding style for the |
|||
linux kernel. Coding style is very personal, and I won't _force_ my |
|||
views on anybody, but this is what goes for anything that I have to be |
|||
able to maintain, and I'd prefer it for most other things too. Please |
|||
at least consider the points made here. |
|||
|
|||
First off, I'd suggest printing out a copy of the GNU coding standards, |
|||
and NOT read it. Burn them, it's a great symbolic gesture. |
|||
|
|||
Anyway, here goes: |
|||
|
|||
|
|||
Chapter 1: Indentation |
|||
|
|||
Tabs are 8 characters, and thus indentations are also 8 characters. |
|||
There are heretic movements that try to make indentations 4 (or even 2!) |
|||
characters deep, and that is akin to trying to define the value of PI to |
|||
be 3. |
|||
|
|||
Rationale: The whole idea behind indentation is to clearly define where |
|||
a block of control starts and ends. Especially when you've been looking |
|||
at your screen for 20 straight hours, you'll find it a lot easier to see |
|||
how the indentation works if you have large indentations. |
|||
|
|||
Now, some people will claim that having 8-character indentations makes |
|||
the code move too far to the right, and makes it hard to read on a |
|||
80-character terminal screen. The answer to that is that if you need |
|||
more than 3 levels of indentation, you're screwed anyway, and should fix |
|||
your program. |
|||
|
|||
In short, 8-char indents make things easier to read, and have the added |
|||
benefit of warning you when you're nesting your functions too deep. |
|||
Heed that warning. |
|||
|
|||
|
|||
Chapter 2: Placing Braces |
|||
|
|||
The other issue that always comes up in C styling is the placement of |
|||
braces. Unlike the indent size, there are few technical reasons to |
|||
choose one placement strategy over the other, but the preferred way, as |
|||
shown to us by the prophets Kernighan and Ritchie, is to put the opening |
|||
brace last on the line, and put the closing brace first, thusly: |
|||
|
|||
if (x is true) { |
|||
we do y |
|||
} |
|||
|
|||
However, there is one special case, namely functions: they have the |
|||
opening brace at the beginning of the next line, thus: |
|||
|
|||
int function(int x) |
|||
{ |
|||
body of function |
|||
} |
|||
|
|||
Heretic people all over the world have claimed that this inconsistency |
|||
is ... well ... inconsistent, but all right-thinking people know that |
|||
(a) K&R are _right_ and (b) K&R are right. Besides, functions are |
|||
special anyway (you can't nest them in C). |
|||
|
|||
Note that the closing brace is empty on a line of its own, _except_ in |
|||
the cases where it is followed by a continuation of the same statement, |
|||
ie a "while" in a do-statement or an "else" in an if-statement, like |
|||
this: |
|||
|
|||
do { |
|||
body of do-loop |
|||
} while (condition); |
|||
|
|||
and |
|||
|
|||
if (x == y) { |
|||
.. |
|||
} else if (x > y) { |
|||
... |
|||
} else { |
|||
.... |
|||
} |
|||
|
|||
Rationale: K&R. |
|||
|
|||
Also, note that this brace-placement also minimizes the number of empty |
|||
(or almost empty) lines, without any loss of readability. Thus, as the |
|||
supply of new-lines on your screen is not a renewable resource (think |
|||
25-line terminal screens here), you have more empty lines to put |
|||
comments on. |
|||
|
|||
|
|||
Chapter 3: Naming |
|||
|
|||
C is a Spartan language, and so should your naming be. Unlike Modula-2 |
|||
and Pascal programmers, C programmers do not use cute names like |
|||
ThisVariableIsATemporaryCounter. A C programmer would call that |
|||
variable "tmp", which is much easier to write, and not the least more |
|||
difficult to understand. |
|||
|
|||
HOWEVER, while mixed-case names are frowned upon, descriptive names for |
|||
global variables are a must. To call a global function "foo" is a |
|||
shooting offense. |
|||
|
|||
GLOBAL variables (to be used only if you _really_ need them) need to |
|||
have descriptive names, as do global functions. If you have a function |
|||
that counts the number of active users, you should call that |
|||
"count_active_users()" or similar, you should _not_ call it "cntusr()". |
|||
|
|||
Encoding the type of a function into the name (so-called Hungarian |
|||
notation) is brain damaged - the compiler knows the types anyway and can |
|||
check those, and it only confuses the programmer. No wonder MicroSoft |
|||
makes buggy programs. |
|||
|
|||
LOCAL variable names should be short, and to the point. If you have |
|||
some random integer loop counter, it should probably be called "i". |
|||
Calling it "loop_counter" is non-productive, if there is no chance of it |
|||
being mis-understood. Similarly, "tmp" can be just about any type of |
|||
variable that is used to hold a temporary value. |
|||
|
|||
If you are afraid to mix up your local variable names, you have another |
|||
problem, which is called the function-growth-hormone-imbalance syndrome. |
|||
See next chapter. |
|||
|
|||
|
|||
Chapter 4: Functions |
|||
|
|||
Functions should be short and sweet, and do just one thing. They should |
|||
fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24, |
|||
as we all know), and do one thing and do that well. |
|||
|
|||
The maximum length of a function is inversely proportional to the |
|||
complexity and indentation level of that function. So, if you have a |
|||
conceptually simple function that is just one long (but simple) |
|||
case-statement, where you have to do lots of small things for a lot of |
|||
different cases, it's OK to have a longer function. |
|||
|
|||
However, if you have a complex function, and you suspect that a |
|||
less-than-gifted first-year high-school student might not even |
|||
understand what the function is all about, you should adhere to the |
|||
maximum limits all the more closely. Use helper functions with |
|||
descriptive names (you can ask the compiler to in-line them if you think |
|||
it's performance-critical, and it will probably do a better job of it |
|||
that you would have done). |
|||
|
|||
Another measure of the function is the number of local variables. They |
|||
shouldn't exceed 5-10, or you're doing something wrong. Re-think the |
|||
function, and split it into smaller pieces. A human brain can |
|||
generally easily keep track of about 7 different things, anything more |
|||
and it gets confused. You know you're brilliant, but maybe you'd like |
|||
to understand what you did 2 weeks from now. |
|||
|
|||
|
|||
Chapter 5: Commenting |
|||
|
|||
Comments are good, but there is also a danger of over-commenting. NEVER |
|||
try to explain HOW your code works in a comment: it's much better to |
|||
write the code so that the _working_ is obvious, and it's a waste of |
|||
time to explain badly written code. |
|||
|
|||
Generally, you want your comments to tell WHAT your code does, not HOW. |
|||
Also, try to avoid putting comments inside a function body: if the |
|||
function is so complex that you need to separately comment parts of it, |
|||
you should probably go back to chapter 4 for a while. You can make |
|||
small comments to note or warn about something particularly clever (or |
|||
ugly), but try to avoid excess. Instead, put the comments at the head |
|||
of the function, telling people what it does, and possibly WHY it does |
|||
it. |
|||
|
|||
|
|||
Chapter 6: You've made a mess of it |
|||
|
|||
That's OK, we all do. You've probably been told by your long-time Unix |
|||
user helper that "GNU emacs" automatically formats the C sources for |
|||
you, and you've noticed that yes, it does do that, but the defaults it |
|||
uses are less than desirable (in fact, they are worse than random |
|||
typing - a infinite number of monkeys typing into GNU emacs would never |
|||
make a good program). |
|||
|
|||
So, you can either get rid of GNU emacs, or change it to use saner |
|||
values. To do the latter, you can stick the following in your .emacs file: |
|||
|
|||
(defun linux-c-mode () |
|||
"C mode with adjusted defaults for use with the Linux kernel." |
|||
(interactive) |
|||
(c-mode) |
|||
(c-set-style "K&R") |
|||
(setq c-basic-offset 8)) |
|||
|
|||
This will define the M-x linux-c-mode command. When hacking on a |
|||
module, if you put the string -*- linux-c -*- somewhere on the first |
|||
two lines, this mode will be automatically invoked. Also, you may want |
|||
to add |
|||
|
|||
(setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode) |
|||
auto-mode-alist)) |
|||
|
|||
to your .emacs file if you want to have linux-c-mode switched on |
|||
automagically when you edit source files under /usr/src/linux. |
|||
|
|||
But even if you fail in getting emacs to do sane formatting, not |
|||
everything is lost: use "indent". |
|||
|
|||
Now, again, GNU indent has the same brain dead settings that GNU emacs |
|||
has, which is why you need to give it a few command line options. |
|||
However, that's not too bad, because even the makers of GNU indent |
|||
recognize the authority of K&R (the GNU people aren't evil, they are |
|||
just severely misguided in this matter), so you just give indent the |
|||
options "-kr -i8" (stands for "K&R, 8 character indents"). |
|||
|
|||
"indent" has a lot of options, and especially when it comes to comment |
|||
re-formatting you may want to take a look at the manual page. But |
|||
remember: "indent" is not a fix for bad programming. |
|||
|
|||
|
|||
Chapter 7: Configuration-files |
|||
|
|||
For configuration options (arch/xxx/config.in, and all the Config.in files), |
|||
somewhat different indentation is used. |
|||
|
|||
An indention level of 3 is used in the code, while the text in the config- |
|||
options should have an indention-level of 2 to indicate dependencies. The |
|||
latter only applies to bool/tristate options. For other options, just use |
|||
common sense. An example: |
|||
|
|||
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then |
|||
tristate 'Apply nitroglycerine inside the keyboard (DANGEROUS)' CONFIG_BOOM |
|||
if [ "$CONFIG_BOOM" != "n" ]; then |
|||
bool ' Output nice messages when you explode' CONFIG_CHEER |
|||
fi |
|||
fi |
|||
|
|||
Generally, CONFIG_EXPERIMENTAL should surround all options not considered |
|||
stable. All options that are known to trash data (experimental write- |
|||
support for file-systems, for instance) should be denoted (DANGEROUS), other |
|||
Experimental options should be denoted (EXPERIMENTAL). |
|||
|
|||
|
|||
Chapter 8: Data structures |
|||
|
|||
Data structures that have visibility outside the single-threaded |
|||
environment they are created and destroyed in should always have |
|||
reference counts. In the kernel, garbage collection doesn't exist (and |
|||
outside the kernel garbage collection is slow and inefficient), which |
|||
means that you absolutely _have_ to reference count all your uses. |
|||
|
|||
Reference counting means that you can avoid locking, and allows multiple |
|||
users to have access to the data structure in parallel - and not having |
|||
to worry about the structure suddenly going away from under them just |
|||
because they slept or did something else for a while. |
|||
|
|||
Note that locking is _not_ a replacement for reference counting. |
|||
Locking is used to keep data structures coherent, while reference |
|||
counting is a memory management technique. Usually both are needed, and |
|||
they are not to be confused with each other. |
|||
|
|||
Many data structures can indeed have two levels of reference counting, |
|||
when there are users of different "classes". The subclass count counts |
|||
the number of subclass users, and decrements the global count just once |
|||
when the subclass count goes to zero. |
|||
|
|||
Examples of this kind of "multi-reference-counting" can be found in |
|||
memory management ("struct mm_struct": mm_users and mm_count), and in |
|||
filesystem code ("struct super_block": s_count and s_active). |
|||
|
|||
Remember: if another thread can find your data structure, and you don't |
|||
have a reference count on it, you almost certainly have a bug. |
@ -0,0 +1,33 @@ |
|||
/**
|
|||
* This file has a different license to the rest of the GFX system. |
|||
* You can copy, modify and distribute this file as you see fit. |
|||
* You do not need to publish your source modifications to this file. |
|||
* The only thing you are not permitted to do is to relicense it |
|||
* under a different license. |
|||
*/ |
|||
|
|||
#ifndef _GFXCONF_H |
|||
#define _GFXCONF_H |
|||
|
|||
/* GFX sub-systems to turn on */ |
|||
#define GFX_USE_GDISP TRUE |
|||
#define GFX_USE_GWIN FALSE |
|||
#define GFX_USE_GEVENT FALSE |
|||
#define GFX_USE_GTIMER FALSE |
|||
#define GFX_USE_GINPUT FALSE |
|||
|
|||
/* Features for the GDISP sub-system. */ |
|||
#define GDISP_NEED_VALIDATION TRUE |
|||
#define GDISP_NEED_CLIP FALSE |
|||
#define GDISP_NEED_TEXT FALSE |
|||
#define GDISP_NEED_CIRCLE FALSE |
|||
#define GDISP_NEED_ELLIPSE FALSE |
|||
#define GDISP_NEED_ARC FALSE |
|||
#define GDISP_NEED_SCROLL FALSE |
|||
#define GDISP_NEED_PIXELREAD FALSE |
|||
#define GDISP_NEED_CONTROL FALSE |
|||
#define GDISP_NEED_MULTITHREAD FALSE |
|||
#define GDISP_NEED_ASYNC FALSE |
|||
#define GDISP_NEED_MSGAPI FALSE |
|||
|
|||
#endif /* _GFXCONF_H */ |
@ -0,0 +1,79 @@ |
|||
/*
|
|||
ChibiOS/GFX - Copyright (C) 2012 |
|||
Joel Bodenmann aka Tectu <joel@unormal.org> |
|||
|
|||
This file is part of ChibiOS/GFX. |
|||
|
|||
ChibiOS/GFX is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ChibiOS/GFX 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 General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "ch.h" |
|||
#include "hal.h" |
|||
#include "gfx.h" |
|||
|
|||
void mandelbrot(float x1, float y1, float x2, float y2) { |
|||
unsigned int i,j, width, height; |
|||
uint16_t iter; |
|||
color_t color; |
|||
float fwidth, fheight; |
|||
|
|||
float sy = y2 - y1; |
|||
float sx = x2 - x1; |
|||
const int MAX = 512; |
|||
|
|||
width = (unsigned int)gdispGetWidth(); |
|||
height = (unsigned int)gdispGetHeight(); |
|||
fwidth = width; |
|||
fheight = height; |
|||
|
|||
for(i = 0; i < width; i++) { |
|||
for(j = 0; j < height; j++) { |
|||
float cy = j * sy / fheight + y1; |
|||
float cx = i * sx / fwidth + x1; |
|||
float x=0.0f, y=0.0f, xx=0.0f, yy=0.0f; |
|||
for(iter=0; iter <= MAX && xx+yy<4.0f; iter++) { |
|||
xx = x*x; |
|||
yy = y*y; |
|||
y = 2.0f*x*y + cy; |
|||
x = xx - yy + cx; |
|||
} |
|||
//color = ((iter << 8) | (iter&0xFF));
|
|||
color = RGB2COLOR(iter<<7, iter<<4, iter); |
|||
gdispDrawPixel(i, j, color); |
|||
} |
|||
} |
|||
} |
|||
|
|||
int main(void) { |
|||
float cx, cy; |
|||
float zoom = 1.0f; |
|||
|
|||
halInit(); |
|||
chSysInit(); |
|||
|
|||
gdispInit(); |
|||
|
|||
/* where to zoom in */ |
|||
cx = -0.086f; |
|||
cy = 0.85f; |
|||
|
|||
while(TRUE) { |
|||
mandelbrot(-2.0f*zoom+cx, -1.5f*zoom+cy, 2.0f*zoom+cx, 1.5f*zoom+cy); |
|||
|
|||
zoom *= 0.7f; |
|||
if(zoom <= 0.00001f) |
|||
zoom = 1.0f; |
|||
} |
|||
} |
|||
|
@ -0,0 +1,43 @@ |
|||
/**
|
|||
* This file has a different license to the rest of the GFX system. |
|||
* You can copy, modify and distribute this file as you see fit. |
|||
* You do not need to publish your source modifications to this file. |
|||
* The only thing you are not permitted to do is to relicense it |
|||
* under a different license. |
|||
*/ |
|||
|
|||
#ifndef _GFXCONF_H |
|||
#define _GFXCONF_H |
|||
|
|||
/* GFX sub-systems to turn on */ |
|||
#define GFX_USE_GDISP TRUE |
|||
#define GFX_USE_GWIN FALSE |
|||
#define GFX_USE_GEVENT TRUE |
|||
#define GFX_USE_GTIMER TRUE |
|||
#define GFX_USE_GINPUT TRUE |
|||
|
|||
/* Features for the GDISP sub-system. */ |
|||
#define GDISP_NEED_VALIDATION TRUE |
|||
#define GDISP_NEED_CLIP TRUE |
|||
#define GDISP_NEED_TEXT TRUE |
|||
#define GDISP_NEED_CIRCLE TRUE |
|||
#define GDISP_NEED_ELLIPSE FALSE |
|||
#define GDISP_NEED_ARC FALSE |
|||
#define GDISP_NEED_SCROLL FALSE |
|||
#define GDISP_NEED_PIXELREAD FALSE |
|||
#define GDISP_NEED_CONTROL TRUE |
|||
#define GDISP_NEED_MULTITHREAD TRUE |
|||
#define GDISP_NEED_ASYNC FALSE |
|||
#define GDISP_NEED_MSGAPI FALSE |
|||
|
|||
/* Builtin Fonts */ |
|||
#define GDISP_INCLUDE_FONT_SMALL FALSE |
|||
#define GDISP_INCLUDE_FONT_LARGER FALSE |
|||
#define GDISP_INCLUDE_FONT_UI1 FALSE |
|||
#define GDISP_INCLUDE_FONT_UI2 TRUE |
|||
#define GDISP_INCLUDE_FONT_LARGENUMBERS TRUE |
|||
|
|||
/* Features for the GINPUT sub-system. */ |
|||
#define GINPUT_NEED_MOUSE TRUE |
|||
|
|||
#endif /* _GFXCONF_H */ |
@ -0,0 +1,113 @@ |
|||
/*
|
|||
ChibiOS/GFX - Copyright (C) 2012 |
|||
Joel Bodenmann aka Tectu <joel@unormal.org> |
|||
|
|||
This file is part of ChibiOS/GFX. |
|||
|
|||
ChibiOS/GFX is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ChibiOS/GFX 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 General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "ch.h" |
|||
#include "hal.h" |
|||
#include "gfx.h" |
|||
|
|||
#define COLOR_SIZE 20 |
|||
#define PEN_SIZE 20 |
|||
#define OFFSET 3 |
|||
|
|||
#define COLOR_BOX(a) (ev.x >= a && ev.x <= a + COLOR_SIZE) |
|||
#define PEN_BOX(a) (ev.y >= a && ev.y <= a + COLOR_SIZE) |
|||
#define GET_COLOR(a) (COLOR_BOX(a * COLOR_SIZE + OFFSET)) |
|||
#define GET_PEN(a) (PEN_BOX(a * 2 * PEN_SIZE + OFFSET)) |
|||
#define DRAW_COLOR(a) (a * COLOR_SIZE + OFFSET) |
|||
#define DRAW_PEN(a) (a * 2 * PEN_SIZE + OFFSET) |
|||
#define DRAW_AREA(x, y) (x >= PEN_SIZE + OFFSET + 3 && x <= gdispGetWidth() && \ |
|||
y >= COLOR_SIZE + OFFSET + 3 && y <= gdispGetHeight()) |
|||
|
|||
void drawScreen(void) { |
|||
char *msg = "ChibiOS/GFX"; |
|||
font_t font1, font2; |
|||
|
|||
font1 = gdispOpenFont("UI2 Double"); |
|||
font2 = gdispOpenFont("LargeNumbers"); |
|||
|
|||
gdispClear(White); |
|||
gdispDrawString(gdispGetWidth()-gdispGetStringWidth(msg, font1)-3, 3, msg, font1, Black); |
|||
|
|||
/* colors */ |
|||
gdispFillArea(0 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Black); /* Black */ |
|||
gdispFillArea(1 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Red); /* Red */ |
|||
gdispFillArea(2 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Yellow); /* Yellow */ |
|||
gdispFillArea(3 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Green); /* Green */ |
|||
gdispFillArea(4 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Blue); /* Blue */ |
|||
gdispDrawBox (5 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Black); /* White */ |
|||
|
|||
/* pens */ |
|||
gdispDrawString(OFFSET * 2, DRAW_PEN(1), "1", font2, Black); |
|||
gdispDrawString(OFFSET * 2, DRAW_PEN(2), "2", font2, Black); |
|||
gdispDrawString(OFFSET * 2, DRAW_PEN(3), "3", font2, Black); |
|||
gdispDrawString(OFFSET * 2, DRAW_PEN(4), "4", font2, Black); |
|||
gdispDrawString(OFFSET * 2, DRAW_PEN(5), "5", font2, Black); |
|||
|
|||
gdispCloseFont(font1); |
|||
gdispCloseFont(font2); |
|||
} |
|||
|
|||
GEventMouse ev; |
|||
|
|||
int main(void) { |
|||
color_t color = Black; |
|||
uint16_t pen = 0; |
|||
|
|||
halInit(); |
|||
chSysInit(); |
|||
|
|||
gdispInit(); |
|||
ginputGetMouse(0); |
|||
gdispSetOrientation(GDISP_ROTATE_90); |
|||
|
|||
drawScreen(); |
|||
|
|||
while (TRUE) { |
|||
ginputGetMouseStatus(0, &ev); |
|||
if (!(ev.current_buttons & GINPUT_MOUSE_BTN_LEFT)) |
|||
continue; |
|||
|
|||
/* inside color box ? */ |
|||
if(ev.y >= OFFSET && ev.y <= COLOR_SIZE) { |
|||
if(GET_COLOR(0)) color = Black; |
|||
else if(GET_COLOR(1)) color = Red; |
|||
else if(GET_COLOR(2)) color = Yellow; |
|||
else if(GET_COLOR(3)) color = Green; |
|||
else if(GET_COLOR(4)) color = Blue; |
|||
else if(GET_COLOR(5)) color = White; |
|||
|
|||
/* inside pen box ? */ |
|||
} else if(ev.x >= OFFSET && ev.x <= PEN_SIZE) { |
|||
if(GET_PEN(1)) pen = 0; |
|||
else if(GET_PEN(2)) pen = 1; |
|||
else if(GET_PEN(3)) pen = 2; |
|||
else if(GET_PEN(4)) pen = 3; |
|||
else if(GET_PEN(5)) pen = 4; |
|||
|
|||
/* inside drawing area ? */ |
|||
} else if(DRAW_AREA(ev.x, ev.y)) { |
|||
if(pen == 0) |
|||
gdispDrawPixel(ev.x, ev.y, color); |
|||
else |
|||
gdispFillCircle(ev.x, ev.y, pen, color); |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,41 @@ |
|||
/**
|
|||
* This file has a different license to the rest of the GFX system. |
|||
* You can copy, modify and distribute this file as you see fit. |
|||
* You do not need to publish your source modifications to this file. |
|||
* The only thing you are not permitted to do is to relicense it |
|||
* under a different license. |
|||
*/ |
|||
|
|||
#ifndef _GFXCONF_H |
|||
#define _GFXCONF_H |
|||
|
|||
/* GFX sub-systems to turn on */ |
|||
#define GFX_USE_GDISP TRUE |
|||
#define GFX_USE_GWIN FALSE |
|||
#define GFX_USE_GEVENT FALSE |
|||
#define GFX_USE_GTIMER FALSE |
|||
#define GFX_USE_GINPUT FALSE |
|||
|
|||
/* Features for the GDISP sub-system. */ |
|||
#define GDISP_NEED_VALIDATION FALSE |
|||
#define GDISP_NEED_CLIP FALSE |
|||
#define GDISP_NEED_TEXT TRUE |
|||
#define GDISP_NEED_CIRCLE FALSE |
|||
#define GDISP_NEED_ELLIPSE FALSE |
|||
#define GDISP_NEED_ARC FALSE |
|||
#define GDISP_NEED_SCROLL FALSE |
|||
#define GDISP_NEED_PIXELREAD FALSE |
|||
#define GDISP_NEED_CONTROL TRUE |
|||
#define GDISP_NEED_MULTITHREAD FALSE |
|||
#define GDISP_NEED_ASYNC FALSE |
|||
#define GDISP_NEED_MSGAPI FALSE |
|||
|
|||
/* Builtin Fonts */ |
|||
#define GDISP_INCLUDE_FONT_SMALL FALSE |
|||
#define GDISP_INCLUDE_FONT_LARGER FALSE |
|||
#define GDISP_INCLUDE_FONT_UI1 FALSE |
|||
#define GDISP_INCLUDE_FONT_UI2 TRUE |
|||
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE |
|||
|
|||
#endif /* _GFXCONF_H */ |
|||
|
@ -0,0 +1,146 @@ |
|||
/*
|
|||
ChibiOS/GFX - Copyright (C) 2012 |
|||
Joel Bodenmann aka Tectu <joel@unormal.org> |
|||
|
|||
This file is part of ChibiOS/GFX. |
|||
|
|||
ChibiOS/GFX is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ChibiOS/GFX 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 General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "ch.h" |
|||
#include "hal.h" |
|||
#include "chprintf.h" |
|||
#include "stdlib.h" |
|||
#include "string.h" |
|||
#include "gfx.h" |
|||
|
|||
#define SCB_DEMCR (*(volatile unsigned *)0xE000EDFC) |
|||
#define CPU_RESET_CYCLECOUNTER do { SCB_DEMCR = SCB_DEMCR | 0x01000000; \ |
|||
DWT_CYCCNT = 0; \ |
|||
DWT_CTRL = DWT_CTRL | 1 ; } while(0) |
|||
|
|||
static int uitoa(unsigned int value, char * buf, int max) { |
|||
int n = 0; |
|||
int i = 0; |
|||
unsigned int tmp = 0; |
|||
|
|||
if (NULL == buf) |
|||
return -3; |
|||
|
|||
if (2 > max) |
|||
return -4; |
|||
|
|||
i=1; |
|||
tmp = value; |
|||
if (0 > tmp) { |
|||
tmp *= -1; |
|||
i++; |
|||
} |
|||
for (;;) { |
|||
tmp /= 10; |
|||
if (0 >= tmp) |
|||
break; |
|||
i++; |
|||
} |
|||
if (i >= max) { |
|||
buf[0] = '?'; |
|||
buf[1] = 0x0; |
|||
return 2; |
|||
} |
|||
|
|||
n = i; |
|||
tmp = value; |
|||
if (0 > tmp) { |
|||
tmp *= -1; |
|||
} |
|||
buf[i--] = 0x0; |
|||
for (;;) { |
|||
buf[i--] = (tmp % 10) + '0'; |
|||
tmp /= 10; |
|||
if (0 >= tmp) { |
|||
break; |
|||
} |
|||
} |
|||
if (-1 != i) { |
|||
buf[i--] = '-'; |
|||
} |
|||
|
|||
return n; |
|||
} |
|||
|
|||
void benchmark(void) { |
|||
uint32_t i, pixels, ms, pps; |
|||
char pps_str[25]; |
|||
coord_t height, width, rx, ry, rcx, rcy; |
|||
color_t random_color; |
|||
font_t font; |
|||
|
|||
gdispSetOrientation(GDISP_ROTATE_90); |
|||
gdispClear(Black); |
|||
|
|||
width = gdispGetWidth(); |
|||
height = gdispGetHeight(); |
|||
font = gdispOpenFont("UI2 Double"); |
|||
|
|||
gdispDrawStringBox(0, 0, width, 30, "ChibiOS/GFX - Benchmark", font, White, justifyCenter); |
|||
|
|||
font = gdispOpenFont("UI2"); |
|||
gdispDrawStringBox(0, height/2, width, 30, "5000 random rectangles", font, White, justifyCenter); |
|||
|
|||
chThdSleepMilliseconds(3000); |
|||
|
|||
/* seed for the rand() */ |
|||
srand(DWT_CYCCNT); |
|||
pixels = 0; |
|||
|
|||
CPU_RESET_CYCLECOUNTER; |
|||
|
|||
for (i = 0; i < 5000; i++) { |
|||
random_color = (rand() % 65535); |
|||
rx = (rand() % (width-10)); |
|||
ry = (rand() % (height-10)); |
|||
rcx = (rand() % ((width-rx)-10))+10; |
|||
rcy = (rand() % ((height-ry)-10))+10; |
|||
|
|||
gdispFillArea(rx, ry, rcx, rcy, random_color); |
|||
pixels += (rcx+1)*(rcy+1); |
|||
} |
|||
|
|||
ms = DWT_CYCCNT / 168000; |
|||
pps = (float)pixels/((float)ms/1000.0f); |
|||
|
|||
memset (pps_str, 0, sizeof(pps_str)); |
|||
uitoa(pps, pps_str, sizeof(pps_str)); |
|||
strcat(pps_str, " Pixels/s"); |
|||
|
|||
font = gdispOpenFont("UI2 Double"); |
|||
gdispClear(Black); |
|||
gdispDrawStringBox(0, 0, width, 30, "ChibiOS/GFX - Benchmark", font, White, justifyCenter); |
|||
gdispDrawStringBox(0, height/2, width, 30, pps_str, font, White, justifyCenter); |
|||
//gdispDrawString(20, height/2, pps_str, font, White);
|
|||
} |
|||
|
|||
int main(void) { |
|||
halInit(); |
|||
chSysInit(); |
|||
gdispInit(); |
|||
|
|||
benchmark(); |
|||
|
|||
while(TRUE) { |
|||
chThdSleepMilliseconds(500); |
|||
} |
|||
|
|||
return 0; |
|||
} |
@ -0,0 +1,43 @@ |
|||
/**
|
|||
* This file has a different license to the rest of the GFX system. |
|||
* You can copy, modify and distribute this file as you see fit. |
|||
* You do not need to publish your source modifications to this file. |
|||
* The only thing you are not permitted to do is to relicense it |
|||
* under a different license. |
|||
*/ |
|||
|
|||
#ifndef _GFXCONF_H |
|||
#define _GFXCONF_H |
|||
|
|||
/* GFX sub-systems to turn on */ |
|||
#define GFX_USE_GDISP TRUE |
|||
#define GFX_USE_GWIN TRUE |
|||
#define GFX_USE_GEVENT FALSE |
|||
#define GFX_USE_GTIMER FALSE |
|||
#define GFX_USE_GINPUT FALSE |
|||
|
|||
/* Features for the GDISP sub-system. */ |
|||
#define GDISP_NEED_VALIDATION TRUE |
|||
#define GDISP_NEED_CLIP TRUE |
|||
#define GDISP_NEED_TEXT TRUE |
|||
#define GDISP_NEED_CIRCLE FALSE |
|||
#define GDISP_NEED_ELLIPSE FALSE |
|||
#define GDISP_NEED_ARC FALSE |
|||
#define GDISP_NEED_SCROLL FALSE |
|||
#define GDISP_NEED_PIXELREAD FALSE |
|||
#define GDISP_NEED_CONTROL FALSE |
|||
#define GDISP_NEED_MULTITHREAD FALSE |
|||
#define GDISP_NEED_ASYNC FALSE |
|||
#define GDISP_NEED_MSGAPI FALSE |
|||
|
|||
/* Builtin Fonts */ |
|||
#define GDISP_INCLUDE_FONT_SMALL TRUE |
|||
#define GDISP_INCLUDE_FONT_LARGER FALSE |
|||
#define GDISP_INCLUDE_FONT_UI1 FALSE |
|||
#define GDISP_INCLUDE_FONT_UI2 TRUE |
|||
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE |
|||
|
|||
/* Features for the GWIN sub-system. */ |
|||
#define GWIN_NEED_CONSOLE TRUE |
|||
|
|||
#endif /* _GFXCONF_H */ |
@ -0,0 +1,87 @@ |
|||
/*
|
|||
ChibiOS/GFX - Copyright (C) 2012 |
|||
Joel Bodenmann aka Tectu <joel@unormal.org> |
|||
|
|||
This file is part of ChibiOS/GFX. |
|||
|
|||
ChibiOS/GFX is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ChibiOS/GFX 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 General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "ch.h" |
|||
#include "hal.h" |
|||
#include "chprintf.h" |
|||
#include "gfx.h" |
|||
|
|||
/* The handles for our three consoles */ |
|||
GHandle GW1, GW2, GW3; |
|||
|
|||
/* The streams for our three consoles */ |
|||
BaseSequentialStream *S1, *S2, *S3; |
|||
|
|||
int main(void) { |
|||
uint8_t i; |
|||
font_t font1, font2; |
|||
|
|||
halInit(); |
|||
chSysInit(); |
|||
|
|||
/* initialize and clear the display */ |
|||
gdispInit(); |
|||
gdispClear(Black); |
|||
font1 = gdispOpenFont("UI2 Double"); |
|||
font2 = gdispOpenFont("Small"); |
|||
|
|||
/* create the three console windows and set a font for each */ |
|||
GW1 = gwinCreateConsole(NULL, 0, 0, gdispGetWidth(), gdispGetHeight()/2, font1); |
|||
GW2 = gwinCreateConsole(NULL, 0, gdispGetHeight()/2, gdispGetWidth()/2, gdispGetHeight(), font2); |
|||
GW3 = gwinCreateConsole(NULL, gdispGetWidth()/2, gdispGetHeight()/2, gdispGetWidth(), gdispGetHeight(), font2); |
|||
|
|||
/* Set the fore- and background colors for each console */ |
|||
gwinSetColor(GW1, Green); |
|||
gwinSetBgColor(GW1, Black); |
|||
gwinSetColor(GW2, White); |
|||
gwinSetBgColor(GW2, Blue); |
|||
gwinSetColor(GW3, Black); |
|||
gwinSetBgColor(GW3, Red); |
|||
|
|||
/* clear all console windows - to set background */ |
|||
gwinClear(GW1); |
|||
gwinClear(GW2); |
|||
gwinClear(GW3); |
|||
|
|||
/* receive the stream pointers of each console */ |
|||
S1 = gwinGetConsoleStream(GW1); |
|||
S2 = gwinGetConsoleStream(GW2); |
|||
S3 = gwinGetConsoleStream(GW3); |
|||
|
|||
/* Output some data on the first console */ |
|||
for(i = 0; i < 10; i++) { |
|||
chprintf(S1, "Hello ChibiOS/GFX!\r\n"); |
|||
} |
|||
|
|||
/* Output some data on the second console */ |
|||
for(i = 0; i < 16; i++) { |
|||
chprintf(S2, "Message Nr.: %d\r\n", i+1); |
|||
} |
|||
|
|||
/* Output some data on the third console */ |
|||
for(i = 0; i < 18; i++) { |
|||
chprintf(S3, "Message Nr.: %d\r\n", i+1); |
|||
} |
|||
|
|||
while(TRUE) { |
|||
chThdSleepMilliseconds(500); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,33 @@ |
|||
/**
|
|||
* This file has a different license to the rest of the GFX system. |
|||
* You can copy, modify and distribute this file as you see fit. |
|||
* You do not need to publish your source modifications to this file. |
|||
* The only thing you are not permitted to do is to relicense it |
|||
* under a different license. |
|||
*/ |
|||
|
|||
#ifndef _GFXCONF_H |
|||
#define _GFXCONF_H |
|||
|
|||
/* GFX sub-systems to turn on */ |
|||
#define GFX_USE_GDISP TRUE |
|||
#define GFX_USE_GWIN FALSE |
|||
#define GFX_USE_GEVENT FALSE |
|||
#define GFX_USE_GTIMER FALSE |
|||
#define GFX_USE_GINPUT FALSE |
|||
|
|||
/* Features for the GDISP sub-system. */ |
|||
#define GDISP_NEED_VALIDATION TRUE |
|||
#define GDISP_NEED_CLIP TRUE |
|||
#define GDISP_NEED_TEXT FALSE |
|||
#define GDISP_NEED_CIRCLE FALSE |
|||
#define GDISP_NEED_ELLIPSE FALSE |
|||
#define GDISP_NEED_ARC FALSE |
|||
#define GDISP_NEED_SCROLL FALSE |
|||
#define GDISP_NEED_PIXELREAD FALSE |
|||
#define GDISP_NEED_CONTROL FALSE |
|||
#define GDISP_NEED_MULTITHREAD FALSE |
|||
#define GDISP_NEED_ASYNC FALSE |
|||
#define GDISP_NEED_MSGAPI FALSE |
|||
|
|||
#endif /* _GFXCONF_H */ |
@ -0,0 +1,52 @@ |
|||
/*
|
|||
ChibiOS/GFX - Copyright (C) 2012 |
|||
Joel Bodenmann aka Tectu <joel@unormal.org> |
|||
|
|||
This file is part of ChibiOS/GFX. |
|||
|
|||
ChibiOS/GFX is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ChibiOS/GFX 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 General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "ch.h" |
|||
#include "hal.h" |
|||
#include "gfx.h" |
|||
|
|||
int main(void) { |
|||
coord_t width, height; |
|||
coord_t i, j; |
|||
|
|||
halInit(); |
|||
chSysInit(); |
|||
|
|||
/* Initialize and clear the display */ |
|||
gdispInit(); |
|||
gdispClear(Black); |
|||
|
|||
// Get the screen size
|
|||
width = gdispGetWidth(); |
|||
height = gdispGetHeight(); |
|||
|
|||
// Code Here
|
|||
gdispDrawBox(10, 10, width/2, height/2, Yellow); |
|||
gdispFillArea(width/2, height/2, width/2-10, height/2-10, Blue); |
|||
gdispDrawLine(5, 30, width-50, height-40, Red); |
|||
|
|||
for(i = 5, j = 0; i < width && j < height; i += 7, j += i/20) |
|||
gdispDrawPixel (i, j, White); |
|||
|
|||
while(TRUE) { |
|||
chThdSleepMilliseconds(500); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,33 @@ |
|||
/**
|
|||
* This file has a different license to the rest of the GFX system. |
|||
* You can copy, modify and distribute this file as you see fit. |
|||
* You do not need to publish your source modifications to this file. |
|||
* The only thing you are not permitted to do is to relicense it |
|||
* under a different license. |
|||
*/ |
|||
|
|||
#ifndef _GFXCONF_H |
|||
#define _GFXCONF_H |
|||
|
|||
/* GFX sub-systems to turn on */ |
|||
#define GFX_USE_GDISP TRUE |
|||
#define GFX_USE_GWIN FALSE |
|||
#define GFX_USE_GEVENT FALSE |
|||
#define GFX_USE_GTIMER FALSE |
|||
#define GFX_USE_GINPUT FALSE |
|||
|
|||
/* Features for the GDISP sub-system. */ |
|||
#define GDISP_NEED_VALIDATION TRUE |
|||
#define GDISP_NEED_CLIP TRUE |
|||
#define GDISP_NEED_TEXT FALSE |
|||
#define GDISP_NEED_CIRCLE TRUE |
|||
#define GDISP_NEED_ELLIPSE TRUE |
|||
#define GDISP_NEED_ARC TRUE |
|||
#define GDISP_NEED_SCROLL FALSE |
|||
#define GDISP_NEED_PIXELREAD FALSE |
|||
#define GDISP_NEED_CONTROL FALSE |
|||
#define GDISP_NEED_MULTITHREAD FALSE |
|||
#define GDISP_NEED_ASYNC FALSE |
|||
#define GDISP_NEED_MSGAPI FALSE |
|||
|
|||
#endif /* _GFXCONF_H */ |
@ -0,0 +1,51 @@ |
|||
/*
|
|||
ChibiOS/GFX - Copyright (C) 2012 |
|||
Joel Bodenmann aka Tectu <joel@unormal.org> |
|||
|
|||
This file is part of ChibiOS/GFX. |
|||
|
|||
ChibiOS/GFX is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ChibiOS/GFX 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 General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "ch.h" |
|||
#include "hal.h" |
|||
#include "gfx.h" |
|||
|
|||
int main(void) { |
|||
coord_t width, height; |
|||
|
|||
halInit(); |
|||
chSysInit(); |
|||
|
|||
/* Initialize and clear the display */ |
|||
gdispInit(); |
|||
gdispClear(Black); |
|||
|
|||
// Get the screen size
|
|||
width = gdispGetWidth(); |
|||
height = gdispGetHeight(); |
|||
|
|||
// Code Here
|
|||
gdispDrawCircle(width/2, height/2, 20, Yellow); |
|||
gdispFillCircle (width/4, height/4, 50, Blue); |
|||
gdispFillEllipse (width-100, height-100, 30, 60, Red); |
|||
gdispDrawEllipse (width-100, height-100, 50, 20, Yellow); |
|||
gdispDrawArc(width-width/8, height/8, 30, 10, 70, Gray); |
|||
gdispFillArc(width/8, height/8, 30, 10, 70, Gray); |
|||
|
|||
while(TRUE) { |
|||
chThdSleepMilliseconds(500); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,33 @@ |
|||
/**
|
|||
* This file has a different license to the rest of the GFX system. |
|||
* You can copy, modify and distribute this file as you see fit. |
|||
* You do not need to publish your source modifications to this file. |
|||
* The only thing you are not permitted to do is to relicense it |
|||
* under a different license. |
|||
*/ |
|||
|
|||
#ifndef _GFXCONF_H |
|||
#define _GFXCONF_H |
|||
|
|||
/* GFX sub-systems to turn on */ |
|||
#define GFX_USE_GDISP TRUE |
|||
#define GFX_USE_GWIN FALSE |
|||
#define GFX_USE_GEVENT FALSE |
|||
#define GFX_USE_GTIMER FALSE |
|||
#define GFX_USE_GINPUT FALSE |
|||
|
|||
/* Features for the GDISP sub-system. */ |
|||
#define GDISP_NEED_VALIDATION TRUE |
|||
#define GDISP_NEED_CLIP TRUE |
|||
#define GDISP_NEED_TEXT TRUE |
|||
#define GDISP_NEED_CIRCLE FALSE |
|||
#define GDISP_NEED_ELLIPSE FALSE |
|||
#define GDISP_NEED_ARC FALSE |
|||
#define GDISP_NEED_SCROLL FALSE |
|||
#define GDISP_NEED_PIXELREAD FALSE |
|||
#define GDISP_NEED_CONTROL FALSE |
|||
#define GDISP_NEED_MULTITHREAD FALSE |
|||
#define GDISP_NEED_ASYNC FALSE |
|||
#define GDISP_NEED_MSGAPI FALSE |
|||
|
|||
#endif /* _GFXCONF_H */ |
@ -0,0 +1,72 @@ |
|||
/*
|
|||
ChibiOS/GFX - Copyright (C) 2012 |
|||
Joel Bodenmann aka Tectu <joel@unormal.org> |
|||
|
|||
This file is part of ChibiOS/GFX. |
|||
|
|||
ChibiOS/GFX is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ChibiOS/GFX 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 General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "ch.h" |
|||
#include "hal.h" |
|||
#include "gfx.h" |
|||
|
|||
int main(void) { |
|||
coord_t width, height; |
|||
font_t font1, font2, font3, font4; |
|||
const char *msg; |
|||
|
|||
halInit(); |
|||
chSysInit(); |
|||
|
|||
/* Initialize and clear the display */ |
|||
gdispInit(); |
|||
gdispClear(Black); |
|||
|
|||
// Get the screen size
|
|||
width = gdispGetWidth(); |
|||
height = gdispGetHeight(); |
|||
|
|||
// Get the fonts we want to use
|
|||
font1 = gdispOpenFont("UI2"); |
|||
font2 = gdispOpenFont("UI2 Double"); |
|||
font3 = gdispOpenFont("UI2 Narrow"); |
|||
font4 = gdispOpenFont("LargeNumbers"); |
|||
|
|||
// Display large numbers on the right (measuring the string)
|
|||
msg = "123456"; |
|||
gdispDrawString(width-gdispGetStringWidth(msg, font4)-3, 3, msg, font4, Green); |
|||
|
|||
// Display the font name under it.
|
|||
msg = gdispGetFontName(font4); |
|||
gdispDrawString(width-gdispGetStringWidth(msg, font1)-3, 20, msg, font1, Green); |
|||
|
|||
// Demonstrate our other fonts
|
|||
gdispDrawString(10, 10, "Writing with Font 'UI2'", font1, Yellow); |
|||
gdispFillString(10, 35, "Writing with Font 'UI2 Double'", font2, Red, White); |
|||
gdispDrawStringBox(0, 50, width, 40, "Writing with Font 'UI2 Narrow'", font3, Red, justifyCenter); |
|||
gdispFillStringBox(0, 90, width, 40, "Filled Centered", font3, Pink, Gray, justifyCenter); |
|||
|
|||
// Clean up the fonts
|
|||
gdispCloseFont(font1); |
|||
gdispCloseFont(font2); |
|||
gdispCloseFont(font3); |
|||
gdispCloseFont(font4); |
|||
|
|||
// Wait forever
|
|||
while(TRUE) { |
|||
chThdSleepMilliseconds(500); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,47 @@ |
|||
/**
|
|||
* This file has a different license to the rest of the GFX system. |
|||
* You can copy, modify and distribute this file as you see fit. |
|||
* You do not need to publish your source modifications to this file. |
|||
* The only thing you are not permitted to do is to relicense it |
|||
* under a different license. |
|||
*/ |
|||
|
|||
#ifndef _GFXCONF_H |
|||
#define _GFXCONF_H |
|||
|
|||
/* GFX sub-systems to turn on */ |
|||
#define GFX_USE_GDISP TRUE |
|||
#define GFX_USE_GWIN TRUE |
|||
#define GFX_USE_GEVENT TRUE |
|||
#define GFX_USE_GTIMER TRUE |
|||
#define GFX_USE_GINPUT TRUE |
|||
|
|||
/* Features for the GDISP sub-system. */ |
|||
#define GDISP_NEED_VALIDATION TRUE |
|||
#define GDISP_NEED_CLIP TRUE |
|||
#define GDISP_NEED_TEXT TRUE |
|||
#define GDISP_NEED_CIRCLE FALSE |
|||
#define GDISP_NEED_ELLIPSE FALSE |
|||
#define GDISP_NEED_ARC FALSE |
|||
#define GDISP_NEED_SCROLL FALSE |
|||
#define GDISP_NEED_PIXELREAD FALSE |
|||
#define GDISP_NEED_CONTROL FALSE |
|||
#define GDISP_NEED_MULTITHREAD TRUE |
|||
#define GDISP_NEED_ASYNC FALSE |
|||
#define GDISP_NEED_MSGAPI FALSE |
|||
|
|||
/* Builtin Fonts */ |
|||
#define GDISP_INCLUDE_FONT_SMALL FALSE |
|||
#define GDISP_INCLUDE_FONT_LARGER FALSE |
|||
#define GDISP_INCLUDE_FONT_UI1 FALSE |
|||
#define GDISP_INCLUDE_FONT_UI2 TRUE |
|||
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE |
|||
|
|||
/* Features for the GWIN sub-system. */ |
|||
#define GWIN_NEED_BUTTON TRUE |
|||
#define GWIN_NEED_CONSOLE TRUE |
|||
|
|||
/* Features for the GINPUT sub-system. */ |
|||
#define GINPUT_NEED_MOUSE TRUE |
|||
|
|||
#endif /* _GFXCONF_H */ |
@ -0,0 +1,349 @@ |
|||
/*
|
|||
ChibiOS/GFX - Copyright (C) 2012 |
|||
Joel Bodenmann aka Tectu <joel@unormal.org> |
|||
|
|||
This file is part of ChibiOS/GFX. |
|||
|
|||
ChibiOS/GFX is free software; you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation; either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
ChibiOS/GFX 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 General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "ch.h" |
|||
#include "hal.h" |
|||
#include "chprintf.h" |
|||
#include "gfx.h" |
|||
|
|||
static GConsoleObject gc; |
|||
static GButtonObject gNext; |
|||
static GButtonObject gPrev; |
|||
static GListener gl; |
|||
|
|||
/*------------------------------------------------------------------------*
|
|||
* GINPUT Touch Driver Calibrator. * |
|||
*------------------------------------------------------------------------*/ |
|||
int main(void) { |
|||
GSourceHandle gs, gsNext, gsPrev; |
|||
GEvent *pe; |
|||
GEventMouse *pem; |
|||
GEventGWinButton *peb; |
|||
coord_t swidth, sheight; |
|||
GHandle ghc, ghNext, ghPrev; |
|||
BaseSequentialStream *gp; |
|||
GEventType deviceType; |
|||
font_t font; |
|||
|
|||
halInit(); // Initialise the Hardware
|
|||
chSysInit(); // Initialize the OS
|
|||
gdispInit(); // Initialize the display
|
|||
|
|||
// Get the display dimensions
|
|||
swidth = gdispGetWidth(); |
|||
sheight = gdispGetHeight(); |
|||
ghNext = ghPrev = 0; |
|||
|
|||
// Create our title
|
|||
font = gdispOpenFont("UI2"); |
|||
gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Red, White, justifyLeft); |
|||
|
|||
// Create our main display window
|
|||
ghc = gwinCreateConsole(&gc, 0, 20, swidth, sheight-20, font); |
|||
gwinClear(ghc); |
|||
gp = gwinGetConsoleStream(ghc); |
|||
|
|||
// Initialize the mouse in our special no calibration mode.
|
|||
geventListenerInit(&gl); |
|||
gs = ginputGetMouse(9999); |
|||
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA); |
|||
|
|||
/*
|
|||
* Test: Device Type |
|||
*/ |
|||
|
|||
StepDeviceType: |
|||
gwinClear(ghc); |
|||
gwinSetColor(ghc, Yellow); |
|||
chprintf(gp, "\n1. DEVICE TYPE\n\n"); |
|||
|
|||
pem = (GEventMouse *)&gl.event; |
|||
ginputGetMouseStatus(0, pem); |
|||
deviceType = pem->type; |
|||
|
|||
gwinSetColor(ghc, White); |
|||
chprintf(gp, "This is detected as a %s device\n\n", |
|||
deviceType == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN")); |
|||
|
|||
if (ghNext) |
|||
chprintf(gp, "Press Next or Back to continue.\n"); |
|||
else if (deviceType == GEVENT_MOUSE) |
|||
chprintf(gp, "Click the mouse button to move on to the next test.\n"); |
|||
else |
|||
chprintf(gp, "Press and release your finger to move on to the next test.\n"); |
|||
|
|||
while(1) { |
|||
pe = geventEventWait(&gl, TIME_INFINITE); |
|||
if (pe->type == GEVENT_GWIN_BUTTON) { |
|||
peb = (GEventGWinButton *)pe; |
|||
if (peb->button == ghPrev) |
|||
goto StepClickJitter; |
|||
if (peb->button == ghNext) |
|||
break; |
|||
} |
|||
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { |
|||
pem = (GEventMouse *)pe; |
|||
if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) |
|||
break; |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
* Test: Mouse raw reading jitter |
|||
*/ |
|||
|
|||
StepRawJitter: |
|||
gwinClear(ghc); |
|||
gwinSetColor(ghc, Yellow); |
|||
chprintf(gp, "\n2. GINPUT_MOUSE_READ_CYCLES\n\n"); |
|||
|
|||
gwinSetColor(ghc, White); |
|||
if (deviceType == GEVENT_MOUSE) |
|||
chprintf(gp, "Press and hold the mouse button.\n\n"); |
|||
else |
|||
chprintf(gp, "Press and hold on the surface.\n\n"); |
|||
chprintf(gp, "Numbers will display in this window.\n" |
|||
"Ensure that values don't jump around very much when your finger is stationary.\n\n" |
|||
"Increasing GINPUT_MOUSE_READ_CYCLES helps reduce jitter but increases CPU usage.\n\n"); |
|||
|
|||
if (ghNext) |
|||
chprintf(gp, "Press Next or Back to continue.\n"); |
|||
else if (deviceType == GEVENT_MOUSE) |
|||
chprintf(gp, "Release the mouse button to move on to the next test.\n"); |
|||
else |
|||
chprintf(gp, "Release your finger to move on to the next test.\n"); |
|||
|
|||
// For this test turn on ALL mouse movement events
|
|||
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER); |
|||
|
|||
while(1) { |
|||
pe = geventEventWait(&gl, TIME_INFINITE); |
|||
if (pe->type == GEVENT_GWIN_BUTTON) { |
|||
peb = (GEventGWinButton *)pe; |
|||
if (peb->button == ghPrev) |
|||
goto StepDeviceType; |
|||
if (peb->button == ghNext) |
|||
break; |
|||
} |
|||
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { |
|||
pem = (GEventMouse *)pe; |
|||
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) |
|||
chprintf(gp, "%u:%u\n", pem->x, pem->y); |
|||
if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) |
|||
break; |
|||
} |
|||
} |
|||
|
|||
// Reset to just changed movements.
|
|||
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA); |
|||
|
|||
/*
|
|||
* Test: Calibration |
|||
*/ |
|||
|
|||
StepCalibrate: |
|||
gwinClear(ghc); |
|||
gwinSetColor(ghc, Yellow); |
|||
chprintf(gp, "\n3. GINPUT_MOUSE_CALIBRATION_ERROR\n\n"); |
|||
gwinSetColor(ghc, Gray); |
|||
chprintf(gp, "Ensure GINPUT_MOUSE_NEED_CALIBRATION = TRUE and GINPUT_MOUSE_CALIBRATION_ERROR is >= 0\n\n"); |
|||
gwinSetColor(ghc, White); |
|||
chprintf(gp, "You will be presented with a number of points to touch.\nPress them in turn.\n\n" |
|||
"If the calibration repeatedly fails, increase GINPUT_MOUSE_CALIBRATION_ERROR and try again.\n\n"); |
|||
|
|||
if (ghNext) |
|||
chprintf(gp, "Press Next to start the calibration.\n"); |
|||
else if (deviceType == GEVENT_MOUSE) |
|||
chprintf(gp, "Click the mouse button to start the calibration.\n"); |
|||
else |
|||
chprintf(gp, "Press and release your finger to start the calibration.\n"); |
|||
|
|||
while(1) { |
|||
pe = geventEventWait(&gl, TIME_INFINITE); |
|||
if (pe->type == GEVENT_GWIN_BUTTON) { |
|||
peb = (GEventGWinButton *)pe; |
|||
if (peb->button == ghPrev) |
|||
goto StepRawJitter; |
|||
if (peb->button == ghNext) |
|||
break; |
|||
} |
|||
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { |
|||
pem = (GEventMouse *)pe; |
|||
if (!ghNext && (pem->meta & GMETA_MOUSE_UP)) |
|||
break; |
|||
} |
|||
} |
|||
|
|||
// Calibrate
|
|||
ginputCalibrateMouse(0); |
|||
|
|||
/* From now on we can use Next and Previous Buttons */ |
|||
if (!ghNext) { |
|||
|
|||
ghNext = gwinCreateButton(&gNext, swidth-50, 0, 50, 20, font, GBTN_NORMAL); |
|||
gwinSetButtonText(ghNext, "Next", FALSE); |
|||
gsNext = gwinGetButtonSource(ghNext); |
|||
geventAttachSource(&gl, gsNext, 0); |
|||
gwinAttachButtonMouseSource(ghNext, gs); |
|||
|
|||
ghPrev = gwinCreateButton(&gPrev, swidth-100, 0, 50, 20, font, GBTN_NORMAL); |
|||
gwinSetButtonText(ghPrev, "Back", FALSE); |
|||
gsPrev = gwinGetButtonSource(ghPrev); |
|||
geventAttachSource(&gl, gsPrev, 0); |
|||
gwinAttachButtonMouseSource(ghPrev, gs); |
|||
|
|||
#if 0 |
|||
{ |
|||
GSourceHandle gsButton1, gsButton2; |
|||
|
|||
// Attach a couple of hardware toggle buttons to our Next and Back buttons as well.
|
|||
// We can always use the mouse to trigger the buttons if you don't want to use hardware toggles.
|
|||
// This code depends on your hardware. Turn it on only if you have
|
|||
// defined a board definition for your toggle driver. Then change
|
|||
// the next two lines to be correct for your hardware. The values
|
|||
// below are correct for the Win32 toggle driver.
|
|||
gsButton1 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY1); |
|||
gsButton2 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY2); |
|||
gwinAttachButtonToggleSource(ghNext, gsButton2); |
|||
gwinAttachButtonToggleSource(ghPrev, gsButton1); |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
// Calibration used the whole screen - re-establish our title
|
|||
gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Green, White, justifyLeft); |
|||
gwinButtonDraw(ghNext); |
|||
gwinButtonDraw(ghPrev); |
|||
|
|||
/*
|
|||
* Test: Mouse movement jitter |
|||
*/ |
|||
|
|||
StepJitter: |
|||
gwinClear(ghc); |
|||
gwinSetColor(ghc, Yellow); |
|||
chprintf(gp, "\n4. GINPUT_MOUSE_MOVE_JITTER\n\n"); |
|||
|
|||
gwinSetColor(ghc, White); |
|||
if (deviceType == GEVENT_MOUSE) |
|||
chprintf(gp, "Press and hold the mouse button and move around as if to draw.\n\n"); |
|||
else |
|||
chprintf(gp, "Press firmly on the surface and move around as if to draw.\n\n"); |
|||
|
|||
chprintf(gp, "Dots will display in this window. Ensure that when you stop moving your finger that " |
|||
"new dots stop displaying.\nNew dots should only display when your finger is moving.\n\n" |
|||
"Adjust GINPUT_MOUSE_MOVE_JITTER to the smallest value that this reliably works for.\n\n"); |
|||
chprintf(gp, "Press Next or Back to continue.\n\n"); |
|||
|
|||
while(1) { |
|||
pe = geventEventWait(&gl, TIME_INFINITE); |
|||
if (pe->type == GEVENT_GWIN_BUTTON) { |
|||
peb = (GEventGWinButton *)pe; |
|||
if (peb->button == ghPrev) |
|||
goto StepCalibrate; |
|||
if (peb->button == ghNext) |
|||
break; |
|||
} |
|||
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { |
|||
pem = (GEventMouse *)pe; |
|||
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) |
|||
chprintf(gp, "."); |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
* Test: Polling frequency |
|||
*/ |
|||
|
|||
StepPolling: |
|||
gwinClear(ghc); |
|||
gwinSetColor(ghc, Yellow); |
|||
chprintf(gp, "\n5. GINPUT_MOUSE_POLL_PERIOD\n\n"); |
|||
|
|||
gwinSetColor(ghc, White); |
|||
chprintf(gp, "Press firmly on the surface (or press and hold the mouse button) and move around as if to draw.\n\n"); |
|||
chprintf(gp, "A green line will follow your finger.\n" |
|||
"Adjust GINPUT_MOUSE_POLL_PERIOD to the highest value that provides a line without " |
|||
"gaps that are too big.\nDecreasing the value increases CPU usage.\n" |
|||
"About 25 (millisecs) normally produces good results." |
|||
"This test can be ignored for interrupt driven drivers.\n\n"); |
|||
chprintf(gp, "Press Next or Back to continue.\n\n"); |
|||
|
|||
while(1) { |
|||
pe = geventEventWait(&gl, TIME_INFINITE); |
|||
if (pe->type == GEVENT_GWIN_BUTTON) { |
|||
peb = (GEventGWinButton *)pe; |
|||
if (peb->button == ghPrev) |
|||
goto StepJitter; |
|||
if (peb->button == ghNext) |
|||
break; |
|||
} |
|||
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { |
|||
pem = (GEventMouse *)pe; |
|||
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT)) |
|||
gdispDrawPixel(pem->x, pem->y, Green); |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
* Test: Click Jitter |
|||
*/ |
|||
|
|||
StepClickJitter: |
|||
gwinClear(ghc); |
|||
gwinSetColor(ghc, Yellow); |
|||
chprintf(gp, "\n6. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n"); |
|||
|
|||
gwinSetColor(ghc, White); |
|||
chprintf(gp, "Press and release the touch surface to \"click\".\nTry both short and long presses.\n"); |
|||
chprintf(gp, "For a mouse click with the left and right buttons.\n\n"); |
|||
chprintf(gp, "Dots will display in this window. A yellow dash is a left (or short) click. " |
|||
"A red x is a right (or long) click.\n\n" |
|||
"Adjust GINPUT_MOUSE_CLICK_JITTER to the smallest value that this reliably works for.\n" |
|||
"Adjust GINPUT_MOUSE_CLICK_TIME to adjust distinguishing short vs long presses.\n" |
|||
"TIME_INFINITE means there are no long presses (although a right mouse button will still work).\n\n" |
|||
"Note: moving your finger (mouse) during a click cancels it.\n\n"); |
|||
chprintf(gp, "This is the last test but you can press Next or Back to continue.\n\n"); |
|||
|
|||
while(1) { |
|||
pe = geventEventWait(&gl, TIME_INFINITE); |
|||
if (pe->type == GEVENT_GWIN_BUTTON) { |
|||
peb = (GEventGWinButton *)pe; |
|||
if (peb->button == ghPrev) |
|||
goto StepPolling; |
|||
if (peb->button == ghNext) |
|||
break; |
|||
} |
|||
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) { |
|||
pem = (GEventMouse *)pe; |
|||
if ((pem->meta & GMETA_MOUSE_CLICK)) { |
|||
gwinSetColor(ghc, Yellow); |
|||
chprintf(gp, |