2020-01-18 09:38:21 +01:00
/*
* Copyright ( c ) 2018 - 2020 , Andreas Kling < kling @ serenityos . org >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
*
* 1. Redistributions of source code must retain the above copyright notice , this
* list of conditions and the following disclaimer .
*
* 2. Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY ,
* OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2020-08-10 22:28:38 +02:00
# include "HackStudio.h"
2020-09-19 17:25:05 +03:00
# include "HackStudioWidget.h"
2019-10-21 18:46:55 +02:00
# include "Project.h"
2020-01-15 20:42:54 -06:00
# include <AK/StringBuilder.h>
2020-08-12 23:23:45 +02:00
# include <LibCore/ArgsParser.h>
2020-04-25 00:01:19 +03:00
# include <LibCore/Event.h>
# include <LibCore/EventLoop.h>
2020-02-06 15:04:03 +01:00
# include <LibCore/File.h>
2020-02-06 20:33:02 +01:00
# include <LibGUI/Application.h>
# include <LibGUI/MenuBar.h>
# include <LibGUI/MessageBox.h>
# include <LibGUI/Widget.h>
# include <LibGUI/Window.h>
2020-04-25 00:01:19 +03:00
# include <LibThread/Lock.h>
# include <LibThread/Thread.h>
2020-04-06 01:03:15 +03:00
# include <LibVT/TerminalWidget.h>
2020-08-13 00:25:37 +02:00
# include <fcntl.h>
2020-06-28 13:40:10 -04:00
# include <spawn.h>
2019-10-21 18:46:55 +02:00
# include <stdio.h>
2020-08-13 00:25:37 +02:00
# include <sys/types.h>
2019-12-29 09:25:50 +11:00
# include <sys/wait.h>
2019-10-21 18:46:55 +02:00
# include <unistd.h>
2020-08-17 15:22:30 +02:00
using namespace HackStudio ;
2020-09-19 17:25:05 +03:00
static RefPtr < GUI : : Window > s_window ;
static RefPtr < HackStudioWidget > s_hack_studio_widget ;
2020-08-15 10:58:16 +03:00
2020-09-19 17:25:05 +03:00
static bool make_is_available ( ) ;
static void update_path_environment_variable ( ) ;
2019-10-27 12:55:10 +01:00
2020-09-19 17:25:05 +03:00
int main ( int argc , char * * argv )
2019-10-21 18:46:55 +02:00
{
2020-11-21 22:12:37 +03:00
if ( pledge ( " stdio tty accept rpath cpath wpath shared_buffer proc exec unix fattr thread unix sendfd " , nullptr ) < 0 ) {
2020-01-11 21:17:56 +01:00
perror ( " pledge " ) ;
return 1 ;
}
2020-07-04 14:05:19 +02:00
auto app = GUI : : Application : : construct ( argc , argv ) ;
2019-10-21 18:46:55 +02:00
2020-11-21 22:12:37 +03:00
if ( pledge ( " stdio tty accept rpath cpath wpath shared_buffer proc exec fattr thread unix sendfd " , nullptr ) < 0 ) {
2020-01-12 11:59:11 +01:00
perror ( " pledge " ) ;
return 1 ;
}
2020-09-19 17:25:05 +03:00
s_window = GUI : : Window : : construct ( ) ;
s_window - > resize ( 840 , 600 ) ;
s_window - > set_icon ( Gfx : : Bitmap : : load_from_file ( " /res/icons/16x16/app-hack-studio.png " ) ) ;
2019-11-05 21:07:39 +01:00
2020-09-19 17:25:05 +03:00
update_path_environment_variable ( ) ;
2020-01-15 20:42:54 -06:00
2019-12-29 09:25:50 +11:00
if ( ! make_is_available ( ) )
2020-09-19 17:25:05 +03:00
GUI : : MessageBox : : show ( s_window , " The 'make' command is not available. You probably want to install the binutils, gcc, and make ports from the root of the Serenity repository. " , " Error " , GUI : : MessageBox : : Type : : Error ) ;
2019-12-29 09:25:50 +11:00
2020-08-13 00:25:37 +02:00
const char * path_argument = nullptr ;
2020-08-12 23:23:45 +02:00
Core : : ArgsParser args_parser ;
2020-08-13 00:25:37 +02:00
args_parser . add_positional_argument ( path_argument , " Path to a workspace or a file " , " path " , Core : : ArgsParser : : Required : : No ) ;
2020-08-12 23:23:45 +02:00
args_parser . parse ( argc , argv ) ;
2020-08-05 16:39:55 +02:00
2020-08-13 00:25:37 +02:00
auto argument_absolute_path = Core : : File : : real_path_for ( path_argument ) ;
2019-10-28 18:48:53 +01:00
2020-12-10 18:59:03 +01:00
auto project_path = argument_absolute_path ;
if ( argument_absolute_path . is_null ( ) )
project_path = Core : : File : : real_path_for ( " . " ) ;
2020-09-27 00:11:15 +03:00
s_hack_studio_widget = s_window - > set_main_widget < HackStudioWidget > ( project_path ) ;
2020-12-10 18:59:03 +01:00
s_window - > set_title ( String : : formatted ( " {} - HackStudio " , s_hack_studio_widget - > project ( ) . name ( ) ) ) ;
auto menubar = GUI : : MenuBar : : construct ( ) ;
2020-09-19 17:25:05 +03:00
s_hack_studio_widget - > initialize_menubar ( menubar ) ;
app - > set_menubar ( menubar ) ;
2020-04-04 12:18:40 +02:00
2020-09-19 17:25:05 +03:00
s_window - > show ( ) ;
2019-10-21 22:13:20 +02:00
2020-09-19 17:25:05 +03:00
s_hack_studio_widget - > update_actions ( ) ;
2019-10-21 22:13:20 +02:00
2020-07-04 14:05:19 +02:00
return app - > exec ( ) ;
2019-10-21 18:46:55 +02:00
}
2019-10-22 22:15:43 +02:00
2020-09-19 17:25:05 +03:00
static bool make_is_available ( )
2019-10-22 22:15:43 +02:00
{
2020-09-19 17:25:05 +03:00
pid_t pid ;
const char * argv [ ] = { " make " , " --version " , nullptr } ;
posix_spawn_file_actions_t action ;
posix_spawn_file_actions_init ( & action ) ;
posix_spawn_file_actions_addopen ( & action , STDOUT_FILENO , " /dev/null " , O_WRONLY , 0 ) ;
if ( ( errno = posix_spawnp ( & pid , " make " , & action , nullptr , const_cast < char * * > ( argv ) , environ ) ) ) {
perror ( " posix_spawn " ) ;
return false ;
}
int wstatus ;
waitpid ( pid , & wstatus , 0 ) ;
posix_spawn_file_actions_destroy ( & action ) ;
return WEXITSTATUS ( wstatus ) = = 0 ;
2019-10-22 22:15:43 +02:00
}
2019-10-22 22:18:46 +02:00
2020-09-19 17:25:05 +03:00
static void update_path_environment_variable ( )
2019-10-22 22:18:46 +02:00
{
2020-09-19 17:25:05 +03:00
StringBuilder path ;
path . append ( getenv ( " PATH " ) ) ;
if ( path . length ( ) )
path . append ( " : " ) ;
path . append ( " /bin:/usr/bin:/usr/local/bin " ) ;
setenv ( " PATH " , path . to_string ( ) . characters ( ) , true ) ;
2020-03-13 15:38:21 +02:00
}
2020-09-19 17:25:05 +03:00
namespace HackStudio {
2019-10-26 21:45:29 +02:00
2020-09-19 17:25:05 +03:00
GUI : : TextEditor & current_editor ( )
{
return s_hack_studio_widget - > current_editor ( ) ;
}
2019-10-27 12:55:10 +01:00
2020-09-19 17:25:05 +03:00
void open_file ( const String & file_name )
{
return s_hack_studio_widget - > open_file ( file_name ) ;
2019-10-23 20:54:41 +02:00
}
2019-12-29 09:25:50 +11:00
2020-09-19 17:25:05 +03:00
RefPtr < EditorWrapper > current_editor_wrapper ( )
2019-12-29 09:25:50 +11:00
{
2020-09-19 17:25:05 +03:00
if ( ! s_hack_studio_widget )
return nullptr ;
return s_hack_studio_widget - > current_editor_wrapper ( ) ;
}
2020-08-13 00:25:37 +02:00
2020-09-19 17:25:05 +03:00
Project & project ( )
{
return s_hack_studio_widget - > project ( ) ;
2019-12-29 09:25:50 +11:00
}
2020-08-17 15:22:30 +02:00
2020-09-19 17:25:05 +03:00
String currently_open_file ( )
{
if ( ! s_hack_studio_widget )
return { } ;
return s_hack_studio_widget - > currently_open_file ( ) ;
2020-08-17 15:22:30 +02:00
}
2020-09-19 17:25:05 +03:00
void set_current_editor_wrapper ( RefPtr < EditorWrapper > wrapper )
2020-08-17 15:22:30 +02:00
{
2020-09-19 17:25:05 +03:00
s_hack_studio_widget - > set_current_editor_wrapper ( wrapper ) ;
}
2020-08-17 15:22:30 +02:00
}