Add some buffer management routines

This commit is contained in:
Sasha Koshka 2023-11-06 02:53:19 -05:00
parent e042d5b45e
commit e6ca2a97fc
4 changed files with 124 additions and 1 deletions

View File

@ -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!"
}

View File

@ -0,0 +1,25 @@
#ifndef _XmdBuffer_h
#define _XmdBuffer_h
#include <stddef.h>
/* 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

61
libXmd/src/Buffer.c Normal file
View File

@ -0,0 +1,61 @@
#include <Xmd/Buffer.h>
#include <stdlib.h>
#include <string.h>
#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);
}

37
libXmd/src/Icon.c Normal file
View File

@ -0,0 +1,37 @@
#include <Xmd/Icon.h>
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;
}