mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 16:48:35 -07:00
Merge branch 'dev' of https://github.com/flipperdevices/flipperzero-firmware into xfw-dev
This commit is contained in:
@@ -24,6 +24,12 @@ Canvas* canvas_init() {
|
|||||||
Canvas* canvas = malloc(sizeof(Canvas));
|
Canvas* canvas = malloc(sizeof(Canvas));
|
||||||
canvas->compress_icon = compress_icon_alloc();
|
canvas->compress_icon = compress_icon_alloc();
|
||||||
|
|
||||||
|
// Initialize mutex
|
||||||
|
canvas->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
|
|
||||||
|
// Initialize callback array
|
||||||
|
CanvasCallbackPairArray_init(canvas->canvas_callback_pair);
|
||||||
|
|
||||||
// Setup u8g2
|
// Setup u8g2
|
||||||
u8g2_Setup_st756x_flipper(&canvas->fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32);
|
u8g2_Setup_st756x_flipper(&canvas->fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32);
|
||||||
canvas->orientation = CanvasOrientationHorizontal;
|
canvas->orientation = CanvasOrientationHorizontal;
|
||||||
@@ -42,9 +48,21 @@ Canvas* canvas_init() {
|
|||||||
void canvas_free(Canvas* canvas) {
|
void canvas_free(Canvas* canvas) {
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
compress_icon_free(canvas->compress_icon);
|
compress_icon_free(canvas->compress_icon);
|
||||||
|
CanvasCallbackPairArray_clear(canvas->canvas_callback_pair);
|
||||||
|
furi_mutex_free(canvas->mutex);
|
||||||
free(canvas);
|
free(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void canvas_lock(Canvas* canvas) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
furi_check(furi_mutex_acquire(canvas->mutex, FuriWaitForever) == FuriStatusOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void canvas_unlock(Canvas* canvas) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
furi_check(furi_mutex_release(canvas->mutex) == FuriStatusOk);
|
||||||
|
}
|
||||||
|
|
||||||
void canvas_reset(Canvas* canvas) {
|
void canvas_reset(Canvas* canvas) {
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
|
|
||||||
@@ -58,6 +76,18 @@ void canvas_reset(Canvas* canvas) {
|
|||||||
void canvas_commit(Canvas* canvas) {
|
void canvas_commit(Canvas* canvas) {
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
u8g2_SendBuffer(&canvas->fb);
|
u8g2_SendBuffer(&canvas->fb);
|
||||||
|
|
||||||
|
// Iterate over callbacks
|
||||||
|
canvas_lock(canvas);
|
||||||
|
for
|
||||||
|
M_EACH(p, canvas->canvas_callback_pair, CanvasCallbackPairArray_t) {
|
||||||
|
p->callback(
|
||||||
|
canvas_get_buffer(canvas),
|
||||||
|
canvas_get_buffer_size(canvas),
|
||||||
|
canvas_get_orientation(canvas),
|
||||||
|
p->context);
|
||||||
|
}
|
||||||
|
canvas_unlock(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* canvas_get_buffer(Canvas* canvas) {
|
uint8_t* canvas_get_buffer(Canvas* canvas) {
|
||||||
@@ -606,3 +636,28 @@ void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation) {
|
|||||||
CanvasOrientation canvas_get_orientation(const Canvas* canvas) {
|
CanvasOrientation canvas_get_orientation(const Canvas* canvas) {
|
||||||
return canvas->orientation;
|
return canvas->orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void canvas_add_framebuffer_callback(Canvas* canvas, CanvasCommitCallback callback, void* context) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
|
||||||
|
const CanvasCallbackPair p = {callback, context};
|
||||||
|
|
||||||
|
canvas_lock(canvas);
|
||||||
|
furi_assert(!CanvasCallbackPairArray_count(canvas->canvas_callback_pair, p));
|
||||||
|
CanvasCallbackPairArray_push_back(canvas->canvas_callback_pair, p);
|
||||||
|
canvas_unlock(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
void canvas_remove_framebuffer_callback(
|
||||||
|
Canvas* canvas,
|
||||||
|
CanvasCommitCallback callback,
|
||||||
|
void* context) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
|
||||||
|
const CanvasCallbackPair p = {callback, context};
|
||||||
|
|
||||||
|
canvas_lock(canvas);
|
||||||
|
furi_assert(CanvasCallbackPairArray_count(canvas->canvas_callback_pair, p) == 1);
|
||||||
|
CanvasCallbackPairArray_remove_val(canvas->canvas_callback_pair, p);
|
||||||
|
canvas_unlock(canvas);
|
||||||
|
}
|
||||||
@@ -8,11 +8,31 @@
|
|||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
#include <u8g2.h>
|
#include <u8g2.h>
|
||||||
#include <toolbox/compress.h>
|
#include <toolbox/compress.h>
|
||||||
|
#include <m-array.h>
|
||||||
|
#include <m-algo.h>
|
||||||
|
#include <furi.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef void (*CanvasCommitCallback)(
|
||||||
|
uint8_t* data,
|
||||||
|
size_t size,
|
||||||
|
CanvasOrientation orientation,
|
||||||
|
void* context);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CanvasCommitCallback callback;
|
||||||
|
void* context;
|
||||||
|
} CanvasCallbackPair;
|
||||||
|
|
||||||
|
ARRAY_DEF(CanvasCallbackPairArray, CanvasCallbackPair, M_POD_OPLIST);
|
||||||
|
|
||||||
|
#define M_OPL_CanvasCallbackPairArray_t() ARRAY_OPLIST(CanvasCallbackPairArray, M_POD_OPLIST)
|
||||||
|
|
||||||
|
ALGO_DEF(CanvasCallbackPairArray, CanvasCallbackPairArray_t);
|
||||||
|
|
||||||
/** Canvas structure
|
/** Canvas structure
|
||||||
*/
|
*/
|
||||||
struct Canvas {
|
struct Canvas {
|
||||||
@@ -23,6 +43,8 @@ struct Canvas {
|
|||||||
uint8_t width;
|
uint8_t width;
|
||||||
uint8_t height;
|
uint8_t height;
|
||||||
CompressIcon* compress_icon;
|
CompressIcon* compress_icon;
|
||||||
|
CanvasCallbackPairArray_t canvas_callback_pair;
|
||||||
|
FuriMutex* mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Allocate memory and initialize canvas
|
/** Allocate memory and initialize canvas
|
||||||
@@ -102,6 +124,27 @@ void canvas_draw_u8g2_bitmap(
|
|||||||
const uint8_t* bitmap,
|
const uint8_t* bitmap,
|
||||||
uint8_t rotation);
|
uint8_t rotation);
|
||||||
|
|
||||||
|
/** Add canvas commit callback.
|
||||||
|
*
|
||||||
|
* This callback will be called upon Canvas commit.
|
||||||
|
*
|
||||||
|
* @param canvas Canvas instance
|
||||||
|
* @param callback CanvasCommitCallback
|
||||||
|
* @param context CanvasCommitCallback context
|
||||||
|
*/
|
||||||
|
void canvas_add_framebuffer_callback(Canvas* canvas, CanvasCommitCallback callback, void* context);
|
||||||
|
|
||||||
|
/** Remove canvas commit callback.
|
||||||
|
*
|
||||||
|
* @param canvas Canvas instance
|
||||||
|
* @param callback CanvasCommitCallback
|
||||||
|
* @param context CanvasCommitCallback context
|
||||||
|
*/
|
||||||
|
void canvas_remove_framebuffer_callback(
|
||||||
|
Canvas* canvas,
|
||||||
|
CanvasCommitCallback callback,
|
||||||
|
void* context);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -304,14 +304,6 @@ static void gui_redraw(Gui* gui) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvas_commit(gui->canvas);
|
canvas_commit(gui->canvas);
|
||||||
for
|
|
||||||
M_EACH(p, gui->canvas_callback_pair, CanvasCallbackPairArray_t) {
|
|
||||||
p->callback(
|
|
||||||
canvas_get_buffer(gui->canvas),
|
|
||||||
canvas_get_buffer_size(gui->canvas),
|
|
||||||
canvas_get_orientation(gui->canvas),
|
|
||||||
p->context);
|
|
||||||
}
|
|
||||||
} while(false);
|
} while(false);
|
||||||
|
|
||||||
gui_unlock(gui);
|
gui_unlock(gui);
|
||||||
@@ -541,12 +533,7 @@ void gui_view_port_send_to_back(Gui* gui, ViewPort* view_port) {
|
|||||||
void gui_add_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback, void* context) {
|
void gui_add_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback, void* context) {
|
||||||
furi_assert(gui);
|
furi_assert(gui);
|
||||||
|
|
||||||
const CanvasCallbackPair p = {callback, context};
|
canvas_add_framebuffer_callback(gui->canvas, callback, context);
|
||||||
|
|
||||||
gui_lock(gui);
|
|
||||||
furi_assert(!CanvasCallbackPairArray_count(gui->canvas_callback_pair, p));
|
|
||||||
CanvasCallbackPairArray_push_back(gui->canvas_callback_pair, p);
|
|
||||||
gui_unlock(gui);
|
|
||||||
|
|
||||||
// Request redraw
|
// Request redraw
|
||||||
gui_update(gui);
|
gui_update(gui);
|
||||||
@@ -555,12 +542,7 @@ void gui_add_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback, vo
|
|||||||
void gui_remove_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback, void* context) {
|
void gui_remove_framebuffer_callback(Gui* gui, GuiCanvasCommitCallback callback, void* context) {
|
||||||
furi_assert(gui);
|
furi_assert(gui);
|
||||||
|
|
||||||
const CanvasCallbackPair p = {callback, context};
|
canvas_remove_framebuffer_callback(gui->canvas, callback, context);
|
||||||
|
|
||||||
gui_lock(gui);
|
|
||||||
furi_assert(CanvasCallbackPairArray_count(gui->canvas_callback_pair, p) == 1);
|
|
||||||
CanvasCallbackPairArray_remove_val(gui->canvas_callback_pair, p);
|
|
||||||
gui_unlock(gui);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t gui_get_framebuffer_size(const Gui* gui) {
|
size_t gui_get_framebuffer_size(const Gui* gui) {
|
||||||
@@ -625,14 +607,14 @@ Gui* gui_alloc() {
|
|||||||
gui->thread_id = furi_thread_get_current_id();
|
gui->thread_id = furi_thread_get_current_id();
|
||||||
// Allocate mutex
|
// Allocate mutex
|
||||||
gui->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
gui->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
furi_check(gui->mutex);
|
|
||||||
// Layers
|
// Layers
|
||||||
for(size_t i = 0; i < GuiLayerMAX; i++) {
|
for(size_t i = 0; i < GuiLayerMAX; i++) {
|
||||||
ViewPortArray_init(gui->layers[i]);
|
ViewPortArray_init(gui->layers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drawing canvas
|
// Drawing canvas
|
||||||
gui->canvas = canvas_init();
|
gui->canvas = canvas_init();
|
||||||
CanvasCallbackPairArray_init(gui->canvas_callback_pair);
|
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
gui->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
gui->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
|
||||||
@@ -640,7 +622,6 @@ Gui* gui_alloc() {
|
|||||||
gui->ascii_queue = furi_message_queue_alloc(8, sizeof(AsciiEvent));
|
gui->ascii_queue = furi_message_queue_alloc(8, sizeof(AsciiEvent));
|
||||||
gui->ascii_events = furi_record_open(RECORD_ASCII_EVENTS);
|
gui->ascii_events = furi_record_open(RECORD_ASCII_EVENTS);
|
||||||
|
|
||||||
furi_check(gui->input_events);
|
|
||||||
furi_pubsub_subscribe(gui->input_events, gui_input_events_callback, gui);
|
furi_pubsub_subscribe(gui->input_events, gui_input_events_callback, gui);
|
||||||
furi_check(gui->ascii_events);
|
furi_check(gui->ascii_events);
|
||||||
furi_pubsub_subscribe(gui->ascii_events, gui_ascii_events_callback, gui);
|
furi_pubsub_subscribe(gui->ascii_events, gui_ascii_events_callback, gui);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <furi_hal_rtc.h>
|
#include <furi_hal_rtc.h>
|
||||||
#include <m-array.h>
|
#include <m-array.h>
|
||||||
#include <m-algo.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "canvas.h"
|
#include "canvas.h"
|
||||||
@@ -45,17 +44,6 @@
|
|||||||
|
|
||||||
ARRAY_DEF(ViewPortArray, ViewPort*, M_PTR_OPLIST);
|
ARRAY_DEF(ViewPortArray, ViewPort*, M_PTR_OPLIST);
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GuiCanvasCommitCallback callback;
|
|
||||||
void* context;
|
|
||||||
} CanvasCallbackPair;
|
|
||||||
|
|
||||||
ARRAY_DEF(CanvasCallbackPairArray, CanvasCallbackPair, M_POD_OPLIST);
|
|
||||||
|
|
||||||
#define M_OPL_CanvasCallbackPairArray_t() ARRAY_OPLIST(CanvasCallbackPairArray, M_POD_OPLIST)
|
|
||||||
|
|
||||||
ALGO_DEF(CanvasCallbackPairArray, CanvasCallbackPairArray_t);
|
|
||||||
|
|
||||||
/** Gui structure */
|
/** Gui structure */
|
||||||
struct Gui {
|
struct Gui {
|
||||||
// Thread and lock
|
// Thread and lock
|
||||||
@@ -67,7 +55,6 @@ struct Gui {
|
|||||||
bool direct_draw;
|
bool direct_draw;
|
||||||
ViewPortArray_t layers[GuiLayerMAX];
|
ViewPortArray_t layers[GuiLayerMAX];
|
||||||
Canvas* canvas;
|
Canvas* canvas;
|
||||||
CanvasCallbackPairArray_t canvas_callback_pair;
|
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
FuriMessageQueue* input_queue;
|
FuriMessageQueue* input_queue;
|
||||||
|
|||||||
Reference in New Issue
Block a user