An example of a remote display implementation
#include "devlib.h" #include "devlib_error.h" #include "example.h" #include "property_protocol.h" #include <stdio.h> // For debugging only #include <stdlib.h> // For debugging only // Global variables exposed to property access: struct my_globals g_globals = { .zoom = 0.5, .buffer = { 0 }, .string = "Default", .mode = 0, .count = 0, .flag = 0, #ifdef EXPERIMENTAL .demo = 42 #endif }; ImgBuffer g_imgbuf; /* Handler for property 'Start' */ int set_stream_start(DEVICE d, DCValue *in) { netpp_log(DCLOG_VERBOSE, "Get 'stream_start'"); return 0; } /* Handler for property 'Stop' */ int set_stream_stop(DEVICE d, DCValue *in) { netpp_log(DCLOG_VERBOSE, "Get 'stream_stop'"); return 0; } int get_buffer(DEVICE d, DCValue *out) { int warn = 0; switch (out->type) { case DC_COMMAND: // This is a buffer update action netpp_log(DCLOG_VERBOSE, "Release buffer"); g_globals.count++; break; case DC_UNDEFINED: case DC_BUFFER: // You must do a buffer size check here: netpp_log(DCLOG_VERBOSE, "Get buffer, len %d", out->len); if (out->len < BUFSIZE) { // In this scenario, we do not tolerate a request of // less than BUFSIZE bytes. So we report back the correct // size and a size mismatch: out->len = BUFSIZE; return DCERR_PROPERTY_SIZE_MATCH; } else if (out->len > BUFSIZE) { out->len = BUFSIZE; // This warning explicitely reports to the caller, // that the request was served, but something has changed. // So, we tolerate a request of more data than available. warn = DCWARN_PROPERTY_MODIFIED; } // Set data gathering pointer: out->value.p = g_globals.buffer; break; default: return DCERR_PROPERTY_TYPE_MATCH; } return warn; } int set_buffer(DEVICE d, DCValue *in) { switch (in->type) { case DC_COMMAND: // This is a buffer update action // Fill in update code netpp_log(DCLOG_VERBOSE, "Update buffer len %d", in->len); break; case DC_INVALID: case DC_BUFFER: // You must do a buffer size check here: netpp_log(DCLOG_VERBOSE, "Set buffer len %d", in->len); if (in->len > BUFSIZE) { in->len = BUFSIZE; return DCERR_PROPERTY_SIZE_MATCH; } // Tell engine where the data will go to: in->value.p = g_globals.buffer; break; default: return DCERR_PROPERTY_TYPE_MATCH; } return 0; } static float g_val = 3.1415926; int set_floatval(DEVICE d, DCValue *in) { g_val = in->value.f; printf("Set float value to %f\n", g_val); return 0; } int get_floatval(DEVICE d, DCValue *out) { printf("Get float value %f\n", g_val); out->value.f = g_val; return 0; } int get_dyndata(DEVICE d, DCValue *out) { out->value.p = "<This string doesn't change>"; return 0; } int set_dyndata(DEVICE d, DCValue *in) { int size; size = in->len; static char *data = 0; switch (in->type) { case DC_COMMAND: if (!data) break; printf("String size: %d\n", size); printf("\n------ begin -----\n"); puts(data); printf("\n------ end -------\n"); free(data); data = NULL; break; case DC_STRING: if (data) free(data); data = (char *) malloc(size); if (!data) return DCERR_MALLOC; in->value.p = data; break; default: return DCERR_PROPERTY_TYPE_MATCH; } return 0; }