@@ -496,21 +496,49 @@ km_load_file(const char *filename, struct xrdp_keymap *keymap)
496
496
return rv ;
497
497
}
498
498
499
+ /*****************************************************************************/
500
+ /***
501
+ * looks up a keylayout in a list of values
502
+ *
503
+ * @param keylayout (e.g. 000000409)
504
+ * @param items List of items (one of which is returned)
505
+ * @param values List of hexadecimal lookup values
506
+ * @param rdp_layout Buffer for result
507
+ * @param rdp_layout_len Size of rdp_layout
508
+ * @return != 0 for a successful lookup
509
+ */
510
+ static int
511
+ lookup_keylayout (int keylayout ,
512
+ const struct list * items ,
513
+ const struct list * values ,
514
+ char rdp_layout [], unsigned int rdp_layout_len )
515
+ {
516
+ int index ;
517
+ for (index = 0 ; index < items -> count ; index ++ )
518
+ {
519
+ const char * item = (const char * )list_get_item (items , index );
520
+ const char * value = (const char * )list_get_item (values , index );
521
+ if (g_atoix (value ) == keylayout )
522
+ {
523
+ strlcpy (rdp_layout , item , rdp_layout_len );
524
+ return 1 ;
525
+ }
526
+ }
527
+ return 0 ;
528
+ }
499
529
/*****************************************************************************/
500
530
void
501
531
xrdp_init_xkb_layout (struct xrdp_client_info * client_info )
502
532
{
503
533
int fd ;
504
534
int index = 0 ;
505
- int bytes ;
506
- struct list * names = (struct list * )NULL ;
507
- struct list * items = (struct list * )NULL ;
508
- struct list * values = (struct list * )NULL ;
509
- char * item = (char * )NULL ;
510
- char * value = (char * )NULL ;
511
- char * q = (char * )NULL ;
512
- char keyboard_cfg_file [256 ] = { 0 };
513
- char rdp_layout [256 ] = { 0 };
535
+ struct list * names = NULL ;
536
+ struct list * items = NULL ;
537
+ struct list * values = NULL ;
538
+ const char * item = NULL ;
539
+ const char * value = NULL ;
540
+ const char * q = NULL ;
541
+ const char * keyboard_cfg_file = XRDP_CFG_PATH "/xrdp_keyboard.ini" ;
514
542
515
543
const struct xrdp_keyboard_overrides * ko =
516
544
& client_info -> xrdp_keyboard_overrides ;
@@ -542,31 +570,34 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
542
570
}
543
571
/* infer model/variant */
544
572
/* TODO specify different X11 keyboard models/variants */
545
- g_memset ( client_info -> model , 0 , sizeof ( client_info -> model )) ;
546
- g_memset ( client_info -> variant , 0 , sizeof ( client_info -> variant )) ;
547
- g_strncpy (client_info -> layout , "us" , sizeof (client_info -> layout ) - 1 );
573
+ client_info -> model [ 0 ] = '\0' ;
574
+ client_info -> variant [ 0 ] = '\0' ;
575
+ strlcpy (client_info -> layout , "us" , sizeof (client_info -> layout ));
548
576
if (client_info -> keyboard_subtype == 3 )
549
577
{
550
578
/* macintosh keyboard */
551
- bytes = sizeof (client_info -> variant );
552
- g_strncpy (client_info -> variant , "mac" , bytes - 1 );
579
+ strlcpy (client_info -> variant , "mac" , sizeof (client_info -> variant ));
553
580
}
554
581
else if (client_info -> keyboard_subtype == 0 )
555
582
{
556
583
/* default - standard subtype */
557
584
client_info -> keyboard_subtype = 1 ;
558
585
}
559
586
560
- g_snprintf (keyboard_cfg_file , 255 , "%s/xrdp_keyboard.ini" , XRDP_CFG_PATH );
561
587
LOG (LOG_LEVEL_DEBUG , "keyboard_cfg_file %s" , keyboard_cfg_file );
562
588
563
589
fd = g_file_open_ro (keyboard_cfg_file );
564
590
565
591
if (fd >= 0 )
566
592
{
567
593
int section_found = -1 ;
568
- char section_rdp_layouts [256 ] = { 0 };
569
- char section_layouts_map [256 ] = { 0 };
594
+ char section_rdp_layouts [256 ];
595
+ char section_layouts_map [256 ];
596
+ char rdp_layout [256 ];
597
+
598
+ section_rdp_layouts [0 ] = '\0' ;
599
+ section_layouts_map [0 ] = '\0' ;
600
+ rdp_layout [0 ] = '\0' ;
570
601
571
602
names = list_create ();
572
603
names -> auto_free = 1 ;
@@ -578,17 +609,17 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
578
609
file_read_sections (fd , names );
579
610
for (index = 0 ; index < names -> count ; index ++ )
580
611
{
581
- q = (char * )list_get_item (names , index );
582
- if (g_strncasecmp ("default" , q , 8 ) != 0 )
612
+ q = (const char * )list_get_item (names , index );
613
+ if (g_strcasecmp ("default" , q ) != 0 )
583
614
{
584
615
int i ;
585
616
586
617
file_read_section (fd , q , items , values );
587
618
588
619
for (i = 0 ; i < items -> count ; i ++ )
589
620
{
590
- item = (char * )list_get_item (items , i );
591
- value = (char * )list_get_item (values , i );
621
+ item = (const char * )list_get_item (items , i );
622
+ value = (const char * )list_get_item (values , i );
592
623
LOG (LOG_LEVEL_DEBUG , "xrdp_init_xkb_layout: item %s value %s" ,
593
624
item , value );
594
625
if (g_strcasecmp (item , "keyboard_type" ) == 0 )
@@ -613,41 +644,40 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
613
644
{
614
645
if (section_found != -1 && section_found == index )
615
646
{
616
- g_strncpy (section_rdp_layouts , value , 255 );
647
+ strlcpy (section_rdp_layouts , value ,
648
+ sizeof (section_rdp_layouts ));
617
649
}
618
650
}
619
651
else if (g_strcasecmp (item , "layouts_map" ) == 0 )
620
652
{
621
653
if (section_found != -1 && section_found == index )
622
654
{
623
- g_strncpy (section_layouts_map , value , 255 );
655
+ strlcpy (section_layouts_map , value ,
656
+ sizeof (section_layouts_map ));
624
657
}
625
658
}
626
659
else if (g_strcasecmp (item , "model" ) == 0 )
627
660
{
628
661
if (section_found != -1 && section_found == index )
629
662
{
630
- bytes = sizeof (client_info -> model );
631
- g_memset (client_info -> model , 0 , bytes );
632
- g_strncpy (client_info -> model , value , bytes - 1 );
663
+ strlcpy (client_info -> model , value ,
664
+ sizeof (client_info -> model ));
633
665
}
634
666
}
635
667
else if (g_strcasecmp (item , "variant" ) == 0 )
636
668
{
637
669
if (section_found != -1 && section_found == index )
638
670
{
639
- bytes = sizeof (client_info -> variant );
640
- g_memset (client_info -> variant , 0 , bytes );
641
- g_strncpy (client_info -> variant , value , bytes - 1 );
671
+ strlcpy (client_info -> variant , value ,
672
+ sizeof (client_info -> variant ));
642
673
}
643
674
}
644
675
else if (g_strcasecmp (item , "options" ) == 0 )
645
676
{
646
677
if (section_found != -1 && section_found == index )
647
678
{
648
- bytes = sizeof (client_info -> options );
649
- g_memset (client_info -> options , 0 , bytes );
650
- g_strncpy (client_info -> options , value , bytes - 1 );
679
+ strlcpy (client_info -> options , value ,
680
+ sizeof (client_info -> options ));
651
681
}
652
682
}
653
683
else
@@ -670,21 +700,26 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
670
700
671
701
if (section_found == -1 )
672
702
{
673
- g_memset (section_rdp_layouts , 0 , sizeof (char ) * 256 );
674
- g_memset (section_layouts_map , 0 , sizeof (char ) * 256 );
675
703
// read default section
704
+ strlcpy (section_rdp_layouts , "default_rdp_layouts" ,
705
+ sizeof (section_rdp_layouts ));
706
+ strlcpy (section_layouts_map , "default_layouts_map" ,
707
+ sizeof (section_layouts_map ));
708
+
676
709
file_read_section (fd , "default" , items , values );
677
710
for (index = 0 ; index < items -> count ; index ++ )
678
711
{
679
- item = (char * )list_get_item (items , index );
680
- value = (char * )list_get_item (values , index );
712
+ item = (const char * )list_get_item (items , index );
713
+ value = (const char * )list_get_item (values , index );
681
714
if (g_strcasecmp (item , "rdp_layouts" ) == 0 )
682
715
{
683
- g_strncpy (section_rdp_layouts , value , 255 );
716
+ strlcpy (section_rdp_layouts , value ,
717
+ sizeof (section_rdp_layouts ));
684
718
}
685
719
else if (g_strcasecmp (item , "layouts_map" ) == 0 )
686
720
{
687
- g_strncpy (section_layouts_map , value , 255 );
721
+ strlcpy (section_layouts_map , value ,
722
+ sizeof (section_layouts_map ));
688
723
}
689
724
}
690
725
list_clear (items );
@@ -693,53 +728,44 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
693
728
694
729
/* load the map */
695
730
file_read_section (fd , section_rdp_layouts , items , values );
696
- for (index = 0 ; index < items -> count ; index ++ )
731
+ if (!lookup_keylayout (client_info -> keylayout , items , values ,
732
+ rdp_layout , sizeof (rdp_layout )))
697
733
{
698
- int rdp_layout_id ;
699
- item = (char * )list_get_item (items , index );
700
- value = (char * )list_get_item (values , index );
701
- rdp_layout_id = g_atoix (value );
702
- if (rdp_layout_id == client_info -> keylayout )
734
+ if ((client_info -> keylayout & ~0xffff ) != 0 )
703
735
{
704
- g_strncpy (rdp_layout , item , 255 );
705
- break ;
706
- }
707
- }
708
- if (rdp_layout [0 ] == '\0' && (client_info -> keylayout & ~0xffff ) != 0 )
709
- {
710
- // We failed to match the layout, but we may be able
711
- // to match on the lower 16-bits
712
- int alt_layout = client_info -> keylayout & 0xffff ;
713
- for (index = 0 ; index < items -> count ; index ++ )
714
- {
715
- item = (char * )list_get_item (items , index );
716
- value = (char * )list_get_item (values , index );
717
- int rdp_layout_id = g_atoix (value );
718
- if (rdp_layout_id == alt_layout )
736
+ // We failed to match the layout, but we may be able
737
+ // to match on the lower 16-bits
738
+ int alt_layout = client_info -> keylayout & 0xffff ;
739
+ if (lookup_keylayout (alt_layout , items , values ,
740
+ rdp_layout , sizeof (rdp_layout )))
719
741
{
720
- g_strncpy (rdp_layout , item , 255 );
721
742
LOG (LOG_LEVEL_INFO ,
722
743
"Failed to match layout 0x%08X, but matched 0x%04X to %s" ,
723
744
client_info -> keylayout , alt_layout , rdp_layout );
724
- break ;
725
745
}
726
746
}
727
747
}
728
748
list_clear (items );
729
749
list_clear (values );
730
- file_read_section (fd , section_layouts_map , items , values );
731
- for (index = 0 ; index < items -> count ; index ++ )
750
+
751
+ // If we found a layout in the rdp layouts section, copy the
752
+ // corresponding X11 layout name to the client layout, e.g. if we
753
+ // matched 0xe0200411 to 'rdp_layout_jp, copy 'jp' for the client.
754
+ if (rdp_layout [0 ] != '\0' )
732
755
{
733
- item = (char * )list_get_item (items , index );
734
- value = (char * )list_get_item (values , index );
735
- if (g_strcasecmp (item , rdp_layout ) == 0 )
756
+ file_read_section (fd , section_layouts_map , items , values );
757
+ for (index = 0 ; index < items -> count ; index ++ )
736
758
{
737
- bytes = sizeof (client_info -> layout );
738
- g_strncpy (client_info -> layout , value , bytes - 1 );
739
- break ;
759
+ item = (const char * )list_get_item (items , index );
760
+ value = (const char * )list_get_item (values , index );
761
+ if (g_strcasecmp (item , rdp_layout ) == 0 )
762
+ {
763
+ strlcpy (client_info -> layout , value ,
764
+ sizeof (client_info -> layout ));
765
+ break ;
766
+ }
740
767
}
741
768
}
742
-
743
769
list_delete (names );
744
770
list_delete (items );
745
771
list_delete (values );
@@ -756,8 +782,8 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
756
782
}
757
783
758
784
// Initialise the rules and a few keycodes for xorgxrdp
759
- snprintf (client_info -> xkb_rules , sizeof ( client_info -> xkb_rules ),
760
- "%s" , scancode_get_xkb_rules ( ));
785
+ strlcpy (client_info -> xkb_rules , scancode_get_xkb_rules ( ),
786
+ sizeof ( client_info -> xkb_rules ));
761
787
if (keylayout_supports_caps_lock (client_info -> keylayout ))
762
788
{
763
789
client_info -> x11_keycode_caps_lock =
0 commit comments