Code

Added description for terminals
[gosa.git] / gosa-plugins / goto / admin / systems / goto / class_terminalService.inc
1 <?php
3 class termservice extends plugin
4 {
5   /* CLI vars */
6   var $cli_summary= "Manage terminal service aspects";
7   var $cli_description= "Some longer text\nfor help";
8   var $cli_parameters= array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
10   /* Generic terminal attributes */
11   var $gotoLpdEnable= FALSE;
12   var $gotoXMonitor= "";
13   var $gotoXMethod= "default";
14   var $gotoXdmcpServer= "";
15   var $gotoXDriver= "";
16   var $gotoXResolution= "";
17   var $gotoXColordepth= "";
18   var $gotoXHsync= "";
19   var $gotoXVsync= "";
20   var $gotoXKbModel= "";
21   var $gotoXKbLayout= "";
22   var $gotoXKbVariant= "";
23   var $gotoXMouseType= "";
24   var $gotoXMouseport= "";
25   var $gotoLpdServer= "";
26   var $gotoScannerEnable= "";
27   var $gotoScannerModel= "";
28   var $gotoScannerClients= "";
29   var $gotoScannerBackend= "";
30   var $goFonHardware= "automatic";
32   var $AutoSync = false;
33   var $view_logged = FALSE;
35   /* Needed values and lists */
36   var $ignore_account= TRUE;
37   var $base= "";
38   var $cn= "";
39   var $orig_dn= "";
40   var $XMethods= array();
41   var $XDrivers= array();
42   var $XResolutions= array();
43   var $XColordepths= array();
44   var $XKbModels= array ();
45   var $XKbLayouts= array ();
46   var $XKbVariants= array ();
47   var $MouseTypes= array();
48   var $MousePorts= array();
49   var $hardware_list= array();
50   var $used_hardware= array();
53   /* attribute list for save action */
54   var $attributes= array("gotoLpdEnable", "gotoXMonitor", "gotoXMethod", "gotoXdmcpServer",
55       "gotoXDriver", "gotoXResolution", "gotoXColordepth",
56       "gotoXHsync", "gotoXVsync", "gotoLpdEnable", "gotoLpdServer",
57       "gotoScannerEnable", "gotoScannerModel", "gotoScannerClients",
58       "gotoScannerBackend", "gotoXKbModel", "gotoXKbLayout", "gotoXKbVariant",
59       "gotoXMouseType", "gotoXMouseport", "goFonHardware");
60   var $objectclasses= array("GOhard");
62   var $is_ogroup        = FALSE;
63   var $is_ogroup_member = FALSE;
65   var $selected_xdmcp_servers = array();
66   var $inherited_xdmcp_servers = array();
68   function termservice (&$config, $dn= NULL, $parent= NULL)
69   {
70     plugin::plugin ($config, $dn, $parent);
71     $this->orig_dn= $this->dn;
73     /* Check if we are a part of an ogroup.
74      * In this case, we have to hide all the inherit stuff.
75      */ 
76     if(isset($parent) && get_class($parent) == "ogroup"){
77       $this->is_ogroup = TRUE;
78     }
80     /* Check if we are member of an object group.
81      */
82     $ldap= $this->config->get_ldap_link();
83     $ldap->cd($this->config->current['BASE']);
84     $ldap->search("(&(objectClass=gotoWorkstationTemplate)(member=".LDAP::prepare4filter($this->dn)."))");
85     if($ldap->count()){
86       $this->is_ogroup_member = TRUE;
87     }
89     /* Get list of available xdrivers */
90     $this->XDrivers = $this->getListOfXDrivers();
92     /* Create a list of available resolutions.
93      */     
94     $this->XResolutions= array(
95           "640x480"   =>  "640x480",
96           "800x600"   =>  "800x600",
97           "1024x768"  =>  "1024x768",
98           "1152x864"  =>  "1152x864",
99           "1280x1024" =>  "1280x1024",
100           "1400x1050" =>  "1400x1050",
101           "1600x1200" =>  "1600x1200");
103     if(isset($this->config->data['MAIN']['RESOLUTION_HOOK'])){
104       $file = $this->config->data['MAIN']['RESOLUTION_HOOK'];
105       if(is_readable($file)){
106         $str = file_get_contents($file);
107         $lines = split("\n",$str);
108         foreach($lines as $line){
109           $line = trim($line);
110           if(!empty($line)){
111             $this->XResolutions[$line]=$line;
112           }
113         }
114       }else{
115         print_red(sprintf(_("You have specified an external resolution hook which can't be read, please check the permission of the file '%s'."),$file));
116       }
117     }
119     /* Create a set of selectable color depths
120      */
121     $this->XColordepths= array(
122         "8"        => "8 " ._("bit"),
123         "15"       => "15 "._("bit"),
124         "16"       => "16 "._("bit"),
125         "24"       => "24 "._("bit"));
127     
128     /* Create a set of selectable keyboard models
129      */
130     $this->XKbModels = array();
131     foreach(array ("btc9000", "chicony", "compaq", "dell", "dell101", "everex",
132           "flexpro", "geniuscomfy", "hp", "itouch", "jp106", "logicordless",
133           "logiinetnav", "logiinternet", "macintosh", "microsoft",
134           "microsoftpro", "omnikey101", "pc101", "pc102", "pc104",
135           "pc105", "rapidaccess", "rapidaccess2", "winbook") as $type){
136       $this->XKbModels[$type] = $type;
137     }
139     /* Additional values will be extracted from CONFIG_DIR.keyboardLayouts */
140     $this->XKbLayouts = array("de"=> "de","intl" =>"intl","us" =>"us");
141     $this->XKbVariants= array("nodeadkeys"=>"nodeadkeys", "basic"=>"basic");
142     $this->MouseTypes = array("ImPS/2"=>"ImPS/2","PS/2"=>"PS/2", "explorerps/2"=>"explorerps/2",
143                               "Microsoft"=>"Microsoft","Logitech"=>"Logitech");
144     $this->MousePorts = array("/dev/ttyS0"=>"/dev/ttyS0",
145                               "/dev/ttyS1"=>"/dev/ttyS1","/dev/psaux"=>"/dev/psaux", 
146                               "/dev/input/mice"=>"/dev/input/mice");
147  
149     /* Try to read additional keyboard layouts
150      */
151     if(file_exists(CONFIG_DIR."/keyboardLayouts")){
152       if(is_readable(CONFIG_DIR."/keyboardLayouts")){
153         $str = file_get_contents(CONFIG_DIR."/keyboardLayouts");
154         $tmp = split("\n",$str);
155         foreach($tmp as $entry){
156           if((!empty($entry)) && (!preg_match("/^#/",$entry))){
157             $entry = trim($entry);
158             $tmp2 = split ("\:",$entry);
159             $la =   trim($tmp2[0]);   // What would be saved to ldap
160             $da =   trim($tmp2[1]);   // This wis displayed in the listbox
161             $this->XKbLayouts [ $la] = $da;
162           }
163         }
164       }
165     }
167     /* Terminal server methods 
168      */
169     if($this->is_ogroup_member){
170       $this->XMethods["default"]= _("inherited");
171     }
172     $this->XMethods["xdmcp"]  = _("XDMCP");
173     $this->XMethods["ldm"]    = _("LDM");
174     $this->XMethods["rdp"]    = _("Windows RDP");
175     $this->XMethods["citrix"] = _("ICA client");
177     /* Get selected gotoXdmcpServer 
178      */
179     $this->selected_xdmcp_servers = array();
180     if(isset($this->attrs['gotoXdmcpServer'])){
181       for($i = 0 ; $i < $this->attrs['gotoXdmcpServer']['count'] ; $i++){
182         $this->selected_xdmcp_servers[] = $this->attrs['gotoXdmcpServer'][$i];
183       }
184     }
186     /* Load phone hardware list 
187      */
188     $ldap= $this->config->get_ldap_link();
189     $ldap->cd($this->config->current['BASE']);
190     $ldap->search("(objectClass=goFonHardware)", array('cn', 'description'));
191     while ($attrs= $ldap->fetch()){
192       $cn= $attrs['cn'][0];
193       if (isset($attrs['description'])){
194         $description= " - ".$attrs['description'][0];
195       } else {
196         $description= "";
197       }
198       $this->hardware_list[$cn]= "$cn$description";
199     }
201     /* Eventually colorize phones */
202     $ldap->cd($this->config->current['BASE']);
203     $ldap->search("(goFonHardware=*)",array('cn','dn','goFonHardware'));
204     while($attrs = $ldap->fetch()){
205         $cn = $attrs['goFonHardware'][0];
206         if(isset($this->hardware_list[$cn])){
207           $this->used_hardware[$cn]= $cn;
208         }
209     }
210     $this->hardware_list["automatic"]= _("automatic");
211     ksort($this->hardware_list);
213     /* Convert gotoLpdEnable 
214      */
215     $this->gotoLpdEnable= preg_match("/yes/i",$this->gotoLpdEnable);
218     /* Load hardware list */
219     $ldap= $this->config->get_ldap_link();
220     $ldap->cd($this->config->current['BASE']);
221     $map= array(
222         "gotoXResolution", 
223         "gotoXColordepth", 
224         "gotoXKbModel", 
225         "gotoXKbLayout",
226 #        "gotoXDriver",
227         "gotoXdmcpServer",
228         "gotoXKbVariant",
229         "gotoXMouseType", 
230         "gotoXMethod",
231         "gotoXMouseport");
232     $ldap->search("(&(objectClass=gotoWorkstationTemplate)(member=".LDAP::prepare4filter($this->dn)."))",$map);
233     if ($ldap->count() == 1){
234       $attrs= $ldap->fetch();
235       foreach ($map as $name){
236         if (!isset($attrs[$name][0])){
237           continue;
238         }
240         switch ($name){
241 #         case 'gotoXDriver': 
242 #           $this->XDrivers = array('default' => _("inherited").' ['.$attrs[$name][0].']' ) + $this->XDrivers;
243 #           break;
244           case 'gotoXMethod': 
245             $this->XMethods = array('default' => _("inherited").' ['.$attrs[$name][0].']' ) + $this->XMethods;
246             if(isset($attrs['gotoXdmcpServer'])){
247               for($i = 0 ; $i < $attrs['gotoXdmcpServer']['count'] ; $i++){
248                 $this->inherited_xdmcp_servers[] = $attrs['gotoXdmcpServer'][$i];
249               }
250             }
251             break;
252           case 'gotoXResolution':
253             $this->XResolutions= array('default' => _("inherited").' ['.$attrs[$name][0].']' ) + $this->XResolutions;
254             break;
255           case 'gotoXColordepth':
256             $this->XColordepths= array('default' => _("inherited").' ['.$attrs[$name][0].' '._('Bit').']') + $this->XColordepths;
257             break;
258           case 'gotoXKbModel':
259             $this->XKbModels= array('default' => _("inherited").' ['.$attrs[$name][0].']') + $this->XKbModels;
260             break;
261           case 'gotoXKbLayout':
262             $this->XKbLayouts= array('default' => _("inherited").' ['.$attrs[$name][0].']' ) + $this->XKbLayouts;
263             break;
264           case 'gotoXKbVariant':
265             $this->XKbVariants= array('default' => _("inherited").' ['.$attrs[$name][0].']' ) + $this->XKbVariants;
266             break;
267           case 'gotoXMouseType':
268             $this->MouseTypes= array('AUTO' => _("inherited").' ['.$attrs[$name][0].']' ) + $this->MouseTypes;
269             break;
270           case 'gotoXMouseport':
271             $this->MousePorts= array('AUTO' => _("inherited").' ['.$attrs[$name][0].']' ) + $this->MousePorts;
272             break;
273         }
274       }
275     }
277     if(preg_match("/\+/",$this->gotoXHsync)){
278       $this->AutoSync = true;
279       $this->gotoXHsync = preg_replace("/\+/","-",$this->gotoXHsync);
280       $this->gotoXVsync = preg_replace("/\+/","-",$this->gotoXVsync);
281     }
282   }
285   function execute()
286   {
287     /* Call parent execute */
288     plugin::execute();
290     if($this->is_account && !$this->view_logged){
291       $this->view_logged = TRUE;
292       new log("view","terminal/".get_class($this),$this->dn);
293     }
295     /* Do we need to flip is_account state? */
296     if (isset($_POST['modify_state'])){
297       $this->is_account= !$this->is_account;
298     }
300     /* Do we represent a valid terminal? */
301     if (!$this->is_account && $this->parent === NULL){
302       $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\">&nbsp;<b>".
303         _("This 'dn' has no terminal features.")."</b>";
304       return ($display);
305     }
307     /* Show main page */
308     $smarty= get_smarty();
310     /* Assign acls */
311     $tmp= $this->plInfo();
312     foreach($tmp['plProvidedAcls'] as $name => $translation){
313       $smarty->assign($name."ACL",$this->getacl($name));
314     }
316     if(isset($_POST['gotoXdmcpServer_add']) && isset($_POST['XdmcpAddServer'])){
317       if(!in_array($_POST['gotoXdmcpServer_add'],$this->selected_xdmcp_servers)){
318         $this->selected_xdmcp_servers[] = $_POST['gotoXdmcpServer_add'];
319       }
320     }
322     if(isset($_POST['selected_xdmcp_servers']) && isset($_POST['XdmcpDelServer'])){
323       $tmp = array();
324       foreach($this->selected_xdmcp_servers as $name){
325         if(!in_array($name,$_POST['selected_xdmcp_servers'])){
326           $tmp[] =  $name;
327         }
328       }
329       $this->selected_xdmcp_servers = $tmp;
330     }
332     /* Arrays */ 
333     foreach(array("XMethods", "XDrivers", "XResolutions", "XColordepths",
334           "XKbModels","XKbVariants","MouseTypes", "MousePorts") as $val){
335       $smarty->assign("$val", $this->$val);
336     }
337     $smarty->assign("XKbLayouts",   $this->XKbLayouts);
338     $smarty->assign("XKbLayoutKeys",array_flip($this->XKbLayouts));
339     $smarty->assign("nfsservers", $this->config->data['SERVERS']['NFS']);
340   
341     
342     /* Create a list of useable servers for the currently selected 
343      *  connection type.
344      */ 
345     $xdmcp_types =  $this->config->data['SERVERS']['TERMINAL_SESSION_TYPES'];
346     $available_servers = array();
347     foreach($xdmcp_types as $servername =>$supported_types){
348       if(in_array(strtoupper($this->gotoXMethod),$supported_types)){
349         $available_servers[]  = $servername;
350       }
351     }
353     /* Append additional information to invalid server selections.
354      */
355     $tmp = array();
356     foreach($this->selected_xdmcp_servers as $server){
357       if(in_array($server,$available_servers)){
358         $tmp[$server] = $server;
359       }else{
360         $tmp[$server] = $server."&nbsp;-&nbsp;"._("Unsupported");
361       }
362     }
364     /* Remove already selected servers from available list. 
365      */
366     foreach($available_servers as $key => $server){
367       if(isset($tmp[$server])){
368         unset($available_servers[$key]);
369       }
370     }
372     $smarty->assign("selected_xdmcp_servers", $tmp);
373     $smarty->assign("inherited_xdmcp_servers", $this->inherited_xdmcp_servers);
374     $smarty->assign("available_xdmcp_servers", $available_servers);
376     /* Variables - select */
377     foreach(array("gotoXMethod","gotoXDriver", "gotoXResolution", "gotoXColordepth", 
378           "gotoLpdServer", "gotoXKbModel", "gotoXKbLayout",
379           "gotoXKbVariant", "gotoXMouseType", "gotoXMouseport") as $val){
381       $smarty->assign($val."_select", $this->$val);
382     }
384     /* Variables */
385     foreach(array("gotoXHsync", "gotoXVsync") as $val){
386       $smarty->assign($val, $this->$val);
387     }
388     $smarty->assign("staticAddress", "");
390     /* Checkboxes */
391     foreach(array("gotoLpdEnable", "gotoScannerEnable") as $val){
392       if ($this->$val == TRUE) {
393         $smarty->assign("$val", "checked");
394       } else {
395         $smarty->assign("$val", "");
396       }
397     }
399     /* Phone stuff */
400     $smarty->assign ("goFonHardware", $this->goFonHardware);
401     $hl= "<select size=\"1\" name=\"goFonHardware\" title=\"".
402          _("Choose the phone located at the current terminal")."\" >\n";
403     foreach ($this->hardware_list as $cn => $description){
404       if ($cn == $this->goFonHardware){
405         $selected= "selected";
406       } else {
407         $selected= "";
408       }
409       if (isset($this->used_hardware[$cn])){
410         $color= "style=\"color:#A0A0A0\"";
411       } else {
412         $color= "";
413       }
414       $hl.= "  <option $color label=\"$cn\" value=\"$cn\" $selected>$description</option>\n";
415     }
416     $hl.= "</select>\n";
417     $smarty->assign ("hardware_list", $hl);
418     $smarty->assign ("gotoXMonitor", $this->gotoXMonitor);
420     $smarty->assign("AutoSyncACL",$this->getacl("AutoSync"));
422     $smarty->assign("AutoSyncCHK"," ");
423     if($this->AutoSync){
424       $smarty->assign("AutoSyncCHK"," checked ");
425       $smarty->assign("gotoXVsyncACL", preg_replace("/w/","",$this->getacl("gotoXVsync")));
426       $smarty->assign("gotoXHsyncACL", preg_replace("/w/","",$this->getacl("gotoXHsync")));
427     }
429     /* Show main page */
430     return($smarty->fetch (get_template_path('terminalService.tpl', TRUE,dirname(__FILE__))));
431   }
433   function remove_from_parent()
434   {
435     new log("remove","terminal/".get_class($this),$this->dn,array_keys($this->attrs));
436     $this->handle_post_events("remove");
438     plugin::remove_from_parent();
439     $ldap = $this->config->get_ldap_link();
440     $ldap->cd($this->dn);
441     $ldap->modify($this->attrs);
442     show_ldap_error($ldap->get_error(),_("Could not remove terminal service."));
443   }
446   /* Save data to object */
447   function save_object()
448   {
449     plugin::save_object();
451     /* Save checkbox state */
452     if (isset ($_POST['gotoXMethod'])){
453       foreach (array("gotoLpdEnable", "gotoScannerEnable") as $val){
455         if($this->acl_is_writeable($val)){
456           if (!isset ($_POST["$val"])){
457             $this->$val= FALSE;
458           } else {
459             $this->$val= TRUE;
460           }
461         }
462       }
463     } 
465     if(isset($_POST['gotoXDriver'])){
466       if(isset($_POST['AutoSync'])){
467         $this->AutoSync = true;
468       }else{
469         $this->AutoSync = false;
470       }
471     }
473     /* Default entries can use blank hsync/vsync entries */
474     if ($this->dn != "" && $this->cn != "default" && $this->cn != "default"){
476       /* But only if no auto sync is enabled... */
477       if (!$this->AutoSync){
479         /* Check vsync for correct usage */
480         $val= preg_replace ("/\s/", "", $this->gotoXVsync);
481         if (!preg_match ("/^\d+(\.\d+)?([-]\d+(\.\d+)?)?$/", $val) && $this->acl_is_writeable("gotoXVsync")){
483           $message[]= _("Please specify a valid VSync range.");
484         } elseif ($this->acl_is_writeable("gotoXVsync")){
485           list($v1,$v2)= preg_split ("/[-+]/", $val);
486           if ($v2 != ""){
487             if ($v1 > $v2){
488               $message[]= _("Please specify a valid VSync range.");
489             }
490           }
491         }
493         /* Check hsync for correct usage */
494         $val= preg_replace ("/\s/", "", $this->gotoXHsync);
495         if (!preg_match ("/^\d+(\.\d+)?([-]\d+(\.\d+)?)?$/", $val) && $this->acl_is_writeable("gotoXHsync")){
497           $message[]= _("Please specify a valid HSync range.");
498         } elseif ($this->acl_is_writeable("gotoXHsync")){
499           list($v1,$v2)= preg_split ("/[-+]/", $val);
500           if ($v2 != ""){
501             if ($v1 > $v2){
502               $message[]= _("Please specify a valid HSync range.");
503             }
504           }
505         }
506       }
507     }
508   }
511   /* Check supplied data */
512   function check()
513   {
514     /* Call common method to give check the hook */
515     $message= plugin::check();
517     if($this->gotoXMethod != "default"){
518       $xdmcp_types =  $this->config->data['SERVERS']['TERMINAL_SESSION_TYPES'];
519       $available_servers = array();
520       foreach($xdmcp_types as $servername =>$supported_types){
521         if(in_array(strtoupper($this->gotoXMethod),$supported_types)){
522           $available_servers[]  = $servername;
523         }
524       }
525       foreach($this->selected_xdmcp_servers as $server){
526         if(!in_array($server,$available_servers)){
527           $message[] = _("Remote desktop settings contains servers that do not support the selected connection method.");
528           break;
529         }
530       }
531     }
533     return ($message);
534   }
537   /* Save to LDAP */
538   function save()
539   {
540     /* Convert to string */
541     $this->gotoLpdEnable= $this->gotoLpdEnable?"Yes":"No";
543     if($this->is_ogroup){
544       $this->objectclasses = array("gotoWorkstationTemplate");
545     }else{
546       $this->objectclasses = array("GOhard");
547     }
549     plugin::save();
551     /* Strip out 'default' values */
552     foreach(array("gotoXMethod","gotoXDriver", "gotoXResolution", "gotoXColordepth",
553           "gotoLpdServer", "gotoXKbModel", "gotoXKbLayout",
554           "gotoXKbVariant", "gotoXMouseType", "gotoXMouseport") as $val){
556       if ($this->attrs[$val] == "default"){
557         $this->attrs[$val]= array();
558       }
559     }
561     if($this->gotoXMethod == "default"){
562       $this->attrs['gotoXdmcpServer'] = array();
563       $this->attrs['gotoXMethod'] = array();
564     }else{
565       $this->attrs['gotoXdmcpServer'] = array_values($this->selected_xdmcp_servers);
566     }
569     if($this->AutoSync){
570       $this->attrs['gotoXHsync'] = "30+55";
571       $this->attrs['gotoXVsync'] = "50+70";
572     }
574     /* Write back to ldap */
575     $ldap= $this->config->get_ldap_link();
576     $ldap->cd($this->dn);
577     $this->cleanup();
578     $ldap->modify ($this->attrs); 
579     new log("modify","terminal/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
581     show_ldap_error($ldap->get_error(), sprintf(_("Saving of object system terminal/service with dn '%s' failed."),$this->dn));
582     $this->handle_post_events("modify");
583   }
586   function getListOfXDrivers()
587   {
588     $drivers = array("default" => "["._("unknown")."]");
590     /* Generate a list of xdrivers from CONFIG_DIR/xdrivers */
591     if (file_exists(CONFIG_DIR.'/xdrivers')){
592       $xdrivers = file (CONFIG_DIR.'/xdrivers');
593       foreach ($xdrivers as $line){
594         if (!preg_match ("/^#/", $line)){
595           $drivers[]= trim($line);
596         }
597       }
598     } else {
599       foreach( array(
600           "ati", "atimisc", "chips", "cirrus", "cyrix", "fbdev", "fglrx",
601           "i128", "i740", "i810", "imstt", "mga", "neomagic", "newport", "nsc",  "nv", "nvidia",
602           "r128", "radeon", "rendition", "s3", "s3virge", "savage", "siliconmotion",
603           "sis", "tdfx", "tga", "trident", "tseng", "vesa", "vga", "vmware") as $driver){
604         $drivers[] = $driver;
605       }
606     }
607     return($drivers);
608   }
611   /* Return plugin informations for acl handling */
612   static function plInfo()
613   {
614     return (array(
615           "plShortName"   => _("Service"),
616           "plDescription" => _("Terminal service"),
617           "plSelfModify"  => FALSE,
618           "plDepends"     => array(),
619           "plPriority"    => 3,
620           "plSection"     => array("administration"),
621           "plCategory"    => array("terminal"),
623           "plProvidedAcls"=> array(
624             "gotoXMonitor"            => _("Monitor"),
625             "gotoXMethod"             => _("Method"),
626             "gotoXdmcpServer"         => _("Remote desktop"),
627             "gotoXDriver"             => _("Gfx driver"),
628             "gotoXResolution"         => _("Gfx resolution"),
629             "gotoXColordepth"         => _("Gfx color depth"),
630             "gotoXHsync"              => _("Hsync"),
631             "gotoXVsync"              => _("Vsync"),
632             "AutoSync"                => _("Auto-Sync"),
633             "gotoLpdEnable"           => _("Printer service enabled"),
634             "gotoLpdServer"           => _("Spool server"),
635             "gotoScannerEnable"       => _("Scanner enabled"),
636             "gotoXKbModel"            => _("Keyboard model"),
637             "gotoXKbLayout"           => _("Keyboard layout"),
638             "gotoXKbVariant"          => _("Keyboard variant"),
639             "gotoXMouseType"          => _("Mouse type"),
640             "gotoXMouseport"          => _("Mouse port"),
641             "goFonHardware"           => _("Telephone hardware"))
642           ));
643   }
646 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
647 ?>