diff --git a/libXmd/build.sh b/libXmd/build.sh index 6f85513..0d821af 100755 --- a/libXmd/build.sh +++ b/libXmd/build.sh @@ -3,7 +3,7 @@ . ../scripts/flags.sh function build() { - cc $CFLAGS -shared -o "lib/libXmd.so" *.c || \ + cc $CFLAGS -Iinclude -shared -o "lib/libXmd.so" src/*.c || \ echo "XXX FAIL!" } diff --git a/libXmd/include/Xmd/Buffer.h b/libXmd/include/Xmd/Buffer.h new file mode 100644 index 0000000..067de08 --- /dev/null +++ b/libXmd/include/Xmd/Buffer.h @@ -0,0 +1,25 @@ +#ifndef _XmdBuffer_h +#define _XmdBuffer_h + +#include + +/* Buffer is a struct that keeps track of a variable length array of data. It + is like a piggy bank, you can add stuff to it and then break it to get access + to all the things you put in. It is intended to be used for reading in + variable length strings and files. */ +typedef struct _XmdBuffer XmdBuffer; + +/* XmdBufferNew creates a new buffer with the specified element size. */ +XmdBuffer *XmdBufferNew (size_t element); + +/* XmdBufferPush adds a new element to the buffer. */ +void XmdBufferPush (XmdBuffer *buffer, void *element); + +/* XmdBufferBreak frees the buffer without freeing its data. Its data is + returned and must be freed manually at some point. */ +void *XmdBufferBreak (XmdBuffer *buffer); + +/* XmdBufferFree frees the buffer and any data associated with it. */ +void XmdBufferFree (XmdBuffer *buffer); + +#endif diff --git a/libXmd/src/Buffer.c b/libXmd/src/Buffer.c new file mode 100644 index 0000000..e2d42cb --- /dev/null +++ b/libXmd/src/Buffer.c @@ -0,0 +1,61 @@ +#include +#include +#include + +#define XmdBUFFER_GROWTH_FACTOR 2 + +struct _XmdBuffer { + void * data; + size_t element; + size_t length; + size_t capacity; +}; + +static void XmdBufferResize (XmdBuffer *buffer, size_t length); +static void XmdBufferFit (XmdBuffer *buffer); +static void *XmdBufferOffset (XmdBuffer *buffer, size_t index); + +XmdBuffer *XmdBufferNew (size_t element) { + XmdBuffer *buffer = calloc(1, sizeof(XmdBuffer)); + buffer->element = element; + buffer->capacity = 1; + XmdBufferFit(buffer); + return buffer; +} + +void XmdBufferResize (XmdBuffer *buffer, size_t length) { + buffer->length = length; + XmdBufferFit(buffer); +} + +void XmdBufferFit (XmdBuffer *buffer) { + if (buffer->length > buffer->capacity) { + buffer->capacity *= XmdBUFFER_GROWTH_FACTOR; + buffer->data = realloc ( + buffer->data, + buffer->capacity * buffer->element); + } +} + +void *XmdBufferOffset (XmdBuffer *buffer, size_t index) { + return buffer->data + (index * buffer->element); +} + +void XmdBufferPush (XmdBuffer *buffer, void *element) { + XmdBufferResize(buffer, buffer->length + 1); + memcpy ( + XmdBufferOffset(buffer, buffer->length - 1), + element, + buffer->element); +} + +void *XmdBufferBreak (XmdBuffer *buffer) { + void *data = buffer->data; + free(buffer); + return data; +} + +void XmdBufferFree (XmdBuffer *buffer) { + free(buffer->data); + free(buffer); +} diff --git a/libXmd/src/Icon.c b/libXmd/src/Icon.c new file mode 100644 index 0000000..0db3852 --- /dev/null +++ b/libXmd/src/Icon.c @@ -0,0 +1,37 @@ +#include + +Pixmap _XmdLoadBitmapIcon (Widget widget, unsigned char *bits, int width, int height) { + Pixel fg, bg; + XtVaGetValues (widget, + XmNforeground, &fg, + XmNbackground, &bg, + NULL); + return XCreatePixmapFromBitmapData ( + XtDisplay (widget), + RootWindowOfScreen(XtScreen(widget)), + (char *)(bits), width, height, + fg, bg, DefaultDepthOfScreen(XtScreen(widget))); +} + +Pixmap XmdReadBitmapFile (Widget widget, const char *filename) { + Pixel fg, bg; + XtVaGetValues (widget, + XmNforeground, &fg, + XmNbackground, &bg, + NULL); + unsigned int width, height; + unsigned char *data; + int garbage; + XReadBitmapFileData ( + filename, + &width, &height, + &data, + &garbage, &garbage); + Pixmap result = XCreatePixmapFromBitmapData ( + XtDisplay (widget), + RootWindowOfScreen(XtScreen(widget)), + (char *)(data), width, height, + fg, bg, DefaultDepthOfScreen(XtScreen(widget))); + XFree(data); + return result; +}