跳轉至內容

Aros/開發人員/文件/HIDD/圖形

來自華夏公益教科書
Aros 華夏公益教科書的導航欄
Aros 使用者
Aros 使用者文件
Aros 使用者常見問題解答
Aros 使用者應用程式
Aros 使用者 DOS Shell
Aros/使用者/AmigaLegacy
Aros 開發文件
Aros 開發人員文件
從 AmigaOS/SDL 移植軟體
Zune 初學者
Zune .MUI 類
SDL 初學者
Aros 開發人員構建系統
特定平臺
Aros x86 完整系統 HCL
Aros x86 音訊/影片支援
Aros x86 網路支援
Aros Intel AMD x86 安裝
Aros 儲存支援 IDE SATA 等
Aros Poseidon USB 支援
x86-64 支援
Motorola 68k Amiga 支援
Linux 和 FreeBSD 支援
Windows Mingw 和 MacOSX 支援
Android 支援
Arm Raspberry Pi 支援
PPC Power Architecture
雜項
Aros 公共許可證

所有顯示驅動程式操作都已移至 monitorclass。這應該可以作為良好的抽象層。為了完成這個,讓我們新增 monitorclass 將是 Intuition 與圖形驅動程式對話的唯一地方。所有其他函式將使用 monitorclass 而不是直接呼叫驅動程式。目前這只是 OpenScreen()。唯一的例外將是 pointerclass,它在精靈的點陣圖中安裝一個顏色對映。順便說一下,實際上我們也可以刪除它,我們需要在 AllocSpriteDataA() 中新增另一個標記,類似於 SPRITEA_Palette。

1. 在 GRUB 命令列中指定 gfx= 和 lib= 仍然有效。只要 DEVS:Monitors/Default 檔案存在,它就會起作用。

2. 如果你想的話,你可以載入額外的驅動程式。對於新式驅動程式,只需將驅動程式從 Storage/Monitors 移動到 Devs/Monitors。目前只有 SDL 驅動程式是新式的。你也可以使用你的舊驅動程式(NVidia、Radeon、VMWare)。要做到這一點,請在 Devs/Monitors 中複製 Storage/Monitors/Wrapper 檔案(名稱無關緊要,你可以將副本命名為 "NVidia"、"ATI" - 任何你喜歡的名稱)並編輯圖示的工具型別(在其中指定庫和 HIDD 名稱)。請注意,你不能同時擁有多個相同舊式驅動程式的例項 - 它們的設計根本不是為了實現這一點。

3. 不要嘗試做一些奇怪的事情,比如透過 Wrapper 同時例項化 VGA 和 VESA。這些驅動程式很特殊,它們只能管理單個顯示器,並且它們不能共存,即使在理論上也是如此。這就是硬體的工作方式,而不是軟體問題。隨著時間的推移,它們將被重寫,變得更加健壯,並且對這種強姦具有更強的抵抗力。:)

4. 對於託管:你可以建立多個 GDI 顯示器(在 Windows 上),只需編輯 GDI 圖示的工具型別。SDL 在設計上不允許這樣做(同樣,SDL 設計,而不是驅動程式設計)。X11 可以允許這樣做,但它太古老了。需要志願者來修復它。我可以解釋如何做。

5. 你可以在執行時新增顯示驅動程式。只需雙擊其檔案就可以了!但是請注意,在你執行 VGA 或 VESA 模式時這樣做可能會導致問題(如果新的驅動程式嘗試從 VGA 驅動程式那裡竊取硬體,而 VGA 驅動程式正在顯示你的螢幕)。只需重啟,一切都會好起來的。正確的引導模式關閉是一個棘手的部分,目前有點設計不足。把它看作一個正在進行的工作。如果你運行針對不同卡的驅動程式,就不會有問題。如果你已經運行了本地驅動程式 - 同樣,沒有問題,本地模式驅動程式可以完美地共存(例如 NVidia + ATI)。

FindName("hidd.graphics.gc") 可以像屬性 ID 一樣處理。方法 ID 也按順序編號。知道第一個方法的 ID(即基本 ID)就足夠了,然後將 mo_... 偏移量加到它上面。

將顯示驅動程式的初始化移動到 C:LoadMonDrvs。不!它現在處於這個位置是有道理的。載入顯示驅動程式意味著解除安裝引導模式驅動程式。解除安裝驅動程式在技術上只有在根本沒有螢幕的情況下才有可能。因此,從一個沒有啟動序列的 shell 中執行 C:LoadMonDrvs,甚至由於某些錯誤而自動打開了 shell,都將導致崩潰。恕我直言,這很不友好。

> 雖然我相信在 PC 架構中(仍然?)存在一些技術原因,需要 AROS 確保在 Intuition 啟動之前載入顯示驅動程式。這不是 PC 架構的限制。這是 AROS 的限制。如果驅動程式有一些點陣圖,它就不能被解除安裝。從理論上講,可以透過強制關閉所有視窗和螢幕來實現安全解除安裝,但這將很困難,並且可能需要大量的程式碼。所以,請把它放在這裡。並在引導選單中的 "顯示選項" 中新增一個 "不要載入顯示驅動程式" 複選框。

目前,AROS 中的每個 HIDD 點陣圖都有一個 Hidd_BitMap_GfxHidd 屬性,用於指示建立該點陣圖的驅動程式。通常情況下,涉及此點陣圖的所有操作都應該使用此驅動程式執行。例如,如果我要為某些繪圖建立 GC,我應該在點陣圖的驅動程式上呼叫 HIDD_Gfx_NewGC()。

但是,如果操作涉及兩個點陣圖怎麼辦?例如 CopyBox()?我應該在哪個驅動程式上呼叫它?這裡至少有三種情況


  • 兩個點陣圖都屬於同一個驅動程式。
  • 這是一個簡單明瞭的案例。
  • 一個位圖是記憶體點陣圖,另一個位圖是顯示驅動程式的點陣圖。

有點棘手。我應該呼叫哪個驅動程式?記憶體驅動程式還是卡驅動程式?記憶體驅動程式相對較慢,但可以與任何東西一起使用。卡驅動程式怎麼樣?它有可能使用 DMA 來加速操作。但是,在建立記憶體點陣圖時,需要考慮點陣圖的一些限制(例如對齊方式)。因為只有卡驅動程式知道這些限制,所以我們應該在它的驅動程式上呼叫 HIDD_Gfx_NewBitMap() 來建立記憶體點陣圖。但是,我們現在可能不知道在建立點陣圖時使用哪個驅動程式。好吧,可能的解決方案是查詢朋友點陣圖。如果沒有朋友 - 抱歉,運氣不佳。這意味著我們始終在卡的驅動程式上執行 CopyBox()。卡驅動程式應該檢查記憶體點陣圖,如果可能的話加速操作(它在正確的位置並且具有正確的格式)。否則,呼叫超類。

both  bitmaps are display bitmaps but belong to different drivers (different displays on different GFX cards).

是問題最大的情況。呼叫哪個驅動程式?從理論上講,兩張卡有可能執行從一張卡到另一張卡的 DMA 資料傳輸嗎?或者同一張卡的兩個獨立輸出(從機器的角度來看,它們是兩個不同的裝置 AFAIK)?

下一個大問題是,如何處理兩個物件池。其中一個儲存 GC,另一個儲存臨時平面點陣圖物件。從第一點來看,它們應該只是全域性的。但只是從第一點來看。如果我們更深入一點,GC 類可能會被子類化(目前還沒有人這樣做,這就是它仍然有效的原因)。目前,graphics.library 只是建立 CLID_HIDD_GC 類的物件,考慮到子類,這是錯誤的。GC 應該使用 HIDD_Gfx_NewGC() 在將使用它們的驅動程式上建立。這意味著 GC 快取應該保持特定於驅動程式。

至於平面點陣圖,情況要複雜得多。上面我們得出結論,如果記憶體點陣圖符合特定要求,它們可以是 VRAM 點陣圖的朋友。在這種情況下,卡驅動程式可以使用硬體加速來處理它們。但是,這意味著我們不能從快取中取出任意空物件並將其附加到任意點陣圖。點陣圖是在沒有任何東西的情況下建立的,因此嘗試附加具有指向 GFX 驅動程式的 GfxHidd 屬性的物件是毫無意義的。它很可能不會起作用!即使我們為每個驅動程式都有單獨的池,這也無濟於事,因為臨時物件不會以任何方式與其點陣圖相關聯。池變成了汙水池。:)

是的,我們始終可以使用記憶體驅動程式建立平面點陣圖(CLID_HIDD_Gfx 類的物件)。但是,在這種情況下,我們應該準備好,因為與平面點陣圖一起工作始終很慢,因為它始終使用 CPU 執行。

1. nvidia 或 ati hidds(或任何其他 hidds)都不允許直接戳 gfx.hidd 的私有平面 bm 資料。2. 給定字型的平面點陣圖只建立 *一次*,並被多次使用。3. nvidia 和 ati hidds 可能會在其中儲存以最佳方式最佳化字型繪製的平面資料。

graphics.library 不會直接戳此點陣圖,因此 nvidia 和 ati hidds 有它們自己的平面點陣圖,它們 *被允許* 直接戳。看看那裡定義的 BlitColorExpansion 方法。

畫素格式

[編輯 | 編輯原始碼]

在 HIDD_BM_GetImage() 和 HIDD_BM_PutImage() 呼叫中使用 vHidd_StdPixFmt_ARGB32 而不是 vHidd_StdPixFmt_Native32。

這真是奇怪的行為。首先,你設定了 aHidd_Gfx_SupportsHWCursor 為 TRUE 嗎?如果沒有,你會得到未定義的行為,因為 fakegfx.hidd 會插入,而它依賴於幀緩衝區的存在。

螢幕拖動

[編輯 | 編輯原始碼]

你可以實現螢幕拖動。注意兩個屬性:

aHidd_BitMap_LeftEdge

aHidd_BitMap_TopEdge。

ScrollVPort() 只設置它們。在程式碼中做你需要做的任何事情。它們也應該可以獲取(超類總是返回 0)。這用於為驅動程式提供修復無效偏移的能力。設定這些屬性後,ScrollVPort() 會獲取它們,只有在獲取它們之後才會進入 ViewPort。這樣你就可以限制滾動。

偏移量從物理螢幕角落到點陣圖角落(即,如果你在比螢幕大的點陣圖周圍平移,它將為負值)。

為了告訴 Intuition 螢幕可能比顯示器更大或更小,還有額外的同步屬性:Sync_VMin、Sync_VMax、Sync_HMin、Sync_HMax。預設情況下,它們分別等於 HDisp 和 VDisp,但如果你顯式設定它們,它將被覆蓋。

幀緩衝區

[編輯 | 編輯原始碼]

首先,我可以解釋當你呼叫 DoSuperMethod() 時為什麼它以這種方式工作。看看基類中的 Show() 實現。如果幀緩衝區不存在,它將返回 NULL。這意味著 SDD(GfxBase)->frontbm(參見 rom/graphics/grtaphics_driver.c,SDD(GfxBase)->driver_LoadView())將始終保持 NULL。在比較之前,這樣 Show() 就不會對同一個點陣圖呼叫兩次。

我想你需要在 driver_LoadView() 中新增一些除錯輸出,以便檢視發生了什麼以及為什麼。記住,當你始終在你的 Show() 中返回 msg->bitMap 時,事情應該能夠正常工作。

對 driver_LoadView() 中實際做了什麼的一些解釋

當系統使用幀緩衝區時,只有一個幀緩衝區點陣圖是真正可顯示的,它總是顯示在螢幕上。graphics.hidd 基類在它的 Show() 中只是將要顯示的點陣圖複製到幀緩衝區,並返回幀緩衝區指標。然後 driver_LoadView() 中的程式碼獲取正在顯示的 struct BitMap 並交換其中的物件。原始物件儲存在 SDD(GfxBase)->bm_bak 中。另外還有兩個儲存的東西是顏色模型編號和顏色對映物件。從 Show() 中返回原始指標使這段程式碼實際上什麼也不做(物件被交換為自身)。

以下方法和屬性已新增到我們的圖形類中:

1. HIDD_Gfx_GetGamma() 和 HIDD_Gfx_SetGamma() - 在自動文件中解釋。它們的設計方式使得可以在它的基礎上實現 MorphOS API(如果我們想要的話)。

2. 更改顯示頻率。為了使它們可更改,你必須:- 為你的同步物件提供 aHidd_Sync_Variable = TRUE。- 你的同步物件應包含完整資料(aHidd_Sync_HSyncStart、aHidd_Sync_HSyncEnd、aHidd_Sync_VSyncStart 和 aHidd_Sync_VSyncEnd 不應為零)。

Implement  HIDD_Gfx_SetMode()  method  in your graphics driver.

此方法現在接收指向已修改的同步物件的指標。你沒有切換螢幕,所以你保留當前點陣圖。你只是收到通知,表明此同步已更改。驅動程式預計會檢查給定的同步是否當前顯示,並在需要時重建顯示。

Show gets called with bitmap
From bitmap I extract ModeID
Using ModeID I get Sync from moHidd_Gfx_GetMode
This sync is stored

我應該將傳遞的 Sync 與我在 Show() 期間儲存的 Sync 進行比較嗎?如果是,比較應該如何進行 - 透過檢查指標(它是同一個物件)還是透過檢查兩個同步之間的 aoHidd_Sync_HDisp/aoHidd_Sync_VDisp?另外,如果我傳遞的同步具有與當前同步不同的 hdisp/vdisp(意味著我需要新的點陣圖)怎麼辦?

為了嘗試 (2),MonED 程式可以做到。它可以作為 Prefs/Monitor 構建。它預設情況下不會被構建,因為目前它非常實驗性。

P.S. MonitorSpec 中 total_color_clocks 的修改會導致 aHidd_Sync_PixelClock 的修改,而 aHidd_Sync_HTotal 保持不變。我不知道它是否正確,如果需要,請修改它。但是,如果這兩個引數都需要更改,也許需要直接訪問同步物件。同步物件指標被放置到 SpecialMonitor->reserved1 中,我認為它將永遠保留在那裡。

首先,現在獲取物件並對其使用 OOP 呼叫完全沒問題。相應的 MonitorSpec 將被自動維護。

其次,同步物件變得非常智慧,它不允許修改不應該修改的東西(例如 VDisp/HDisp、Variable、Description 等)。

第三,現在你將收到通知,如果某些東西真的發生了變化(某個計時屬性被提供給了 OOP_SetAttrs())。

第四,do_monitor() 仍然存在,它仍然有效。但是我將其更改為修改 HTotal 而不是 PixelClock。我認為它接近原始行為。我同意它不適合我們的影片硬體,所以你可以隨意從頭開始編寫你自己的顯示模式編輯器。:)

一個關聯的同步物件可以在 MonitorSpec->ms_Object 中找到(這是從未使用過的 DisplayInfoDatabase 列表的別名欄位)。你可以簡單地獲取此物件,並對其使用 OOP_GetAttr() 和 OOP_SetAttrs()。你的圖形驅動程式將被同步物件自動通知,你不需要自己呼叫 SetMode()。

HIDD_Gfx_NewOverlay() 只為疊加保留記憶體。保留記憶體與當前螢幕模式無關。接下來需要將疊加顯示在螢幕上。我建議會有一個 HIDD_Overlay_Show() 方法。

由於疊加物件是由圖形驅動程式物件建立的,因此驅動程式可以使用疊加類實現的私有屬性傳遞對任何所需資料的引用。

驅動程式根據給定的矩形和當前可見顯示的解析度準備縮放。

這也透過從驅動程式物件傳遞資料到疊加物件來實現。

我會將此留給驅動程式。許多卡支援 *任何* 關鍵顏色,但是假設所有圖形晶片都符合這種說法將是一個錯誤的決定。讓圖形驅動程式自行決定。

嗯... 我在這裡看到一個大問題... 正如我所理解的,顏色鍵用於啟用具有附加疊加層的深度排列視窗。疊加層的區域被關鍵顏色填充,疊加層僅透過此顏色可見。

但讓我們想象一下這樣的情況...

+------------------+
|                  |
|  video window    |
|          +--------------+
|          |     some     |
+----------|     fancy    |
           |    painting  |
           +--------------+

如果關鍵顏色恰好在“一些花哨的繪畫”中出現,那麼影片將在那裡而不是它出現的地方可見,在它覆蓋影片視窗的部分。該怎麼辦?我怎麼知道關鍵顏色永遠不會出現在桌面上?它是誰生成的並不重要。第二個視窗甚至可以在顏色生成時未開啟。

順便說一句,不要忘記實現 SwapVLayerBuffer() 和 VOA_DoubleBuffer/VOA_MultiBuffer 標籤。使用 mplayer 及其字幕,尤其是在三緩衝疊加層時,效果要好得多。:)

關於深度,它遵循 Intuition 視窗,但要實現這一點,你需要在建立 vlayer 時設定 VOA_ColorKey 標籤(我認為這將預設情況下用某種特定填充色填充 Intuition)。使用此顏色鍵,cgxvideo 知道在視窗的哪個地方顯示疊加影片,在哪個地方不顯示。因此,如果視窗被部分或全部覆蓋,vlayer 將相應地進行處理,遵循深度排列。

顏色鍵將是下一個問題。因此,我理解正確嗎?

1. 如果你將 VOA_ColorKey 指定為 TRUE,系統將拾取一些用於鍵控的顏色,並在視窗中的疊加層區域用此顏色填充。2. 我可以在任何時候使用 VOA_ColorKey 和 VOA_ColorKeyPen 的 GetVLayerAttr() 獲取顏色值和筆號。3. 之後,影片疊加層將根據用關鍵顏色填充的顯示部分進行裁剪。

驅動程式應該提供關鍵顏色值(因為硬體可能對其施加一些限制)還是庫應該拾取它並提供給驅動程式。

如果(理論上)一個顯示器上可能存在多個疊加層?對於少於兩塊顯示卡來說,多個真正的疊加層聽起來非常不可能——實際上,cgxvideo 的 API 允許這樣做,但是這從未在 AOS 下實現(至少在公開可用的卡上是這樣)。

通常情況下,應用程式希望獲得單個的快速疊加層——如果有多個疊加層,並且所有額外的疊加層速度較慢,那麼這就會引發一個問題,為什麼在這種情況下不直接對點陣圖進行 blit 操作。

因此,如果存在多個疊加層——其中一些是模擬的,並且可能模擬速度很慢——那麼也應該有一種方法讓應用程式確定當前鎖定的疊加層是否是真正的疊加層。這樣,它們就可以在這兩種方法之間進行選擇(例如,使用自己的 AltiVec 程式碼並直接 blit)。

這取決於硬體,實際上也取決於驅動程式。影片疊加層可以以兩種方式實現:

1. 作為 gfx 卡支援的真正的疊加層。在這裡,允許一、二或三個疊加層物件同時共存(儘管一個疊加層是最常見的情況)。2. 疊加層可以是 3D 引擎 blit 的 2D 表面。在這裡,可用疊加層的數量僅受可用記憶體的限制。

實現一個類似於點陣圖類的影片疊加層類。這將允許建立多個疊加層(如果某些硬體支援的話)。順便說一句,也許點陣圖和疊加層沒有什麼區別?沒有必要為點陣圖和疊加層都提供相同的設定?在這種情況下,我們將不得不擴充套件畫素格式類以適應新的格式(如 YUV 或 YPbPr)。通常情況下,人們不會對疊加層物件使用任何像線/矩形繪製這樣的方法。直接訪問 YUV 資料更有可能。你可能已經檢查過了,但是關於 cgxvideo,以下幾點需要牢記:

SRCFMT_YUV16
(not recommended, use YCbCr16 instead)
SRCFMT_YCbCr16
SRCFMT_RGB15PC
SRCFMT_RGB16PC

即,需要支援四種格式,而 YUV 不是推薦的一種格式。

YcbCr16 工作良好,並且明顯比 RGB 更適合像 mplayer 這樣的應用程式,它提供 YUV 資料。但是你的 cgxvideo 文件有點過時了。幾年來還有一種額外的畫素格式:SRCFMT_YCbCr420(YV420,平面疊加層),當 gfx 卡支援它時,它非常有趣,因為它只需要 12 個位/畫素,而不是 16 個位/畫素,在複製時可以帶來不錯的速度提升。

ScreenDepth()

[編輯 | 編輯原始碼]

Screendepth() 始終呼叫 RethinkDisplay(),即使螢幕順序沒有改變。如果您檢視 ScreenDepth() 程式碼,您會發現它會檢查螢幕是否已經是第一個/最後一個。您可以嘗試將 RethinkDisplay() 移到這些條件中。

另一方面,據我所知,原始的 MrgCop() 不會在已經啟用的檢視上覆蓋螢幕。因此,實際的問題可能是您的驅動程式中的實現不正確。

我建議使用以下模型:每個點陣圖包含兩種狀態:實際狀態和待處理狀態。待處理狀態在 PrepareViewPorts 期間重新計算,在 ShowViewPorts 期間待處理狀態變為活動狀態。只有當新狀態與舊狀態不同時,才會發生實際的硬體更新。是的,ShowViewPorts 在活動檢視上緊隨 PrepareViewPorts 之後。

多顯示器/卡簡介

[編輯 | 編輯原始碼]

使用不同的驅動程式例項比引入像單元這樣的新概念更容易。此外,它完美地契合了 OOP 正規化。

驅動程式 = 類,例項 = 物件。同一卡上的多個輸出 = 多個類似卡 = 一個類的多個物件。

首先,DEVS:Monitors 和 SYS:Storage/Monitors 目錄出現了。目前 Storage/Monitors 是空的(除了託管埠),DEVS:Monitors 只包含單個 Wrapper 檔案。現在顯示驅動程式可以以新形式出現 - 作為放置在 DEVS:Monitors 目錄中的普通可執行檔案。構建此類驅動程式的示例是 arch/all-hosted/hidd/sdl 中的 SDL 驅動程式。注意 startup.c 檔案及其註釋。

為了編寫一個啟動時驅動程式(可用於啟動系統),需要在驅動程式中新增一個簡單的 struct Resident,它將呼叫其啟動程式碼。無需構建庫或類似的東西。

Wrapper 程式的功能是載入以舊方式指定(在核心命令列或 S:hidd.prefs 檔案中)的顯示驅動程式。注意,它完全忽略了輸入驅動程式,它們現在完全分離了。這允許使用舊的顯示驅動程式,直到它們被重寫。

我強烈建議顯示驅動程式作者將他們的程式碼轉換為新形式。一段時間後,對 S:hidd.prefs 和命令列引數的支援將被完全移除。

顯示驅動程式啟動程式碼應執行以下操作

1. 開啟所需的庫,獲取 OOP 屬性基類,建立 OOP 類。類不必是公開的,沒有人會透過名稱引用它們。

2. 掃描可用硬體(PCI 匯流排、OF 樹,等等)併為每個支援的裝置建立圖形驅動程式物件。

3. 對每個建立的物件呼叫 graphics.library/AddDisplayDriver()。該函式在成功時返回零,在失敗時返回非零值。在出現雙啟動(如果使用者雙擊您的驅動程式圖示,只是為了好玩  :))的情況下,驅動程式作者應該做什麼完全取決於驅動程式作者。通常,驅動程式不應重新新增已經使用的硬體。我們當前的 PCI 子系統不支援裝置所有權,也許需要更改這一點。您可以自由地發明任何東西。例如,SDL 驅動程式透過將它的 OOP 類註冊為公開的,並在每次啟動時嘗試找到這個類來做到這一點。如果該類已經存在,則我們已經在執行。

注意,當前 AddDisplayDriver() 是一個 HACK!它關閉並銷燬之前安裝的顯示驅動程式,並將其從資料庫中刪除。所以現在不要建立超過一個物件。在您的程式碼中實現一些 #define。當 graphics.library 完全支援多顯示環境時,需要刪除此 #define。客戶端唯一知道的是“我們有一個顯示器,這裡就是它的例項”。AddDisplayDriver() 函式執行此操作。它將驅動程式插入資料庫併為其分配監視器 ID(模式 ID 的上半部分)。僅此而已。之後,使用者可以在哪個顯示器上開啟他們的螢幕。所有顯示器的工作方式類似。

使用者只需要將顯示驅動程式從 Storage/Monitors 移動到 DEVS:Monitors 就可以啟用它。如果它找到硬體,它將自動安裝到系統中。如果沒有可用的硬體,它將不做任何事情。

顯示驅動程式可能有圖示。載入程式程式碼檢視 STARTPRI 工具型別並使用它的值作為優先順序級別。這樣做是為了使顯示模式 ID 分配在未來更可預測(ID 按驅動程式載入的順序分配)。

注意,SDL 驅動程式不能再從 S:hidd.prefs 載入,因為它不再是庫了!只需將其放置到 DEVS:Monitors 並重啟,其餘操作將自動完成。

注意,目前不能動態新增顯示驅動程式。嘗試這樣做會導致不可預知的結果。這是 graphics.library 的問題,支援不完整。所以,現在不要嘗試手動執行顯示驅動程式!特別是 Wrapper,它目前在設計上無法進行雙啟動保護(好吧,可以,但我不想麻煩程式碼,這些程式碼過一段時間就會消失)。

第 2 部分。輸入子系統。

為了透明地處理(可能是多個)輸入源,設計了兩個新的 HIDD:keyboard.hidd 和 mouse.hidd。它們與 PCI“主類”的作用相同。它們負責驅動程式和客戶端之間的通訊。

為了開始與輸入子系統對話,程式(或驅動程式)需要建立一個 CLID_Hidd_Kbd(鍵盤)或 CLID_Hidd_Mouse(滑鼠)的例項。程式可以在物件建立期間提供回撥函式,在這種情況下,程式將充當客戶端並接收輸入事件。回撥在中斷上下文中執行,與以前一樣。目前,唯一的客戶端是 keyboard.device 和 gameport.device。lowlevel.library 歡迎加入他們  :)。

為了註冊輸入驅動程式,需要在“主”物件上呼叫 AddHardwareDriver() 方法。此呼叫的引數是驅動程式類指標(而不是 ID!)和可選的附加標籤列表。您不需要提供預先製作的物件,因為主類需要為每個驅動程式提供自己的回撥函式。

可以在任何時刻註冊驅動程式,沒有任何限制。

來自多個驅動程式的輸入流只是合併成一個單一的流。

AddHardwareDriver() 返回指向驅動程式例項的指標。它可以隨時使用 RemHardwareDriver() 移除。無需在上面呼叫 OOP_DisposeObject(),因為 RemHardwareDriver() 會自行執行此操作。

!!! 我需要幫助  !!!

其他架構需要進行一些清理。需要將啟動程式碼新增到 PC 原生滑鼠和鍵盤驅動程式中。他們需要學習如何自行註冊。目前,它們由 dosboot resident 使用向後相容的 kludge 程式碼註冊,該程式碼依賴於舊式的 struct BootConfig。我知道,Michal 討厭它,它確實需要被移除(目前 X11 和 PC 原生輸入依賴於它,我認為我很快就會自己更新 X11)。此領域的其他一些任務是

1. 在 bootmenu 中實現啟動選項和顯示選項螢幕。啟動選項螢幕可能會呈現與原始 AmigaOS 類似的選擇。顯示選項螢幕至少可以包含一個取消選中標記,它會停用載入顯示驅動程式(這就是我決定將載入程式放在 dosboot 中而不是放在 Startup-sequence 中的原因)。也許它甚至可以做一些更高階的事情,比如列出可用的驅動程式並允許停用其中一些(可以透過更多 dosboot 大修來實現)。2. 將序列滑鼠驅動程式與 PS/2 滑鼠驅動程式分離。新的輸入子系統允許它們共存,甚至同時協同工作。3. 在 lowlevel.library 中實現更多功能(因為目前可能存在多個輸入事件監聽器)。4. 為 Monitors 抽屜和顯示驅動程式繪製圖標  :)。

華夏公益教科書