// ============================================================================ // lib/framebuffer.cpp — kcon:: delegation layer // // The kcon:: namespace preserves the original console API. All rendering // is now handled by whichever ConsoleDriver is active (typically // FramebufferConsole via the driver framework). Formatting functions // (put_hex, put_dec, kprintf) are kept here since they are pure formatters // that call putchar/puts. // ============================================================================ #include #include #include namespace kcon { // ── Lifecycle ───────────────────────────────────────────────────────────── void init(const FramebufferInfo& fb) { #ifdef CONFIG_DRIVER_FBCON console::init_framebuffer(fb); #endif (void)fb; } // ── Character / string output (delegate to active console) ──────────────── void putchar(char c) { if (auto* con = console::active()) { con->putchar(c); } } void puts(const char* s) { while (*s) putchar(*s++); } void println(const char* s) { puts(s); putchar('\n'); } void clear() { if (auto* con = console::active()) { con->clear(); } } // ── Formatting (unchanged — these only call putchar/puts) ───────────────── void put_hex(uint64_t val) { puts("0x"); bool leading = true; for (int i = 60; i >= 0; i -= 4) { uint8_t nibble = (val >> i) & 0xF; if (nibble == 0 && leading && i > 0) continue; leading = false; putchar(nibble < 10 ? '0' + nibble : 'A' + nibble - 10); } if (leading) putchar('0'); } void put_dec(uint64_t val) { if (val == 0) { putchar('0'); return; } char buf[20]; int i = 0; while (val > 0) { buf[i++] = '0' + (val % 10); val /= 10; } for (int j = i - 1; j >= 0; j--) putchar(buf[j]); } void kprintf(const char* fmt, ...) { va_list args; va_start(args, fmt); while (*fmt) { if (*fmt != '%') { putchar(*fmt++); continue; } fmt++; // skip '%' switch (*fmt) { case 's': { const char* s = va_arg(args, const char*); puts(s ? s : "(null)"); break; } case 'd': { int64_t v = va_arg(args, int64_t); if (v < 0) { putchar('-'); v = -v; } put_dec(static_cast(v)); break; } case 'u': { uint64_t v = va_arg(args, uint64_t); put_dec(v); break; } case 'x': case 'p': { uint64_t v = va_arg(args, uint64_t); put_hex(v); break; } case '%': putchar('%'); break; case '\0': goto done; default: putchar('%'); putchar(*fmt); break; } fmt++; } done: va_end(args); } } // namespace kcon