Systemicus чаcть 2: GUI

    
 
Пост в продовження даної теми . Трохи більше місяця тому я показав ОС Systemicus і її повільне подобу графічного інтерфейсу. Весь цей час (коли воно було в моєму розпорядженні) я працював над поліпшеннями і тепер уявляю на суд громадськості результати. Бути може, ця стаття допоможе кому-небудь в розробці своєї GUI, т.к. я не знайшов хороших матеріалів по деяких аспектах даної теми.
 
 
 

Загальні підсумки

Як і обіцяв в минулій темі знайшов тонке місце (точніше місця) в продуктивності — ними виявилися планувальник (циклічний) і помилка подвійний перемальовування всіх вікон.
Анти-підсумком стала проблема розміру виконуваного файлу оболонки (explorer.exe). Я сподівався вмістити весь код оболонки в одну секцію PE (4096 байт), але поки цього не вийшло. Секція коду на даний момент складає 4800 байт (сам файлик важить майже 10 Кб :-(). Можливо, в майбутньому вдасться трохи скоротити розмір, але тому в оболонці багато що ще потрібно буде додати, то розмір explorer.exe може досягти навіть 16 кілобайт.
 
 

Принцип роботи

Відразу зазначу, що скупий платить двічі. Через мого бажання заощадити зайвих 64 Кб оперативної пам'яті, я спочатку відхилив шлях створення байтовой маски екрану (де кожного пікселя відповідає байт з номером вікна [вікон передбачено до 256]). І проблема не тільки в економії пам'яті, але і в економії ресурсів процесора, адже у відсутності даної технології нету необхідності перед виведенням кожного пікселя екрану перевіряти його приналежність до певного вікна. Але… коли справа дійшла до кліппінга (тобто отрисовки тільки частини вікна, яке лежить під іншим вікном) я зрозумів, як глибоко помилився. Благо було б, якщо мальованої вікно лежить тільки під одним віконцем — там кліппінг можна обчислити — всього-то прямокутна область. А що робити, якщо мальованої вікно перекривають самим непотрібним чином відразу кілька інших вікон і мальованої область виявляється досить химерної форми?
Загалом, повернувся назад і ввів байтовую маску екрана. Витрата пам'яті збільшився, зате зменшилася кількість коду (обчислювати стало легше, хоча це не означає, що підвищилася швидкість).
 
Отже, все просто до неподобства. Є байтовая маска екрану, де кожного пікселя присвоюється нульове значення або інше, якщо точка належить вікну. Є структура вікон, вона у мене такого виду:
 
 
WNDLIST_ITEM:
   .handle      dd 0   ; +00
   .x           dd 0   ; +04
   .y           dd 0   ; +08
   .width       dd 0   ; +12
   .height      dd 0   ; +16
   .flags       dd 0   ; +20
   .rsrc        dd 0   ; +24
   .parent      dd 0   ; +28
   .wbmp        dd 0   ; +32
   .caption     dd 0   ; +36
   ; if DESKTOP: db Leftbuttonstate  ; +36
   ;             db RightButtonState ; +37
   ;             dw reserved         ; +38
   .clickx      dw 0   ; +40
   .clicky      dw 0   ; +42
   .winstyle    dd 0
                db 16 dup 0   

Значення parent і winstyle виявилися невикористовуваними і тому зарезервованими (як і 16 байт після). Маючи ці дані ми можемо побудувати вікно в прихованому буфері wbmp (технологія подвійний буферизації). З метою економії пам'яті в буфері все малюється 8-бітним кольором (наразі використовується лише 16), тобто 1 байт на точку, а при виведенні на екран цей колір перетвориться в 24/32-разрядний за допомогою таблиці зіставлення значень кольорів.
 
Всі операції отрисовки при появі різних подій вікна відбувається в буфері, а на екран виводиться буфер цілком (або частково), тобто безпосередньо в екран нічого не малюється (текст, кнопки і т.п.).
 
Тепер про елементи вікна. Для всіх елементів усіх вікон існує всього одна загальна глобальна таблиця елементів, кожен елемент якої містить посилання на вікно (1 байт, тому вікон всього 256 максимум), позиція щодо вікна і розміри елемента (по 2 байти), байт стану і 2 подвійних слова — посилання (на текст, наприклад для кнопок або інша інофрмація для інших елементів) і extras (іконка для кнопки або інші дані в залежності від типу елемента). Байт стану: молодші 4 біта вказують на тип елемента (кнопка, чекбокс, текстове поле і т.п.), старші на його стан (активний чи, hover).
 
Головний процес Explorer'а отримує подія від драйвера мишки. Що відбувається: за координатами покажчика шукається вікно. Вікну передається параметри покажчика, а саме чи натиснута клавіша, якщо натиснута, то це натискання або відпускання клавіші. При натисканні спочатку активізуємо вікно, тобто робимо його активним і перемальовували на передньому плані. Далі по глобальній таблиці елементів шукаємо всі елементи, що належать вікна, а серед них — підпадають під координати мишки. Якщо знайшли, то відповідно до параметрів покажчика мишки обробляємо (малюємо, перемальовували і т.п.).
Якщо ж покажчик знаходиться поза вікон, то це подія також обробляється. У даному випадку, якщо натиснуто клавіша на робочому столі, а меню Пуск відкрито — то потрібно його закрити. Надалі ці події потрібні будуть для створення ярликів та інших функцій робочого столу.
 
Маючи даний функціонал, не складає труднощів реалізувати прості функції оболонки — обробку подій, перетягування вікон, кліппінг накладень вікон між собою.
 
 

План на найближче майбутнє

У поточній реалізації залишилося багато проблем, зокрема, іноді з'являються помилки при відображенні курсора мишки після кліка по робочому столу — копія курсора залишається на столі)) Є й деякі інші проблеми, втім невеликі.
З важливого — повноцінний елемент textarea з прокруткою тексту, взаємозв'язок радіокнопок одного імені (тобто включення тільки однієї кнопки в один момент часу для групи radiobuttons). Це зі складностей. Цікавою, але не дуже важким завданням залишається прив'язка додатків до їх вікнам, тому що зараз це всі тестові вікна, що виводяться самої оболонкою.
 
Є ідея реалізації терміналу створенням вікна і копіюванням в нього вмісту з адреси 0xB8000 (природно, перетворюючи кожен символ в площу пікселів 8 * 16).
 
А далі — портирование пари-трійки додатків, в першу чергу fasmw, якої-небудь маленької іграшки і, напевно, калькулятора. Після чого отпишусь шановному хабрасообществу.
 
І наостанок невелике відео. Нету, відео не викладу, тому що CamStudio дуже загальмовує Qemu. Викладаю образ для запуску Qemu. Вибирайте Partition 2, режим будь, але а 640 * 480 є невелика проблема з фоном) І не сваріть, це АЛЬФА… багато багів. Лаяти будете за бета-версію :-) Також, прошу вибачення за стиль і помилки (якщо є), вже глибока ніч…
 
Посилання на файл: http://nebka.ru/files/647-0.02_qemu.7z
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.