Войти
ПрограммированиеФорумОбщее

Linux - X11 (2 стр)

Страницы: 1 2 3 Следующая »
#15
14:01, 24 янв. 2009

Mi6gan
>А чем тебе SDL так не угодил? Если игрушка, то рано или поздно под винду порт понадобиться... будешь писать лишние строки кода для реализации этого всего >через WinAPI?
Поддержка ffb у джоев там есть? Да и не факт. что под винду нужно будет...


#16
14:29, 24 янв. 2009

> Поддержка ffb у джоев там есть?

с версии 1.3 вроде появилась, но она еще не вышла официально :)

#17
0:18, 25 янв. 2009

Andru
>с версии 1.3 вроде появилась, но она еще не вышла официально :)

Ага, а еще у них с версии 1.3 появляется коммерческая лицензия и чем все это кончится не ясно...

#18
19:39, 25 янв. 2009

Експерименты показали, что ключевым параметром функции XLookupKeysym() является третий, т.е. загадочный "index" о котором ман не объясняет ни слова.
Бит 0 задаёт верхний регистр (т.е. нажат ли шифт)
Бит 1 (внимание, фанфары!) задаёт (у меня) русскую раскладку.
Т.е. 0 - получаем латинские строчные, 1 - латинские заглавные, 2 - русские строчные, 3 - русские заглавные.

И теперь начинается самое интересное: откуда мне этот индекс брать, и как определить, какая раскладка сейчас выбрана в системе? Допустим, за шифтом я сам могу последить (а как же CapsLock?) - а текущую раскладку откуда узнать?
:(

#19
20:05, 25 янв. 2009

Cheb

XmbLookupString тебе в помощь. Правила создания XIC/XIM я не помню.

По уму, нужно смотреть на сорцы GDK/QT и драть реализацию с них.

#20
20:45, 25 янв. 2009

Оо-кей... Значит, раскладка передаётся в 13-м бите поля state структуры XKeyEvent. Чистый, незамутнённый метод тыка - и хоть бы строчка в хоть какой-нибудь бы документации >:(

Сле-едующая засада. В русской раскладке игнорируется пробел. В смысле, XLookupKeysym(), падла, возвращает ноль. :(

#21
20:54, 25 янв. 2009

>XmbLookupString тебе в помощь. Правила создания XIC/XIM я не помню.
Упустил твой пост пока експериментировал...

Короче, *почти* разобрался - за исключением, что падла не только пробел, а и некоторые цифровые клавиши не ловит для русской раскладки. Пришлось делать хак.

З.Ы. Уррря, заработала! :)
(где
  f_KeyState - мой массив с булевыми значениями нажатости,
  OnType() - мой метод, передающий введённый текст на дальнейшую обработку.

      XNextEvent ( Display, @Event );
      case Event._type of
......
        KeyPress: begin
          if not f_KeyState[(event.xKey.keycode - 8) and $FF] then begin
            f_KeyState[(event.xKey.keycode - 8) and $FF]:=true;
            i:= -1;
            if MotherState.TextInput then begin
              s:= (event.xkey.state and $1) or ((event.xkey.state shr (13 - 1)) and 2);
              sym:= XLookupKeysym(@event.xkey, s);
              if sym = 0 
                then sym:= XLookupKeysym(@event.xkey, s and 1); //hackaround!
              i:= X11ConvertKeySymToUnicode(sym); //an ugly, ugly function
            end;
            if i > 0 then OnType(WideChar(i));
..........

где X11ConvertKeySymToUnicode() - ужасная на лицо функция, выдранная с мясом из исходников ФриПаскаля

Function X11ConvertKeySymToUnicode(sym : TKeySym) : Integer;
Begin
  If (sym >= $20) And (sym <= $7E) Then
    Exit(sym);
  Case sym Of
    XKc_Cyrillic_GHE_bar           : Exit($492);
    XK_Cyrillic_ghe_bar            : Exit($493);
    XKc_Cyrillic_ZHE_descender     : Exit($496);
    XK_Cyrillic_zhe_descender      : Exit($497);
    XKc_Cyrillic_KA_descender      : Exit($49A);
    XK_Cyrillic_ka_descender       : Exit($49B);
    XKc_Cyrillic_KA_vertstroke     : Exit($49C);
    XK_Cyrillic_ka_vertstroke      : Exit($49D);
    XKc_Cyrillic_EN_descender      : Exit($4A2);
    XK_Cyrillic_en_descender       : Exit($4A3);
    XKc_Cyrillic_U_straight        : Exit($4AE); 
....и далее в том же духе на сотню строк...

#22
21:09, 25 янв. 2009

Cheb

Угу. Без "Xmb*/Xutf8*" оно примерно так и должно выглядеть. В GDK аналогичная хрень лежит в файле `gdkkeyuni.c`.

#23
22:50, 2 фев. 2009

А как спрятать стандартный курсор при наведении его на окно приложения?

#24
23:41, 2 фев. 2009

Мне известен только один метод: создать и загрузить полностью прозрачный курсор!

Могу поделиться велосипедом. Но это *ужасный* велосипед. Dire Bicycle.

type
  TCLWindow = class
  protected
   {$ifdef unix}
    display: PDisplay;
    screen: integer;
    context: GLXContext;
    WindowHandle: GLXDrawable;
    Visual: PXVisualInfo;
    icon_hwcursor: TCursor;
   {$else}
...
   {$endif}
    CursorCreated,
    GLInitialized: boolean;
...
    PointerBitmap: record
      Bitmap: array[0..31, 0..31, 0..3] of byte;
      Andmask, XorMask: array [0..31] of dword;
    end;
    PointerXHotSpot, PointerYHotSpot: integer;
    procedure _UploadPointer;
...
  end;    

  procedure TCLWindow._UploadPointer;
  var
    PixmapF, PixmapB: TPixmap;
    cursor_fg, cursor_bg : TXColor;
    screen_colormap : TColormap;
    rc : TStatus;
    GC : TGC;
    rValues : TXGCValues;
    x, y: integer;
    OldCursor: TCursor;
  begin
    _UploadGLcursor;
    OldCursor:= icon_hwcursor;
    
    screen_colormap := XDefaultColormap(display, XDefaultScreen(display));//screen);
    (* выделяем черный и белый цвета *)
    rc := XAllocNamedColor(display, screen_colormap, 'black', @cursor_fg, @cursor_fg);
    if (rc = 0) then Die('XAllocNamedColor() failed: unable to alloc "black"');
    rc := XAllocNamedColor(display, screen_colormap, 'white', @cursor_bg, @cursor_bg);
    if (rc = 0) then Die('XAllocNamedColor() failed: unable to alloc "white"');
    PixmapF:= XCreatePixmap(display, WindowHandle, 32, 32, 1);
    PixmapB:= XCreatePixmap(display, WindowHandle, 32, 32, 1);

    //all this stuff only to fill the bitmap with zeroes
    rValues.foreground := 0;
    rValues.background := 0;
    GC:= XCreateGC(Display, PixmapF, GCForeground, @rValues);
    //create a blank transparent cursor at first
    XSetForeground(display, GC, 0);
    for y:=0 to 31 do
      for x:= 0 to 31 do
        XDrawPoint(Display, PixmapF, GC, x, y);
    if MotherState.UseHardware1bitCursor then begin
      //fill it with the mask data
      XSetForeground(display, GC, 1);

      for y:=0 to 31 do
        with PointerBitmap do
          for x:= 0 to 31 do
            if (XorMask[y] and (1 shl x)) <> 0 //white pixel
              then XDrawPoint(Display, PixmapF, GC, x, y);
    end;
    XFreeGC(Display, GC);


    GC:= XCreateGC(Display, PixmapB, GCForeground, @rValues);
    XSetForeground(display, GC, 0);
    for y:=0 to 31 do
      for x:= 0 to 31 do
        XDrawPoint(Display, PixmapB, GC, x, y);
    if MotherState.UseHardware1bitCursor then begin
      XSetForeground(display, GC, 1);
      for y:=0 to 31 do
        with PointerBitmap do
          for x:= 0 to 31 do
            if (AndMask[y] and (1 shl x)) = 0 // black pixel
                then XDrawPoint(Display, PixmapB, GC, x, y);
    end;
    XFreeGC(Display, GC);
    
    icon_hwcursor := XCreatePixmapCursor(
      display, PixmapF, PixmapB, @cursor_fg, @cursor_bg, PointerXHotSpot, PointerYHotSpot);
    XFreePixmap(display, PixmapF);
    XFreePixmap(display, PixmapB);
    XDefineCursor(display, WindowHandle, icon_hwcursor);
    if CursorCreated then begin
      XFreeCursor(display, OldCursor);
      XFlush(display);
    end;
    CursorCreated:= True;
  end; 

#25
0:12, 3 фев. 2009

> А как спрятать стандартный курсор при наведении его на окно приложения?

Как написал Cheb, назначить для него прозрачный курсор :) Делается через нехитрый способ создания прозрачного pixmap'а с помощью маски. Мой велосипед может будет проще для восприятия

var
  scr_Display  : PDisplay; // для XOpenDisplay
  wnd_Handle : TWindow; // хэндл окна
  app_Cursor : TCursor = None;
...
procedure wnd_ShowCursor( const Show : Boolean );;
  var
    mask   : TPixmap;
    xcolor : TXColor;
begin
  case Show of
    TRUE:
      if app_Cursor <> None Then
        begin
          XFreeCursor( scr_Display, app_Cursor );
          app_Cursor := None;
          XDefineCursor( scr_Display, wnd_Handle, app_Cursor );
        end;
    FALSE:
      begin
        mask := XCreatePixmap( scr_Display, wnd_Handle, 1, 1, 1 );
        FillChar( xcolor, SizeOf( xcolor ), 0 );
        app_Cursor := XCreatePixmapCursor( scr_Display, mask, mask, @xcolor, @xcolor, 0, 0 );
        XDefineCursor( scr_Display, wnd_Handle, app_Cursor );
      end;
   end;
end;

Для C++ это что-то вроде этого(функция просто создает пустой курсор):

static Cursor CreateNullCursor(Display *display, Window root)
{
  Pixmap cursormask;
  XGCValues xgc;
  GC gc;
  XColor dummycolour;
  Cursor cursor;

  cursormask = XCreatePixmap(display, root, 1, 1, 1);
  xgc.function = GXclear;
  gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
  XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
  dummycolour.pixel = 0;
  dummycolour.red = 0;
  dummycolour.flags = 04;
  cursor = XCreatePixmapCursor(display, cursormask, cursormask, &dummycolour,&dummycolour, 0,0);
  XFreePixmap(display,cursormask);
  XFreeGC(display,gc);
  return cursor;
}
В общем google search code и ключевое слово XCreatePixmapCursor тебе помогут :) Либо читай доументацию по этим функциям.

#26
0:28, 3 фев. 2009

Cheb
Пропустил я темку. Код функции X11ConvertKeySymToUnicode убил... вы товарищ извращенец 8) Чем не устроила Xutf8LookupString? :)

var
  app_XIM    : PXIM;
  app_XIC    : PXIC;
...
  // Создать XIM/XIC
  app_XIM := XOpenIM( scr_Display, nil, nil, nil );
  app_XIC := XCreateIC( app_XIM, [ XNInputStyle, XIMPreeditNothing or XIMStatusNothing, 0 ] );


 // В KeyPress получать символ в Utf8. Тут для размера стоит 2, т.к. хватает для русской и английской раскладки
...
 var
    Event  : TXEvent;
    Keysym : TKeySym;
    Status : TStatus;
    c   : array[ 0..1 ] of Char;
...
  len := Xutf8LookupString( app_XIC, @Event, @c, 2, @Keysym, @Status );
В итоге в c будет сохранен код символа. Если len = 1, значит вкладываемся в первые 128 символа из ASCII. Больше - значит UTF-8 и решаем чего делать.

Это конечно абы как собрано, но почитав что-нить на эту тему, можно вкрай разобраться как оно должно быть в идеале, но мне было лень, т.к. это вполне себе работает )

правка: Забыл еще момент, в FreePascal порой дебильные хедеры для X11. Функци Xut8LookupString описана там страшным образом. Я использую вот эту:

function Xutf8LookupString( ic : PXIC; event : PXKeyPressedEvent;
                            buffer_return : PChar; bytes_buffer : Integer;
                            keysym_return : PKeySym; status_return : PStatus ) : integer; cdecl; external;
#27
15:35, 4 фев. 2009

Поставил GLU Mesa, получил "ошибка: нет декларации ‘glXGetProcAddressARB’ в этой области видимости" при компиляции, люди, чего я снес, подскажите?!
К сожалению при установке того пакета не видел чего он ломает....

Вообще, какие пакеты надо поставить для спокойного использования OpenGL+GLu?

glXGetProcAddressARB->glXGetProcAddress помогло :(

#28
22:40, 4 фев. 2009

>Код функции X11ConvertKeySymToUnicode убил... вы товарищ извращенец 8)
Я не виноватый! Это цельнотянутое!

>glXGetProcAddressARB->glXGetProcAddress помогло :(
Оооочень распространённая засада. У одного вендора функция с ARB, у другого - нет... И поди разберись, почему оно Access Violation выкидывает.

#29
15:03, 5 фев. 2009

Заразный X сервер имплементирует автоповтор клавиш, посылая пары событий отпускание/нажатие вместо простой цепочки нажатий как в виндовс.
Пришлось городить кручёный хак (ибо в режиме текстового ввода автоповтор, всё же, нужен.)

  function DivineScanCode(var event: TXEvent): integer;
  var
    sym: TKeySym;
  begin
    sym:= XLookupKeysym(@event.xkey, 0);
    case sym of
      XK_Home               :Exit(ord(KEY_HOME));
      XK_Left               :Exit(ord(KEY_LEFT));  
.... и все клавиши, коды которых в иксах отличаются от скэнкодов IBM PC XT
      XK_Super_R            :Exit(ord(KEY_RIGHT_WINDOWS)); 
    else
      Result:= (event.xKey.keycode - 8) and $FF;
    end;
  end;

  Procedure TCLWindow.OneCycle;
  var
    Event, NextEvent: TXEvent;
    i, s: integer;
    sym: TKeySym;
    scancode: integer;
    ItsAutoRepeat, GotNext: boolean;
  begin
    _CheckCursorMode();
    While XPending(Display) > 0 do begin
      XNextEvent ( Display, @Event );
      if Event._type = KeyRelease then begin
        scancode:= DivineScanCode(event);
        //defeat the auto-repeat feature!
        GotNext:= No;
        ItsAutoRepeat:= No;
        if XPending(Display) > 0 then begin
          GotNext:= Yes;
          XNextEvent ( Display, @NextEvent );
          ItsAutoRepeat:= (NextEvent._type = KeyPress) and (NextEvent.xkey.keycode = Event.xkey.keycode) and (NextEvent.xkey.time = Event.xkey.time);
        end;
        if f_KeyState[scancode] and not ItsAutoRepeat then begin
          f_KeyState[scancode]:= false;
          OnRelease(scancode);
        end;
        if GotNext then Event:= NextEvent;
      end;

      case Event._type of
        KeyPress: begin
          scancode:= DivineScanCode(event);
          i:= -1;
          if MotherState.TextInput then begin
            s:= (event.xkey.state and $1) or ((event.xkey.state shr (13 - 1)) and 2);
            sym:= XLookupKeysym(@event.xkey, s);
            if sym = 0
              then sym:= XLookupKeysym(@event.xkey, s and 1);
            i:= X11ConvertKeySymToUnicode(sym); //an ugly, ugly function
          end;
          if i > 0 then begin
            OnType(WideChar(i));
            OnPress(0); //mouse movement message to make any text editors update their state
          end;
          if (not f_KeyState[scancode]) or (ItsAutoRepeat and MotherState.TextInput
            and (TKey(scancode) in KeysAcceptingAutoRepeatInTextInputMode))
          then begin
            f_KeyState[scancode]:=true;
            if (i <= 0) or (TKey(scancode) in KeysWorkingInTextInputMode)
              then OnPress(scancode);
          end;
        end;
.....

З.Ы. Скэн-коды клавиатуры - абсолютно постоянная величина, не менявшаяся с 1982 года. Они же ЕМНИП - коды клавиш в директиксе.
Я стараюсь делать привязку именно к ним, для всех платформ: уже достало что в редакторах (тот же GIMP) все хоткеи перестают работать стоит переключиться на русскую раскладку.

>в FreePascal порой дебильные хедеры для X11. Функци Xut8LookupString описана там страшным образом. Я использую вот эту:
Спасибо, запомню на будущее. Сейчас бы с классами гуя разобраться (кнопки там, лабели, текстовые редакторы и прочий съестной припас).

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.