Fun with C
My entry: Xannotate, a desktop annotation tool.
EDIT: add screenshot.
EDIT: Version 2014-07-27 now supports three pens, eraser, and support for alpha transparency (faster!) if you run a compositing manager (xcompmgr, compton, or kwin). Still works even if you don't have them.
Draw with left-button, erase with right-button. Shift-left-click changes pens. 'Pause' to enter/leave drawing mode, Shift-Pause to show/hide drawing, Ctrl-Pause to clear drawing and start over, Alt-Shift-Pause to capture a screenshot (in PNG format, with or without your drawing in it). Ctrl-Shift-Pause to exit.
And you can change "Pause" to something else.
Depends only on Xlib (libX11, libXext, libXrender) and pnglite which is included.
EDIT: add screenshot.
EDIT: Version 2014-07-27 now supports three pens, eraser, and support for alpha transparency (faster!) if you run a compositing manager (xcompmgr, compton, or kwin). Still works even if you don't have them.
Draw with left-button, erase with right-button. Shift-left-click changes pens. 'Pause' to enter/leave drawing mode, Shift-Pause to show/hide drawing, Ctrl-Pause to clear drawing and start over, Alt-Shift-Pause to capture a screenshot (in PNG format, with or without your drawing in it). Ctrl-Shift-Pause to exit.
And you can change "Pause" to something else.
Depends only on Xlib (libX11, libXext, libXrender) and pnglite which is included.
- Attachments
-
- xannotate00000.png
- The annotation was done directly on screen, not in mtpaint
- (43.07 KiB) Downloaded 689 times
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]
JB how are you capturing keypresses would same be used for onscreen keyboard under fatdog64 and ARM?
I keep bringing this up because it has halted the project at a year now. I am having the yearly visit with the Dr. next week. She moved on and had most of our ideas done in window tablets since then. I posted a link to the news story ( That should have been a show with Fatdog !!)
I keep bringing this up because it has halted the project at a year now. I am having the yearly visit with the Dr. next week. She moved on and had most of our ideas done in window tablets since then. I posted a link to the news story ( That should have been a show with Fatdog !!)
In writing something in C, sometimes one gets carried away in writing the code and fails to add sufficient comment sections to the code to explain what a section of the code is supposed to do.
And later, without comments in the code, one may go back to code he/she has written and be at a loss as to trying to make sense of it.
So with any C code, I recommend heavy commenting.
It only increases the source code file size and and does not increase the size of the compiled result.
Also, it helps others in understanding what the code does.
And keep in mind that C programmers may not have the level of experience you have. So cryptic comments will not help.
And later, without comments in the code, one may go back to code he/she has written and be at a loss as to trying to make sense of it.
So with any C code, I recommend heavy commenting.
It only increases the source code file size and and does not increase the size of the compiled result.
Also, it helps others in understanding what the code does.
And keep in mind that C programmers may not have the level of experience you have. So cryptic comments will not help.
I disagree. heavily commented code should be avoided to much cludder. Take a look at BKs scripts. Impossible to follow due to curtains of comments. On the other hand look and Kirks and JBs just enough at the key points of flow to speed understanding.8-bit wrote:In writing something in C, sometimes one gets carried away in writing the code and fails to add sufficient comment sections to the code to explain what a section of the code is supposed to do.
And later, without comments in the code, one may go back to code he/she has written and be at a loss as to trying to make sense of it.
So with any C code, I recommend heavy commenting.
It only increases the source code file size and and does not increase the size of the compiled result.
Also, it helps others in understanding what the code does.
And keep in mind that C programmers may not have the level of experience you have. So cryptic comments will not help.
I followed a winner of the C http://www0.us.ioccc.org/
http://blog.aerojockey.com/post/iocccsim
in a job and ahhhhhh the horror. I took a c test that used the winners of that contest to get a job. I SO RAILED AGAINST that as a testing criteria I even correctly pointed out Carl had gave the interview the idea to use this as a C skill test, AND I WOULD NEVER SUBJECT ANYONE TO SUCH A NIGHTMARE, I do not justify my job security to code obfuscation. Got the job offer but refused ( second time working after Carl I learned my lession )
xvkbd should have worked. I remember I tested it and it did. I'm not too confident of matchbox_keyboard. Anyway, the way I capture the keyboard is XGrabKey - every X-based "hotkey" manager would do it that way, nothing special.Ted Dog wrote:JB how are you capturing keypresses would same be used for onscreen keyboard under fatdog64 and ARM?
I keep bringing this up because it has halted the project at a year now. I am having the yearly visit with the Dr. next week. She moved on and had most of our ideas done in window tablets since then. I posted a link to the news story ( That should have been a show with Fatdog !!)
I have another entry for this: Xscreenshot, a simple program to take screenshot of selected area of the desktop. Its specialty: you can use it to quickly take successive screenshots. Especially useful when taking screenshot for documentation. Saves to PNG file. Depends only on Xlib.
xannotate is 22K, xscreenshot is 17K. This is on x86_64; I'm sure it is smaller on x86.
Enjoy.
From the readme:
README wrote:xscreenshot is a simple program to take screenshot of your desktop.
You can run it to take a single screenshot, or run it in multiple-shots mode.
The single-shot mode is meant to be used with other hotkey programs
(such as xbindkeys). In this mode, once you have taken your screenshot
it will exit. This is the default mode.
In multiple-shots mode, xscreenshot will run until you tell it to exit.
You can toggle between normal mode, or screenshot taking mode.
In normal mode, the mouse can be used as normal (hence the name).
In screenshot mode, you can take multiple screenshots, one after another.
The screenshot is saved as PNG file.
Mouse buttons
-------------
Left-click: press to start selection, move to choose, release to take a shot.
Right-click:
- if pressed during active selection (that is, when left-button is pressed too):
cancel selection, and you can start over.
- if pressed when there is no active selection:
- in single-shot mode, xscreenshot will exit
- in multiple-shot mode: no effect
Keys usage
----------
Hotkey - toggle screenshot/normal mode
Ctrl-Shift-hotkey - terminate xscreenshot
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]
More xlib/cairo fun ... I really should learn xcb next as xlib can suck
pmck
Compiled on 64 it's 20k stripped. Slightly less on x86.
pmck
Compiled on 64 it's 20k stripped. Slightly less on x86.
Free virtual beer/coffee/other beverage for the one who solves the quit bug!readme wrote:pmck
====
a poor man's clock
This is a simple analog clock based on xlib and cairo.
This is not meant for production systems as it has bugs and was written just as
a proof of concept.
Build
-----
Just run 'make' and install the pmck the binary in your path. Optionally,
install the pmckrc file to $HOME/.config/ and edit to your preferences.
Usage
-----
Just run 'pmck' from the command line, it needs no options. It will read an rc file
in $HOME/.config/pmckrc to set different features. There is an example rc file
provided. This should be self explanatory. You can set the size, background
and foreground colours and the style, 2 to choose from. You can autostart it if
you wish. See your distro's documentation for this feature.
On some window managers the root window is not the desktop window. In the case
of ROX-Filer pinboard this is easily overcome by finding the child window which
is "ROX-Pinboard", which in most cases is the very first child. However, in the
case of XFCE I had trouble coding the correct window so added 1 single option to the
command line; the desktop window ID which can be found by running "xwininfo" and
clicking on a blank part of the desktop. The string will be a hex value something
like "0xae44010". Just type (or script) "pmck $hex_value_here". This should work
with any other WM/DE also as it overrides the internal algorithm.
Bugs
----
- must quit with CTRL-C or kill, there is code block supposed to quit with 'q'..
- redraws forever, so may use too much CPU and eventually memory
- may run 1 or 2 seconds behind system time.
- need a click on desktop to display (rox bug - FIXED)
- some window managers may need the the window on top for the clock to display
- can flicker at times of heavy load or on slow machines
- a compositor such as xcompmgr is needed so artefacts do not display under clockface
- at larger sizes the second hand may flicker or disappear
Puppy Linux Blog - contact me for access
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
maybe try
Code: Select all
while (1) {
XNextEvent(dpy, &e);
if(e.type == Expose && e.xexpose.count < 1) {
//while (1) {
paint(cs, width, height, style);
// usleep(500000);
//}
}
else if (e.type == KeyPress) {
char buf[128] = {0};
KeySym keysym;
XLookupString(&e.xkey, buf, sizeof buf, &keysym, NULL);
if (keysym == XK_q) {
break;
}
}
usleep(500000); //moved here for cpu usage
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].
Nope. Clock doesn't redraw and it doesn't quit. Sorry, no chocolates.
Puppy Linux Blog - contact me for access
Make sure you prepare plenty of beers and chocolates Better make it real not virtual
change
to
then change your loop to this one.
To quit, click the clock, then press q.
change
Code: Select all
XSelectInput(dpy, win, ExposureMask|KeyPressMask);
Code: Select all
XSelectInput(dpy, win, ExposureMask|KeyPressMask|ButtonPressMask);
Code: Select all
while (1) {
while (XPending (dpy))
{
XNextEvent(dpy, &e);
if (e.type == KeyPress) {
char buf[128] = {0};
KeySym keysym;
XLookupString(&e.xkey, buf, sizeof(buf), &keysym, NULL);
if (keysym == XK_q) {
goto finish;
}
} else if (e.type == ButtonPress) {
XSetInputFocus (dpy, win, RevertToNone, CurrentTime);
}
}
paint(cs, width, height, style);
usleep(500000);
}
finish:
cairo_surface_destroy(cs);
XCloseDisplay(dpy);
Doesn't work for me. I only run openbox + rox; and I have to resort to using xwininfo trick.On some window managers the root window is not the desktop window. In the case
of ROX-Filer pinboard this is easily overcome by finding the child window which
is "ROX-Pinboard", which in most cases is the very first child.
Not enough. Do this: run pmck; cover it with something, show it again (and see the garbage), *then* run xcompmgr. xcompmgr will not remove that garbage (in fact it will keep it). Learn to use XShapeCombineMask instead, and you will not depend on xcompmgr at all.- a compositor such as xcompmgr is needed so artefacts do not display under clockface
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]
Almost ...Virtual only.
The problem is the logic. The clock draw needs it's own 'true' loop for some reason.. but of course that never ends so the next part of the program can't take place. So, I added the XPending() (EDIT: as you did but I shifted the paint() call to before the XPending())call to the true loop, reduced the sleep a bit and it works, but it tends to flicker a bit more. It's taking too long to draw. The clock face is quite complex, figuring out 56 different angles to draw at, plus font characters then the actual hand drawing operation. This (I think) can be sped up if I put the actual face on another surface, however, once the hands are drawn that surface needs to be refreshed. I'll think about that, (as I have done).
As for the clock error for fatdog rox, maybe the desktop isn't the first child window? I guess I could test for that, one day .
I'll also look into XShapeCombineMask().
The problem is the logic. The clock draw needs it's own 'true' loop for some reason.. but of course that never ends so the next part of the program can't take place. So, I added the XPending() (EDIT: as you did but I shifted the paint() call to before the XPending())call to the true loop, reduced the sleep a bit and it works, but it tends to flicker a bit more. It's taking too long to draw. The clock face is quite complex, figuring out 56 different angles to draw at, plus font characters then the actual hand drawing operation. This (I think) can be sped up if I put the actual face on another surface, however, once the hands are drawn that surface needs to be refreshed. I'll think about that, (as I have done).
Code: Select all
while (1) {
paint(cs, width, height, style);
while (XPending (dpy)) {
XNextEvent(dpy, &e);
if (e.type == KeyPress) {
char buf[128] = {0};
KeySym keysym;
XLookupString(&e.xkey, buf, sizeof(buf), &keysym, NULL);
if (keysym == XK_q) {
goto finish;
}
} else if (e.type == ButtonPress) {
XSetInputFocus (dpy, win, RevertToNone, CurrentTime);
}
}
usleep(200000); /*reduced as Xpending() takes time */
}
finish:
cairo_surface_destroy(cs);
XCloseDisplay(dpy);
I'll also look into XShapeCombineMask().
Last edited by 01micko on Wed 30 Jul 2014, 02:07, edited 2 times in total.
Puppy Linux Blog - contact me for access
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
here is the beginning of object oriented C tutorial using structs and function pointers:
Code: Select all
#include <stdio.h>
/* this is an example how to use structs and function pointers for an imaginary camera API
each camera type can supply its own functions, properties etc... so we need a way to map the functions to our API
*/
/* we have to forward declare the struct due to circular reference */
struct camera_t;
/* functions operate on a single camera struct, modify it directly and return success/failure as int */
typedef int (*Fi)(camera_t *);
/* We'll use these to access functions, insert new ones before NUM_FUNCS */
enum{ NOOP, ZOOM_IN, ZOOM_OUT, ZOOM_STOP, INFRA_ON, INFRA_OFF, NUM_FUNCS};
typedef struct camera_t{
unsigned properties;
unsigned action;
FILE *readbuf; /* using FILE* vs fd for portability ...win32 etc... */
FILE *writebuf;
Fi funcs[NUM_FUNCS]; /* note NUM_FUNCS as in previous enum */
}camera_t;
enum{
zoomCapable = 1,
zoomingIn = 2,
zoomingOut = 4,
infraredCapable = 8,
infraredOn = 16,
//.... =32, ...=64 etc...
};//flags to be set in properties
/* provide a noop action for first function and unsupported functions*/
int noop(camera_t cam){return 0;}
//these would be in the camera's header/object included as reference
int startZoomIn(camera_t *cam);//ZOOM_IN
int startZoomOut(camera_t *cam);//ZOOM_OUT
int stopZoom(camera_t *cam);//ZOOM_STOP
int infraOn(camera_t *cam);//INFRA_ON
int infraOff(camera_t *cam);//INFRA_OFF
/* using a macro to initialize a struct directly provides more compact code
than initializing each member separately in a function and returning it.
*/
#define initCam(name, prop,action,rbuf,wbuf,zin,zout,zstop,ion,ioff) \
camera_t name = {prop,action,rbuf,wbuf,{noop,zin,zout,zstop,ion,ioff}}
//assign camera's corresponding functions in same order as enum above
initCam(mycam,zoomCapable|infraredCapable, 0, stdin, stdout, startZoomIn,
startZoomOut,stopZoom,infraOn,infraOff);
//usage
mycam.funcs[INFRA_ON](&mycam);
/* notice the &, that is because the functions take a pointer to a camera_t struct;
the & give the address of mycam, which is the same as if we set up a pointer to it.
This allows all of our functions to operate on a single instance of camera_t without copying it into and out of functions.
This reduces code size and complexity, while allowing us to use an int return value to indicate error/success
*/
/* more complex usage */
int run(camera_t *cam){
unsigned action = cam->action; //use a local copy so we can reset .action
cam->action=0; //reset the action
/* note the '->' and no '&' now vs. '.' with '&cam'; we are using a pointer to camera_t */
if (action< NUM_FUNCS) return cam->funcs[action](cam);
else return -1;
}
while(1){
if (mycam.action && run(&mycam) == -1)
printf("error"); /*could add: %d\n", errno); or similar here */
sleep(1); /* only handle events once per second to reduce cpu usage*/
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].
Try this to reduce the flicker:01micko wrote:but it tends to flicker a bit more.
instead of
Code: Select all
cs = cairo_xlib_surface_create(dpy, win,
DefaultVisual(dpy, scr), width, height);
Code: Select all
Pixmap pixmap = XCreatePixmap (dpy, win, width, height, mydepth);
XFillRectangle (dpy, pixmap, DefaultGC(dpy, scr), 0,0, width, height);
cs = cairo_xlib_surface_create(dpy, pixmap,
DefaultVisual(dpy, scr), width, height);
Code: Select all
paint(cs, width, height, style);
Code: Select all
XCopyArea (dpy, pixmap, win, DefaultGC (dpy, scr), 0,0, width, height, 0,0);
EDIT: you can also do this in the "pure cairo" way by using a second cairo surface, like this:
Code: Select all
cs = cairo_xlib_surface_create(dpy, win,
DefaultVisual(dpy, scr), width, height);
cairo_surface_t *csbuf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cspaint = cairo_create (cs);
cairo_set_source_surface (cspaint, csbuf, 0, 0);
Code: Select all
paint(csbuf, width, height, style);
cairo_paint (cspaint);
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]
hmmm... It's been about 6 years since I last programmed in C, but I thought I'd take a look at the recommended book as an alternative to my trusty old Kernighan and Dennis Ritchie (K&R) C book (which the author of the above book seems to somewhat despise...). All I can say is that this new book's teaching approach is to start reasonably slow and then, suddenly, jump in the deep end! I imagine 'some' newcomers to C will have a brain explosion (or implosion) when they are suddenly confronted with Ch17 and 18 (they probably won't find ch 15 or 16 particulary easy either, but the killer blow will be ch 17 I think!).darkcity wrote: For anyone wanting to learn this language I'd recommend it.
http://c.learncodethehardway.org/book/
Unfortunately (as far as this recommended book is concerned), I love the K&R style of C programming (which is probably me showing my age), preferring pointer arithmetic to array indexing always, so some of the code style in the book is as painful to me as K&R style is to the author. I haven't read the whole thing yet, so can't comment on his claims that K&R includes a lot of bad code - I can say, however, that K&R includes lots of nice diagrams, which, as far as I'm concerned, nicely explain the subtle differences in how array indexing works compared to using pointers. Perhaps compilers have ironed out the differences nowadays, but still, I like a diagram or two in order to illustrate how C views memory. A picture is indeed worth a thousand words.
I'm not saying this is a bad book, however; for quick learners, who don't mind deep water, it may be very good, but for many newbies I think it could make them feel that C is impossibly hard to learn, which it isn't. Best for such learners, that they stick with the simpler basics first and then try to get their heads round pointers (which aren't so difficult actually, and little diagramatic pictures of 'what's pointing to what' really help), without jumping off the deep end until they are sure they are still afloat...
From memory, what I liked most about the K&R C book, is that it really reinforces how close to UNIX, C is, so after working through the book you really also begin to understand UNIX/Linux at a deeper system level, which leaves you understanding better the relationship between processes and their children and so on. The drawback of K&R may be that it is somewhat dry and technical in style - it hasn't been written to keep the reader amused... and it is now an ancient book of course.
William
EDIT: Actually, the example code in ch 18 is rather nice. The author is clearly very used to object oriented programming and likes C to be molded to mimic that. I like the way he uses compare_cb, via pointers to function to override the actual operation of the function, which is like a form of polymorphism (the actual function used changes depending on whether, sorted-order, reverse order, or strange-order, is passed to the test-sorting routine).
github mcewanw
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
K&R was written before many of the C standards were implemented, so it was common to use things like:mcewanw wrote:... preferring pointer arithmetic to array indexing always, so some of the code style in the book is as painful to me as K&R style is to the author ...what I liked most about the K&R C book, is that it really reinforces how close to UNIX, C is, so after working through the book you really also begin to understand UNIX/Linux at a deeper system level, which leaves you understanding better the relationship between processes and their children and so on. The drawback of K&R may be that it is somewhat dry and technical in style - it hasn't been written to keep the reader amused... and it is now an ancient book of course.
William
EDIT: Actually, the example code in ch 18 is rather nice. The author is clearly very used to object oriented programming and likes C to be molded to mimic that. I like the way he uses compare_cb, via pointers to function to override the actual operation of the function, which is like a form of polymorphism (the actual function used changes depending on whether, sorted-order, reverse order, or strange-order, is passed to the test-sorting routine).
Code: Select all
void* (*f)()=dlsym(handle, "my_function");
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].
pmck is vastly improved.
https://github.com/01micko/pmck
- - more efficient, now the usleep is 950000
- fixed background artefact issues
- added antialiasing (YMMV - seems to depend on a lot of things, wm, video driver etc, but I do need to fix up the XRender part)
- improved desktop detection
- reduced flicker thanks to jamesbond's pure cairo method plus the efficiency
- - learned that CAIRO_OPERATOR_OVER works well on the pixmap for shaping which vastly improves the rendering on screen
- fixed a few small bugs
- every math computation is related directly to the specified size now so that everything scales, including font and clock face markings.
https://github.com/01micko/pmck
Last edited by 01micko on Thu 14 Aug 2014, 23:40, edited 1 time in total.
Puppy Linux Blog - contact me for access
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
@micko - do you think that with your new knowledge of xlib, you'd be able to figure out how to wedge in the ability to make jwm tray backgrounds transparent? The traybuttons already copy their colors from the tray, but to make a tray copy any colors from the root window, you have to change the whole opacity, so to be completely tranparent, the buttons would be invisible.
I think the area to start is in tray.c at:
I think you should be able to check
This has been nagging at me for a while, because that is the only thing stopping from having pseudo desktop icons. (just put a vertical tray at a fixed position with an icon button and a label button) ... discussed in this issue
Well that and tooltips on the tray but not in the menu where they would be useful for more detailed package descriptions. We've always had this amateurish halfway in-between mix of short,long and no descriptions in the menu.
I think the area to start is in tray.c at:
Code: Select all
/** Draw the tray background on a drawable. */
void ClearTrayDrawable(const TrayComponentType *cp)
{
const Drawable d = cp->pixmap != None ? cp->pixmap : cp->window;
if(colors[COLOR_TRAY_BG1] == colors[COLOR_TRAY_BG2]) {
JXSetForeground(display, rootGC, colors[COLOR_TRAY_BG1]);
JXFillRectangle(display, d, rootGC, 0, 0, cp->width, cp->height);
} else {
DrawHorizontalGradient(d, rootGC, colors[COLOR_TRAY_BG1],
colors[COLOR_TRAY_BG2], 0, 0,
cp->width, cp->height);
}
}
Code: Select all
//pseudo code
#define COLOR_TRAY_BG_NONE some_value //probably in colors.h
if (colors[COLOR_TRAY_BG1] == COLOR_TRAY_BG_NONE)
JXCopyArea( a, b, c, d, e, f, g, h, i, j ) //from root window
Well that and tooltips on the tray but not in the menu where they would be useful for more detailed package descriptions. We've always had this amateurish halfway in-between mix of short,long and no descriptions in the menu.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].
My understanding of Shape is still in the development stage .technosaurus wrote:@micko - do you think that with your new knowledge of xlib, you'd be able to figure out how to wedge in the ability to make jwm tray backgrounds transparent?
That said, I have just forked jwm and will take a look.
Puppy Linux Blog - contact me for access
- technosaurus
- Posts: 4853
- Joined: Mon 19 May 2008, 01:24
- Location: Blue Springs, MO
- Contact:
Good to hear, I don't think shape will play into it, just {J}XCopyArea()01micko wrote:My understanding of Shape is still in the development stage .
That said, I have just forked jwm and will take a look.
Here are some little C tricks: (*some of these require std=c99)
Code: Select all
/** If a function calls for a pointer to a struct, you can do this: */
the_func(&(the_struct_t){.x=7,.a=1,.b=2});
//Note: struct members can be assigned by name and out of order
/** You can avoid using malloc if the variable is not returned */
void myfunc(size_t len){ char buf[len]; ... }
/** You can even use a variable length array in a struct */
struct s { int x; int y; char data[]; };
//Note: the variable length array must come at the end.
/** You can partially initialize arrays ... even out of order */
struct{int x,y;}points[4] = {[1].y=10,[3].x=10,[2]={10,10}};
//Note: all other values are initialized to 0. -> 10x10 box
/** You can use enums to represent numerical values in readable form */
enum{ NOTHING, MAGIC_WORD, COLOR, ANIMAL, NUMBER_of_ENUMS};
//Note: if you don't assign specific values, the last enum == count
/** You can use sorted structs to have a binary-searchable map */
const struct {const char* s; int type;} map[] = {
{"", NOTHING},
{"abracadabra", MAGIC_WORD},
{"blue",COLOR},
{"cat", ANIMAL},
{"zoom-wap",MAGIC_WORD}
}
/** You can write a macro to give you array[] size (not (*) pointers) */
#define arr_sz(x) ((sizeof(x))/(sizeof(x[0])))
/** Binary search is simple, start in the middle and compare:
* If they are equal : return your match
* If your value is < current : reset your bottom to next index
* If your value is > current : reset your top to previous index
* Set index ~halfway bottom and top or (top-bottom)/2
* If bot > top, then its not found
*
* Here is an example using previous enum and map:
*/
int get_type(const char *s){
int cmp,
bot=0, //1st element in map[]
top=arr_sz(map)-1, //last element in map[]
i=top/2 //~halfway into map[]
for (;bot<=top;){
cmp=strcmp(s,map[i].s); //compare input *s to map.s
if (! cmp) return map[i].type; //match found
else if (cmp>0) bot=i+1; //set bottom to next string
else top=i-1; //set top to previous string
i=(bot+top)/2; //go ~halfway between bot and top
}
return NOTHING; //not in map
}
/** To "map" consecutive integers to strings is much simpler */
const char *enum_strings[]={
"", //NOTHING == 0
"MAGIC_WORD", //MAGIC_WORD == 1
"COLOR", //COLOR == 2
"ANIMAL" //ANIMAL == 3
};
/** Now the enum is the index so you can just do this: */
const char *get_enum_string(size_t i){
return enum_strings[ ( i < NUMBER_of_ENUMS ) ? i : 0 ];
}
/** Function pointers can point to 99% of functions (so long as the
* return fits in a void*) if you use: */
typedef void* (*func_t)(); //Note: this is not C standards,
//but Posix recommends it for dlsym()
enum{FOO,BAR,BAZ,EXIT};
func_t f[4]={myfoo,mybar,mybaz,exit};
!f[FOO](foo_a) && !f[BAR](bar_b,!0) && !f[BAZ](1,2,3,4) || f[EXIT](0);
/** You can use a union so multiple structs can use the same memory. */
union{
uint8_t data[4096]; //4096 is a common PAGESIZE
struct{uint8_t pad[24];uint32_t magic}myfs;
struct{uint8_t pad[2048];uint32_t magic}yourfs;
struct{uint8_t pad[4000];uint32_t magic}anotherfs;
}myunion;
//here you can read in a page to myunion.data and access it directly
//via myunion.myfs.magic or myunion.myfs.magic
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].
Dunno. Haven't got that far into it.. but it is still on the 'to do'Ages ago, technosaurus wrote:Good to hear, I don't think shape will play into it, just {J}XCopyArea()01micko wrote:My understanding of Shape is still in the development stage .
That said, I have just forked jwm and will take a look.
Thanks. I'm 99% of the time using std=gnu99, which I suppose just adds the _GNU_SOURCE definition?technosaurus wrote:Here are some little C tricks: (*some of these require std=c99)Code: Select all
...
Anyway, I have been playing with bitmaps (.xbm) and 'coloring' in an attempt to create a light weight set of desktop icons. The code attached is very much a work in progress (as you will see ). However it was somewhat educational; and the icons do render and expose properly on a JWM desktop with <Backround="image" ... />
Would be nice if I could run this from 1 executable without too much bother. I suppose I could go the 'desktop' route and render each bitmap (pixmap) on a pseudo 'root' window.. dunno yet.
I also have a much, much prettier version using cairo for icons and pango to to get nice text which can convert (almost) any .desktop file (atm supports .svg, .png and .xpm .. and localisation.. at least with latin charsets). But it kind of is reinventing the wheel when ROX does that nicely enough anyway.
- Attachments
-
- bittop(2).png
- on a real desktop in slacko64
- (185.23 KiB) Downloaded 724 times
-
- bittop-2.tar.gz
- source, builds 4 execs for 4 icons placed on screen.. kill rox before using!
- (4.12 KiB) Downloaded 193 times
-
- bittop(1).png
- tahrpup in VM
- (31.91 KiB) Downloaded 695 times
Puppy Linux Blog - contact me for access