123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659 |
- /*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
- // We need to include stdio.h below. Turn off GFILE_NEED_STDIO just for this file to prevent conflicts
- #define GFILE_NEED_STDIO_MUST_BE_OFF
- #include "gfx.h"
- #if GFX_USE_GDISP
- #define GDISP_DRIVER_VMT GDISPVMT_Win32
- #include "gdisp_lld_config.h"
- #include "../../../src/gdisp/gdisp_driver.h"
- // Configuration parameters for this driver
- #ifndef GDISP_SCREEN_WIDTH
- #define GDISP_SCREEN_WIDTH 640
- #endif
- #ifndef GDISP_SCREEN_HEIGHT
- #define GDISP_SCREEN_HEIGHT 480
- #endif
- #ifndef GDISP_WIN32_USE_INDIRECT_UPDATE
- /**
- * Setting this to TRUE delays updating the screen
- * to the windows paint routine. Due to the
- * drawing lock this does not add as much speed
- * as might be expected but it is still faster in
- * all tested circumstances and for all operations
- * even draw_pixel().
- * This is probably due to drawing operations being
- * combined as the update regions are merged.
- * The only time you might want to turn this off is
- * if you are debugging drawing and want to see each
- * pixel as it is set.
- */
- #define GDISP_WIN32_USE_INDIRECT_UPDATE TRUE
- #endif
- #ifndef GKEYBOARD_WIN32_NO_LAYOUT
- /**
- * Setting this to TRUE turns off the layout engine.
- * In this situation "cooked" characters are returned but
- * shift states etc are lost.
- * As only a limited number of keyboard layouts are currently
- * defined for Win32 in uGFX (currently only US English), setting this
- * to TRUE enables the windows keyboard mapping to be pass non-English
- * characters to uGFX or to handle non-standard keyboard layouts at
- * the expense of losing special function keys etc.
- */
- #define GKEYBOARD_WIN32_NO_LAYOUT FALSE
- #endif
- #ifndef GKEYBOARD_WIN32_DEFAULT_LAYOUT
- #define GKEYBOARD_WIN32_DEFAULT_LAYOUT KeyboardLayout_Win32_US
- #endif
- // How far extra windows (multiple displays) should be offset from the first.
- #define DISPLAY_X_OFFSET 50
- #define DISPLAY_Y_OFFSET 50
- // Oops - name clashes with Win32 symbols
- #undef Red
- #undef Green
- #undef Blue
- #define WIN32_LEAN_AND_MEAN
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <windows.h>
- #include <wingdi.h>
- #include <assert.h>
- #define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
- #define GDISP_FLG_HASTOGGLE (GDISP_FLG_DRIVER<<1)
- #if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
- #define GDISP_FLG_WSTREAM (GDISP_FLG_DRIVER<<3)
- #define GDISP_FLG_WRAPPED (GDISP_FLG_DRIVER<<4)
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
- /* Include toggle support code */
- #include "../../../src/ginput/ginput_driver_toggle.h"
- // Hack until toggle use gdriver.
- static GDisplay *toggleWindow;
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- // Include mouse support code
- #define GMOUSE_DRIVER_VMT GMOUSEVMT_Win32
- #include "../../../src/ginput/ginput_driver_mouse.h"
- // Forward definitions
- static bool_t Win32MouseInit(GMouse *m, unsigned driverinstance);
- static bool_t Win32MouseRead(GMouse *m, GMouseReading *prd);
- const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
- {
- GDRIVER_TYPE_MOUSE,
- GMOUSE_VFLG_NOPOLL|GMOUSE_VFLG_DYNAMICONLY,
- // Extra flags for testing only
- //GMOUSE_VFLG_TOUCH|GMOUSE_VFLG_SELFROTATION|GMOUSE_VFLG_DEFAULTFINGER
- //GMOUSE_VFLG_CALIBRATE|GMOUSE_VFLG_CAL_EXTREMES|GMOUSE_VFLG_CAL_TEST|GMOUSE_VFLG_CAL_LOADFREE
- //GMOUSE_VFLG_ONLY_DOWN|GMOUSE_VFLG_POORUPDOWN
- sizeof(GMouse),
- _gmouseInitDriver, _gmousePostInitDriver, _gmouseDeInitDriver
- },
- 1, // z_max
- 0, // z_min
- 1, // z_touchon
- 0, // z_touchoff
- { // pen_jitter
- 0, // calibrate
- 0, // click
- 0 // move
- },
- { // finger_jitter
- 0, // calibrate
- 2, // click
- 2 // move
- },
- Win32MouseInit, // init
- 0, // deinit
- Win32MouseRead, // get
- 0, // calsave
- 0 // calload
- }};
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD
- #define GKEYBOARD_DRIVER_VMT GKEYBOARDVMT_Win32
- #include "../../../src/ginput/ginput_driver_keyboard.h"
- #if !GKEYBOARD_WIN32_NO_LAYOUT
- #if GKEYBOARD_LAYOUT_OFF
- #error "The Win32 keyboard driver is using the layout engine. Please set GKEYBOARD_LAYOUT_OFF=FALSE or GKEYBOARD_WIN32_NO_LAYOUT=TRUE."
- #endif
- #include "../../../src/ginput/ginput_keyboard_microcode.h"
- // Forward definitions
- extern uint8_t GKEYBOARD_WIN32_DEFAULT_LAYOUT[];
- // This is the layout code for the English US keyboard.
- // We make it public so that a user can switch to a different layout if required.
- uint8_t KeyboardLayout_Win32_US[] = {
- KMC_HEADERSTART, KMC_HEADER_ID1, KMC_HEADER_ID2, KMC_HEADER_VER_1,
- // Transient Shifters: SHIFT, CTRL, ALT, WINKEY
- /* 1 */KMC_RECORDSTART, 9, // SHIFT (left & Right)
- KMC_TEST_CODETABLE, 2, VK_SHIFT, VK_LSHIFT,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_SHIFT_L_BIT|KMC_BIT_CLEAR,
- KMC_ACT_DONE,
- /* 2 */KMC_RECORDSTART, 9,
- KMC_TEST_CODETABLE, 2, VK_SHIFT, VK_LSHIFT,
- KMC_TEST_STATEBIT, GKEYSTATE_SHIFT_L_BIT|KMC_BIT_CLEAR,
- KMC_ACT_STATEBIT, GKEYSTATE_SHIFT_L_BIT,
- KMC_ACT_DONE,
- /* 3 */KMC_RECORDSTART, 7,
- KMC_TEST_CODE, VK_RSHIFT,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_SHIFT_R_BIT|KMC_BIT_CLEAR,
- KMC_ACT_DONE,
- /* 4 */KMC_RECORDSTART, 7,
- KMC_TEST_CODE, VK_RSHIFT,
- KMC_TEST_STATEBIT, GKEYSTATE_SHIFT_R_BIT|KMC_BIT_CLEAR,
- KMC_ACT_STATEBIT, GKEYSTATE_SHIFT_R_BIT,
- KMC_ACT_DONE,
- /* 5 */KMC_RECORDSTART, 9, // CONTROL (left & Right)
- KMC_TEST_CODETABLE, 2, VK_CONTROL, VK_LCONTROL,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_CTRL_L_BIT|KMC_BIT_CLEAR,
- KMC_ACT_DONE,
- /* 6 */KMC_RECORDSTART, 9,
- KMC_TEST_CODETABLE, 2, VK_CONTROL, VK_LCONTROL,
- KMC_TEST_STATEBIT, GKEYSTATE_CTRL_L_BIT|KMC_BIT_CLEAR,
- KMC_ACT_STATEBIT, GKEYSTATE_CTRL_L_BIT,
- KMC_ACT_DONE,
- /* 7 */KMC_RECORDSTART, 7,
- KMC_TEST_CODE, VK_RCONTROL,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_CTRL_R_BIT|KMC_BIT_CLEAR,
- KMC_ACT_DONE,
- /* 8 */KMC_RECORDSTART, 7,
- KMC_TEST_CODE, VK_RCONTROL,
- KMC_TEST_STATEBIT, GKEYSTATE_CTRL_R_BIT|KMC_BIT_CLEAR,
- KMC_ACT_STATEBIT, GKEYSTATE_CTRL_R_BIT,
- KMC_ACT_DONE,
- /* 9 */KMC_RECORDSTART, 9, // ALT (left & Right)
- KMC_TEST_CODETABLE, 2, VK_MENU, VK_LMENU,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_ALT_L_BIT|KMC_BIT_CLEAR,
- KMC_ACT_DONE,
- /* 10 */KMC_RECORDSTART, 9,
- KMC_TEST_CODETABLE, 2, VK_MENU, VK_LMENU,
- KMC_TEST_STATEBIT, GKEYSTATE_ALT_L_BIT|KMC_BIT_CLEAR,
- KMC_ACT_STATEBIT, GKEYSTATE_ALT_L_BIT,
- KMC_ACT_DONE,
- /* 11 */KMC_RECORDSTART, 7,
- KMC_TEST_CODE, VK_RMENU,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_ALT_R_BIT|KMC_BIT_CLEAR,
- KMC_ACT_DONE,
- /* 12 */KMC_RECORDSTART, 7,
- KMC_TEST_CODE, VK_RMENU,
- KMC_TEST_STATEBIT, GKEYSTATE_ALT_R_BIT|KMC_BIT_CLEAR,
- KMC_ACT_STATEBIT, GKEYSTATE_ALT_R_BIT,
- KMC_ACT_DONE,
- /* 13 */KMC_RECORDSTART, 9, // WinKey (left or right)
- KMC_TEST_CODETABLE, 2, VK_LWIN, VK_RWIN,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_WINKEY_BIT|KMC_BIT_CLEAR,
- KMC_ACT_DONE,
- /* 14 */KMC_RECORDSTART, 9,
- KMC_TEST_CODETABLE, 2, VK_LWIN, VK_RWIN,
- KMC_TEST_STATEBIT, GKEYSTATE_WINKEY_BIT|KMC_BIT_CLEAR,
- KMC_ACT_STATEBIT, GKEYSTATE_WINKEY_BIT,
- KMC_ACT_DONE,
- // Locking Shifters: CAPSLOCK, NUMLOCK and SCROLLLOCK
- /* 15 */KMC_RECORDSTART, 7, // CAPSLOCK (keyup only)
- KMC_TEST_CODE, VK_CAPITAL,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_CAPSLOCK_BIT|KMC_BIT_INVERT,
- KMC_ACT_DONE,
- /* 16 */KMC_RECORDSTART, 7, // NUMLOCK (keyup only)
- KMC_TEST_CODE, VK_NUMLOCK,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_NUMLOCK_BIT|KMC_BIT_INVERT,
- KMC_ACT_DONE,
- /* 17 */KMC_RECORDSTART, 7, // SCROLLLOCK (keyup only)
- KMC_TEST_CODE, VK_SCROLL,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_SCROLLLOCK_BIT|KMC_BIT_INVERT,
- KMC_ACT_DONE,
- // Keyup, Repeat
- /* 18 */KMC_RECORDSTART, 18, // Clear any shifter keys that got through
- KMC_TEST_CODETABLE, 14, VK_SHIFT, VK_LSHIFT, VK_RSHIFT,
- VK_CONTROL, VK_LCONTROL, VK_RCONTROL,
- VK_MENU, VK_LMENU, VK_RMENU,
- VK_LWIN, VK_RWIN,
- VK_CAPITAL, VK_NUMLOCK, VK_SCROLL,
- KMC_ACT_RESET,
- KMC_ACT_STOP,
- /* 19 */KMC_RECORDSTART, 4, // Skip special codes 0x00 (Keyup) & 0x01 (Repeat)
- KMC_TEST_CODERANGE, 0x00, 0x01,
- KMC_ACT_STOP,
- /* 20 */KMC_RECORDSTART, 6, // Keyup
- KMC_ACT_STATEBIT, GKEYSTATE_KEYUP_BIT|KMC_BIT_CLEAR,
- KMC_TEST_LASTCODE, 0x00,
- KMC_ACT_STATEBIT, GKEYSTATE_KEYUP_BIT,
- /* 21 */KMC_RECORDSTART, 6, // Repeat
- KMC_ACT_STATEBIT, GKEYSTATE_REPEAT_BIT|KMC_BIT_CLEAR,
- KMC_TEST_LASTCODE, 0x01,
- KMC_ACT_STATEBIT, GKEYSTATE_REPEAT_BIT,
- // 0 - 9
- /* 22 */KMC_RECORDSTART, 7, // Alt 0-9
- KMC_TEST_ALT,
- KMC_TEST_CODERANGE, '0', '9',
- KMC_ACT_CHARADD, 10,
- KMC_ACT_STOP,
- /* 23 */KMC_RECORDSTART, 17, // Shifted 0-9
- KMC_TEST_SHIFT,
- KMC_TEST_CODERANGE, '0', '9',
- KMC_ACT_CHARTABLE, 10, ')', '!', '@', '#', '$', '%', '^', '&', '*', '(',
- KMC_ACT_DONE,
- /* 24 */KMC_RECORDSTART, 5, // 0 - 9
- KMC_TEST_CODERANGE, '0', '9',
- KMC_ACT_CHARCODE,
- KMC_ACT_DONE,
- // A - Z
- /* 25 */KMC_RECORDSTART, 7, // Control A-Z
- KMC_TEST_CTRL,
- KMC_TEST_CODERANGE, 'A', 'Z',
- KMC_ACT_CHARRANGE, 1,
- KMC_ACT_DONE,
- /* 26 */KMC_RECORDSTART, 7, // No Caps A-Z
- KMC_TEST_NOCAPS,
- KMC_TEST_CODERANGE, 'A', 'Z',
- KMC_ACT_CHARRANGE, 'a',
- KMC_ACT_DONE,
- /* 27 */KMC_RECORDSTART, 5, // Caps A-Z
- KMC_TEST_CODERANGE, 'A', 'Z',
- KMC_ACT_CHARCODE,
- KMC_ACT_DONE,
- // Number pad
- /* 28 */KMC_RECORDSTART, 7, // Alt Number pad
- KMC_TEST_ALT,
- KMC_TEST_CODERANGE, VK_NUMPAD0, VK_NUMPAD9,
- KMC_ACT_CHARADD, 10,
- KMC_ACT_STOP,
- /* 29 */KMC_RECORDSTART, 5,
- KMC_TEST_ALT,
- KMC_TEST_CODERANGE, VK_MULTIPLY, VK_DIVIDE,
- KMC_ACT_STOP,
- /* 30 */KMC_RECORDSTART, 7, // Number pad with Numlock
- KMC_TEST_NUMLOCK,
- KMC_TEST_CODERANGE, VK_NUMPAD0, VK_NUMPAD9,
- KMC_ACT_CHARRANGE, '0',
- KMC_ACT_DONE,
- /* 31 */KMC_RECORDSTART, 13,
- KMC_TEST_NUMLOCK,
- KMC_TEST_CODERANGE, VK_MULTIPLY, VK_DIVIDE,
- KMC_ACT_CHARTABLE, 6, '*', '+', GKEY_ENTER, '-', '.', '/',
- KMC_ACT_DONE,
- /* 32 */KMC_RECORDSTART, 4, // Number pad with no Numlock
- KMC_TEST_CODE, VK_NUMPAD5,
- KMC_ACT_RESET,
- KMC_ACT_STOP,
- /* 33 */KMC_RECORDSTART, 12,
- KMC_TEST_CODERANGE, VK_MULTIPLY, VK_DIVIDE,
- KMC_ACT_CHARTABLE, 6, '*', '+', GKEY_ENTER, '-', GKEY_DEL, '/',
- KMC_ACT_DONE,
- /* 34 */KMC_RECORDSTART, 18,
- KMC_TEST_CODERANGE, VK_NUMPAD0, VK_NUMPAD9,
- KMC_ACT_STATEBIT, GKEYSTATE_SPECIAL_BIT,
- KMC_ACT_CHARTABLE, 10, GKEY_INSERT, GKEY_END, GKEY_DOWN, GKEY_PAGEDOWN, GKEY_LEFT, '5', GKEY_RIGHT, GKEY_HOME, GKEY_UP, GKEY_PAGEUP,
- KMC_ACT_DONE,
- // Symbols
- /* 35 */KMC_RECORDSTART, 14, // Shifted Symbols
- KMC_TEST_SHIFT,
- KMC_TEST_CODERANGE, VK_OEM_1, VK_OEM_3,
- KMC_ACT_CHARTABLE, 7, ':', '+', '<', '_', '>', '?', '~',
- KMC_ACT_DONE,
- /* 36 */KMC_RECORDSTART, 11,
- KMC_TEST_SHIFT,
- KMC_TEST_CODERANGE, VK_OEM_4, VK_OEM_7,
- KMC_ACT_CHARTABLE, 4, '{', '|', '}', '"',
- KMC_ACT_DONE,
- /* 37 */KMC_RECORDSTART, 13, // Non-shifted Symbols
- KMC_TEST_CODERANGE, VK_OEM_1, VK_OEM_3,
- KMC_ACT_CHARTABLE, 7, ';', '=', ',', '-', '.', '/', '`',
- KMC_ACT_DONE,
- /* 38 */KMC_RECORDSTART, 10,
- KMC_TEST_CODERANGE, VK_OEM_4, VK_OEM_7,
- KMC_ACT_CHARTABLE, 4, '[', '\\', ']', '\'',
- KMC_ACT_DONE,
- // Special Keys
- // Extra special keys like Media and Browser keys are still to be implemented.
- /* 39 */KMC_RECORDSTART, 17, // Normal Control Type Keys
- KMC_TEST_CODETABLE, 6, VK_BACK, VK_TAB, VK_RETURN, VK_ESCAPE, VK_SPACE, VK_DELETE,
- KMC_ACT_CHARTABLE, 6, GKEY_BACKSPACE, GKEY_TAB, GKEY_ENTER, GKEY_ESC, GKEY_SPACE, GKEY_DEL,
- KMC_ACT_DONE,
- /* 40 */KMC_RECORDSTART, 35, // Special Keys
- KMC_TEST_CODETABLE, 14, VK_PRIOR, VK_NEXT,
- VK_HOME, VK_END,
- VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN,
- VK_INSERT,
- VK_SNAPSHOT, VK_SLEEP, VK_PAUSE, VK_CANCEL,
- VK_APPS,
- KMC_ACT_STATEBIT, GKEYSTATE_SPECIAL_BIT,
- KMC_ACT_CHARTABLE, 14, GKEY_PAGEUP, GKEY_PAGEDOWN,
- GKEY_HOME, GKEY_END,
- GKEY_LEFT, GKEY_RIGHT, GKEY_UP, GKEY_DOWN,
- GKEY_INSERT,
- GKEY_PRINTSCREEN, GKEY_SLEEP, GKEY_CTRLPAUSE, GKEY_CTRLBREAK,
- GKEY_RIGHTCLICKKEY,
- KMC_ACT_DONE,
- /* 41 */KMC_RECORDSTART, 8, // F1 .. F15
- KMC_TEST_CODERANGE, VK_F1, VK_F15,
- KMC_ACT_STATEBIT, GKEYSTATE_SPECIAL_BIT,
- KMC_ACT_CHARRANGE, GKEY_FN1,
- KMC_ACT_DONE,
- // Anything else
- /* 40 */KMC_RECORDSTART, 1, // Just send the scan code to the user
- KMC_ACT_DONE,
- // EOF
- KMC_RECORDSTART, 0
- };
- #elif !GKEYBOARD_LAYOUT_OFF
- #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT
- #warning "The WIN32 keyboard driver is not using the layout engine. If no other keyboard is using it consider defining GKEYBOARD_LAYOUT_OFF=TRUE to save code size."
- #elif GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_MACRO
- COMPILER_WARNING("The WIN32 keyboard driver is not using the layout engine. If no other keyboard is using it consider defining GKEYBOARD_LAYOUT_OFF=TRUE to save code size.")
- #endif
- #endif
- // Forward definitions
- static bool_t Win32KeyboardInit(GKeyboard *k, unsigned driverinstance);
- static int Win32KeyboardGetData(GKeyboard *k, uint8_t *pch, int sz);
- const GKeyboardVMT const GKEYBOARD_DRIVER_VMT[1] = {{
- {
- GDRIVER_TYPE_KEYBOARD,
- GKEYBOARD_VFLG_NOPOLL, // GKEYBOARD_VFLG_DYNAMICONLY
- sizeof(GKeyboard),
- _gkeyboardInitDriver, _gkeyboardPostInitDriver, _gkeyboardDeInitDriver
- },
- // The Win32 keyboard layout
- #if GKEYBOARD_WIN32_NO_LAYOUT
- 0,
- #else
- GKEYBOARD_WIN32_DEFAULT_LAYOUT,
- #endif
- Win32KeyboardInit, // init
- 0, // deinit
- Win32KeyboardGetData, // getdata
- 0 // putdata void (*putdata)(GKeyboard *k, char ch); Optional
- }};
- static int keypos;
- static uint8_t keybuffer[8];
- static GKeyboard *keyboard;
- #endif
- static DWORD winThreadId;
- static volatile bool_t QReady;
- static HANDLE drawMutex;
- static HWND hWndParent = 0;
- /*===========================================================================*/
- /* Driver local routines . */
- /*===========================================================================*/
- #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
- #define WIN32_BUTTON_AREA 16
- #else
- #define WIN32_BUTTON_AREA 0
- #endif
- #define APP_NAME "uGFX"
- typedef struct winPriv {
- HWND hwnd;
- HDC dcBuffer;
- HBITMAP dcBitmap;
- HBITMAP dcOldBitmap;
- #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- coord_t mousex, mousey;
- uint16_t mousebuttons;
- GMouse *mouse;
- bool_t mouseenabled;
- void (*capfn)(void * hWnd, GDisplay *g, uint16_t buttons, coord_t x, coord_t y);
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
- uint8_t toggles;
- #endif
- #if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
- coord_t x0, y0, x1, y1;
- coord_t x, y;
- #endif
- } winPriv;
- void gfxEmulatorSetParentWindow(void *hwnd) {
- hWndParent = (HWND)hwnd;
- }
- #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- void gfxEmulatorMouseInject(GDisplay *g, uint16_t buttons, coord_t x, coord_t y) {
- winPriv * priv;
-
- priv = (winPriv *)g->priv;
- priv->mousebuttons = buttons;
- priv->mousex = x;
- priv->mousey = y;
- if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL)) // For normal setup this is always TRUE
- _gmouseWakeup(priv->mouse);
- }
- void gfxEmulatorMouseEnable(GDisplay *g, bool_t enabled) {
- ((winPriv *)g->priv)->mouseenabled = enabled;
- }
- void gfxEmulatorMouseCapture(GDisplay *g, void (*capfn)(void * hWnd, GDisplay *g, uint16_t buttons, coord_t x, coord_t y)) {
- ((winPriv *)g->priv)->capfn = capfn;
- }
- #endif
- static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
- {
- HDC dc;
- PAINTSTRUCT ps;
- GDisplay * g;
- winPriv * priv;
- #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- uint16_t btns;
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
- HBRUSH hbrOn, hbrOff;
- HPEN pen;
- RECT rect;
- HGDIOBJ old;
- POINT p;
- coord_t pos;
- uint8_t bit;
- #endif
- switch (Msg) {
- case WM_CREATE:
- // Get our GDisplay structure and attach it to the window
- g = (GDisplay *)((LPCREATESTRUCT)lParam)->lpCreateParams;
- priv = (winPriv *)g->priv;
- SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)g);
- // Fill in the private area
- priv->hwnd = hWnd;
- dc = GetDC(hWnd);
- priv->dcBitmap = CreateCompatibleBitmap(dc, g->g.Width, g->g.Height);
- priv->dcBuffer = CreateCompatibleDC(dc);
- ReleaseDC(hWnd, dc);
- priv->dcOldBitmap = SelectObject(priv->dcBuffer, priv->dcBitmap);
- // Mark the window as ready to go
- g->flags |= GDISP_FLG_READY;
- break;
- #if GFX_USE_GINPUT && (GINPUT_NEED_MOUSE || GINPUT_NEED_TOGGLE)
- case WM_LBUTTONDOWN:
- // Get our GDisplay structure
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- // Handle mouse down on the window
- #if GINPUT_NEED_MOUSE
- if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
- btns = priv->mousebuttons;
- btns |= GINPUT_MOUSE_BTN_LEFT;
- goto mousemove;
- }
- #endif
- // Handle mouse down on the toggle area
- #if GINPUT_NEED_TOGGLE
- if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) {
- bit = 1 << ((coord_t)LOWORD(lParam)*8/g->g.Width);
- priv->toggles ^= bit;
- rect.left = 0;
- rect.right = GDISP_SCREEN_WIDTH;
- rect.top = GDISP_SCREEN_HEIGHT;
- rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
- InvalidateRect(hWnd, &rect, FALSE);
- UpdateWindow(hWnd);
- #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
- ginputToggleWakeup();
- #endif
- }
- #endif
- break;
- case WM_LBUTTONUP:
- // Get our GDisplay structure
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- // Handle mouse up on the toggle area
- #if GINPUT_NEED_TOGGLE
- if ((g->flags & GDISP_FLG_HASTOGGLE)) {
- if ((priv->toggles & 0x0F)) {
- priv->toggles &= ~0x0F;
- rect.left = 0;
- rect.right = GDISP_SCREEN_WIDTH;
- rect.top = GDISP_SCREEN_HEIGHT;
- rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
- InvalidateRect(hWnd, &rect, FALSE);
- UpdateWindow(hWnd);
- #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
- ginputToggleWakeup();
- #endif
- }
- }
- #endif
- // Handle mouse up on the window
- #if GINPUT_NEED_MOUSE
- if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
- btns = priv->mousebuttons;
- btns &= ~GINPUT_MOUSE_BTN_LEFT;
- goto mousemove;
- }
- #endif
- break;
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- case WM_MBUTTONDOWN:
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
- btns = priv->mousebuttons;
- btns |= GINPUT_MOUSE_BTN_MIDDLE;
- goto mousemove;
- }
- break;
- case WM_MBUTTONUP:
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
- btns = priv->mousebuttons;
- btns &= ~GINPUT_MOUSE_BTN_MIDDLE;
- goto mousemove;
- }
- break;
- case WM_RBUTTONDOWN:
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
- btns = priv->mousebuttons;
- btns |= GINPUT_MOUSE_BTN_RIGHT;
- goto mousemove;
- }
- break;
- case WM_RBUTTONUP:
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
- btns = priv->mousebuttons;
- btns &= ~GINPUT_MOUSE_BTN_RIGHT;
- goto mousemove;
- }
- break;
- case WM_MOUSEMOVE:
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT)
- break;
- btns = priv->mousebuttons;
- mousemove:
- if (priv->capfn)
- priv->capfn(hWnd, g, btns, (coord_t)LOWORD(lParam), (coord_t)HIWORD(lParam));
- if (priv->mouseenabled) {
- priv->mousebuttons = btns;
- priv->mousex = (coord_t)LOWORD(lParam);
- priv->mousey = (coord_t)HIWORD(lParam);
- if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL)) // For normal setup this is always TRUE
- _gmouseWakeup(priv->mouse);
- }
- break;
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD
- case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
- case WM_KEYDOWN:
- case WM_KEYUP:
- // A layout is being used: Send scan codes to the keyboard buffer
- if (keyboard && keyboard->pLayout && keypos < (int)sizeof(keybuffer)-1 && (wParam & 0xFF) > 0x01) {
- if (Msg == WM_KEYUP || Msg == WM_SYSKEYUP)
- keybuffer[keypos++] = 0x00; // Keyup
- else if (HIWORD(lParam) & KF_REPEAT)
- keybuffer[keypos++] = 0x01; // Repeat
- keybuffer[keypos++] = wParam;
- if ((gkvmt(keyboard)->d.flags & GKEYBOARD_VFLG_NOPOLL)) // For normal setup this is always TRUE
- _gkeyboardWakeup(keyboard);
- }
- return 0;
- case WM_CHAR:
- // A layout is not being used: Send character codes to the keyboard buffer
- if (keyboard && !keyboard->pLayout && keypos < (int)sizeof(keybuffer)) {
- wchar_t w;
- int len;
- // Convert from a UTF16 character to a UTF8 string.
- w = wParam;
- len = WideCharToMultiByte(CP_UTF8, 0, &w, 1, (char *)(keybuffer+keypos), sizeof(keybuffer)-keypos, 0, 0);
- keypos += len;
- if (len && (gkvmt(keyboard)->d.flags & GKEYBOARD_VFLG_NOPOLL)) // For normal setup this is always TRUE
- _gkeyboardWakeup(keyboard);
- }
- return 0;
- /*
- case WM_DEADCHAR:
- case WM_SYSCHAR:
- case WM_SYSDEADCHAR:
- break;
- */
- #endif
- case WM_ERASEBKGND:
- // Pretend we have erased the background.
- // We know we don't really need to do this as we
- // redraw the entire surface in the WM_PAINT handler.
- return TRUE;
- case WM_PAINT:
- // Get our GDisplay structure
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- // Paint the main window area
- WaitForSingleObject(drawMutex, INFINITE);
- dc = BeginPaint(hWnd, &ps);
- BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
- ps.rcPaint.right - ps.rcPaint.left,
- (ps.rcPaint.bottom > GDISP_SCREEN_HEIGHT ? GDISP_SCREEN_HEIGHT : ps.rcPaint.bottom) - ps.rcPaint.top,
- priv->dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
- // Paint the toggle area
- #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
- if (ps.rcPaint.bottom >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) {
- pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
- hbrOn = CreateSolidBrush(RGB(0, 0, 255));
- hbrOff = CreateSolidBrush(RGB(128, 128, 128));
- old = SelectObject(dc, pen);
- MoveToEx(dc, 0, GDISP_SCREEN_HEIGHT, &p);
- LineTo(dc, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
- for(pos = 0, bit=1; pos < GDISP_SCREEN_WIDTH; pos=rect.right, bit <<= 1) {
- rect.left = pos;
- rect.right = pos + GDISP_SCREEN_WIDTH/8;
- rect.top = GDISP_SCREEN_HEIGHT;
- rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
- FillRect(dc, &rect, (priv->toggles & bit) ? hbrOn : hbrOff);
- if (pos > 0) {
- MoveToEx(dc, rect.left, rect.top, &p);
- LineTo(dc, rect.left, rect.bottom);
- }
- }
- DeleteObject(hbrOn);
- DeleteObject(hbrOff);
- SelectObject(dc, old);
- }
- #endif
- EndPaint(hWnd, &ps);
- ReleaseMutex(drawMutex);
- break;
- case WM_DESTROY:
- // Get our GDisplay structure
- g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
- priv = (winPriv *)g->priv;
- // Restore the window and free our bitmaps
- SelectObject(priv->dcBuffer, priv->dcOldBitmap);
- DeleteDC(priv->dcBuffer);
- DeleteObject(priv->dcBitmap);
- // Cleanup the private area
- gfxFree(priv);
- // Quit the application
- PostQuitMessage(0);
- // Actually the above doesn't work (who knows why)
- ExitProcess(0);
- break;
- default:
- return DefWindowProc(hWnd, Msg, wParam, lParam);
- }
- return 0;
- }
- static DWORD WINAPI WindowThread(void *param) {
- (void)param;
- MSG msg;
- // Establish this thread as a message queue thread
- winThreadId = GetCurrentThreadId();
- PeekMessage(&msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
- QReady = TRUE;
- // Create the window class
- {
- WNDCLASS wc;
- ATOM winClass;
- wc.style = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC;
- wc.lpfnWndProc = (WNDPROC)myWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = GetModuleHandle(0);
- wc.hIcon = LoadIcon(0, IDI_APPLICATION);
- wc.hCursor = LoadCursor(0, IDC_ARROW);
- wc.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = 0;
- wc.lpszClassName = APP_NAME;
- winClass = RegisterClass(&wc);
- assert(winClass != 0);
- }
- do {
- // This is a high priority task - make sure other tasks get a go.
- Sleep(1);
- while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
- // Is this our special thread message to create a new window?
- if (!msg.hwnd && msg.message == WM_USER) {
- RECT rect;
- GDisplay *g;
- g = (GDisplay *)msg.lParam;
- // Set the window rectangle
- rect.top = 0; rect.bottom = g->g.Height;
- rect.left = 0; rect.right = g->g.Width;
- #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
- if ((g->flags & GDISP_FLG_HASTOGGLE))
- rect.bottom += WIN32_BUTTON_AREA;
- #endif
- AdjustWindowRect(&rect, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0);
- // Create the window
- msg.hwnd = CreateWindow(APP_NAME, "", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_BORDER, msg.wParam*DISPLAY_X_OFFSET, msg.wParam*DISPLAY_Y_OFFSET,
- rect.right-rect.left, rect.bottom-rect.top,
- hWndParent, 0,
- GetModuleHandle(0), g);
- assert(msg.hwnd != 0);
- // Or just a normal window message
- } else {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- } while (msg.message != WM_QUIT);
- ExitProcess(0);
- return msg.wParam;
- }
- /*===========================================================================*/
- /* Driver exported functions. */
- /*===========================================================================*/
- LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
- winPriv * priv;
- char buf[132];
- // Initialise the window thread and the window class (if it hasn't been done already)
- if (!QReady) {
- HANDLE hth;
- // Create the draw mutex
- drawMutex = CreateMutex(0, FALSE, 0);
- // Create the thread
- if (!(hth = CreateThread(0, 0, WindowThread, 0, CREATE_SUSPENDED, 0)))
- return FALSE;
- SetThreadPriority(hth, THREAD_PRIORITY_ABOVE_NORMAL);
- ResumeThread(hth);
- CloseHandle(hth);
- // Wait for our thread to be ready
- while (!QReady)
- Sleep(1);
- }
- // Initialise the GDISP structure
- g->g.Orientation = GDISP_ROTATE_0;
- g->g.Powermode = powerOn;
- g->g.Backlight = 100;
- g->g.Contrast = 50;
- g->g.Width = GDISP_SCREEN_WIDTH;
- g->g.Height = GDISP_SCREEN_HEIGHT;
- // Turn on toggles for the first GINPUT_TOGGLE_CONFIG_ENTRIES windows
- #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
- if (g->controllerdisplay < GINPUT_TOGGLE_CONFIG_ENTRIES) {
- g->flags |= GDISP_FLG_HASTOGGLE;
- toggleWindow = g;
- }
- #endif
- // Create a private area for this window
- priv = gfxAlloc(sizeof(winPriv));
- assert(priv != 0);
- memset(priv, 0, sizeof(winPriv));
- g->priv = priv;
- #if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
- // Initialise with an invalid window
- g->flags &= ~GDISP_FLG_WSTREAM;
- #endif
- g->board = 0; // no board interface for this controller
- // Create the window in the message thread
- PostThreadMessage(winThreadId, WM_USER, (WPARAM)g->controllerdisplay, (LPARAM)g);
- // Wait for the window creation to complete (for safety)
- while(!(((volatile GDisplay *)g)->flags & GDISP_FLG_READY))
- Sleep(1);
- // Create the associated mouse
- #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- priv->mouseenabled = hWndParent ? FALSE : TRUE;
- priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g);
- #endif
- sprintf(buf, APP_NAME " - %u", g->systemdisplay+1);
- SetWindowText(priv->hwnd, buf);
- ShowWindow(priv->hwnd, SW_SHOW);
- UpdateWindow(priv->hwnd);
- return TRUE;
- }
- #if GDISP_HARDWARE_FLUSH
- LLDSPEC void gdisp_lld_flush(GDisplay *g) {
- winPriv * priv;
- priv = g->priv;
- UpdateWindow(priv->hwnd);
- }
- #endif
- #if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
- void BAD_PARAMETER(const char *msg) {
- fprintf(stderr, "%s\n", msg);
- }
- #endif
- #if GDISP_HARDWARE_STREAM_WRITE
- LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
- winPriv * priv;
- if (g->flags & GDISP_FLG_WSTREAM)
- BAD_PARAMETER("write_start: already in streaming mode");
- if (g->p.cx <= 0 || g->p.cy <= 0 || g->p.x < 0 || g->p.y < 0 || g->p.x+g->p.cx > g->g.Width || g->p.y+g->p.cy > g->g.Height)
- BAD_PARAMETER("write_start: bad window parameter");
- priv = g->priv;
- priv->x0 = g->p.x; priv->x1 = g->p.x + g->p.cx - 1;
- priv->y0 = g->p.y; priv->y1 = g->p.y + g->p.cy - 1;
- #if GDISP_HARDWARE_STREAM_POS
- priv->x = g->p.x-1; // Make sure these values are invalid (for testing)
- priv->y = g->p.y-1;
- #else
- priv->x = g->p.x;
- priv->y = g->p.y;
- #endif
- g->flags |= GDISP_FLG_WSTREAM;
- g->flags &= ~GDISP_FLG_WRAPPED;
- }
- LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
- winPriv * priv;
- int x, y;
- COLORREF color;
- priv = g->priv;
- color = gdispColor2Native(g->p.color);
- if (!(g->flags & GDISP_FLG_WSTREAM))
- BAD_PARAMETER("write_color: not in streaming mode");
- if (priv->x < priv->x0 || priv->x > priv->x1 || priv->y < priv->y0 || priv->y > priv->y1)
- BAD_PARAMETER("write_color: cursor outside streaming area");
- if (g->flags & GDISP_FLG_WRAPPED) {
- BAD_PARAMETER("write_color: Warning - Area wrapped.");
- g->flags &= ~GDISP_FLG_WRAPPED;
- }
- #if GDISP_NEED_CONTROL
- switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- default:
- x = priv->x;
- y = priv->y;
- break;
- case GDISP_ROTATE_90:
- x = priv->y;
- y = g->g.Width - 1 - priv->x;
- break;
- case GDISP_ROTATE_180:
- x = g->g.Width - 1 - priv->x;
- y = g->g.Height - 1 - priv->y;
- break;
- case GDISP_ROTATE_270:
- x = g->g.Height - 1 - priv->y;
- y = priv->x;
- break;
- }
- #else
- x = priv->x;
- y = priv->y;
- #endif
- // Draw the pixel on the screen and in the buffer.
- WaitForSingleObject(drawMutex, INFINITE);
- SetPixel(priv->dcBuffer, x, y, color);
- #if GDISP_WIN32_USE_INDIRECT_UPDATE
- ReleaseMutex(drawMutex);
- {
- RECT r;
- r.left = x; r.right = x+1;
- r.top = y; r.bottom = y+1;
- InvalidateRect(priv->hwnd, &r, FALSE);
- }
- #else
- {
- HDC dc;
- dc = GetDC(priv->hwnd);
- SetPixel(dc, x, y, color);
- ReleaseDC(priv->hwnd, dc);
- ReleaseMutex(drawMutex);
- }
- #endif
- // Update the cursor
- if (++priv->x > priv->x1) {
- priv->x = priv->x0;
- if (++priv->y > priv->y1) {
- g->flags |= GDISP_FLG_WRAPPED;
- priv->y = priv->y0;
- }
- }
- }
- LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
- if (!(g->flags & GDISP_FLG_WSTREAM))
- BAD_PARAMETER("write_stop: not in streaming mode");
- g->flags &= ~GDISP_FLG_WSTREAM;
- }
- #if GDISP_HARDWARE_STREAM_POS
- LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
- winPriv * priv;
- priv = g->priv;
- if (!(g->flags & GDISP_FLG_WSTREAM))
- BAD_PARAMETER("write_pos: not in streaming mode");
- if (g->p.x < priv->x0 || g->p.x > priv->x1 || g->p.y < priv->y0 || g->p.y > priv->y1)
- BAD_PARAMETER("write_color: new cursor outside streaming area");
- priv->x = g->p.x;
- priv->y = g->p.y;
- }
- #endif
- #endif
- #if GDISP_HARDWARE_STREAM_READ
- LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
- winPriv * priv;
- if (g->flags & GDISP_FLG_WSTREAM)
- BAD_PARAMETER("read_start: already in streaming mode");
- if (g->p.cx <= 0 || g->p.cy <= 0 || g->p.x < 0 || g->p.y < 0 || g->p.x+g->p.cx > g->g.Width || g->p.y+g->p.cy > g->g.Height)
- BAD_PARAMETER("read_start: bad window parameter");
- priv = g->priv;
- priv->x0 = g->p.x; priv->x1 = g->p.x + g->p.cx - 1;
- priv->y0 = g->p.y; priv->y1 = g->p.y + g->p.cy - 1;
- priv->x = g->p.x;
- priv->y = g->p.y;
- g->flags |= GDISP_FLG_WSTREAM;
- g->flags &= ~GDISP_FLG_WRAPPED;
- }
- LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
- winPriv * priv;
- COLORREF color;
- priv = g->priv;
- if (!(g->flags & GDISP_FLG_WSTREAM))
- BAD_PARAMETER("read_color: not in streaming mode");
- if (priv->x < priv->x0 || priv->x > priv->x1 || priv->y < priv->y0 || priv->y > priv->y1)
- BAD_PARAMETER("read_color: cursor outside streaming area");
- if (g->flags & GDISP_FLG_WRAPPED) {
- BAD_PARAMETER("read_color: Warning - Area wrapped.");
- g->flags &= ~GDISP_FLG_WRAPPED;
- }
- WaitForSingleObject(drawMutex, INFINITE);
- #if GDISP_NEED_CONTROL
- switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- default:
- color = GetPixel(priv->dcBuffer, priv->x, priv->y);
- break;
- case GDISP_ROTATE_90:
- color = GetPixel(priv->dcBuffer, priv->y, g->g.Width - 1 - priv->x);
- break;
- case GDISP_ROTATE_180:
- color = GetPixel(priv->dcBuffer, g->g.Width - 1 - priv->x, g->g.Height - 1 - priv->y);
- break;
- case GDISP_ROTATE_270:
- color = GetPixel(priv->dcBuffer, g->g.Height - 1 - priv->y, priv->x);
- break;
- }
- #else
- color = GetPixel(priv->dcBuffer, priv->x, priv->y);
- #endif
- ReleaseMutex(drawMutex);
- // Update the cursor
- if (++priv->x > priv->x1) {
- priv->x = priv->x0;
- if (++priv->y > priv->y1) {
- g->flags |= GDISP_FLG_WRAPPED;
- priv->y = priv->y0;
- }
- }
- return gdispNative2Color(color);
- }
- LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
- if (!(g->flags & GDISP_FLG_WSTREAM))
- BAD_PARAMETER("write_stop: not in streaming mode");
- g->flags &= ~GDISP_FLG_WSTREAM;
- }
- #endif
- #if GDISP_HARDWARE_DRAWPIXEL
- LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
- winPriv * priv;
- int x, y;
- COLORREF color;
- priv = g->priv;
- color = gdispColor2Native(g->p.color);
- #if GDISP_NEED_CONTROL
- switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- default:
- x = g->p.x;
- y = g->p.y;
- break;
- case GDISP_ROTATE_90:
- x = g->p.y;
- y = g->g.Width - 1 - g->p.x;
- break;
- case GDISP_ROTATE_180:
- x = g->g.Width - 1 - g->p.x;
- y = g->g.Height - 1 - g->p.y;
- break;
- case GDISP_ROTATE_270:
- x = g->g.Height - 1 - g->p.y;
- y = g->p.x;
- break;
- }
- #else
- x = g->p.x;
- y = g->p.y;
- #endif
- // Draw the pixel on the screen and in the buffer.
- WaitForSingleObject(drawMutex, INFINITE);
- SetPixel(priv->dcBuffer, x, y, color);
- #if GDISP_WIN32_USE_INDIRECT_UPDATE
- ReleaseMutex(drawMutex);
- {
- RECT r;
- r.left = x; r.right = x+1;
- r.top = y; r.bottom = y+1;
- InvalidateRect(priv->hwnd, &r, FALSE);
- }
- #else
- {
- HDC dc;
- dc = GetDC(priv->hwnd);
- SetPixel(dc, x, y, color);
- ReleaseDC(priv->hwnd, dc);
- ReleaseMutex(drawMutex);
- }
- #endif
- }
- #endif
- /* ---- Optional Routines ---- */
- #if GDISP_HARDWARE_FILLS
- LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
- winPriv * priv;
- RECT rect;
- HBRUSH hbr;
- COLORREF color;
- priv = g->priv;
- color = gdispColor2Native(g->p.color);
- hbr = CreateSolidBrush(color);
- #if GDISP_NEED_CONTROL
- switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- default:
- rect.top = g->p.y;
- rect.bottom = rect.top + g->p.cy;
- rect.left = g->p.x;
- rect.right = rect.left + g->p.cx;
- break;
- case GDISP_ROTATE_90:
- rect.bottom = g->g.Width - g->p.x;
- rect.top = rect.bottom - g->p.cx;
- rect.left = g->p.y;
- rect.right = rect.left + g->p.cy;
- break;
- case GDISP_ROTATE_180:
- rect.bottom = g->g.Height - g->p.y;
- rect.top = rect.bottom - g->p.cy;
- rect.right = g->g.Width - g->p.x;
- rect.left = rect.right - g->p.cx;
- break;
- case GDISP_ROTATE_270:
- rect.top = g->p.x;
- rect.bottom = rect.top + g->p.cx;
- rect.right = g->g.Height - g->p.y;
- rect.left = rect.right - g->p.cy;
- break;
- }
- #else
- rect.top = g->p.y;
- rect.bottom = rect.top + g->p.cy;
- rect.left = g->p.x;
- rect.right = rect.left + g->p.cx;
- #endif
- WaitForSingleObject(drawMutex, INFINITE);
- FillRect(priv->dcBuffer, &rect, hbr);
- #if GDISP_WIN32_USE_INDIRECT_UPDATE
- ReleaseMutex(drawMutex);
- InvalidateRect(priv->hwnd, &rect, FALSE);
- #else
- {
- HDC dc;
- dc = GetDC(priv->hwnd);
- FillRect(dc, &rect, hbr);
- ReleaseDC(priv->hwnd, dc);
- ReleaseMutex(drawMutex);
- }
- #endif
- DeleteObject(hbr);
- }
- #endif
- #if GDISP_HARDWARE_BITFILLS && GDISP_NEED_CONTROL
- static pixel_t *rotateimg(GDisplay *g, const pixel_t *buffer) {
- pixel_t *dstbuf;
- pixel_t *dst;
- const pixel_t *src;
- size_t sz;
- coord_t i, j;
- // Allocate the destination buffer
- sz = (size_t)g->p.cx * (size_t)g->p.cy;
- if (!(dstbuf = (pixel_t *)malloc(sz * sizeof(pixel_t))))
- return 0;
- // Copy the bits we need
- switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- default:
- return 0; // not handled as it doesn't need to be.
- case GDISP_ROTATE_90:
- for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) {
- dst = dstbuf+sz-g->p.cy+j;
- for(i = 0; i < g->p.cx; i++, dst -= g->p.cy)
- *dst = *src++;
- }
- break;
- case GDISP_ROTATE_180:
- for(dst = dstbuf+sz, src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx)
- for(i = 0; i < g->p.cx; i++)
- *--dst = *src++;
- break;
- case GDISP_ROTATE_270:
- for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) {
- dst = dstbuf+g->p.cy-j-1;
- for(i = 0; i < g->p.cx; i++, dst += g->p.cy)
- *dst = *src++;
- }
- break;
- }
- return dstbuf;
- }
- #endif
- #if GDISP_HARDWARE_BITFILLS
- #if COLOR_SYSTEM != GDISP_COLORSYSTEM_TRUECOLOR || COLOR_TYPE_BITS <= 8
- #error "GDISP Win32: This driver's bitblit currently only supports true-color with bit depths > 8 bits."
- #endif
- LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
- winPriv * priv;
- pixel_t * buffer;
- RECT rect;
- BITMAPV4HEADER bmpInfo;
- // Make everything relative to the start of the line
- priv = g->priv;
- buffer = g->p.ptr;
- buffer += g->p.x2*g->p.y1;
- memset(&bmpInfo, 0, sizeof(bmpInfo));
- bmpInfo.bV4Size = sizeof(bmpInfo);
- bmpInfo.bV4Planes = 1;
- bmpInfo.bV4BitCount = COLOR_TYPE_BITS;
- bmpInfo.bV4AlphaMask = 0;
- bmpInfo.bV4RedMask = RGB2COLOR(255,0,0);
- bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0);
- bmpInfo.bV4BlueMask = RGB2COLOR(0,0,255);
- bmpInfo.bV4V4Compression = BI_BITFIELDS;
- bmpInfo.bV4XPelsPerMeter = 3078;
- bmpInfo.bV4YPelsPerMeter = 3078;
- bmpInfo.bV4ClrUsed = 0;
- bmpInfo.bV4ClrImportant = 0;
- bmpInfo.bV4CSType = 0; //LCS_sRGB;
- #if GDISP_NEED_CONTROL
- switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- default:
- bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t);
- bmpInfo.bV4Width = g->p.x2;
- bmpInfo.bV4Height = -g->p.cy; /* top-down image */
- rect.top = g->p.y;
- rect.bottom = rect.top+g->p.cy;
- rect.left = g->p.x;
- rect.right = rect.left+g->p.cx;
- break;
- case GDISP_ROTATE_90:
- if (!(buffer = rotateimg(g, buffer))) return;
- bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
- bmpInfo.bV4Width = g->p.cy;
- bmpInfo.bV4Height = -g->p.cx; /* top-down image */
- rect.bottom = g->g.Width - g->p.x;
- rect.top = rect.bottom-g->p.cx;
- rect.left = g->p.y;
- rect.right = rect.left+g->p.cy;
- break;
- case GDISP_ROTATE_180:
- if (!(buffer = rotateimg(g, buffer))) return;
- bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
- bmpInfo.bV4Width = g->p.cx;
- bmpInfo.bV4Height = -g->p.cy; /* top-down image */
- rect.bottom = g->g.Height-1 - g->p.y;
- rect.top = rect.bottom-g->p.cy;
- rect.right = g->g.Width - g->p.x;
- rect.left = rect.right-g->p.cx;
- break;
- case GDISP_ROTATE_270:
- if (!(buffer = rotateimg(g, buffer))) return;
- bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
- bmpInfo.bV4Width = g->p.cy;
- bmpInfo.bV4Height = -g->p.cx; /* top-down image */
- rect.top = g->p.x;
- rect.bottom = rect.top+g->p.cx;
- rect.right = g->g.Height - g->p.y;
- rect.left = rect.right-g->p.cy;
- break;
- }
- #else
- bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t);
- bmpInfo.bV4Width = g->p.x2;
- bmpInfo.bV4Height = -g->p.cy; /* top-down image */
- rect.top = g->p.y;
- rect.bottom = rect.top+g->p.cy;
- rect.left = g->p.x;
- rect.right = rect.left+g->p.cx;
- #endif
- WaitForSingleObject(drawMutex, INFINITE);
- SetDIBitsToDevice(priv->dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
- #if GDISP_WIN32_USE_INDIRECT_UPDATE
- ReleaseMutex(drawMutex);
- InvalidateRect(priv->hwnd, &rect, FALSE);
- #else
- {
- HDC dc;
- dc = GetDC(priv->hwnd);
- SetDIBitsToDevice(dc, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
- ReleaseDC(priv->hwnd, dc);
- ReleaseMutex(drawMutex);
- }
- #endif
- #if GDISP_NEED_CONTROL
- if (buffer != (pixel_t *)g->p.ptr)
- free(buffer);
- #endif
- }
- #endif
- #if GDISP_HARDWARE_PIXELREAD
- LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
- winPriv * priv;
- COLORREF color;
- priv = g->priv;
- WaitForSingleObject(drawMutex, INFINITE);
- #if GDISP_NEED_CONTROL
- switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- default:
- color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
- break;
- case GDISP_ROTATE_90:
- color = GetPixel(priv->dcBuffer, g->p.y, g->g.Width - 1 - g->p.x);
- break;
- case GDISP_ROTATE_180:
- color = GetPixel(priv->dcBuffer, g->g.Width - 1 - g->p.x, g->g.Height - 1 - g->p.y);
- break;
- case GDISP_ROTATE_270:
- color = GetPixel(priv->dcBuffer, g->g.Height - 1 - g->p.y, g->p.x);
- break;
- }
- #else
- color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
- #endif
- ReleaseMutex(drawMutex);
- return gdispNative2Color(color);
- }
- #endif
- #if GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL
- LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g) {
- winPriv * priv;
- RECT rect;
- coord_t lines;
- priv = g->priv;
- #if GDISP_NEED_CONTROL
- switch(g->g.Orientation) {
- case GDISP_ROTATE_0:
- default:
- rect.top = g->p.y;
- rect.bottom = rect.top+g->p.cy;
- rect.left = g->p.x;
- rect.right = rect.left+g->p.cx;
- lines = -g->p.y1;
- goto vertical_scroll;
- case GDISP_ROTATE_90:
- rect.bottom = g->g.Width - g->p.x;
- rect.top = rect.bottom-g->p.cx;
- rect.left = g->p.y;
- rect.right = rect.left+g->p.cy;
- lines = -g->p.y1;
- goto horizontal_scroll;
- case GDISP_ROTATE_180:
- rect.bottom = g->g.Height - g->p.y;
- rect.top = rect.bottom-g->p.cy;
- rect.right = g->g.Width - g->p.x;
- rect.left = rect.right-g->p.cx;
- lines = g->p.y1;
- vertical_scroll:
- if (lines > 0) {
- rect.bottom -= lines;
- } else {
- rect.top -= lines;
- }
- if (g->p.cy >= lines && g->p.cy >= -lines) {
- WaitForSingleObject(drawMutex, INFINITE);
- ScrollDC(priv->dcBuffer, 0, lines, &rect, 0, 0, 0);
- #if GDISP_WIN32_USE_INDIRECT_UPDATE
- ReleaseMutex(drawMutex);
- InvalidateRect(priv->hwnd, &rect, FALSE);
- #else
- {
- HDC dc;
- dc = GetDC(priv->hwnd);
- ScrollDC(dc, 0, lines, &rect, 0, 0, 0);
- ReleaseDC(priv->hwnd, dc);
- ReleaseMutex(drawMutex);
- }
- #endif
- }
- break;
- case GDISP_ROTATE_270:
- rect.top = g->p.x;
- rect.bottom = rect.top+g->p.cx;
- rect.right = g->g.Height - g->p.y;
- rect.left = rect.right-g->p.cy;
- lines = g->p.y1;
- horizontal_scroll:
- if (lines > 0) {
- rect.right -= lines;
- } else {
- rect.left -= lines;
- }
- if (g->p.cy >= lines && g->p.cy >= -lines) {
- WaitForSingleObject(drawMutex, INFINITE);
- ScrollDC(priv->dcBuffer, lines, 0, &rect, 0, 0, 0);
- #if GDISP_WIN32_USE_INDIRECT_UPDATE
- ReleaseMutex(drawMutex);
- InvalidateRect(priv->hwnd, &rect, FALSE);
- #else
- {
- HDC dc;
- dc = GetDC(priv->hwnd);
- ScrollDC(dc, lines, 0, &rect, 0, 0, 0);
- ReleaseDC(priv->hwnd, dc);
- ReleaseMutex(drawMutex);
- }
- #endif
- }
- break;
- }
- #else
- rect.top = g->p.y;
- rect.bottom = rect.top+g->p.cy;
- rect.left = g->p.x;
- rect.right = rect.left+g->p.cx;
- lines = -g->p.y1;
- if (lines > 0) {
- rect.bottom -= lines;
- } else {
- rect.top -= lines;
- }
- if (g->p.cy >= lines && g->p.cy >= -lines) {
- WaitForSingleObject(drawMutex, INFINITE);
- ScrollDC(priv->dcBuffer, 0, lines, &rect, 0, 0, 0);
- #if GDISP_WIN32_USE_INDIRECT_UPDATE
- ReleaseMutex(drawMutex);
- InvalidateRect(priv->hwnd, &rect, FALSE);
- #else
- {
- HDC dc;
- dc = GetDC(priv->hwnd);
- ScrollDC(dc, 0, lines, &rect, 0, 0, 0);
- ReleaseDC(priv->hwnd, dc);
- ReleaseMutex(drawMutex);
- }
- #endif
- }
- #endif
- }
- #endif
- #if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
- LLDSPEC void gdisp_lld_control(GDisplay *g) {
- switch(g->p.x) {
- case GDISP_CONTROL_ORIENTATION:
- if (g->g.Orientation == (orientation_t)g->p.ptr)
- return;
- switch((orientation_t)g->p.ptr) {
- case GDISP_ROTATE_0:
- case GDISP_ROTATE_180:
- g->g.Width = GDISP_SCREEN_WIDTH;
- g->g.Height = GDISP_SCREEN_HEIGHT;
- break;
- case GDISP_ROTATE_90:
- case GDISP_ROTATE_270:
- g->g.Height = GDISP_SCREEN_WIDTH;
- g->g.Width = GDISP_SCREEN_HEIGHT;
- break;
- default:
- return;
- }
- g->g.Orientation = (orientation_t)g->p.ptr;
- return;
- /*
- case GDISP_CONTROL_POWER:
- case GDISP_CONTROL_BACKLIGHT:
- case GDISP_CONTROL_CONTRAST:
- */
- }
- }
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
- static bool_t Win32MouseInit(GMouse *m, unsigned driverinstance) {
- (void) m;
- (void) driverinstance;
- return TRUE;
- }
- static bool_t Win32MouseRead(GMouse *m, GMouseReading *pt) {
- GDisplay * g;
- winPriv * priv;
- g = m->display;
- priv = g->priv;
- pt->x = priv->mousex;
- pt->y = priv->mousey;
- pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 1 : 0;
- pt->buttons = priv->mousebuttons;
- #if GDISP_NEED_CONTROL
- // If the self-rotation has been set in the VMT then do that here (TESTING ONLY)
- if ((gmvmt(m)->d.flags & GMOUSE_VFLG_SELFROTATION)) { // For normal setup this is always False
- coord_t t;
- switch(gdispGGetOrientation(m->display)) {
- case GDISP_ROTATE_0:
- default:
- break;
- case GDISP_ROTATE_90:
- t = pt->x;
- pt->x = g->g.Width - 1 - pt->y;
- pt->y = t;
- break;
- case GDISP_ROTATE_180:
- pt->x = g->g.Width - 1 - pt->x;
- pt->y = g->g.Height - 1 - pt->y;
- break;
- case GDISP_ROTATE_270:
- t = pt->y;
- pt->y = g->g.Height - 1 - pt->x;
- pt->x = t;
- break;
- }
- }
- #endif
- return TRUE;
- }
- #endif /* GINPUT_NEED_MOUSE */
- #if GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD
- static bool_t Win32KeyboardInit(GKeyboard *k, unsigned driverinstance) {
- (void) driverinstance;
- // Only one please
- if (keyboard)
- return FALSE;
- keyboard = k;
- return TRUE;
- }
- static int Win32KeyboardGetData(GKeyboard *k, uint8_t *pch, int sz) {
- int i, j;
- (void) k;
- if (!keypos)
- return 0;
- for(i = 0; i < keypos && i < sz; i++)
- pch[i] = keybuffer[i];
- keypos -= i;
- for(j=0; j < keypos; j++)
- keybuffer[j] = keybuffer[i+j];
- return i;
- }
- #endif
- #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
- #if GINPUT_TOGGLE_CONFIG_ENTRIES > 1
- #error "GDISP Win32: GINPUT_TOGGLE_CONFIG_ENTRIES must be 1 until Toggles can use GDriver"
- #endif
- const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES];
- void ginput_lld_toggle_init(const GToggleConfig *ptc) {
- // Save the associated window struct
- //ptc->id = &GDISP_WIN32[ptc - GInputToggleConfigTable];
- ((GToggleConfig *)ptc)->id = 0;
- // We have 8 buttons per window.
- ((GToggleConfig *)ptc)->mask = 0xFF;
- // No inverse or special mode
- ((GToggleConfig *)ptc)->invert = 0x00;
- ((GToggleConfig *)ptc)->mode = 0;
- }
- unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc) {
- (void) ptc;
- // This should use ID
- if (!toggleWindow)
- return 0;
- return ((winPriv *)toggleWindow->priv)->toggles;
- //return ((winPriv *)((GDisplay *)(ptc->id))->priv)->toggles;
- }
- #endif /* GINPUT_NEED_TOGGLE */
- #endif /* GFX_USE_GDISP */
|