@@ -8,6 +8,7 @@
#include <charset.h>
#include <dm.h>
+#include <malloc.h>
#include <spl.h>
#include <video.h>
#include <video_console.h>
@@ -188,6 +189,27 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp)
return console_normal_putc_xy(dev, x_frac, y, cp);
}
+static int console_simple_ctx_new(struct udevice *dev, void **ctxp)
+{
+ struct console_ctx *ctx;
+
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx)
+ return -ENOMEM;
+
+ memset(ctx, '\0', sizeof(*ctx));
+ *ctxp = ctx;
+
+ return 0;
+}
+
+static int console_simple_ctx_dispose(struct udevice *dev, void *ctx)
+{
+ free(ctx);
+
+ return 0;
+}
+
struct vidconsole_ops console_ops = {
.putc_xy = console_putc_xy,
.move_rows = console_move_rows,
@@ -195,6 +217,8 @@ struct vidconsole_ops console_ops = {
.get_font_size = console_simple_get_font_size,
.get_font = console_simple_get_font,
.select_font = console_simple_select_font,
+ .ctx_new = console_simple_ctx_new,
+ .ctx_dispose = console_simple_ctx_dispose,
#ifdef CONFIG_CURSOR
.get_cursor_info = console_get_cursor_info,
.entry_save = normal_entry_save,
@@ -1149,6 +1149,27 @@ static int truetype_nominal(struct udevice *dev, const char *name, uint size,
return 0;
}
+static int truetype_ctx_new(struct udevice *dev, void **ctxp)
+{
+ struct console_tt_ctx *ctx;
+
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx)
+ return -ENOMEM;
+
+ memset(ctx, '\0', sizeof(*ctx));
+ *ctxp = ctx;
+
+ return 0;
+}
+
+static int truetype_ctx_dispose(struct udevice *dev, void *ctx)
+{
+ free(ctx);
+
+ return 0;
+}
+
static int truetype_entry_save(struct udevice *dev, struct abuf *buf)
{
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
@@ -1331,6 +1352,8 @@ struct vidconsole_ops console_truetype_ops = {
.select_font = truetype_select_font,
.measure = truetype_measure,
.nominal = truetype_nominal,
+ .ctx_new = truetype_ctx_new,
+ .ctx_dispose = truetype_ctx_dispose,
.entry_save = truetype_entry_save,
.entry_restore = truetype_entry_restore,
.get_cursor_info = truetype_get_cursor_info,
@@ -690,6 +690,38 @@ int vidconsole_nominal(struct udevice *dev, const char *name, uint size,
return 0;
}
+int vidconsole_ctx_new(struct udevice *dev, void **ctxp)
+{
+ struct vidconsole_ops *ops = vidconsole_get_ops(dev);
+ void *ctx;
+ int ret;
+
+ if (!ops->ctx_new)
+ return -ENOSYS;
+
+ ret = ops->ctx_new(dev, &ctx);
+ if (ret)
+ return ret;
+ *ctxp = ctx;
+
+ return 0;
+}
+
+int vidconsole_ctx_dispose(struct udevice *dev, void *ctx)
+{
+ struct vidconsole_ops *ops = vidconsole_get_ops(dev);
+ int ret;
+
+ if (!ops->ctx_dispose)
+ return -ENOSYS;
+
+ ret = ops->ctx_dispose(dev, ctx);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
int vidconsole_entry_save(struct udevice *dev, struct abuf *buf)
{
struct vidconsole_ops *ops = vidconsole_get_ops(dev);
@@ -348,6 +348,28 @@ struct vidconsole_ops {
int (*nominal)(struct udevice *dev, const char *name, uint size,
uint num_chars, struct vidconsole_bbox *bbox);
+ /**
+ * ctx_new() - Create a new context for a client
+ *
+ * Allocates and initialises a context for a client of the vidconsole.
+ * The driver determines what information is stored in the context.
+ *
+ * @dev: Console device to use
+ * @ctxp: Returns new context, on success
+ * Return: 0 on success, -ENOMEM if out of memory
+ */
+ int (*ctx_new)(struct udevice *dev, void **ctxp);
+
+ /**
+ * ctx_dispose() - Dispose of a context
+ *
+ * Frees any memory allocated for the context.
+ *
+ * @dev: Console device to use
+ * @ctx: Context to dispose of
+ */
+ int (*ctx_dispose)(struct udevice *dev, void *ctx);
+
/**
* entry_save() - Save any text-entry information for later use
*
@@ -456,6 +478,28 @@ int vidconsole_measure(struct udevice *dev, const char *name, uint size,
int vidconsole_nominal(struct udevice *dev, const char *name, uint size,
uint num_chars, struct vidconsole_bbox *bbox);
+/**
+ * vidconsole_ctx_new() - Create a new context for a client
+ *
+ * Allocates and initialises a context for a client of the vidconsole.
+ * The driver determines what information is stored in the context.
+ *
+ * @dev: Console device to use
+ * @ctxp: Returns new context, on success
+ * Return: 0 on success, -ENOMEM if out of memory
+ */
+int vidconsole_ctx_new(struct udevice *dev, void **ctxp);
+
+/**
+ * vidconsole_ctx_dispose() - Dispose of a context
+ *
+ * Frees any memory allocated for the context.
+ *
+ * @dev: Console device to use
+ * @ctx: Context to dispose of
+ */
+int vidconsole_ctx_dispose(struct udevice *dev, void *ctx);
+
/**
* vidconsole_entry_save() - Save any text-entry information for later use
*
@@ -1493,3 +1493,25 @@ static int dm_test_video_sync_damage(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_video_sync_damage, UTF_SCAN_PDATA | UTF_SCAN_FDT);
+
+/* Test vidconsole context allocation */
+static int dm_test_video_context_alloc(struct unit_test_state *uts)
+{
+ struct udevice *dev, *con;
+ void *ctx;
+
+ ut_assertok(select_vidconsole(uts, "vidconsole0"));
+ ut_assertok(video_get_nologo(uts, &dev));
+ ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
+
+ ut_assertok(vidconsole_ctx_new(con, &ctx));
+ ut_assertnonnull(ctx);
+
+ ut_assertok(vidconsole_ctx_dispose(con, ctx));
+
+ /* Dispose should handle NULL gracefully */
+ ut_assertok(vidconsole_ctx_dispose(con, NULL));
+
+ return 0;
+}
+DM_TEST(dm_test_video_context_alloc, UTF_SCAN_PDATA | UTF_SCAN_FDT);