From 4bd8667e1d3a518ab35b5e8dde5c664826f86c75 Mon Sep 17 00:00:00 2001 From: bgk Date: Wed, 23 Apr 2008 11:54:54 +0000 Subject: [PATCH] GTK GUI : The window can now be resized when using the Xv output. The display stretches to fit the window with aspect ratio correction. git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@492 a31d4220-a93d-0410-bf67-fe4944624d44 --- src/gtk/screenarea-gtk.cpp | 6 ++--- src/gtk/screenarea-gtk.h | 2 +- src/gtk/screenarea-xvideo.cpp | 49 +++++++++++++++++++++++------------ src/gtk/screenarea-xvideo.h | 9 +++++-- src/gtk/screenarea.cpp | 10 ++++++- src/gtk/screenarea.h | 3 ++- src/gtk/window.cpp | 10 ++++--- 7 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/gtk/screenarea-gtk.cpp b/src/gtk/screenarea-gtk.cpp index 56fe6adf..9400d12c 100644 --- a/src/gtk/screenarea-gtk.cpp +++ b/src/gtk/screenarea-gtk.cpp @@ -103,15 +103,13 @@ void ScreenAreaGtk::vDrawPixels(u8 * _puiData) queue_draw_area(0, 0, m_iAreaWidth, m_iAreaHeight); } -void ScreenAreaGtk::vDrawColor(u32 _uiColor) +void ScreenAreaGtk::vDrawBlackScreen() { - _uiColor = GUINT32_TO_BE(_uiColor) << 8; - u32 * puiPixel = m_puiPixels; u32 * puiEnd = m_puiPixels + m_iAreaWidth * m_iAreaHeight; while (puiPixel != puiEnd) { - *puiPixel++ = _uiColor; + *puiPixel++ = 0; } queue_draw_area(0, 0, m_iAreaWidth, m_iAreaHeight); diff --git a/src/gtk/screenarea-gtk.h b/src/gtk/screenarea-gtk.h index 910a49b7..efa18491 100644 --- a/src/gtk/screenarea-gtk.h +++ b/src/gtk/screenarea-gtk.h @@ -31,7 +31,7 @@ public: ScreenAreaGtk(int _iWidth, int _iHeight, int _iScale = 1); virtual ~ScreenAreaGtk(); void vDrawPixels(u8 * _puiData); - void vDrawColor(u32 _uiColor); // 0xRRGGBB + void vDrawBlackScreen(); protected: bool on_expose_event(GdkEventExpose * _pstEvent); diff --git a/src/gtk/screenarea-xvideo.cpp b/src/gtk/screenarea-xvideo.cpp index 81e29974..8b304476 100644 --- a/src/gtk/screenarea-xvideo.cpp +++ b/src/gtk/screenarea-xvideo.cpp @@ -31,11 +31,15 @@ namespace VBA { +template T min( T x, T y ) { return x < y ? x : y; } +template T max( T x, T y ) { return x > y ? x : y; } + ScreenAreaXv::ScreenAreaXv(int _iWidth, int _iHeight, int _iScale) : ScreenArea(_iWidth, _iHeight, _iScale), m_puiPixels(0), m_puiDelta(0), - m_iFilterScale(1) + m_iAreaTop(0), + m_iAreaLeft(0) { XvAdaptorInfo *pAdaptors; unsigned int iNumAdaptors; @@ -161,19 +165,23 @@ void ScreenAreaXv::vDrawPixels(u8 * _puiData) m_pXvImage, 0, 0, iScaledWidth, iScaledHeight, - 0, 0, + m_iAreaLeft, m_iAreaTop, m_iAreaWidth + 4, m_iAreaHeight + 4, True); gdk_display_sync(gtk_widget_get_display(pDrawingArea)); } -void ScreenAreaXv::vDrawColor(u32 _uiColor) +void ScreenAreaXv::vDrawBlackScreen() { + modify_bg(get_state(), Gdk::Color("black")); } void ScreenAreaXv::vUpdateSize() { + const int iScaledWidth = m_iFilterScale * m_iWidth; + const int iScaledHeight = m_iFilterScale * m_iHeight; + if (m_puiPixels != NULL) { delete[] m_puiPixels; @@ -189,21 +197,14 @@ void ScreenAreaXv::vUpdateSize() XShmDetach(m_pDisplay, &m_oShm); } - m_iFilterScale = 1; - if (m_iScale == 2 && m_vFilter2x != NULL) - { - m_iFilterScale = 2; - } - - m_iAreaWidth = m_iScale * m_iWidth; - m_iAreaHeight = m_iScale * m_iHeight; + vOnWidgetResize(); m_pXvImage = XvShmCreateImage(m_pDisplay, m_iXvPortId, - m_iFormat, + m_iFormat, 0, - m_iFilterScale * m_iWidth + 4, - m_iFilterScale * m_iHeight + 4, + iScaledWidth + 4, + iScaledHeight + 4, &m_oShm); m_oShm.shmid = shmget(IPC_PRIVATE, m_pXvImage->data_size, IPC_CREAT | 0777); @@ -214,12 +215,12 @@ void ScreenAreaXv::vUpdateSize() XShmAttach(m_pDisplay, &m_oShm); - m_puiPixels = new u32[m_iAreaWidth * m_iAreaHeight]; + m_puiPixels = new u32[iScaledWidth * iScaledHeight]; m_puiDelta = new u8[(m_iWidth + 2) * (m_iHeight + 2) * 4]; memset(m_puiDelta, 255, (m_iWidth + 2) * (m_iHeight + 2) * 4); - set_size_request(m_iAreaWidth, m_iAreaHeight); + set_size_request(m_iScale * m_iWidth, m_iScale* m_iHeight); } void ScreenAreaXv::vRGB32toYUY2 (unsigned char* dest_ptr, @@ -280,4 +281,20 @@ void ScreenAreaXv::vRGB32toYUY2 (unsigned char* dest_ptr, } } +void ScreenAreaXv::vOnWidgetResize() +{ + double dAspectRatio = m_iWidth / (double)m_iHeight; + + m_iAreaHeight = min(get_height(), get_width() / dAspectRatio); + m_iAreaWidth = min(get_width(), get_height() * dAspectRatio); + + m_iAreaTop = (get_height() - m_iAreaHeight) / 2; + m_iAreaLeft = (get_width() - m_iAreaWidth) / 2; +} + +bool ScreenAreaXv::on_configure_event(GdkEventConfigure * event) +{ + vOnWidgetResize(); +} + } // namespace VBA diff --git a/src/gtk/screenarea-xvideo.h b/src/gtk/screenarea-xvideo.h index 8f3804d6..969db390 100644 --- a/src/gtk/screenarea-xvideo.h +++ b/src/gtk/screenarea-xvideo.h @@ -37,7 +37,10 @@ public: ScreenAreaXv(int _iWidth, int _iHeight, int _iScale = 1); virtual ~ScreenAreaXv(); void vDrawPixels(u8 * _puiData); - void vDrawColor(u32 _uiColor); // 0xRRGGBB + void vDrawBlackScreen(); + +protected: + bool on_configure_event(GdkEventConfigure * event); private: Display *m_pDisplay; @@ -48,9 +51,11 @@ private: XShmSegmentInfo m_oShm; u32 * m_puiPixels; u8 * m_puiDelta; - int m_iFilterScale; + int m_iAreaTop; + int m_iAreaLeft; void vUpdateSize(); + void vOnWidgetResize(); void vRGB32toYUY2 (unsigned char* dest_ptr, int dest_width, int dest_height, diff --git a/src/gtk/screenarea.cpp b/src/gtk/screenarea.cpp index 78620245..139cb7cf 100644 --- a/src/gtk/screenarea.cpp +++ b/src/gtk/screenarea.cpp @@ -26,7 +26,8 @@ namespace VBA ScreenArea::ScreenArea(int _iWidth, int _iHeight, int _iScale) : m_vFilter2x(NULL), m_vFilterIB(NULL), - m_bShowCursor(true) + m_bShowCursor(true), + m_iFilterScale(1) { g_assert(_iWidth >= 1 && _iHeight >= 1 && _iScale >= 1); @@ -85,6 +86,13 @@ void ScreenArea::vSetScale(int _iScale) void ScreenArea::vSetFilter2x(EFilter2x _eFilter2x) { m_vFilter2x = pvGetFilter2x(_eFilter2x, FilterDepth32); + + m_iFilterScale = 1; + if (m_iScale == 2 && m_vFilter2x != NULL) + { + m_iFilterScale = 2; + } + vUpdateSize(); } diff --git a/src/gtk/screenarea.h b/src/gtk/screenarea.h index b835cd2c..f4f39668 100644 --- a/src/gtk/screenarea.h +++ b/src/gtk/screenarea.h @@ -39,7 +39,7 @@ public: void vSetFilter2x(EFilter2x _eFilter2x); void vSetFilterIB(EFilterIB _eFilterIB); virtual void vDrawPixels(u8 * _puiData) = 0; - virtual void vDrawColor(u32 _uiColor) = 0; // 0xRRGGBB + virtual void vDrawBlackScreen() = 0; protected: virtual bool on_motion_notify_event(GdkEventMotion * _pstEvent); @@ -50,6 +50,7 @@ protected: int m_iWidth; int m_iHeight; int m_iScale; + int m_iFilterScale; int m_iAreaWidth; int m_iAreaHeight; Filter2x m_vFilter2x; diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 4bec3e29..7baf3690 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -856,10 +856,11 @@ Window::~Window() void Window::vInitScreenArea() { - Gtk::Container * poC; + Gtk::Alignment * poC; bool bUseXv; - poC = dynamic_cast(m_poXml->get_widget("ScreenContainer")); + poC = dynamic_cast(m_poXml->get_widget("ScreenContainer")); + poC->set(Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER, 0.0, 0.0); bUseXv = m_poDisplayConfig->oGetKey("use_Xv"); if (bUseXv) @@ -867,6 +868,9 @@ void Window::vInitScreenArea() try { m_poScreenArea = Gtk::manage(new ScreenAreaXv(m_iScreenWidth, m_iScreenHeight)); + + // The Xv screen area can handle resizes + poC->set(Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER, 1.0, 1.0); } catch (std::exception e) { @@ -1518,7 +1522,7 @@ void Window::vDrawScreen() void Window::vDrawDefaultScreen() { - m_poScreenArea->vDrawColor(0x000000); // Black + m_poScreenArea->vDrawBlackScreen(); } void Window::vSetDefaultTitle()