2003-08-30 02:40:46 +02:00
/*
2004-07-30 03:35:13 +02:00
* Graphics configuration code
2003-08-30 02:40:46 +02:00
*
* Copyright 2003 Mark Westcott
2004-09-28 05:16:43 +02:00
* Copyright 2003 - 2004 Mike Hearn
2005-07-12 20:11:11 +02:00
* Copyright 2005 Raphael Junqueira
2003-08-30 02:40:46 +02:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2003-08-30 02:40:46 +02:00
*
*/
2006-01-19 11:55:01 +01:00
# define WIN32_LEAN_AND_MEAN
2003-09-06 01:08:26 +02:00
# include <stdarg.h>
2003-08-30 02:40:46 +02:00
# include <stdlib.h>
# include <stdio.h>
2006-01-19 11:55:01 +01:00
# include <windows.h>
2003-09-06 01:08:26 +02:00
# include <wine/debug.h>
2003-08-30 02:40:46 +02:00
# include "resource.h"
# include "winecfg.h"
WINE_DEFAULT_DEBUG_CHANNEL ( winecfg ) ;
2003-09-08 20:58:07 +02:00
# define RES_MAXLEN 5 /* the maximum number of characters in a screen dimension. 5 digits should be plenty, what kind of crazy person runs their screen >10,000 pixels across? */
2007-07-31 00:16:51 +02:00
# define MINDPI 96
2008-03-10 16:54:16 +01:00
# define MAXDPI 480
2007-07-31 00:16:51 +02:00
# define DEFDPI 96
2003-09-08 20:58:07 +02:00
2008-03-10 16:54:16 +01:00
static const WCHAR logpixels_reg [ ] = { ' S ' , ' y ' , ' s ' , ' t ' , ' e ' , ' m ' , ' \\ ' , ' C ' , ' u ' , ' r ' , ' r ' , ' e ' , ' n ' , ' t ' , ' C ' , ' o ' , ' n ' , ' t ' , ' r ' , ' o ' , ' l ' , ' S ' , ' e ' , ' t ' , ' \\ ' , ' H ' , ' a ' , ' r ' , ' d ' , ' w ' , ' a ' , ' r ' , ' e ' , ' ' , ' P ' , ' r ' , ' o ' , ' f ' , ' i ' , ' l ' , ' e ' , ' s ' , ' \\ ' , ' C ' , ' u ' , ' r ' , ' r ' , ' e ' , ' n ' , ' t ' , ' \\ ' , ' S ' , ' o ' , ' f ' , ' t ' , ' w ' , ' a ' , ' r ' , ' e ' , ' \\ ' , ' F ' , ' o ' , ' n ' , ' t ' , ' s ' , 0 } ;
static const WCHAR logpixels [ ] = { ' L ' , ' o ' , ' g ' , ' P ' , ' i ' , ' x ' , ' e ' , ' l ' , ' s ' , 0 } ;
2005-07-12 20:11:11 +02:00
2006-08-18 17:59:39 +02:00
static struct SHADERMODE
{
UINT displayStrID ;
const char * settingStr ;
} const D3D_VS_Modes [ ] = {
{ IDS_SHADER_MODE_HARDWARE , " hardware " } ,
{ IDS_SHADER_MODE_NONE , " none " } ,
{ 0 , 0 }
2005-07-12 20:11:11 +02:00
} ;
2004-09-28 05:55:16 +02:00
int updating_ui ;
2003-09-08 20:58:07 +02:00
2005-06-02 17:11:32 +02:00
static void update_gui_for_desktop_mode ( HWND dialog ) {
2005-10-18 12:35:41 +02:00
int desktopenabled = FALSE ;
2003-09-08 20:58:07 +02:00
2005-10-18 12:35:41 +02:00
WINE_TRACE ( " \n " ) ;
2004-09-28 05:55:16 +02:00
updating_ui = TRUE ;
2006-03-29 13:49:36 +02:00
if ( current_app )
{
disable ( IDC_ENABLE_DESKTOP ) ;
disable ( IDC_DESKTOP_WIDTH ) ;
disable ( IDC_DESKTOP_HEIGHT ) ;
disable ( IDC_DESKTOP_SIZE ) ;
disable ( IDC_DESKTOP_BY ) ;
return ;
}
enable ( IDC_ENABLE_DESKTOP ) ;
2003-09-08 20:58:07 +02:00
/* do we have desktop mode enabled? */
2005-06-23 13:42:54 +02:00
if ( reg_key_exists ( config_key , keypath ( " X11 Driver " ) , " Desktop " ) )
2004-09-28 05:55:16 +02:00
{
2005-01-14 20:48:41 +01:00
char * buf , * bufindex ;
2003-09-30 02:27:55 +02:00
CheckDlgButton ( dialog , IDC_ENABLE_DESKTOP , BST_CHECKED ) ;
2005-01-14 20:48:41 +01:00
2008-02-24 12:09:36 +01:00
buf = get_reg_key ( config_key , keypath ( " X11 Driver " ) , " Desktop " , " 800x600 " ) ;
2005-10-18 12:35:41 +02:00
/* note: this test must match the one in x11drv */
if ( buf [ 0 ] ! = ' n ' & & buf [ 0 ] ! = ' N ' & & buf [ 0 ] ! = ' F ' & & buf [ 0 ] ! = ' f '
& & buf [ 0 ] ! = ' 0 ' ) {
desktopenabled = TRUE ;
enable ( IDC_DESKTOP_WIDTH ) ;
enable ( IDC_DESKTOP_HEIGHT ) ;
enable ( IDC_DESKTOP_SIZE ) ;
enable ( IDC_DESKTOP_BY ) ;
bufindex = strchr ( buf , ' x ' ) ;
if ( bufindex ) {
* bufindex = 0 ;
+ + bufindex ;
SetWindowText ( GetDlgItem ( dialog , IDC_DESKTOP_WIDTH ) , buf ) ;
SetWindowText ( GetDlgItem ( dialog , IDC_DESKTOP_HEIGHT ) , bufindex ) ;
} else {
2006-10-05 11:11:03 +02:00
WINE_TRACE ( " Desktop registry entry is malformed \n " ) ;
2008-02-24 12:09:36 +01:00
SetWindowText ( GetDlgItem ( dialog , IDC_DESKTOP_WIDTH ) , " 800 " ) ;
SetWindowText ( GetDlgItem ( dialog , IDC_DESKTOP_HEIGHT ) , " 600 " ) ;
2005-10-18 12:35:41 +02:00
}
2005-01-14 20:48:41 +01:00
}
HeapFree ( GetProcessHeap ( ) , 0 , buf ) ;
2003-09-08 20:58:07 +02:00
}
2005-10-18 12:35:41 +02:00
if ( ! desktopenabled )
2004-09-28 05:55:16 +02:00
{
2003-09-30 02:27:55 +02:00
CheckDlgButton ( dialog , IDC_ENABLE_DESKTOP , BST_UNCHECKED ) ;
2004-09-28 05:55:16 +02:00
2003-09-30 02:27:55 +02:00
disable ( IDC_DESKTOP_WIDTH ) ;
disable ( IDC_DESKTOP_HEIGHT ) ;
disable ( IDC_DESKTOP_SIZE ) ;
disable ( IDC_DESKTOP_BY ) ;
2003-09-08 20:58:07 +02:00
2003-09-30 02:27:55 +02:00
SetWindowText ( GetDlgItem ( dialog , IDC_DESKTOP_WIDTH ) , " " ) ;
SetWindowText ( GetDlgItem ( dialog , IDC_DESKTOP_HEIGHT ) , " " ) ;
2003-09-08 20:58:07 +02:00
}
2004-09-28 05:55:16 +02:00
updating_ui = FALSE ;
2003-09-08 20:58:07 +02:00
}
2005-09-26 11:51:48 +02:00
static void init_dialog ( HWND dialog )
{
unsigned int it ;
char * buf ;
update_gui_for_desktop_mode ( dialog ) ;
updating_ui = TRUE ;
2004-09-28 06:05:55 +02:00
SendDlgItemMessage ( dialog , IDC_DESKTOP_WIDTH , EM_LIMITTEXT , RES_MAXLEN , 0 ) ;
SendDlgItemMessage ( dialog , IDC_DESKTOP_HEIGHT , EM_LIMITTEXT , RES_MAXLEN , 0 ) ;
2003-09-18 06:32:01 +02:00
2005-12-31 13:32:59 +01:00
buf = get_reg_key ( config_key , keypath ( " X11 Driver " ) , " DXGrab " , " N " ) ;
2003-09-18 06:32:01 +02:00
if ( IS_OPTION_TRUE ( * buf ) )
2004-09-28 06:05:55 +02:00
CheckDlgButton ( dialog , IDC_DX_MOUSE_GRAB , BST_CHECKED ) ;
2003-09-18 06:32:01 +02:00
else
2004-09-28 06:05:55 +02:00
CheckDlgButton ( dialog , IDC_DX_MOUSE_GRAB , BST_UNCHECKED ) ;
2004-09-28 05:55:16 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , buf ) ;
2003-09-22 23:13:51 +02:00
2005-12-22 11:15:32 +01:00
buf = get_reg_key ( config_key , keypath ( " X11 Driver " ) , " Managed " , " Y " ) ;
if ( IS_OPTION_TRUE ( * buf ) )
CheckDlgButton ( dialog , IDC_ENABLE_MANAGED , BST_CHECKED ) ;
else
CheckDlgButton ( dialog , IDC_ENABLE_MANAGED , BST_UNCHECKED ) ;
HeapFree ( GetProcessHeap ( ) , 0 , buf ) ;
2005-07-12 20:11:11 +02:00
SendDlgItemMessage ( dialog , IDC_D3D_VSHADER_MODE , CB_RESETCONTENT , 0 , 0 ) ;
2006-08-18 17:59:39 +02:00
for ( it = 0 ; 0 ! = D3D_VS_Modes [ it ] . displayStrID ; + + it ) {
SendDlgItemMessageW ( dialog , IDC_D3D_VSHADER_MODE , CB_ADDSTRING , 0 ,
( LPARAM ) load_string ( D3D_VS_Modes [ it ] . displayStrID ) ) ;
2005-07-12 20:11:11 +02:00
}
buf = get_reg_key ( config_key , keypath ( " Direct3D " ) , " VertexShaderMode " , " hardware " ) ;
2006-08-18 17:59:39 +02:00
for ( it = 0 ; NULL ! = D3D_VS_Modes [ it ] . settingStr ; + + it ) {
if ( strcmp ( buf , D3D_VS_Modes [ it ] . settingStr ) = = 0 ) {
2005-07-12 20:11:11 +02:00
SendDlgItemMessage ( dialog , IDC_D3D_VSHADER_MODE , CB_SETCURSEL , it , 0 ) ;
break ;
}
}
2006-08-18 17:59:39 +02:00
if ( NULL = = D3D_VS_Modes [ it ] . settingStr ) {
2005-07-12 20:11:11 +02:00
WINE_ERR ( " Invalid Direct3D VertexShader Mode read from registry (%s) \n " , buf ) ;
}
HeapFree ( GetProcessHeap ( ) , 0 , buf ) ;
2006-09-26 20:31:44 +02:00
buf = get_reg_key ( config_key , keypath ( " Direct3D " ) , " PixelShaderMode " , " enabled " ) ;
2005-07-12 20:11:11 +02:00
if ( ! strcmp ( buf , " enabled " ) )
CheckDlgButton ( dialog , IDC_D3D_PSHADER_MODE , BST_CHECKED ) ;
else
CheckDlgButton ( dialog , IDC_D3D_PSHADER_MODE , BST_UNCHECKED ) ;
HeapFree ( GetProcessHeap ( ) , 0 , buf ) ;
2004-09-28 05:55:16 +02:00
updating_ui = FALSE ;
2003-09-08 20:58:07 +02:00
}
2003-08-30 02:40:46 +02:00
2004-09-28 06:05:55 +02:00
static void set_from_desktop_edits ( HWND dialog ) {
char * width , * height , * new ;
2003-08-30 02:40:46 +02:00
2004-09-28 06:05:55 +02:00
if ( updating_ui ) return ;
2003-09-08 20:58:07 +02:00
WINE_TRACE ( " \n " ) ;
2003-08-30 02:40:46 +02:00
2004-11-23 14:50:23 +01:00
width = get_text ( dialog , IDC_DESKTOP_WIDTH ) ;
height = get_text ( dialog , IDC_DESKTOP_HEIGHT ) ;
2004-09-28 06:05:55 +02:00
2005-01-14 20:48:41 +01:00
if ( width = = NULL | | strcmp ( width , " " ) = = 0 ) {
2004-09-28 06:05:55 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , width ) ;
2008-02-24 12:09:36 +01:00
width = strdupA ( " 800 " ) ;
2004-09-28 06:05:55 +02:00
}
2003-09-08 20:58:07 +02:00
2005-01-14 20:48:41 +01:00
if ( height = = NULL | | strcmp ( height , " " ) = = 0 ) {
2004-09-28 06:05:55 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , height ) ;
2008-02-24 12:09:36 +01:00
height = strdupA ( " 600 " ) ;
2004-09-28 06:05:55 +02:00
}
new = HeapAlloc ( GetProcessHeap ( ) , 0 , strlen ( width ) + strlen ( height ) + 2 /* x + terminator */ ) ;
2004-09-28 05:55:16 +02:00
sprintf ( new , " %sx%s " , width , height ) ;
2005-06-23 13:42:54 +02:00
set_reg_key ( config_key , keypath ( " X11 Driver " ) , " Desktop " , new ) ;
2004-09-28 05:55:16 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , width ) ;
HeapFree ( GetProcessHeap ( ) , 0 , height ) ;
HeapFree ( GetProcessHeap ( ) , 0 , new ) ;
2003-08-30 02:40:46 +02:00
}
2005-06-02 17:11:32 +02:00
static void on_enable_desktop_clicked ( HWND dialog ) {
2003-09-08 20:58:07 +02:00
WINE_TRACE ( " \n " ) ;
2004-09-28 06:05:55 +02:00
if ( IsDlgButtonChecked ( dialog , IDC_ENABLE_DESKTOP ) = = BST_CHECKED ) {
2005-01-14 20:48:41 +01:00
set_from_desktop_edits ( dialog ) ;
2003-09-08 20:58:07 +02:00
} else {
2005-06-23 13:42:54 +02:00
set_reg_key ( config_key , keypath ( " X11 Driver " ) , " Desktop " , NULL ) ;
2003-09-08 20:58:07 +02:00
}
2004-09-28 06:05:55 +02:00
update_gui_for_desktop_mode ( dialog ) ;
2003-09-08 20:58:07 +02:00
}
2003-09-18 06:32:01 +02:00
2005-12-22 11:15:32 +01:00
static void on_enable_managed_clicked ( HWND dialog ) {
WINE_TRACE ( " \n " ) ;
if ( IsDlgButtonChecked ( dialog , IDC_ENABLE_MANAGED ) = = BST_CHECKED ) {
set_reg_key ( config_key , keypath ( " X11 Driver " ) , " Managed " , " Y " ) ;
} else {
set_reg_key ( config_key , keypath ( " X11 Driver " ) , " Managed " , " N " ) ;
}
}
2004-09-28 06:05:55 +02:00
static void on_dx_mouse_grab_clicked ( HWND dialog ) {
2005-01-14 20:48:41 +01:00
if ( IsDlgButtonChecked ( dialog , IDC_DX_MOUSE_GRAB ) = = BST_CHECKED )
2005-06-23 13:42:54 +02:00
set_reg_key ( config_key , keypath ( " X11 Driver " ) , " DXGrab " , " Y " ) ;
2003-09-18 06:32:01 +02:00
else
2005-06-23 13:42:54 +02:00
set_reg_key ( config_key , keypath ( " X11 Driver " ) , " DXGrab " , " N " ) ;
2003-09-18 06:32:01 +02:00
}
2005-07-12 20:11:11 +02:00
static void on_d3d_vshader_mode_changed ( HWND dialog ) {
int selected_mode = SendDlgItemMessage ( dialog , IDC_D3D_VSHADER_MODE , CB_GETCURSEL , 0 , 0 ) ;
2006-08-18 17:59:39 +02:00
set_reg_key ( config_key , keypath ( " Direct3D " ) , " VertexShaderMode " ,
D3D_VS_Modes [ selected_mode ] . settingStr ) ;
2005-07-12 20:11:11 +02:00
}
static void on_d3d_pshader_mode_clicked ( HWND dialog ) {
if ( IsDlgButtonChecked ( dialog , IDC_D3D_PSHADER_MODE ) = = BST_CHECKED )
set_reg_key ( config_key , keypath ( " Direct3D " ) , " PixelShaderMode " , " enabled " ) ;
else
set_reg_key ( config_key , keypath ( " Direct3D " ) , " PixelShaderMode " , " disabled " ) ;
}
2007-07-31 00:16:51 +02:00
static INT read_logpixels_reg ( void )
{
DWORD dwLogPixels ;
2008-03-10 16:54:16 +01:00
WCHAR * buf = get_reg_keyW ( HKEY_LOCAL_MACHINE , logpixels_reg , logpixels , NULL ) ;
2007-08-07 21:02:26 +02:00
dwLogPixels = buf ? * buf : DEFDPI ;
2007-07-31 00:16:51 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , buf ) ;
return dwLogPixels ;
}
static void init_dpi_editbox ( HWND hDlg )
{
HWND hDpiEditBox = GetDlgItem ( hDlg , IDC_RES_DPIEDIT ) ;
DWORD dwLogpixels ;
char szLogpixels [ MAXBUFLEN ] ;
2007-08-07 21:02:27 +02:00
updating_ui = TRUE ;
2007-07-31 00:16:51 +02:00
dwLogpixels = read_logpixels_reg ( ) ;
WINE_TRACE ( " %d \n " , ( int ) dwLogpixels ) ;
szLogpixels [ 0 ] = 0 ;
sprintf ( szLogpixels , " %d " , dwLogpixels ) ;
SendMessage ( hDpiEditBox , WM_SETTEXT , 0 , ( LPARAM ) szLogpixels ) ;
2007-08-07 21:02:27 +02:00
updating_ui = FALSE ;
2007-07-31 00:16:51 +02:00
}
static void init_trackbar ( HWND hDlg )
{
HWND hTrackBar = GetDlgItem ( hDlg , IDC_RES_TRACKBAR ) ;
DWORD dwLogpixels ;
2007-08-07 21:02:27 +02:00
updating_ui = TRUE ;
2007-07-31 00:16:51 +02:00
dwLogpixels = read_logpixels_reg ( ) ;
SendMessageW ( hTrackBar , TBM_SETRANGE , TRUE , MAKELONG ( MINDPI , MAXDPI ) ) ;
SendMessageW ( hTrackBar , TBM_SETPOS , TRUE , dwLogpixels ) ;
2007-08-07 21:02:27 +02:00
updating_ui = FALSE ;
2007-07-31 00:16:51 +02:00
}
2005-07-12 20:11:11 +02:00
2003-08-30 02:40:46 +02:00
INT_PTR CALLBACK
2005-09-26 11:51:48 +02:00
GraphDlgProc ( HWND hDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
2003-08-30 02:40:46 +02:00
{
switch ( uMsg ) {
case WM_INITDIALOG :
2007-07-31 00:16:51 +02:00
init_dpi_editbox ( hDlg ) ;
init_trackbar ( hDlg ) ;
2003-08-30 02:40:46 +02:00
break ;
2004-09-28 05:55:16 +02:00
case WM_SHOWWINDOW :
set_window_title ( hDlg ) ;
break ;
2003-08-30 02:40:46 +02:00
case WM_COMMAND :
switch ( HIWORD ( wParam ) ) {
case EN_CHANGE : {
2005-01-14 20:48:41 +01:00
if ( updating_ui ) break ;
2003-08-30 02:40:46 +02:00
SendMessage ( GetParent ( hDlg ) , PSM_CHANGED , 0 , 0 ) ;
2004-09-28 05:55:16 +02:00
if ( ( ( LOWORD ( wParam ) = = IDC_DESKTOP_WIDTH ) | | ( LOWORD ( wParam ) = = IDC_DESKTOP_HEIGHT ) ) & & ! updating_ui )
2004-09-28 06:05:55 +02:00
set_from_desktop_edits ( hDlg ) ;
2003-08-30 02:40:46 +02:00
break ;
}
2003-09-08 20:58:07 +02:00
case BN_CLICKED : {
2004-09-28 05:55:16 +02:00
if ( updating_ui ) break ;
2005-01-14 20:48:41 +01:00
SendMessage ( GetParent ( hDlg ) , PSM_CHANGED , 0 , 0 ) ;
2003-09-08 20:58:07 +02:00
switch ( LOWORD ( wParam ) ) {
2004-09-28 06:05:55 +02:00
case IDC_ENABLE_DESKTOP : on_enable_desktop_clicked ( hDlg ) ; break ;
2005-12-22 11:15:32 +01:00
case IDC_ENABLE_MANAGED : on_enable_managed_clicked ( hDlg ) ; break ;
2004-09-28 06:05:55 +02:00
case IDC_DX_MOUSE_GRAB : on_dx_mouse_grab_clicked ( hDlg ) ; break ;
2005-07-12 20:11:11 +02:00
case IDC_D3D_PSHADER_MODE : on_d3d_pshader_mode_clicked ( hDlg ) ; break ;
2004-09-28 06:05:55 +02:00
}
2003-09-08 20:58:07 +02:00
break ;
}
2003-09-22 21:26:10 +02:00
case CBN_SELCHANGE : {
2005-01-14 20:48:41 +01:00
SendMessage ( GetParent ( hDlg ) , PSM_CHANGED , 0 , 0 ) ;
2005-07-12 20:11:11 +02:00
switch ( LOWORD ( wParam ) ) {
case IDC_D3D_VSHADER_MODE : on_d3d_vshader_mode_changed ( hDlg ) ; break ;
}
2003-09-22 21:26:10 +02:00
break ;
}
2003-09-08 20:58:07 +02:00
2003-08-30 02:40:46 +02:00
default :
break ;
}
break ;
2003-09-08 20:58:07 +02:00
2003-08-30 02:40:46 +02:00
case WM_NOTIFY :
switch ( ( ( LPNMHDR ) lParam ) - > code ) {
case PSN_KILLACTIVE : {
2005-02-15 22:51:06 +01:00
SetWindowLongPtr ( hDlg , DWLP_MSGRESULT , FALSE ) ;
2003-08-30 02:40:46 +02:00
break ;
}
case PSN_APPLY : {
2004-09-28 05:55:16 +02:00
apply ( ) ;
2005-02-15 22:51:06 +01:00
SetWindowLongPtr ( hDlg , DWLP_MSGRESULT , PSNRET_NOERROR ) ;
2003-08-30 02:40:46 +02:00
break ;
}
case PSN_SETACTIVE : {
2004-09-28 06:05:55 +02:00
init_dialog ( hDlg ) ;
2003-08-30 02:40:46 +02:00
break ;
}
}
break ;
2007-07-31 00:16:51 +02:00
case WM_HSCROLL :
switch ( wParam ) {
default : {
char buf [ MAXBUFLEN ] ;
int i = SendMessageW ( GetDlgItem ( hDlg , IDC_RES_TRACKBAR ) , TBM_GETPOS , 0 , 0 ) ;
buf [ 0 ] = 0 ;
sprintf ( buf , " %d " , i ) ;
SendMessage ( GetDlgItem ( hDlg , IDC_RES_DPIEDIT ) , WM_SETTEXT , 0 , ( LPARAM ) buf ) ;
2008-03-10 16:54:16 +01:00
set_reg_key_dwordW ( HKEY_LOCAL_MACHINE , logpixels_reg , logpixels , i ) ;
2007-07-31 00:16:51 +02:00
break ;
}
}
break ;
2003-08-30 02:40:46 +02:00
default :
break ;
}
return FALSE ;
}